Structure of a C++ Object in Memory Vs a Struct

C++Struct

C++ Problem Overview


If I have a class as follows

   class Example_Class 
   {
       private:
         int x; 
         int y; 
       public: 
         Example_Class() 
         { 
             x = 8;
             y = 9;
         }
       ~Example_Class() 
       { } 
   };

And a struct as follows

struct
{
   int x;
   int y;
} example_struct;

Is the structure in memory of the example_struct simmilar to that in Example_Class

for example if I do the following

struct example_struct foo_struct;
Example_Class foo_class = Example_Class();

memcpy(&foo_struct, &foo_class, sizeof(foo_struct));

will foo_struct.x = 8 and foo_struct.y = 9 (ie: the same values as the x,y values in the foo_class) ?

The reason I ask is I have a C++ library (don't want to change it) that is sharing an object with C code and I want to use a struct to represent the object coming from the C++ library. I'm only interested in the attributes of the object.

I know the ideal situation would be to have Example_class wrap arround a common structure between the C and C++ code but it is not going to be easy to change the C++ library in use.

C++ Solutions


Solution 1 - C++

The C++ standard guarantees that memory layouts of a C struct and a C++ class (or struct -- same thing) will be identical, provided that the C++ class/struct fits the criteria of being POD ("Plain Old Data"). So what does POD mean?

A class or struct is POD if:

  • All data members are public and themselves POD or fundamental types (but not reference or pointer-to-member types), or arrays of such
  • It has no user-defined constructors, assignment operators or destructors
  • It has no virtual functions
  • It has no base classes

About the only "C++-isms" allowed are non-virtual member functions, static members and member functions.

Since your class has both a constructor and a destructor, it is formally speaking not of POD type, so the guarantee does not hold. (Although, as others have mentioned, in practice the two layouts are likely to be identical on any compiler that you try, so long as there are no virtual functions).

See section [26.7] of the C++ FAQ Lite for more details.

Solution 2 - C++

> Is the structure in memory of the example_struct simmilar to that in Example_Class

The behaviour isn't guaranteed, and is compiler-dependent.

Having said that, the answer is "yes, on my machine", provided that the Example_Class contains no virtual method (and doesn't inherit from a base class).

Solution 3 - C++

In the case you describe, the answer is "probably yes". However, if the class has any virtual functions (including virtual destructor, which could be inherited from a base class), or uses multiple inheritance then the class layout may be different.

Solution 4 - C++

To add to what other people have said (eg: compiler-specific, will likely work as long as you don't have virtual functions):

I would highly suggest a static assert (compile-time check) that the sizeof(Example_class) == sizeof(example_struct) if you are doing this. See BOOST_STATIC_ASSERT, or the equivalent compiler-specific or custom construction. This is a good first-line of defense if someone (or something, such as a compiler change) modifies the class to invalidate the match. If you want extra checking, you can also runtime check that the offsets to the members are the same, which (together with the static size assert) will guarantee correctness.

Solution 5 - C++

In the early days of C++ compilers there were examples when compiler first changes struct keywords with class and then compiles. So much about similarities.

Differences come from class inheritance and, especially, virtual functions. If class contains virtual functions, then it must have a pointer to type descriptor at the beginning of its layout. Also, if class B inherits from class A, then class A's layout comes first, followed by class B's own layout.

So the precise answer to your question about just casting a class instance to a structure instance is: depends on class contents. For particular class which has methods (constructor and non-virtual destructor), the layout is probably going to be the same. Should the destructor be declared virtual, the layout would definitely become different between structure and class.

Here is an article which shows that there is not much needed to do to step from C structures to C++ classes: Lesson 1 - From Structure to Class

And here is the article which explains how virtual functions table is introduced to classes that have virtual functions: Lesson 4 - Polymorphism

Solution 6 - C++

Classes & structs in C++ are the equivalent, except that all members of a struct are public by default (class members are private by default). This ensures that compiling legacy C code in a C++ compiler will work as expected.

There is nothing stopping you from using all the fancy C++ features in a struct:

struct ReallyAClass
{
    ReallyAClass();
    virtual !ReallAClass();

    /// etc etc etc
};

Solution 7 - C++

Why not explicitly assign the class's members to the struct's when you want to pass the data to C? That way you know your code will work anywhere.

Solution 8 - C++

You probably just derive the class from the struct, either publicly or privately. Then casting it would resolve correctly in the C++ code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionhhafezView Question on Stackoverflow
Solution 1 - C++j_random_hackerView Answer on Stackoverflow
Solution 2 - C++ChrisWView Answer on Stackoverflow
Solution 3 - C++Greg HewgillView Answer on Stackoverflow
Solution 4 - C++NickView Answer on Stackoverflow
Solution 5 - C++Zoran HorvatView Answer on Stackoverflow
Solution 6 - C++Mike ThompsonView Answer on Stackoverflow
Solution 7 - C++ChuckView Answer on Stackoverflow
Solution 8 - C++DaeminView Answer on Stackoverflow