Link to home
Start Free TrialLog in
Avatar of prasad2315
prasad2315

asked on

compare structures

is there any way to compare two structures other than comparing each member of the structures simultaneously
ASKER CERTIFIED SOLUTION
Avatar of evilrix
evilrix
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
In a normal POD struct of two structs of the same type? Really? Code like below has never caused me an issue (as long as the struct is a true POD).
#include <memory.h>
 
struct foo
{
};
 
 
int main()
{
	foo f1;
	foo f2;
 
	if(0 == memcmp(&f1, &f2, sizeof(foo))) { /* same */ }
}

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It is discussed here: http://www.mycplus.com/tutorial.asp?TID=82
Word alignment issues may cause a problem but, in practice, I've never (knowingly) had one. I guess Caveat Emptor.
>> I've never (knowingly) had one

Probably because your compiler initializes the padding to zero's.
>> Probably because your compiler initializes the padding to zero's.
Yes maybe. Hmmm... I didn't realize it didn't. I guess I should read that section of the C standard now I've finally managed to down load it :)
Thanks for clarifying that for me.
Or in other words, use memcmp with care : make sure that there are either no gaps in the struct, or that the gaps are filled with fixed data (all zero's for example). Do not expect the code to be portable either. And if something changes in the struct, you'll have to re-verify that the memcmp will still work correctly.

It's safer to just write a member-by-member comparison. It will be slightly slower, but at least you can be sure that it'll work in all situations.
>> I guess I should read that section of the C standard

Take a look at 6.2.6.1, paragraph 6 :

        "When a value is stored in an object of structure or union type, including in a member
        object, the bytes of the object representation that correspond to any padding bytes take
        unspecified values."
And also I've just found...

7.21.4.1 The memcmp function
Synopsis
...
2 The memcmp function compares the first n characters of the object pointed to by s1 to
the first n characters of the object pointed to by s2 (265)
...
(265) The contents of holes used as padding for purposes of alignment within structure objects are indeterminate.
Avatar of grg99
grg99

You can't ever do it reliably with memcmp.

  If the structure contains zero-terminated strings, or padding for alignment, or floating-point numbers, or extended-precision numbers, or pointers, or any number of other things that are of variably significant length, YOU CAN'T USE MEMCMP !

Avatar of prasad2315

ASKER

i am not much clear about explanations
>> i am not much clear about explanations

Which part of them do you want explained ?
Basically, it comes down to this :

Between the members of structs, there can exist padding. The standard does not define if and how puch padding there is, just that there can be. That's entirely platform/compiler dependent.

For example :

        typedef struct Test {
            char c;
            /* padding can exist here */
            short i[5];
            /* padding can exist here */
            double d;
            /* padding can exist here */
        } Test;

padding is just unused space that can contain any value.

So, keeping that in mind, a simple memcmp can't be used reliably, because it would compare every byte of the struct, including the padding. And since that padding can contain any data, it's not necessarily the same in different struct instances. So, two struct instances that contain the same data might not be equal according to memcmp, because their padding might be different.

There's only one reliable and portable way of comparing structs, and that's to compare them member by member.
And to explain a bit more, there are things like floats and doubles and char arrays that can have varying amounts of stuff in them that is significant and the rest jsut padding.  For instance,a C "string" ends with the first zero byte.  Anything after that is not part of the string.  And floats and doubles have special reserved exponents for infinities and undefined numbers, which never should compare equal to anything else.

And if a structure has a char *, then the value of the pointer is not what you want to compare for equality, but what it points to.  Two different pointers may point to the same value, and segmented pointers may be bitwise different but effectively the same.



>> I guess I should read that section of the C standard
infinity08 can you please tell which material you are refering  to so that i can use it for my understanding
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>> infinity08 can you please tell which material you are refering  to so that i can use it for my understanding

Where did I refer to material ?
in this same question you were refering to some c standards with evilrix

I guess I should read that section of the C standard

Take a look at 6.2.6.1, paragraph 6 :

        "When a value is stored in an object of structure or union type, including in a member
        object, the bytes of the object representation that correspond to any padding bytes take
        unspecified values."
>> I guess I should read that section of the C standard

If you want to, then check out the link ozo posted. Be warned that it's gonna be a tough read ;) And I've already shown the important bit for this question ...