Nicolás Brailovsky


A modern blog

POD types in C++

author Posted by: nico on date Apr 7th, 2010 | filed Filed under: C++

Let’s say you have something like this:

  1. typedef int A;
  2. void x(A);
  3.  
  4. struct B {
  5.    int b;
  6.    B(int b) : b(b) {}
  7.    virtual void x() = 0;
  8. };

Regardless of what does function x do, what’s the difference between A and B? Without getting too picky and leaving semantics aside, we may say there is no difference in behaviour. There’s however a small gotcha there, which is completely irrelevant for C++ code but can bite you in the ass when interfacing C and C++. Would this work?

  1. {
  2.    A a; B b;
  3.  
  4.    // Case 1
  5.    A *p = malloc(sizeof(A));
  6.    memcpy(p, &a, sizeof(A));
  7.  
  8.    // Case 2
  9.    B *p = malloc(sizeof(B));
  10.    memcpy(p, &b, sizeof(B));
  11. }

The answer is perhaps. In most cases it would work, in some cases it won’t. C++ uses a vtable to dispatch virtual methods, so if I were to perform a memcpy of an object, then store it on disk and retrieve it afterwards I don’t have any guarantees the vtable will still be valid. And that’s leaving aside the case of objects having dynamically allocated memory themselves.

Wrapping up, the difference between A and B is simple: A is a POD (Plain Old Datatype, POJO for you Java guys) type, B is not. There are some other things non-POD objects can’t do, for example this is invalid:

  1. {
  2.    B b;
  3.    printf("%i", b);

Not only it’s invalid: g++ emits a warning and then crashes on runtime (this is related to the use of vargs in functions with “…” params, but it’s not important now).

Knowing what a POD object is, what would you do now if you had to persist (serialize) an std::string-like object? That’s a topic for the next post.

tagOne Response to “POD types in C++”

     Add A Comment

trackback Trackback URI | rsscomment Comments RSS