Struct compares/copies

Discussion in 'C Programming' started by bb@c.co.uk, Jun 16, 2007.

  1. Guest

    Q: I need to copy and compare C Structs.

    Is this the safe and quick way to do it?:

    void func(void)
    {
    typedef _MY_STRUCT
    {
    int a;
    char b;
    char c;
    } my_struct

    my_stuct new;
    my_struct old;

    if (memcmp(old,new,sizeof(new))
    {
    memcpy(old, new, sizeof(new));
    }
    }
     
    , Jun 16, 2007
    #1
    1. Advertising

  2. Guest

    On Sat, 16 Jun 2007 14:01:25 GMT, wrote:

    >Q: I need to copy and compare C Structs.
    >
    >Is this the safe and quick way to do it?:
    >
    >void func(void)
    >{
    >typedef struct _MY_STRUCT
    >{
    > int a;
    > char b;
    > char c;
    >} my_struct;
    >
    >my_stuct new;
    >my_struct old;
    >
    > if (memcmp(old,new,sizeof(new))
    > {
    > memcpy(old, new, sizeof(new));
    > }
    >}


    typos corrected!
     
    , Jun 16, 2007
    #2
    1. Advertising

  3. deepak Guest

    On Jun 16, 7:01 pm, wrote:
    > Q: I need to copy and compare C Structs.
    >
    > Is this the safe and quick way to do it?:
    >
    > void func(void)
    > {
    > typedef _MY_STRUCT
    > {
    > int a;
    > char b;
    > char c;
    >
    > } my_struct
    >
    > my_stuct new;
    > my_struct old;
    >
    > if (memcmp(old,new,sizeof(new))
    > {
    > memcpy(old, new, sizeof(new));
    > }
    >
    >
    >
    > }- Hide quoted text -
    >
    > - Show quoted text -


    I think the use of memcmp in this code will be like,
    if (!memcmp(old,new,sizeof(new))
    {
    memcpy(old, new, sizeof(new));
    }

    If the content is same why you need to copy it again?
    Else for me code is ok.
     
    deepak, Jun 16, 2007
    #3
  4. Guest

    On Sat, 16 Jun 2007 14:12:48 -0000, deepak <>
    wrote:

    >On Jun 16, 7:01 pm, wrote:
    >> Q: I need to copy and compare C Structs.
    >>
    >> Is this the safe and quick way to do it?:
    >>
    >> void func(void)
    >> {
    >> typedef _MY_STRUCT
    >> {
    >> int a;
    >> char b;
    >> char c;
    >>
    >> } my_struct
    >>
    >> my_stuct new;
    >> my_struct old;
    >>
    >> if (memcmp(old,new,sizeof(new))
    >> {
    >> memcpy(old, new, sizeof(new));
    >> }
    >>
    >>
    >>
    >> }- Hide quoted text -
    >>
    >> - Show quoted text -

    >
    >I think the use of memcmp in this code will be like,
    >if (!memcmp(old,new,sizeof(new))
    >{
    > memcpy(old, new, sizeof(new));
    >}
    >
    >If the content is same why you need to copy it again?

    Sorry, yes memcmp returns 0 if match. Typo (another one).
    >Else for me code is ok.

    Sweet. Thank-you.
     
    , Jun 16, 2007
    #4
  5. said:

    > Q: I need to copy and compare C Structs.
    >
    > Is this the safe and quick way to do it?:


    Copying is easy: new = old;

    For safe and meaningful comparison, compare on a field-by-field basis,
    comparing the most significant fields first. Typically one would write
    a function to do this.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Jun 16, 2007
    #5
  6. writes:

    > On Sat, 16 Jun 2007 14:12:48 -0000, deepak <>
    > wrote:
    >
    >>On Jun 16, 7:01 pm, wrote:
    >>> Q: I need to copy and compare C Structs.
    >>>
    >>> Is this the safe and quick way to do it?:
    >>>
    >>> void func(void)
    >>> {
    >>> typedef _MY_STRUCT
    >>> {
    >>> int a;
    >>> char b;
    >>> char c;
    >>>
    >>> } my_struct
    >>>
    >>> my_stuct new;
    >>> my_struct old;

    <snip>
    >>I think the use of memcmp in this code will be like,
    >>if (!memcmp(old,new,sizeof(new))
    >>{
    >> memcpy(old, new, sizeof(new));
    >>}
    >>
    >>If the content is same why you need to copy it again?

    > Sorry, yes memcmp returns 0 if match. Typo (another one).
    >>Else for me code is ok.

    > Sweet. Thank-you.


    It is not sweet -- the advice is wrong (except in the oddest of
    situations). It is entirely possible for memcmp to return non-zero
    when the two structures are equal in all important respects (i.e. have
    identical values in all members).

    --
    Ben.
     
    Ben Bacarisse, Jun 16, 2007
    #6
  7. Clark Cox Guest

    On 2007-06-16 07:01:25 -0700, said:

    > Q: I need to copy and compare C Structs.
    >
    > Is this the safe and quick way to do it?:


    [snip memcpy/memcmp-using code]


    No. For copying, you can use the '=' operator in the obvious way:
    old = new;

    For comparing, you'll have to do that yourself, member-by-member. Using
    memcmp isn't a good idea because it doesn't take into account any
    padding that may be contained in the structure's layout (i.e. you could
    actually be comparing bytes that don't contribute in any meaningful way
    to the structure's value).


    --
    Clark S. Cox III
     
    Clark Cox, Jun 16, 2007
    #7
  8. Guest

    >> Q: I need to copy and compare C Structs.
    >>
    >> Is this the safe and quick way to do it?:

    sniip
    >
    >
    >Copying is easy: new = old;

    As the comapre (new == old) made the compiler unhappy I didn't want to
    trust the assign (old = new).
    >
    >For safe and meaningful comparison, compare on a field-by-field basis,
    >comparing the most significant fields first. Typically one would write
    >a function to do this.

    Well once I've found a change I do have to go through each field to
    and action the changes. However the changes are rare, so I wanted to
    get the 'compare' over and done with asap, hence the 'old == new' as
    there can be quite a few fields in the structure (20+ at the mo).

    >It is not sweet -- the advice is wrong (except in the oddest of
    >situations). It is entirely possible for memcmp to return non-zero
    >when the two structures are equal in all important respects (i.e. have
    >identical values in all members).

    Well I have an odd situation because it has worked for me. Can you (if
    you have the time and inclination) tell me why memcmp would do this
    (is it because of 'structure' padding/alignment and that two
    'identical' structs not being identical)? I was concerned (hence the
    question in the 1st place).
     
    , Jun 16, 2007
    #8
  9. writes:

    >>> Q: I need to copy and compare C Structs.
    >>>
    >>> Is this the safe and quick way to do it?:

    > sniip
    >>
    >>
    >>Copying is easy: new = old;

    > As the comapre (new == old) made the compiler unhappy I didn't want to
    > trust the assign (old = new).
    >>
    >>For safe and meaningful comparison, compare on a field-by-field basis,
    >>comparing the most significant fields first. Typically one would write
    >>a function to do this.

    > Well once I've found a change I do have to go through each field to
    > and action the changes. However the changes are rare, so I wanted to
    > get the 'compare' over and done with asap, hence the 'old == new' as
    > there can be quite a few fields in the structure (20+ at the mo).
    >
    >>It is not sweet -- the advice is wrong (except in the oddest of
    >>situations). It is entirely possible for memcmp to return non-zero
    >>when the two structures are equal in all important respects (i.e. have
    >>identical values in all members).

    > Well I have an odd situation because it has worked for me. Can you (if
    > you have the time and inclination) tell me why memcmp would do this
    > (is it because of 'structure' padding/alignment and that two
    > 'identical' structs not being identical)? I was concerned (hence the
    > question in the 1st place).


    Yes, the problem is (mostly) structure padding. If you are certain
    the there is none (on all the platforms you can foresee) or that you
    have set to some known value in every case (because you have used
    memset always) then you might me able to get away with it, but it
    seems to me you would be making a fragile solution.

    There is another sort of padding internal to some types that the
    standard allows. Hence one can not assume that two values that
    compare equal will be equal as far as memcmp is concerned.

    Finally, some types have their own notion of equality that need not be
    byte-for-byte equality. This is most obvious for floating point types
    but it is also possible that two pointers might be == but have distinct
    representations. Similarly, when a type permits trap representations,
    the effect of == and memcmp may be different (but in this case the
    memcmp will succeed in a possibly deceptive way).

    BTW, it is probably not a good idea to join two answers together like
    this. For one thing you can't easily keep the attribution lines (you
    should have kept them, in my opinion).

    --
    Ben.
     
    Ben Bacarisse, Jun 16, 2007
    #9
  10. CBFalconer Guest

    Ben Bacarisse wrote:
    >

    .... snip on comparing structs ...
    >
    > It is not sweet -- the advice is wrong (except in the oddest of
    > situations). It is entirely possible for memcmp to return
    > non-zero when the two structures are equal in all important
    > respects (i.e. have identical values in all members).


    The reason is that there can be padding bytes, which contain data
    that has nothing to do with the value of the struct. You have to
    compare field by field.

    --
    <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
    <http://www.securityfocus.com/columnists/423>
    <http://www.aaxnet.com/editor/edit043.html>
    cbfalconer at maineline dot net



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Jun 16, 2007
    #10
  11. On Sat, 16 Jun 2007 16:09:18 GMT, wrote:

    >>> Q: I need to copy and compare C Structs.
    >>>
    >>> Is this the safe and quick way to do it?:

    >sniip
    >>
    >>
    >>Copying is easy: new = old;

    >As the comapre (new == old) made the compiler unhappy I didn't want to
    >trust the assign (old = new).


    Trust has nothing to do with it. It is a question of what
    capabilities the language provides. If you don't have a decent
    reference manual, get one.

    >>
    >>For safe and meaningful comparison, compare on a field-by-field basis,
    >>comparing the most significant fields first. Typically one would write
    >>a function to do this.

    >Well once I've found a change I do have to go through each field to
    >and action the changes. However the changes are rare, so I wanted to
    >get the 'compare' over and done with asap, hence the 'old == new' as
    >there can be quite a few fields in the structure (20+ at the mo).
    >
    >>It is not sweet -- the advice is wrong (except in the oddest of
    >>situations). It is entirely possible for memcmp to return non-zero
    >>when the two structures are equal in all important respects (i.e. have
    >>identical values in all members).

    >Well I have an odd situation because it has worked for me. Can you (if
    >you have the time and inclination) tell me why memcmp would do this
    >(is it because of 'structure' padding/alignment and that two
    >'identical' structs not being identical)? I was concerned (hence the
    >question in the 1st place).


    Padding is one situation where equal structures can have mismatched
    bits. Pointers are another - it is possible for two pointers to the
    same address to have different bit representations. A system that
    supports -0 is another. 0 and -0 must compare equal but will not have
    the same bit representation. There probably are other situations
    also.


    Remove del for email
     
    Barry Schwarz, Jun 16, 2007
    #11
  12. On Sat, 16 Jun 2007 16:09:18 GMT, bb@...co.uk wrote:
    >Well once I've found a change I do have to go through each field to
    >and action the changes. However the changes are rare, so I wanted to
    >get the 'compare' over and done with asap, hence the 'old == new' as
    >there can be quite a few fields in the structure (20+ at the mo).


    C++ gives you no automatic operator==() and Java no sematically
    correct equals(). Why expect it from C?

    >Well I have an odd situation because it has worked for me.


    You can get away with it if false negatives (false un-equals) are not
    a problem. The code 'just' looks deficient.

    >Can you (if
    >you have the time and inclination) tell me why memcmp would do this
    >(is it because of 'structure' padding/alignment and that two
    >'identical' structs not being identical)? I was concerned (hence the
    >question in the 1st place).


    Look for 'structure padding' e.g. http://c-faq.com/struct/padding.html


    --
    Roland Pibinger
    "The best software is simple, elegant, and full of drama" - Grady Booch
     
    Roland Pibinger, Jun 16, 2007
    #12
  13. Army1987 Guest

    <> ha scritto nel messaggio
    news:...
    >>> Q: I need to copy and compare C Structs.
    >>>
    >>> Is this the safe and quick way to do it?:

    > sniip
    >>
    >>
    >>Copying is easy: new = old;

    > As the comapre (new == old) made the compiler unhappy I didn't want to
    > trust the assign (old = new).
    >>
    >>For safe and meaningful comparison, compare on a field-by-field basis,
    >>comparing the most significant fields first. Typically one would write
    >>a function to do this.

    > Well once I've found a change I do have to go through each field to
    > and action the changes. However the changes are rare, so I wanted to
    > get the 'compare' over and done with asap, hence the 'old == new' as
    > there can be quite a few fields in the structure (20+ at the mo).
    >
    >>It is not sweet -- the advice is wrong (except in the oddest of
    >>situations). It is entirely possible for memcmp to return non-zero
    >>when the two structures are equal in all important respects (i.e. have
    >>identical values in all members).

    > Well I have an odd situation because it has worked for me. Can you (if
    > you have the time and inclination) tell me why memcmp would do this
    > (is it because of 'structure' padding/alignment and that two
    > 'identical' structs not being identical)? I was concerned (hence the
    > question in the 1st place).


    Even if there is no padding, the structures

    struct words {
    char word1[8] = { 'H', 'e', 'l', 'l', 'o', '\0', 42, 73 }
    char word2[8] = { 'w', 'o', 'r', 'l,' 'd', '\0', 1, 95 }
    } a;

    and

    struct words {
    char word1[8] = { 'H', 'e', 'l', 'l', 'o', '\0', 12, 23 }
    char word2[8] = { 'w', 'o', 'r', 'l,' 'd', '\0', 47, 79 }
    } b;

    don't memcmp equal, even if any reasonable person shouldn't
    distinguish them in most cases.
     
    Army1987, Jun 17, 2007
    #13
  14. "Army1987" <> writes:

    > <> ha scritto nel messaggio
    > news:...
    >>>> Q: I need to copy and compare C Structs.
    >>>>
    >>>> Is this the safe and quick way to do it?:

    <snip>
    >>>It is not sweet -- the advice is wrong (except in the oddest of
    >>>situations). It is entirely possible for memcmp to return non-zero
    >>>when the two structures are equal in all important respects (i.e. have
    >>>identical values in all members).

    >> Well I have an odd situation because it has worked for me. Can you (if
    >> you have the time and inclination) tell me why memcmp would do this
    >> (is it because of 'structure' padding/alignment and that two
    >> 'identical' structs not being identical)? I was concerned (hence the
    >> question in the 1st place).

    >
    > Even if there is no padding, the structures
    >
    > struct words {
    > char word1[8] = { 'H', 'e', 'l', 'l', 'o', '\0', 42, 73 }
    > char word2[8] = { 'w', 'o', 'r', 'l,' 'd', '\0', 1, 95 }
    > } a;
    >
    > and
    >
    > struct words {
    > char word1[8] = { 'H', 'e', 'l', 'l', 'o', '\0', 12, 23 }
    > char word2[8] = { 'w', 'o', 'r', 'l,' 'd', '\0', 47, 79 }
    > } b;
    >
    > don't memcmp equal, even if any reasonable person shouldn't
    > distinguish them in most cases.


    A good example, although I feel it worth pointing out to budding
    programmers that this problem is rather different in that it can be
    avoided (at least in principle) by careful use of these fixed-length
    arrays. The other problems cited can't be avoided by the programmer.

    --
    Ben.
     
    Ben Bacarisse, Jun 17, 2007
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RWQ=?=
    Replies:
    0
    Views:
    3,288
    =?Utf-8?B?RWQ=?=
    Apr 18, 2006
  2. Chris Fogelklou
    Replies:
    36
    Views:
    1,391
    Chris Fogelklou
    Apr 20, 2004
  3. Dan Stromberg

    sorting with expensive compares?

    Dan Stromberg, Dec 22, 2005, in forum: Python
    Replies:
    25
    Views:
    591
    Stuart D. Gathman
    Dec 28, 2005
  4. Randall Parker
    Replies:
    1
    Views:
    291
    Mike Meyer
    Jan 13, 2006
  5. Bas Nedermeijer

    Lots of string compares

    Bas Nedermeijer, Oct 23, 2006, in forum: C++
    Replies:
    8
    Views:
    303
    Yannick Tremblay
    Oct 25, 2006
Loading...

Share This Page