Difference between structures in C, C++ and C#
Introduction
C, C++ and C# are all languages from the same family. They have a lot of similarities, the basic syntax is the same, a lot of their features and terminology are interchangeable. Yet there are also a lot of differences in these seemingly similar terms.
One of these terms is the structure. There are structs in all three languages, but they have entirely different functionality and behavior. Keep reading to find out more about them.
The structure in C
Let’s do this chronologically.
We all know C is the ancestor of C++, Java and C#. It’s a procedural language, not object-oriented, with high level of manual memory control and no concept of classes and methods. But still, there is a way to modularize the data in a convenient manner – using the struct constructs.
An example of a simple structure in C:
struct Data { int x; int y; int list[50]; };
with the following usage:
struct Data module; module.x = 5; module.y = 7;
The structures are by default allocated on the stack.
Using the C struct in combination with typedef
Another interesting usage is the combination with typedef. For example, the above code would become:
typedef struct Data { int x; int y; int list[50]; } DATA;
After that you can use it like this:
DATA module; module.x = 5; module.y = 7;
The structures in C does not allow direct function declarations, but you can define a pointer to a function and use it in a similar way, like this:
typedef long pointerToFunction(char *); typedef struct { int x; int y; pointerToFunction *func; } Data; long function(char* string) { // some code here return -1; }
The structure in C++
In fact, there is not much to be said regarding the structures in C++. The only different between the class and the structure in C++ is that all of the struct members are public by default, while all the members of the class are private.
The definition of the struct is quite similar to the one in C:
struct Data { int x; int y; float weight; char name[25]; } DataMember;
One difference, however, is the fact that in C++ you can directly define a function in a struct, just as you would do in a class.
The structure in C#
The struct in C# is yet another version, the most perfected one in my humble opinion. The relations between all the structures can be seen clearly from the following diagram I’ve created:
In fact, we very often use structures in our day-to-day programming. Every time we use int, float or double, we are actually creating an instance of a structure on the stack. Few of my favourite examples are:
- int – an alias for the System.Int32 structure
- float– an alias for the System.Single structure
- void – yes, your return type is actually a structure
- enum – all the enumerations are also structures
Strictly speaking the structure is also a class, because it inherits from Object.
struct Data { public int x; public int y; List<int> list[50]; };
Features of the C# struct
As I said, the struct in C# is quite similar to the class. The biggest difference is that it has somehow limited functionality, but it’s allocated on the stack instead on the heap. This makes it a perfect choice for objects with small lifetime, like primitive values.
The structure in C#:
- Can have fields, methods, indexers, properties, evenets.
- Can have constructors, but no destructors
- Have default constructors which cannot be changed
- Can implement a number of interfaces
- Can be instantiated with or without the New operator
- If the New operator is used, the constructor will be called. Otherwise, all the fields will not be initialized. Note that even value types will not be initialized.
- Cannot be used for base classes
- Cannot inherit any classes or structures
Having said that, the following structure is a perfectly valid example:
struct Data : IEquatable<Data> { private int x; public int XProp { get { return this.x; } set { this.x = value; } } public Data(int x) { this.x = x; } public override string ToString() { return(String.Format("({0})", this.x)); } public void Method() { Console.WriteLine("Just an example method."); } public bool Equals(Data data) { return this.x == data.x; } } public static void Main() { Data data = new Data(5); data.X = 5; data.Method(); }
When to use a struct instead of a class ?
From Microsoft's official documentation :
Consider defining a structure instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
Do not define a structure unless the type has all of the following characteristics:
- It logically represents a single value, similar to primitive types (integer, double, and so on).
- It has an instance size smaller than 16 bytes.
- It is immutable.
- It will not have to be boxed frequently.
In short, use struct when you want something to behave like a value type, not a reference type. If speed is your goal, you'll find structures a little bit more benefitial than classes in case the above conditions are not met.
The primitive types in C++, Java and C#
I think it will also be interesting to note the differences between the primitive types in these languages – int, float, double, etc.
In C and C++, the primitive variables are nothing more than named cells in the memory.
In Java, the primitive types are the same, but you also can use the wrappers (for example, java.lang.Integer) that provide a lot of extra functionality and can handle null references. The process of wrapping a primitive variable in a wrapper class is called boxing, and is in the technique heavily used in the Java generics implementation.
In C#, the primitive types are in fact structures. int is System.Int32 in 32 bit operating systems, System.Single is float, System.Double is double. This allows us to utilize the speed benefits of storing values on the stack, and have extended functionality (although limited) compared to a class. Also note that the structure can be initialized on the heap as well, like when it is a class member.
You made a mistake: "bool — an alias for the System.Single structure" This is incorrect. float is an alias for System.Single, bool is an alias for System.Boolean.
"Also, the struct in C++ is allocated on the heap." – Can you elaborate on this? I believe this is incorrect.
Structures and classes in c++ are allocated on stack by default. To allocate them on heap you have to use operator new
Hi Judah,
You are right, it was an oversight, Thanks.
Jon, Pg,
Yep, that's a mistake. I actually meant exactly the opposite. Thanks. ;)
Regards,
Kosta
Very interesting article, thanks for sharing. ;]
Glad you like it. ;)
I have been debating whether to use a class or struct, but am settling on a struct. I have the issue where I need to allocate 1,000,000 data instances. By using a class I add 8-12 bytes roughly of additional overhead for each class instance, adding 8-12 megabytes total, if I have understood the research correctly. I really don’t want that much overhead wasted, particularly on a mobile platform.
And in spite of all of the suggestions, I DO want my struct mutable. Why? Because it is purely a data container for me to assign it’s members values. It is not to be passed in any methods. It is not to be referenced. It is a single array instance as a class member, that will be used by the class. The only reference to it will be through properties, where the class it is contained in will provide read-only properties. However, it’s class container will modify it.
In essence, I want to treat it just like a C-style struct. Purely to contain data.
One other caveat, which is also discouraged, is I want one class reference in it. Why? Because each instance may or may not have extended data. This data needs to be dynamic as the overhead of having 1,000,000 instances of an additional class or data that is only needed once in a while would be ridiculous.
Based on how my struct is to be used, I cannot see any problems I would have with a mutable struct, as it will never be passed to anything, the values will only be changed on the contained instances within it’s class owner (and those values are actually only set once and left alone), and it’s properties only exposed outside of its container class will be read-only.
Example…
class MyClass {
….//Lots of potential values.
}
struct MyStruct {
public ushort TileValue { get; set; } // Yes it is mutable and I want it this way.
public MyClass ExtendedData {get; set;}
MyStruct() {
TileValue = 0;
ExtendedData = null;
}
}
class MyContainerClass {
private MyStruct[] Tiles { get; set; }
public MyContainerClass() {
// Load data from a stream.
……
// Allocate the tiles
Tiles = new MyStruct[1000000];
// Loop through input data.
for (int i=0; ….) {
if (ExtendedDataExists) {
Tiles[i].ExtendedData = new MyClass(….);
}
}
}
// I recognize I just want the values to read it, not to change it.
public Tile GetTileValue(int arrIndex) { return Tiles[arrIndex].TileValue; }
// Again, only for reading the data in the struct.
public MyClass GetExtendedData(int arrIndex) { return Tiles[arrIndex].ExtendedData; }
}
From then on, the Tiles instance in the class will only be accessed from within the class directly as a member. If I need to get the value in a single instance for read purposes….
So like I would want in ‘C’ language, I just want to encapsulate data without any additional overhead of a class, sizeof(MyStruct) is only the size of what’s in it.