comparing two structures

Discussion in 'C Programming' started by junky_fellow@yahoo.co.in, Sep 14, 2007.

  1. Guest

    Guys,

    Is it a good way to compare two structures for equality by using
    "memcmp" ?

    If not, what could be the problems associated with this ? And what is
    the correct
    method of doing this ?

    thanks for any help.
    , Sep 14, 2007
    #1
    1. Advertising

  2. <> schrieb im Newsbeitrag
    news:...
    > Guys,
    >
    > Is it a good way to compare two structures for equality by using
    > "memcmp" ?
    >
    > If not, what could be the problems associated with this ? And what is
    > the correct
    > method of doing this ?
    >
    > thanks for any help.

    http://c-faq.com/struct/compare.html
    Joachim Schmitz, Sep 14, 2007
    #2
    1. Advertising

  3. said:

    > Guys,
    >
    > Is it a good way to compare two structures for equality by using
    > "memcmp" ?


    No.

    > If not, what could be the problems associated with this ?


    Padding bytes, and dynamically allocated memory pointed to by struct
    members.

    > And what is the correct method of doing this ?


    int cmp(const struct T *a, const struct T *b);

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Sep 14, 2007
    #3
  4. CBFalconer Guest

    Richard Heathfield wrote:
    > said:
    >
    >> Is it a good way to compare two structures for equality by using
    >> "memcmp" ?

    >
    > No.
    >
    >> If not, what could be the problems associated with this ?

    >
    > Padding bytes, and dynamically allocated memory pointed to by
    > struct members.
    >
    >> And what is the correct method of doing this ?

    >
    > int cmp(const struct T *a, const struct T *b);


    Which should resolve to (very roughly}:

    for (c = eachcomponentof a) {
    if ((a->c) != (b->c)) return 0; /* unequal */
    }
    return 1; /* i.e. structures equal */

    Which means you have to write a cmp() each structure type. You may
    have to resolve embedded pointers.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>


    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Sep 14, 2007
    #4
  5. CBFalconer said:

    > Richard Heathfield wrote:


    <snip>
    >>
    >> int cmp(const struct T *a, const struct T *b);

    >
    > Which should resolve to (very roughly}:
    >
    > for (c = eachcomponentof a) {
    > if ((a->c) != (b->c)) return 0; /* unequal */
    > }
    > return 1; /* i.e. structures equal */


    Personally, I would find a relational comparison more generally useful.

    <snip>

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Sep 14, 2007
    #5
  6. John Gordon Guest

    In <> "" <> writes:

    > Is it a good way to compare two structures for equality by using
    > "memcmp" ?


    No.

    > If not, what could be the problems associated with this?


    One such problem is comparison of strings. The contents of a string are
    meaningless after the terminating null byte, but memcmp() wouldn't know
    that.

    --
    John Gordon A is for Amy, who fell down the stairs
    B is for Basil, assaulted by bears
    -- Edward Gorey, "The Gashlycrumb Tinies"
    John Gordon, Sep 14, 2007
    #6
  7. Tor Rustad Guest

    CBFalconer wrote:

    [...]

    > Which should resolve to (very roughly}:
    >
    > for (c = eachcomponentof a) {
    > if ((a->c) != (b->c)) return 0; /* unequal */
    > }
    > return 1; /* i.e. structures equal */
    >
    > Which means you have to write a cmp() each structure type. You may
    > have to resolve embedded pointers.


    Very confusing name choice, unless cmp() return 0 if equal.

    --
    Tor <torust [at] online [dot] no>
    Tor Rustad, Sep 14, 2007
    #7
  8. CBFalconer Guest

    Richard Heathfield wrote:
    > CBFalconer said:
    >> Richard Heathfield wrote:

    >
    > <snip>
    >>>
    >>> int cmp(const struct T *a, const struct T *b);

    >>
    >> Which should resolve to (very roughly}:
    >>
    >> for (c = eachcomponentof a) {
    >> if ((a->c) != (b->c)) return 0; /* unequal */
    >> }
    >> return 1; /* i.e. structures equal */

    >
    > Personally, I would find a relational comparison more generally
    > useful.


    Granted, but generally impossible. For:

    struct foobar {int foo; char bar);

    please define a suitable cmp function that is relational, without
    somehow defining the relative importance of foo and bar. :) I'm
    sure you know this, but the comment is for general consumption.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Sep 14, 2007
    #8
  9. CBFalconer said:

    > Richard Heathfield wrote:

    <snip>
    >>
    >> Personally, I would find a relational comparison more generally
    >> useful.

    >
    > Granted, but generally impossible.


    Generally, yes, but specifically, no. The problem domain expert will be
    able to specify the ordering between two objects of the same structure
    type (and possibly several orderings, in which case several functions
    can be written).

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Sep 14, 2007
    #9
  10. CBFalconer Guest

    Tor Rustad wrote:
    > CBFalconer wrote:
    >
    > [...]
    >
    >> Which should resolve to (very roughly}:
    >>
    >> for (c = eachcomponentof a) {
    >> if ((a->c) != (b->c)) return 0; /* unequal */
    >> }
    >> return 1; /* i.e. structures equal */
    >>
    >> Which means you have to write a cmp() each structure type. You
    >> may have to resolve embedded pointers.

    >
    > Very confusing name choice, unless cmp() return 0 if equal.


    You have my full permission to interchange 0 and 1. :)

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Sep 14, 2007
    #10
  11. Tor Rustad Guest

    CBFalconer wrote:
    > Tor Rustad wrote:
    >> CBFalconer wrote:
    >>
    >> [...]
    >>
    >>> Which should resolve to (very roughly}:
    >>>
    >>> for (c = eachcomponentof a) {
    >>> if ((a->c) != (b->c)) return 0; /* unequal */
    >>> }
    >>> return 1; /* i.e. structures equal */
    >>>
    >>> Which means you have to write a cmp() each structure type. You
    >>> may have to resolve embedded pointers.

    >> Very confusing name choice, unless cmp() return 0 if equal.

    >
    > You have my full permission to interchange 0 and 1. :)


    The API is still broken to my mind. :)

    If first argument is less, then cmp() should return negative (e.g. -1),
    if first argument is greater, then cmp() should return positive (e.g. 1).


    Furthermore, if writing a cmp() function, I rather prefer to use the
    same interface and return value as qsort() and bsearch() expect:

    int cmp_mystruct(const void *, const void *)

    why compare "struct's", unless doing sorting and searching?

    --
    Tor <torust [at] online [dot] no>
    Tor Rustad, Sep 15, 2007
    #11
  12. Tor Rustad said:

    <snip>

    > Furthermore, if writing a cmp() function, I rather prefer to use the
    > same interface and return value as qsort() and bsearch() expect:
    >
    > int cmp_mystruct(const void *, const void *)
    >
    > why compare "struct's", unless doing sorting and searching?


    Well said, although I think I'd like to add an extra void * to that, so
    that the comparison function can use (or provide) additional
    information about the comparison without resorting to global data.
    This, of course, requires ISO to change the spec for qsort and bsearch,
    or provide sensibly-designed versions thereof.

    Jump to it, lads...

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Sep 15, 2007
    #12
  13. pete Guest

    Tor Rustad wrote:

    > Furthermore, if writing a cmp() function, I rather prefer to use the
    > same interface and return value as qsort() and bsearch() expect:
    >
    > int cmp_mystruct(const void *, const void *)
    >
    > why compare "struct's", unless doing sorting and searching?


    If you had a linked list of structures
    and if you had a list sorting function that
    took a compar function pointer as an argument,
    then it would make more sense to have pointers to the list node type.

    --
    pete
    pete, Sep 15, 2007
    #13
  14. CBFalconer Guest

    Tor Rustad wrote:
    > CBFalconer wrote:
    >> Tor Rustad wrote:
    >>> CBFalconer wrote:
    >>>
    >>> [...]
    >>>
    >>>> Which should resolve to (very roughly}:
    >>>>
    >>>> for (c = eachcomponentof a) {
    >>>> if ((a->c) != (b->c)) return 0; /* unequal */
    >>>> }
    >>>> return 1; /* i.e. structures equal */
    >>>>
    >>>> Which means you have to write a cmp() each structure type.
    >>>> You may have to resolve embedded pointers.
    >>>
    >>> Very confusing name choice, unless cmp() return 0 if equal.

    >>
    >> You have my full permission to interchange 0 and 1. :)

    >
    > The API is still broken to my mind. :)
    >
    > If first argument is less, then cmp() should return negative
    > (e.g. -1), if first argument is greater, then cmp() should
    > return positive (e.g. 1).


    But you are dealing with a struct. How do you define 'less' when
    there are multiple components, with no less/greater definition.

    >
    > Furthermore, if writing a cmp() function, I rather prefer to use
    > the same interface and return value as qsort() and bsearch()
    > expect:
    >
    > int cmp_mystruct(const void *, const void *)
    >
    > why compare "struct's", unless doing sorting and searching?


    No, you can compare some fields of structs, but not complete
    structs, for relative magnitude. The problem handled by void* is
    not within the cmp function, but within the caller, who may not
    need to know anything more than the cmp result about the struct.
    The definition of cmp is up to you.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
    CBFalconer, Sep 15, 2007
    #14
  15. CBFalconer said:

    <snip>

    > But you are dealing with a struct. How do you define 'less' when
    > there are multiple components, with no less/greater definition.


    It depends on the domain. You are right that there is no general
    solution, but that does not mean that there are no domain-specific
    solutions. Nor does it mean that you cannot have multiple comparison
    functions for the same type.

    <snip>

    > The definition of cmp is up to you.


    Precisely.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Sep 15, 2007
    #15
  16. Tor Rustad Guest

    CBFalconer wrote:
    > Tor Rustad wrote:
    >> CBFalconer wrote:
    >>> Tor Rustad wrote:
    >>>> CBFalconer wrote:
    >>>>
    >>>> [...]
    >>>>
    >>>>> Which should resolve to (very roughly}:
    >>>>>
    >>>>> for (c = eachcomponentof a) {
    >>>>> if ((a->c) != (b->c)) return 0; /* unequal */
    >>>>> }
    >>>>> return 1; /* i.e. structures equal */
    >>>>>
    >>>>> Which means you have to write a cmp() each structure type.
    >>>>> You may have to resolve embedded pointers.
    >>>> Very confusing name choice, unless cmp() return 0 if equal.
    >>> You have my full permission to interchange 0 and 1. :)

    >> The API is still broken to my mind. :)
    >>
    >> If first argument is less, then cmp() should return negative
    >> (e.g. -1), if first argument is greater, then cmp() should
    >> return positive (e.g. 1).

    >
    > But you are dealing with a struct. How do you define 'less' when
    > there are multiple components, with no less/greater definition.


    Hmmm.. what does this "comparing struct" mean?

    Normally, when comparing ADT, the ADT has a key defined, e.g. like this:

    struct node
    {
    KEY_T id;
    DATA_T data;
    };

    and you only compare the key, not *all* the members of the struct.

    When a programmer name a function cmp(), I expect a compare operation to
    be defined. If only testing for equality, a far better name choice would
    be e.g. 'is_equal()'.

    See return value of memcmp, strcmp, ... it's <0, 0 or >0.

    --
    Tor <torust [at] online [dot] no>
    Tor Rustad, Sep 16, 2007
    #16
  17. Tor Rustad Guest

    pete wrote:
    > Tor Rustad wrote:
    >
    >> Furthermore, if writing a cmp() function, I rather prefer to use the
    >> same interface and return value as qsort() and bsearch() expect:
    >>
    >> int cmp_mystruct(const void *, const void *)
    >>
    >> why compare "struct's", unless doing sorting and searching?

    >
    > If you had a linked list of structures
    > and if you had a list sorting function that
    > took a compar function pointer as an argument,
    > then it would make more sense to have pointers to the list node type.


    Agreed, in this case, I wouldn't use void*, but rather

    int is_equal(KEY_T, KEY_T );
    int is_less (KEY_T, KEY_T );

    --
    Tor <torust [at] online [dot] no>
    Tor Rustad, Sep 16, 2007
    #17
  18. Tor Rustad Guest

    Richard Heathfield wrote:
    > CBFalconer said:


    [...]

    >> The definition of cmp is up to you.

    >
    > Precisely.


    The compiler doesn't mind bad identifiers, but humans do...

    The point is that the standard C library, the *is* functions return
    differently, than the *cmp* functions do.


    So, if you are consistent, you can't object to code with:

    int is_zero(int c)
    {
    return ('0' != c);
    }

    either.

    --
    Tor <torust [at] online [dot] no>
    Tor Rustad, Sep 16, 2007
    #18
  19. Tor Rustad said:

    > Richard Heathfield wrote:
    >> CBFalconer said:

    >
    > [...]
    >
    >>> The definition of cmp is up to you.

    >>
    >> Precisely.

    >
    > The compiler doesn't mind bad identifiers, but humans do...
    >
    > The point is that the standard C library, the *is* functions return
    > differently, than the *cmp* functions do.
    >
    >
    > So, if you are consistent, you can't object to code with:
    >
    > int is_zero(int c)
    > {
    > return ('0' != c);
    > }
    >
    > either.
    >



    You lost me. Remember that my preference is for relational comparison, a
    la strcmp and memcmp, rather than for equality-only comparison.

    If you realised this and still think you have a point, I'd be curious to
    know what that point is.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
    Richard Heathfield, Sep 16, 2007
    #19
    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. tweak
    Replies:
    14
    Views:
    2,761
    Eric Sosman
    Jun 11, 2004
  2. Alfonso Morra
    Replies:
    11
    Views:
    701
    Emmanuel Delahaye
    Sep 24, 2005
  3. , India

    comparing sizes of two structures

    , India, Mar 7, 2007, in forum: C Programming
    Replies:
    20
    Views:
    659
    jaysome
    Mar 8, 2007
  4. Joel VanderWerf
    Replies:
    2
    Views:
    88
  5. Alec Taylor
    Replies:
    0
    Views:
    155
    Alec Taylor
    Mar 2, 2012
Loading...

Share This Page