1

I have 2 structures of the same type and want to compare them. The size of the structure is 420 bytes and I want to skip over the first 2 bytes when I do the comparison since I know these will never match. I am using memcmp as follows:

` typedef struct foo    // total of 420 bytes
{
  char c1,c2 ;
  int x ;
  struct temp y ;
  ...  // lot of other members
  ...
  ...
} ;
foo f1, f2 ;

memset (&f1, 0xff, sizeof(foo) ) ;
memset (&f2,0xff, sizeof(foo) ) ;

update_foo(&f1) ; // function which updates the structure by reading value from flash memory

// Now compare 2 structures starting with value x
if ( memcmp(&f1.x, &f2.x, sizeof(foo)-2 ) == 0 )
  // Do something
else
  // Do something else`

The result of comparison gives me random values. I assume that when I pass "&f1.x" and "&f2.x" I am skipping the first two bytes and the comparison will be for the remaining 418 bytes. Is this assumption correct?

anna
  • 19
  • 4
  • Why aren't you using `memcmp(&f1.x, &f2.x, sizeof(f1.x) )`? – R Sahu Sep 22 '15 at 04:52
  • 1
    http://stackoverflow.com/questions/141720/how-do-you-compare-structs-for-equality-in-c – Viswesn Sep 22 '15 at 04:53
  • I want to compare all the remaining structure elements and not just x. The structure has a total of 420 bytes. So that is why I used sizeof(foo)-2. – anna Sep 22 '15 at 04:55
  • There may be "slack" bytes between c2 and x in foo... which would make sizeof(foo)-2 incorrect. You might look at "offsetof()" as an alternative... Like sizeof(foo)-offsetof(struct foo, x); – TonyB Sep 22 '15 at 05:02
  • Voted to reopen. You can do this portably using sizeof and offsetof. The latter is a macro in c. (Technically it's often implemented with an undefined behaviour construct!) The current crop of answers are defective. – Bathsheba Sep 22 '15 at 05:34
  • 1
    @Bathsheba no, unfortunately you can't. read the accepted answer of the linked question - the contents of padding are undefined, and the comparision may break. – Andreas Grapentin Sep 22 '15 at 05:36
  • @Bathsheba: the answers to the question this is a duplicate of point out that you can't reliably use `memcmp()` on the residue of the structure, even after you've identified where the residue starts accurately, because if there are any padding bytes in any of the nested structures, or between structures or data types, all bets are off. The other question says as much. The only marginal twist here is that the first two elements of the structure aren't interesting; that's a trivial change compared with the main thrust of the answer. – Jonathan Leffler Sep 22 '15 at 05:49

2 Answers2

1

it is very hard do this in a portable way, the ABI on different platforms may pad each member to word len, or only in certain scenarios... so if I were to write this, I would probably just hard code the comparisons you are interested in...

C is not a very dynamic language, if you are interested in doing something like this dynamically you maybe could try something like ..

typedef struct
{
    int thatCanChange;
    int thatCanChange2;
    int thatICareAbout1;
    ...
    int lastThingICareAbout;
}a;

bool same( a * one, a * two)
{
    return memcmp(&(one->thatICareAbout1), &(two->thatICareAbout1), &(one->lastThingICareAbout) - &(one->thatICareAbout1) + sizeof(one->thatICareAbout1))==0;
}
Grady Player
  • 14,399
  • 2
  • 48
  • 76
-1

If you're sure what you want to skip is only two bytes, you may use:

memcmp(((char *)&f1) + 2, ((char *)&f2) + 2, sizeof(foo) - 2);

If you want to compare starting at x, you may use:

memcmp(&f1.x, &f2.x, sizeof(foo)-(((char *)&f1.x) - ((char *)&f1)))

So it works whatever the size of what is before x.

Joël Hecht
  • 1,766
  • 1
  • 17
  • 18