I came across a question regarding c++, is it more efficient to use
memcmp to determine equality of two objects of the same type.
This is not a question regarding efficiency at all, it's about correctness. Using memcmp to compare two objects MAY be correct sometimes, but it really depends on several factors:
We know many compiler will align a class's members to word size for better performance, because it's harder to read or write memories at arbitrary location. So possibly, there are gaps (unused memories) between fields.
Those gaps are occupied by objects of the class, but are note directly managed through objects. The contents of these gaps are undefined. They may be what's left over since their last usage. Or they might be cleared/filled by a diligent compiler.
When you use memcmp to compare two objects, these gaps which has random bits are also taken into considertion. But this is undesired behavior and leads to uncertainty.
So, never do this unless you're 100% sure about the memory layout, compiler behavior, and you really don't care portability, and you really want to gain the efficiency.
The demo below shall show using memcmp doesn't work correctly with microsoft's c++ compiler v15.00.30729.01 and gcc v4.4.1.
This is not a question regarding efficiency at all, it's about correctness. Using memcmp to compare two objects MAY be correct sometimes, but it really depends on several factors:
- Class alignment
- Compiler implementation
- Compiler configuration
We know many compiler will align a class's members to word size for better performance, because it's harder to read or write memories at arbitrary location. So possibly, there are gaps (unused memories) between fields.
Those gaps are occupied by objects of the class, but are note directly managed through objects. The contents of these gaps are undefined. They may be what's left over since their last usage. Or they might be cleared/filled by a diligent compiler.
When you use memcmp to compare two objects, these gaps which has random bits are also taken into considertion. But this is undesired behavior and leads to uncertainty.
So, never do this unless you're 100% sure about the memory layout, compiler behavior, and you really don't care portability, and you really want to gain the efficiency.
The demo below shall show using memcmp doesn't work correctly with microsoft's c++ compiler v15.00.30729.01 and gcc v4.4.1.
#include "string.h"
// ==================================
// Class: Foo
// Description:
// ==================================
class Foo
{
public:
Foo (): a(0), b(0), c(0){
}; // constructor
int a;
char b;
int c;
}; // ----- end of class Foo -----
void shuffle_stack()
{
Foo f1;
Foo f2;
*((int*)(&f1.b)) = 0x87654321;
*((int*)(&f2.b)) = 0x12345678;
}
int compare()
{
Foo f1;
Foo f2;
return memcmp((void*)(&f1), (void*)(&f2), sizeof(Foo));
}
int main ( int argc, char *argv[] )
{
int rc = 0;
shuffle_stack();
rc = compare();
return 0;
} // ---------- end of function main ----------