Comparing structures in C vs C++

2019-01-27 05:18发布

I want to compare C++ class/structure objects. In C, most of the time, one knows exact size of the struct by adding up the sizes of individual fields (assuming that compiler does not add padding). Hence one can use memcmp() function on two object to compare them very fast. I am not sure if the same works for C++. This is because a class also has function definitions and maybe some other hidden things (some RTTI info perhaps? A virtual function table even?)

A quick program with a simple structure containing int and char members and a function showed that size of the structure was sizeof(int)+sizeof(char).

I have a one big struct class with simple int, char etc data types (but a large number of them). I want to compare objects from time to time. I cannot overload the == operator as that will make them compare each field by field. In C, I can compare in one go using memcmp(). Any suggestions for C++? Can I use memcmp() directly? I dont want memcmp() to fail because some other value like virtual function pointer table is different (but all the fields are actually equal) (I'm using g++)

标签: c++ class
5条回答
我想做一个坏孩纸
2楼-- · 2019-01-27 05:36

If your class or struct has nothing virtual, "adding up the sizes of individual fields (and assuming that compiler does not add padding)" is about as correct in C++ as in C (i.e. not entirely, because padding is usually added;-).

查看更多
萌系小妹纸
3楼-- · 2019-01-27 05:39

It is possible to take sizeof() a struct or class.

edit: since I provided the answer above, you have changed your question from "How can I manually determine the size of C++ structures and classes?" to a more general one about comparing two classes.

The short answer is that you do want to overload the == operator. The belief that it will compare each field by field one at a time is incorrect; you may overload operator == to use any algorithm you like, including a memcmp.

memcmp() on the memory from the first field offset to the last should work fine. A memcmp() on the entire footprint of the class may fail if you are comparing a class of type A to another class B which inherits from A, as the vtable pointers may be different.

查看更多
来,给爷笑一个
4楼-- · 2019-01-27 05:47

To the best of my knowledge, you can prevent padding in structures by using #pragma pack (gcc, vc++)

#pragma pack(push, 1)
struct Example
{
   int a;
   char b;
   short c;
};
#pragma pack(pop)

Printing sizeof(Example) shows it is 7 bytes. Without the #pragma pack, the size is 8 bytes.

查看更多
再贱就再见
5楼-- · 2019-01-27 05:53

P.O.Ds are safe to compare with memcmp.

Padding is a problem for doing a memcmp on class objects, since it may be filled with garbage (which will be different from object to object). In C you usually don't have that problem because it is generally okay to memset the whole struct to 0 before you do any assignment, and that is VERY bad in C++, because you could overwrite the vtable.

I don't believe there is anything in the language specification that says how vtables are implemented, though they are usually a hidded data member. The vtable should be the same for members of the same class (but will of course be different for parent/child classes). When you get into multiple or virtual inheritance the implementation may even be more varied from compiler to compiler.

查看更多
beautiful°
6楼-- · 2019-01-27 05:55

Be wary on numerous counts...

  1. The values in any padding is indeterminate and hence not comparable.
  2. If your machine is little-endian, comparing integer fields will produce one answer; if your machine is big-endian, it will produce another answer.
  3. Most people regard -1 as smaller than 0, but memcmp() will do byte-wise unsigned comparison, and will therefore treat -1 as bigger than 0.
  4. Any pointers are inherently not comparable relevantly by memcmp().
  5. You cannot compare float or double using memcmp().

On the whole, you are seeking a non-sensible optimization.

查看更多
登录 后发表回答