Web Images Videos Maps News Shopping Google Mail more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 43 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Follow-up To:
Add Cc | Add Follow-up to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers that you hear
 
Helmut Leitner  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: Helmut Leitner <leit...@hls.via.at>
Date: 1999/06/28
Subject: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
Let's assume that a and b have the same basic data type
(e.g. int, long, float, double ...).

On many platforms it is possible to replace the
comparisions
   a==b        
   a!=b
by
   memcmp(&a,&b,sizeof(a))==0
   memcmp(&a,&b,sizeof(a))

What are the conditions that this will not yield the
desired results?

Can someone give (an) implementation example(s), where
the reasons for this behaviour can be seen?  

The background is the wish of fast and easy comparison
of multicomponent structures (within a perfect hash system):

   typedef struct test {
      char ...
      int ...
      float ...
      ...
   } TEST;

   TEST sa,sb;
   memset(&sa,'\0',sizeof(TEST)); /* or TestClear(&sa); */
   memset(&sb,'\0',sizeof(TEST)); /* or TestClear(&sb); */
   ...
   any standard component assignment. /* or TestSetComponent(&sa,comp) */
   ...
   memcmp(&sa,&sb,sizeof(TEST));

Is it possible to construct such a general system to work
in a portable way on all platforms?

Would it be possible to construct an #if-expression

   #if (expression_memcmp_will_do_the_job)
      TestEqu(psa,psb) (memcmp(psa,psb,sizeof(TEST))==0)
   #else
      (psa->comp1==psb->comp2 && psa->comp2==psb->comp2 && .... )
   #endif

to react to the different situations?

--
Helmut Leitner    leit...@hls.via.at  
Graz, Austria   www.hls-software.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Mesken  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: usur...@euronet.nl (Paul Mesken)
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
On Mon, 28 Jun 1999 10:56:20 +0200, Helmut Leitner

<leit...@hls.via.at> wrote:
>Let's assume that a and b have the same basic data type
>(e.g. int, long, float, double ...).

>On many platforms it is possible to replace the
>comparisions
>   a==b        
>   a!=b
>by
>   memcmp(&a,&b,sizeof(a))==0
>   memcmp(&a,&b,sizeof(a))

If a and b are of the same basic data type then you wouldn't do this.
It's ugly and probably slower. Besides: what if a and/or b have the
storage class specifier  "register"? Then it is illegal to use the
address-of operator on them.

>What are the conditions that this will not yield the
>desired results?

If they are not of the same basic type for example. Unlike using the
equality operators, the memcmp version will not convert them. This
might result in inequality while the values of a and b are the same.

It might look as if the memcmp version can do "clever" comparisons
since it would also accept derived types like structures but even if a
and b are of the same derived type you would still run the risk of
inequality in the case of inequal values in the padding (if any).
Thus, inequality might even appear for structures that are of the same
type and have the same values for their members.

However:

Yes, you first set all char's of the structures to zero. This solves
the problem of the "uninitialized padding".

>Is it possible to construct such a general system to work
>in a portable way on all platforms?

In this particular case I don't see why not.

>Would it be possible to construct an #if-expression

>   #if (expression_memcmp_will_do_the_job)
>      TestEqu(psa,psb) (memcmp(psa,psb,sizeof(TEST))==0)
>   #else
>      (psa->comp1==psb->comp2 && psa->comp2==psb->comp2 && .... )
>   #endif

>to react to the different situations?

I don't see how the expression should look like. Your solution works
as long as you take care to initialize _all_ char's of the structures
to avoid the "inequal padding value" problem and make sure that your a
and b are of the same structure type.

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
alex_krol  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: Alex_K...@scitex.com
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <377738B4.97C7...@hls.via.at>,
  Helmut Leitner <leit...@hls.via.at> wrote:

> Let's assume that a and b have the same basic data type
> (e.g. int, long, float, double ...).

> On many platforms it is possible to replace the
> comparisions
>    a==b
>    a!=b
> by
>    memcmp(&a,&b,sizeof(a))==0
>    memcmp(&a,&b,sizeof(a))

> What are the conditions that this will not yield the
> desired results?

   I can think of two:
  a) holes in data type representation
  b) +0 and -0 for one's complement platforms

--
        Regards,
                Alex Krol
Disclaimer: I'm not speaking for Scitex Corporation Ltd

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Christian Bau  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: christian....@isltd.insignia.com (Christian Bau)
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <377738B4.97C7...@hls.via.at>, Helmut Leitner

<leit...@hls.via.at> wrote:
> Let's assume that a and b have the same basic data type
> (e.g. int, long, float, double ...).

> On many platforms it is possible to replace the
> comparisions
>    a==b        
>    a!=b
> by
>    memcmp(&a,&b,sizeof(a))==0
>    memcmp(&a,&b,sizeof(a))

Quite often it does not work with IEEE standard floating point numbers.
Especially with +0.0 and -0.0 (they compare equal, but have different bit
patterns) and NaN's (they compare different, even if they are identical).

There have been machines with long double = 80 bit + 16 unused bits, for
example the Motorola 68040 and 68020/30 with coprocessor. On these
machines you cannot rely on memcpy at all.

And for structs and unions you will always have a problem because of padding.

Apart from this, it will work on most machines :-(


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Szu-Wen Huang  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: hu...@mnsinc.com (Szu-Wen Huang)
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
Helmut Leitner (leit...@hls.via.at) wrote:

: Let's assume that a and b have the same basic data type
: (e.g. int, long, float, double ...).

: On many platforms it is possible to replace the
: comparisions
:    a==b        
:    a!=b
: by
:    memcmp(&a,&b,sizeof(a))==0
:    memcmp(&a,&b,sizeof(a))

: What are the conditions that this will not yield the
: desired results?

: Can someone give (an) implementation example(s), where
: the reasons for this behaviour can be seen?  

Sure.  Recall the strange segment:offset scheme of addressing
on the 80x86 real mode, where the actual address is computed
as (segment * 16 + offset).  Thus, many segment:offset pairs
actually compute to the same address, and the equality operator
for pointers must handle these.  Typically, they normalize the
pointer before comparison.

Using memcmp() will likely produce false negatives.

: The background is the wish of fast and easy comparison
: of multicomponent structures (within a perfect hash system):
[...]
: Is it possible to construct such a general system to work
: in a portable way on all platforms?

In general, whenever more than one representation is possible
for a single value, your proposal will fail.  If you use a
structure, you should also worry about the value of padding
bytes, which probably means a mandatory memset() after any
malloc().

: Would it be possible to construct an #if-expression

:    #if (expression_memcmp_will_do_the_job)
:       TestEqu(psa,psb) (memcmp(psa,psb,sizeof(TEST))==0)
:    #else
:       (psa->comp1==psb->comp2 && psa->comp2==psb->comp2 && .... )
:    #endif

: to react to the different situations?

Isn't that even longer than just doing the comparison?  :)


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Lutus  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Paul Lutus" <nos...@nosite.com>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
<< Is it possible to construct such a general system to work in a portable
way on all platforms? >>

No, this is not possible. There are any number of reasons an entire
structure's components will not compare successfully, even though each of
the data components are comparable. Some have to do with differences between
platforms, some have to do with differences between structures on a single
platform.

Finally, you will try to compare a double and a float, arguing that they are
really the same number. If you compare them directly, you will get the
expected results. If you use memcmp(), you will not.

--

Paul Lutus
www.arachnoid.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
FigBug  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: FigBug <rrab...@csc.UVic.CA>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?

> Finally, you will try to compare a double and a float, arguing that they are
> really the same number. If you compare them directly, you will get the
> expected results. If you use memcmp(), you will not.

It's not clear to me what "compare them directly" means. Are you saying
you can compare a float to a double using '=='? You can't, it won't work
as expected.

FigBug


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dann Corbit  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Dann Corbit" <dcor...@solutionsiq.com>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
FigBug <rrab...@csc.UVic.CA> wrote in message

news:Pine.SUN.3.96.990628105138.16344A-100000@valdes...

> > Finally, you will try to compare a double and a float, arguing that they
are
> > really the same number. If you compare them directly, you will get the
> > expected results. If you use memcmp(), you will not.

> It's not clear to me what "compare them directly" means. Are you saying
> you can compare a float to a double using '=='? You can't, it won't work
> as expected.

You should not even compare a double to a double using ==.  The C FAQ
addresses this:

14.5:   What's a good way to check for "close enough" floating-point
        equality?

A:      Since the absolute accuracy of floating point values varies, by
        definition, with their magnitude, the best way of comparing two
        floating point values is to use an accuracy threshold which is
        relative to the magnitude of the numbers being compared.  Rather
        than

                double a, b;
                ...
                if(a == b)      /* WRONG */

        use something like

                #include <math.h>

                if(fabs(a - b) <= epsilon * fabs(a))

        for some suitably-chosen degree of closeness epsilon (as long as
        a is nonzero!).

        References: Knuth Sec. 4.2.2 pp. 217-8.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. Newsgroup   http://www.dejanews.com/~c_a_p
C.A.P. FAQ: ftp://38.168.214.175/pub/Chess%20Analysis%20Project%20FAQ.htm


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Lutus  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Paul Lutus" <nos...@nosite.com>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
Of course you can. You may not get what you expect, for an unrelated reason
having to do with the binary storage type, but the compiler will promote the
float to a double before making the comparison. This is not true for
memcmp(), my original point.

--

Paul Lutus
www.arachnoid.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
rawcswi  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: rawc...@my-deja.com
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <Pine.SUN.3.96.990628105138.16344A-100000@valdes>,
  FigBug <rrab...@csc.UVic.CA> wrote:

> > Finally, you will try to compare a double and a float, arguing that they are
> > really the same number. If you compare them directly, you will get the
> > expected results. If you use memcmp(), you will not.

> It's not clear to me what "compare them directly" means. Are you saying
> you can compare a float to a double using '=='? You can't, it won't work
> as expected.

It depends on how it's expected to work.  You can compare a
float and a double, and of course then the float gets converted
to a double.  The values are compared, and == must take into
account the possibility of different representations for the same
value.  For memcmp, objects holding the two values probably
wouldn't even have the same size.

(Round off errors could also cause unexpected results,
but this is true of comparisons of two doubles as well and
memcmp is not going to help the situation at all.  You could
consider an int and a long instead without changing the point.)

--
MJSR

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
FigBug  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: FigBug <rrab...@csc.UVic.CA>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
On Mon, 28 Jun 1999 rawc...@my-deja.com wrote:

> It depends on how it's expected to work.  You can compare a
> float and a double, and of course then the float gets converted
> to a double.  The values are compared, and == must take into
> account the possibility of different representations for the same
> value.  For memcmp, objects holding the two values probably
> wouldn't even have the same size.

> (Round off errors could also cause unexpected results,
> but this is true of comparisons of two doubles as well and
> memcmp is not going to help the situation at all.  You could
> consider an int and a long instead without changing the point.)

The point I was attemping to make was, that the following is useful:

int i;
long int li;

i = 1;
li = 1;

if (i == li) blaa();

and the following won't do anything usefull:

float f;
double d;

f = 1.1;
d = 1.1;

if (f == d) blaa();

Paul's post was unclear, it seemed to claim (to me anyway) that doing the
above was usefull.

FigBug


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lawrence Kirby  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: f...@genesis.demon.co.uk (Lawrence Kirby)
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <377738B4.97C7...@hls.via.at>
           leit...@hls.via.at "Helmut Leitner" writes:

>Let's assume that a and b have the same basic data type
>(e.g. int, long, float, double ...).

>On many platforms it is possible to replace the
>comparisions
>   a==b        
>   a!=b
>by
>   memcmp(&a,&b,sizeof(a))==0
>   memcmp(&a,&b,sizeof(a))

>What are the conditions that this will not yield the
>desired results?

When different bit patterns represent the same value or at least
values that compare equal. There are various reasons why this might
happen.

Firstly any basic type except unsigned char can have "holes" or unused
bits that don't contribute to the value. So these bits can differ (hence
memcmp() will return non-zero) for values that compare equal.

In 1's complement and sign-mangitde format integers 0 and -0 have
different bit representations but compare equal.

In floating point formats such as IEEE-754 there can also be different
representations for 0 and -0. I believe in some floating point
formats there are a large number of representations for zero. Some
floating point formats such as IEEE-754 also create the opposite
problem, NaNs compare unquual to anything even other NaNs so it is possible
for values with identical bit patterns to compare unequal.

Pointers can have different representations for the same address (e.g.
in segnemted archatectures like the 8086). They can also contain other
information such as boundary information (these are sometimes called fat
pointers). So pointers with different bit patterns can compare equal.

Structures and unions can include padding bytes. Since padding does not
contribute to the structure or union's value I don't see anything that
prohibits this padding from changing arbitrarily. There can also be
padding bits where bit-fields are involved.

No.

>Would it be possible to construct an #if-expression

>   #if (expression_memcmp_will_do_the_job)
>      TestEqu(psa,psb) (memcmp(psa,psb,sizeof(TEST))==0)
>   #else
>      (psa->comp1==psb->comp2 && psa->comp2==psb->comp2 && .... )
>   #endif

>to react to the different situations?

Probably the simplest thing to do would be to veryify the platforms
you are interested in yourself and define a macro you can test for
those platforms which fit the bill. However there are lots of
different ways to fail.

--
-----------------------------------------
Lawrence Kirby | f...@genesis.demon.co.uk
Wilts, England | 70734....@compuserve.com
-----------------------------------------


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lawrence Kirby  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: f...@genesis.demon.co.uk (Lawrence Kirby)
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <377b53ef.5062...@news.euronet.nl>
           usur...@euronet.nl "Paul Mesken" writes:

The simple fix for that is to remove the register specifier. If you
are writing the function containing the memcmpÿcall you should have
control of the local variables in the function.

--
-----------------------------------------
Lawrence Kirby | f...@genesis.demon.co.uk
Wilts, England | 70734....@compuserve.com
-----------------------------------------


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Lutus  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Paul Lutus" <nos...@nosite.com>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
<< [about comparing a float and a double] Paul's post was unclear, it seemed
to claim (to me anyway) that doing the above was usefull. >>

It *is* useful. Typically the programmer will know the float will be
converted to a double, then compared to a double. Acknowledging the various
possible errors not related to the problem at hand, in many cases this is
the same as comparing two doubles.

And, granted the limitations of direct comparison of floating-point data
types, it cannot meaningfully be replaced with the memcmp() approach.

--

Paul Lutus
www.arachnoid.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dann Corbit  
View profile   Translate to Translated (View Original)
 More options 28 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Dann Corbit" <dcor...@solutionsiq.com>
Date: 1999/06/28
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
Paul Lutus <nos...@nosite.com> wrote in message

news:TJUd3.97171$_m4.1043847@news2.giganews.com...
> << [about comparing a float and a double] Paul's post was unclear, it
seemed
> to claim (to me anyway) that doing the above was usefull. >>

> It *is* useful. Typically the programmer will know the float will be
> converted to a double, then compared to a double. Acknowledging the
various
> possible errors not related to the problem at hand, in many cases this is
> the same as comparing two doubles.

Quite right, a horrible gaffe (comparing doubles for equality), and
indicates that the programmer is probably incompetent for numerical work.

> And, granted the limitations of direct comparison of floating-point data
> types, it cannot meaningfully be replaced with the memcmp() approach.

Hopefully, it will be replaced with something useful.
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 "The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. Newsgroup   http://www.dejanews.com/~c_a_p
C.A.P. FAQ: ftp://38.168.214.175/pub/Chess%20Analysis%20Project%20FAQ.htm

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lawrence Kirby  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: f...@genesis.demon.co.uk (Lawrence Kirby)
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <EhNd3.96085$_m4.1006...@news2.giganews.com>
           nos...@nosite.com "Paul Lutus" writes:

...

>Finally, you will try to compare a double and a float, arguing that they are
>really the same number. If you compare them directly, you will get the
>expected results. If you use memcmp(), you will not.

This isn't a problem since...

>Helmut Leitner wrote in message <377738B4.97C7...@hls.via.at>...
>>Let's assume that a and b have the same basic data type

--
-----------------------------------------
Lawrence Kirby | f...@genesis.demon.co.uk
Wilts, England | 70734....@compuserve.com
-----------------------------------------

    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Helmut Leitner  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: Helmut Leitner <leit...@hls.via.at>
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?

Paul Lutus wrote:

> << Is it possible to construct such a general system to work in a portable
> way on all platforms? >>

> No, this is not possible.
> There are any number of reasons an entire structure's
> components will not compare successfully
> even though each of the data components are comparable.

Even if the whole data structure is "initialized" in
the best possible way (to be determined)?

> Some have to do with differences between platforms,

This is a bit cryptic to me. If there is no general, portable
way to make memcmp() work, then of course there must be differences
between platforms. But your statement doesn't tell anything...

> some have to do with differences between structures on a single platform.

If we define
   struct test sa,sb;
and initialize them properly (to be determined)
   TestClear(&sa);
   TestClear(&sb);
what can be the differences between these structures.

> Finally, you will try to compare a double and a float

Look at my first sentence (the basic assumption):
  "Let's assume that a and b have the same basic data type"
This clearly excludes comparing pears and apples.

--
Helmut Leitner    leit...@hls.via.at  
Graz, Austria   www.hls-software.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Lutus  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Paul Lutus" <nos...@nosite.com>
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
<< Even if the whole data structure is "initialized" in the best possible
way (to be determined)? >>

Yes. Consider otherwise acceptable data types for C comparisons, such as a
short and a long, or a float and a double (floating-point errors aside).
This is apart from any platform-related issues.

<< Look at my first sentence (the basic assumption): "Let's assume that a
and b have the same basic data type" This clearly excludes comparing pears
and apples. >>

Not at all, and complying C compilers have no objection. Example:

#include <stdio.h>

struct testA {
 short orange;
 long apple;

};

struct testB {
 long orange;
 short apple;

};

struct testC {
 float orange;
 double apple;

};

struct testD {
 double orange;
 float apple;

};

void testPrint(char *prompt, int v)
{
 printf("%s: %s\n",prompt,(v)?"True":"False");

}

int main()
{
 struct testA w = {333,333};
 struct testB x = {333,333};

 struct testC y = {333.125,333.125};
 struct testD z = {333.125,333.125};

 testPrint("member 1 comparison",(w.orange == x.orange));
 testPrint("member 2 comparison",(w.apple == x.apple));
 testPrint("memcmp() comparison", !memcmp(&w,&x,sizeof(w)));

 testPrint("member 1 comparison",(y.orange == z.orange));
 testPrint("member 2 comparison",(y.apple == z.apple));
 testPrint("memcmp() comparison", !memcmp(&y,&z,sizeof(y)));

 return 0;

}

Q.E.D. -- memcmp() is asking for trouble, even on the same platform.
--

Paul Lutus
www.arachnoid.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Heathfield  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: "Richard Heathfield" <compla...@eton.powernet.co.uk>
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
Paul Lutus <nos...@nosite.com> wrote in article
<VS_d3.97674$_m4.1066...@news2.giganews.com>...

<snip>

Paul - you are twisting the sense of the thread right out of shape.

The original question was:

"Let's assume that a and b have the same basic data type
(e.g. int, long, float, double ...). On many platforms it is possible to
replace the comparisions a==b, a!=b by memcmp(&a,&b,sizeof(a))==0,
memcmp(&a,&b,sizeof(a)) - What are the conditions that this will not yield
the desired results?"

Now, there is no way that you can equate y.orange == z.orange with y == z
without twisting reality somewhat. (Comparison of structs using == is of
course not legal C.) And since by your definition y.orange is a float and
z.orange is a double, you are off-beam there too, because a float is not a
double.

You have set up a straw man and you are now giving him a good pasting. But
this does not contribute in any way to answering the original question.

It pains me to see a usually logically-minded person "losing it" in this
fashion. /Please/ read before you think before you post.

(This whole reply would have gone to email if only I had an email address
to send it to. I'm tempted to set one up for you myself.)

--
Richard Heathfield

The bug stops here.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Mesken  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: usur...@euronet.nl (Paul Mesken)
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
On Mon, 28 Jun 99 23:58:28 GMT, f...@genesis.demon.co.uk (Lawrence

If you would want to do that, sure. But the question was about how
equal the memcmp version was to the equality operator version with a
and b being of the same basic data type.

I've seen interesting incompatibilities posted which I didn't think of
myself (how a pointer is stored, the floats (I never do floats) and
particular bit representation schemes for negative numbers) but mine
is the only one that results in an error :-)


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Helmut Leitner  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: Helmut Leitner <leit...@hls.via.at>
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?

 > Firstly any basic type except unsigned char can have "holes" or unused

> bits that don't contribute to the value.

That's what I try to *really* understand.
At the moment (with your help and the other's contributions)
I see five different problems.

A. Clearing the structures including all bits and bytes that
   may not be directly used for component content.

   Solving this problem would result in a
      StructClear(void *p,size_t size);
   My naive implementation for this was  
      memset(p,'\0',size);      

   Might it be possible that this does not reach all bits
   in memory? Could a fp-only implementation (say 96 bit cpu)
   use 64 mantissa-bits for char/int/long/... ?
   So that the memset above would not delete all bits used
   for fp data representation?
   Might it be possible in such cases to switch to a different
   basic data type for the clearing process?
   Can such a data type be selected in a portable way?

B. Assignment to structure components without using
   ambiguous bit representations.  

   Solving this problem would result in a set of
   assignment-functions:

   void IntSetVal(int *pi,int val)
   {
      if(val==0) {
         *pi=0;     /* to avoid the +0/-0 problem */
      } else {
         *pi=val;
      }
   }    

   void StrSizeSetVal(char *d,size_t size,char *s)
   /* usable only for "flat" string components */
   {
      memset(d,'0',size);
      strcpy(d,s); /* no safety intended */
   }  

   void DoubleSetVal(double *pd,double val)
   {
      switch(fpclassify(val)) {
         case FP_INFINITE:
            *pd=INFINITE;
            break;  
         case FP_NAN:
            *pd=NAN;
            break;  
         case FP_ZERO:
            *pd=0.0;
            break;  
         case FP_SUBNORMAL:
            *pd=val; /* no clue, what to do here
            break;
         case FP_NORMAL: default:
            *pd=val;
            break;
      }
   }

   and similar functions:
   void LongSetVal(...)
   void FloatSetVal(...)
   ....

   This leaves the problem of ambiguous pointer representation
   open. Although for some cases (DOS segmented pointer) it might
   be easy to normalize the pointers, I don't know what problems
   could arise on other platforms.

C. Comparing the data structures sa and sb without leaving
   out bits that are used by some component data representation.

   Solving this problem would result in a reliable
   struct-memory-compare functions.

      int StructCmp(void *psa,void *psb,size_t size)
      {
         int ret=memcmp(psa,psb,size);
         if(ret==0) {
            /* what code needed here ??? */
            /* absurd, only to fill the void: */
            while(size>sizeof(double) && ret==0) {
               ret= (*(double *)psa != *(double *)psb)
               size-=sizeof(double);
               psa+=sizeof(double);  
               psb+=sizeof(double);  
            }
         }
         return(ret);
      }

   My naive implementation for this was  
      memcmp(psa,psb,sizeof(*psa));

D. Similar to C, the problem of getting at all bits that
   carry component information e.g. for calulating a hash
   value. Will be solved when C ist solved.

E. May the system touch/change unused padding bytes within
   a structure at will?

> So these bits can differ (hence
> memcmp() will return non-zero) for values that compare equal.

> In 1's complement and sign-mangitde format integers 0 and -0 have
> different bit representations but compare equal.

I tried to account for this in the assignment function.

> In floating point formats such as IEEE-754 there can also be different
> representations for 0 and -0. I believe in some floating point
> formats there are a large number of representations for zero. Some
> floating point formats such as IEEE-754 also create the opposite
> problem, NaNs compare unquual to anything even other NaNs so it is possible
> for values with identical bit patterns to compare unequal.

I tried to simplify the problem by reducing it.
In a real system I woulkd not allow NaNs to creep in, so
this problem would not give me bad dreams.

> Pointers can have different representations for the same address (e.g.
> in segnemted archatectures like the 8086). They can also contain other
> information such as boundary information (these are sometimes called fat
> pointers). So pointers with different bit patterns can compare equal.

Has this to do with access rights?

Would stripping these "fat pointer bits" be possible?

Could we assume, that after
   char PiStr[]="3.14159";
   ...
   char *p=PiStr;
   ...             /* maybe different module */
   char *q=PiStr;
the pointers p and q have the same bit representation?

> Structures and unions can include padding bytes. Since padding does not
> contribute to the structure or union's value I don't see anything that
> prohibits this padding from changing arbitrarily. There can also be
> padding bits where bit-fields are involved.

I try to clear all these bits and bytes and hope/expect
that "the system" will not quietly change them.
Is this unreasonable?

No problem here. It is a question of portability.

> and define a macro you can test for
> those platforms which fit the bill. However there are lots of
> different ways to fail.

I'll try to understand as many of them as possible.

--
Helmut Leitner    leit...@hls.via.at  
Graz, Austria   www.hls-software.com


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
alex_krol  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: Alex_K...@scitex.com
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <3778C338.1ED86...@hls.via.at>,
  Helmut Leitner <leit...@hls.via.at> wrote:

      No, memset looks at an object as an array of unsigned chars;
since there are no holes or paddings in unsigned char, memset reaches
all bits.

    The problem is - no data type except unsigned chars is guaranteed
not to have holes in its binary representation. So, for example,
      int a,b;
      a = 1;
      b = 1;
  -then memcmp(&a,&b,sizeof int) is not guaranteed to compare equal.

    if memcmp returns 0, stuctures *are* equal; the problem is when it
returns non-zero - they still may be equal, except padding bits.

> D. Similar to C, the problem of getting at all bits that
>    carry component information e.g. for calulating a hash
>    value. Will be solved when C ist solved.

> E. May the system touch/change unused padding bytes within
>    a structure at will?

   Nothing forbids it.

    No.

> > Probably the simplest thing to do would be to veryify the platforms
> > you are interested in yourself

> No problem here. It is a question of portability.

> > and define a macro you can test for
> > those platforms which fit the bill. However there are lots of
> > different ways to fail.

> I'll try to understand as many of them as possible.

   The worst possible problem is padding bytes in basic types;
bitfields also don't fit your approach. You may zero all bits
of your structure/object prior to assignment - but that doesn't buy
you much, since in case of holes in type representation you may (and
probably shall) receive padding from the rvalue.

--
        Regards,
                Alex Krol
Disclaimer: I'm not speaking for Scitex Corporation Ltd

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
rawcswi  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: rawc...@my-deja.com
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
In article <Pine.SUN.3.96.990628150217.26440A-100000@valdes>,
  FigBug <rrab...@csc.UVic.CA> wrote:

That certainly wasn't clear from your original post; it would have
helped to mention long and int.  Despite taking part in a long thread
on == with floating point, I still don't even know for sure whether
   double a,b;
   a=1.1;
   b=a;
implies that a==b afterward, let alone declaring a as float and
leaving b as double.  But I am certain that memcmp could
only be worse.

--
MJSR

Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Szu-Wen Huang  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: hu...@mnsinc.com (Szu-Wen Huang)
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?
Helmut Leitner (leit...@hls.via.at) wrote:

[...]
: At the moment (with your help and the other's contributions)
: I see five different problems.
[...]

Wouldn't the solution to these five problems outweigh the cost
of just writing a function to compare the two structures?  If
I was maintaining this program, I'd probably find the mechanism
surprising.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Bill Godfrey  
View profile   Translate to Translated (View Original)
 More options 29 June 1999, 08:00
Newsgroups: comp.lang.c
From: Bill Godfrey <bill-godf...@usa.net>
Date: 1999/06/29
Subject: Re: Expert-Q: (a!=b) != memcmp(&a,&b,sizeof a) ?

hu...@mnsinc.com (Szu-Wen Huang) writes:
> Sure.  Recall the strange segment:offset scheme of addressing
> on the 80x86 real mode, where the actual address is computed
> as (segment * 16 + offset).  Thus, many segment:offset pairs
> actually compute to the same address, and the equality operator
> for pointers must handle these.  Typically, they normalize the
> pointer before comparison.

Not necessarily. Under 8086, all "chunks" of memory have to sit within a
64k segment.

Imagine an arbitary array of 10 ints, at 0x1234:0x0004. When moving a pointer
about this array, only the offset needs changing. a[8] can be found at
0x1234:0x0014 (assuming 2 byte ints).
It's convient to calcuate the offset part and leave the segment well alone.

Later on, somehow the pointer 0x1233:0x0024 came along, and the code compared
== this pointer with a[8]. Using a simple bit compare, a mis-match would
be reported, even though it points to the same adress.

But wait! How did we get a pointer with value 0x1233:0x0024 in the first
place?

Underflowing or overflowing an array subscript? Bzzz. Undefined behaviour.
Pointer arthmetic outside an object's bounds? Bzzz. Undefined behaviour.
(int*)(0x12330024) ? Implementation defined.

Point is, a compiler targeting 8086 can get away with not normalising a
pointer, so long as it does not do any normalising anywhere else.
(Documenting the effect of comparing casted pointers notwithstanding.)
If just pointer gets normalised, then all pointers have to be normalised.

Anyway, I may have missed a legal way to get two representations of a
single pointer under my scheme, so look for any follow-ups before responding.

Bill, normal.


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 43   Newer >
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google