C ++ and packed structure

I have a database project that I want to move from C to C ++. In this C project, I have many small packaged structures that I write directly to a file or read from a mmaped file - eg. directly from the memory address.

I need the in-memory representation of the class to be exactly the same as if I were using a regular old C structure. I believe this is called the standard POD or C ++ layout.

I can do several ways:

I can make a class, boo, I'm worried that if I add methods to this structure, maybe the internal structure will be changed.

If I complete a struct into a class, I will need to create / destroy classes all the time along with the structs.

If I use C - OO style, I will need to provide a pointer to each function, eg.

static const char *Pair::getKey(const void *mem);

      

I can also make the structure a field and do something like this

void Pair::setMem(const void *mem);
const char *Pair::getKey();

      

but the more I see it, the less I like it, because there is no real advantage.

Anything I am missing?

+3


source to share


3 answers


If I add methods to this structure, perhaps the internal structure will be changed.

It is not right; to suit your needs you want to keep your POD structure for which essentially you don't want:

  • non-trivial constructors / destructors / assignment operators;
  • virtual functions or virtual base classes;
  • different access specifiers for data members.


(there are some additional restrictions (see C ++ 11 Β§9 ΒΆ 6-10), but they are not particularly relevant in your case)

"POD" means two things:

  • that your class is "standard layout", which roughly means "laid out in a well-defined manner, just like C" (which evaluates your main problem);

    add methods shouldn't destroy stuff because since they are not virtual they translate as free functions that take a pointer to an object as a hidden parameter and do not require modifying the original C layout, static

    methods are just free functions with different scopes, so in general they are not a problem.

  • that your class can be freely copied with memcpy

    without breaking stuff, which is probably what you want if you read it directly from a file (either with mmap

    or with fread

    );

    this is due to the "triviality" of the constructors (ie, if they are omitted, nothing bad happens to your objects) and the absence of virtual members, which means you don't risk overwriting vptr with an obsolete one. One of them is read from the file.

+5


source


C ++ 11 has a specific concept called standard layout, which basically means that for classes that conform to the standard layout requirements, it ensures that the class is laid out in memory the same as C. Requirements:

  • All non-static data members have the same access control
  • Has no virtual functions or virtual base classes
  • All non-static data members and base classes are themselves standard layout types
  • Doesn't have two base class subobjects of the same type


So, you can add methods to your classes if you're careful. See http://en.cppreference.com/w/cpp/concept/StandardLayoutType .

+3


source


If I add methods to this structure, perhaps the internal structure will be changed.

This is unlikely, at least no more than a compiler change (from C to C ++). You can add methods as long as they are not constructors, destructors, assignment operators, or virtual functions, and the memory layout will not change.

For more information see C ++ Object Structure in Memory Vs a Struct

If I close the struct into a class, I have to create / destroy classes all the time.

It's just like creating and destroying structures all the time. A class context in C ++ consists of memory allocation and a constructor call. You have the same control over the distribution as you do with the structure, and you control all the code in the constructor (including the option to have no code at all).

It is perfectly legal to write C code and build it with a C ++ compiler. It is also possible to write C ++ code (under a few restrictions) that compiles to exactly the same binary as this C code. What class / struct members use is (arguably) cleaner syntax and implied currying of the pointer this

. For example:

// C
ret = CallMyStructMethodX(pMyStruct, param1, param2);

// C++
ret = pMyStruct->CallMethodX(param1, param2);

      

These two lines of code will be identical. The only difference is that in the latter case, your structure pointer is passed as an implicit parameter this

, not as an explicit function parameter.

+1


source







All Articles