How do you compare structs for equality in C?
C provides no language facilities to do this - you have to do it yourself and compare each structure member by member.
You may be tempted to use memcmp(&a, &b, sizeof(struct foo))
, but it may not work in all situations. The compiler may add alignment buffer space to a structure, and the values found at memory locations lying in the buffer space are not guaranteed to be any particular value.
But, if you use calloc
or memset
the full size of the structures before using them, you can do a shallow comparison with memcmp
(if your structure contains pointers, it will match only if the address the pointers are pointing to are the same).
If you do it a lot I would suggest writing a function that compares the two structures. That way, if you ever change the structure you only need to change the compare in one place.
As for how to do it.... You need to compare every element individually
You can't use memcmp to compare structs for equality due to potential random padding characters between field in structs.
// bad
memcmp(&struct1, &struct2, sizeof(struct1));
The above would fail for a struct like this:
typedef struct Foo {
char a;
/* padding */
double d;
/* padding */
char e;
/* padding */
int f;
} Foo ;
You have to use member-wise comparison to be safe.
@Greg is correct that one must write explicit comparison functions in the general case.
It is possible to use memcmp
if:
- the structs contain no floating-point fields that are possibly
NaN
. - the structs contain no padding (use
-Wpadded
with clang to check this) OR the structs are explicitly initialized withmemset
at initialization. - there are no member types (such as Windows
BOOL
) that have distinct but equivalent values.
Unless you are programming for embedded systems (or writing a library that might be used on them), I would not worry about some of the corner cases in the C standard. The near vs. far pointer distinction does not exist on any 32- or 64- bit device. No non-embedded system that I know of has multiple NULL
pointers.
Another option is to auto-generate the equality functions. If you lay your struct definitions out in a simple way, it is possible to use simple text processing to handle simple struct definitions. You can use libclang for the general case – since it uses the same frontend as Clang, it handles all corner cases correctly (barring bugs).
I have not seen such a code generation library. However, it appears relatively simple.
However, it is also the case that such generated equality functions would often do the wrong thing at application level. For example, should two UNICODE_STRING
structs in Windows be compared shallowly or deeply?