473,385 Members | 1,341 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Comparing structs...


Is it legal to compare the contents of two multi-field variables (of the
same struct) using "==" and "!="?

struct
{
int a;
int b;
} x,y;

...

if (x==y) // ?
Or is there a chance that the compiler may, for whatever reason, use
different layouts/paddings for the two variables even though they are of the
same struct?
Mar 29 '06 #1
12 25923
"barcaroller" <ba*********@music.net> writes:
Is it legal to compare the contents of two multi-field variables (of the
same struct) using "==" and "!="?

struct
{
int a;
int b;
} x,y;

...

if (x==y) // ?
No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)
Or is there a chance that the compiler may, for whatever reason, use
different layouts/paddings for the two variables even though they are of the
same struct?


The layout is determined by the type, so that's guaranteed to be the
same. Specifically, the size and offset of a and b, and the size of
the entire struct, is the same for x as it is for y. This would be
a bit clearer if you gave the struct type a name:

struct foo {
int a;
int b;
};

struct foo x, y;

You can use memcmp() to determine whether two objects have the same
representation (this examines all the bits), but the compiler is free
to insert padding between members or after the last one, and the
contents of the padding can be garbage.

The only real way to compare x and y is to compare each member
explicitly:

x.a == y.a && x.b == y.b

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 29 '06 #2
On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:

No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)


Just curious: why? (Is assignment defined but not == an !=.)

It would think that if you are capable of copying one object to an other
you should also be capable of comparing them?

Regards,
Mark.

Mar 29 '06 #3
Mark <ma****@tiscali.nl> wrote in news:pan.2006.03.29.05.43.47.997972
@tiscali.nl:
On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:

No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)


Just curious: why? (Is assignment defined but not == an !=.)

It would think that if you are capable of copying one object to an other
you should also be capable of comparing them?


I don't claim to know what the actual rationale is but the following
argument for not specifiying how structs should be compared makes sense to
me.

Comparison is not well defined. For example, if the struct has pointer
members, does equality mean equality of pointers, or equality of values
pointed to by those pointers.

Or, are all fields relevant for the comparison?

Sinan

--
A. Sinan Unur <1u**@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)
Mar 29 '06 #4
>On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:
No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)

In article <pa****************************@tiscali.nl>
Mark <ma****@tiscali.nl> wrote:Just curious: why? (Is assignment defined but not == an !=.)


It would, I think, have been reasonable[%] for Standard C to have
defined both equality and relational operators for "struct"s,
using the "obvious" definition that:

s1 comparison_op s2

would "mean":

s1.field1 comparison_op s2.field1 &&
s1.field2 comparison_op s2.field2 &&
...
s1.fieldN comparison_op s2.fieldN

Note, however, that in the general case -- using relational operators,
or using equality operators on structures that contain padding --
this would compile to many instructions on most machines. On most
systems today, the ordinary assignment operators compile to just
a few instructions: either an inlined memcpy(), or an actual call
to memcpy(), in most cases.

For a concrete example:

struct big { int n; char c; unsigned short j; double v[1000]; };

struct big v1, v2;
...
v1 = v2;

generally compiles to the equivalent of "memcpy(&v1, &v2, sizeof v1)",
while under this proposal, even:

v1 == v2

would compile to at least two separate comparisons, and probably
at least four: one for v1.n vs v2.n, one for v1.c vs v2.c, and for
v1.j vs v2.j, and perhaps one call to a support library loop for
v1.v vs v2.v. (Note that NaN != NaN but +0.0 == -0.0, so simple
bitwise comparisons will fail for "double"s. So while the first
three comparisons might actually be doable with memcmp(), provided
there is no padding between "c" and "j", the last one cannot.)

[% Or at least not totally *un*reasonable.]
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Mar 29 '06 #5
"A. Sinan Unur" <1u**@llenroc.ude.invalid> writes:
Mark <ma****@tiscali.nl> wrote in news:pan.2006.03.29.05.43.47.997972
@tiscali.nl:
On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:
No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)


Just curious: why? (Is assignment defined but not == an !=.)

It would think that if you are capable of copying one object to an other
you should also be capable of comparing them?


I don't claim to know what the actual rationale is but the following
argument for not specifiying how structs should be compared makes sense to
me.

Comparison is not well defined. For example, if the struct has pointer
members, does equality mean equality of pointers, or equality of values
pointed to by those pointers.

Or, are all fields relevant for the comparison?


I don't think it would make sense to follow pointer members, any more
than "==" on pointers should compare the objects they point to.

There are two plausible ways to define structure comparison. One
would be equivalent to memcmp(), but that would cause problems with
padding bytes. Defining it apply "==" to each member (and each
recursively to members of members) makes sense (<OT>Ada does
this</OT>), but it requires the compiler to generate considerable code
for (x == y), which is generally considered to be against the "spirit
of C".

If you want to compare structures, you can write a function to do the
comparison (though it might be more convenient if the compiler did it
for you). And if you write it yourself, you can allow for cases where
you *don't* want to compare all the members:

struct my_string {
size_t len;
char str[MAX];
};

or where you want to follow pointers:

struct my_string {
size_t len;
char *str;
};

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 29 '06 #6
but the compiler is freeto insert padding between members or after the
last one..

Then How we can prevent the padding from compiler...

Mar 29 '06 #7
"code break" <pk*****@gmail.com> writes:
but the compiler is freeto insert padding between members or after the
last one..
I wrote that. Learn to quote. Read <http://cfaj.freeshell.org/google/>.
Then How we can prevent the padding from compiler...


<http://www.c-faq.com/struct/padding.html>

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 29 '06 #8
A. Sinan Unur wrote:
Mark <ma****@tiscali.nl> wrote in news:pan.2006.03.29.05.43.47.997972
@tiscali.nl:

On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:

No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)


Just curious: why? (Is assignment defined but not == an !=.)

It would think that if you are capable of copying one object to an other
you should also be capable of comparing them?

I don't claim to know what the actual rationale is [...]


Fortunately, the committee that wrote the Standard also
wrote (... wait for it ...) the Rationale! 6.5.9:

"The C89 Committee considered, on more than one occasion,
permitting comparison of structures for equality. Such
proposals foundered on the problem of holes in structures.
A byte-wise comparison of two structures would require
that the holes assuredly be set to zero so that all holes
would compare equal, a difficult task for automatic or
dynamically allocated variables. The possibility of union-
type elements in a structure raises insuperable problems
with this approach. Without the assurance that all holes
were set to zero, the implementation would have to be
prepared to break a structure comparison into an arbitrary
number of member comparisons; a seemingly simple expression
could thus expand into a substantial stretch of code, which
is contrary to the spirit of C."

--
Eric Sosman
es*****@acm-dot-org.invalid

Mar 29 '06 #9
On Wed, 29 Mar 2006 07:33:52 -0500, Eric Sosman wrote:
A. Sinan Unur wrote:
Mark <ma****@tiscali.nl> wrote in news:pan.2006.03.29.05.43.47.997972
@tiscali.nl:

On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:
No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)
Just curious: why? (Is assignment defined but not == an !=.)

It would think that if you are capable of copying one object to an other
you should also be capable of comparing them?

I don't claim to know what the actual rationale is [...]


Fortunately, the committee that wrote the Standard also
wrote (... wait for it ...) the Rationale! 6.5.9:

"The C89 Committee considered, on more than one occasion,
permitting comparison of structures for equality. Such
proposals foundered on the problem of holes in structures.
A byte-wise comparison of two structures would require
that the holes assuredly be set to zero so that all holes
would compare equal, a difficult task for automatic or
dynamically allocated variables. The possibility of union-
type elements in a structure raises insuperable problems
with this approach. Without the assurance that all holes
were set to zero, the implementation would have to be
prepared to break a structure comparison into an arbitrary
number of member comparisons; a seemingly simple expression
could thus expand into a substantial stretch of code, which
is contrary to the spirit of C."


But ofcource!! the padding, why didn't I think of that?! :)

Thanks, everyone, for the answer.

Regards,
Mark,

Mar 29 '06 #10
On 2006-03-29, Keith Thompson <ks***@mib.org> wrote:
"A. Sinan Unur" <1u**@llenroc.ude.invalid> writes:
Mark <ma****@tiscali.nl> wrote in news:pan.2006.03.29.05.43.47.997972
@tiscali.nl:
On Wed, 29 Mar 2006 01:30:55 +0000, Keith Thompson wrote:
No, the "==" and "!=" operators are not defined for structs.
(Assignment is, though.)

Just curious: why? (Is assignment defined but not == an !=.)

It would think that if you are capable of copying one object to an other
you should also be capable of comparing them?


I don't claim to know what the actual rationale is but the following
argument for not specifiying how structs should be compared makes sense to
me.

Comparison is not well defined. For example, if the struct has pointer
members, does equality mean equality of pointers, or equality of values
pointed to by those pointers.

Or, are all fields relevant for the comparison?


I don't think it would make sense to follow pointer members, any more
than "==" on pointers should compare the objects they point to.

There are two plausible ways to define structure comparison. One
would be equivalent to memcmp(), but that would cause problems with
padding bytes. Defining it apply "==" to each member (and each
recursively to members of members) makes sense (<OT>Ada does
this</OT>), but it requires the compiler to generate considerable code
for (x == y), which is generally considered to be against the "spirit
of C".


A compiler could use memcmp and ensure that all padding bits/bytes are
always equal to zero.

It doesn't take considerable code to use "=" on a struct, or to pass or
return it? returning structs was once very messy.
Mar 29 '06 #11
Jordan Abel <ra*******@gmail.com> writes:
On 2006-03-29, Keith Thompson <ks***@mib.org> wrote: [...]
There are two plausible ways to define structure comparison. One
would be equivalent to memcmp(), but that would cause problems with
padding bytes. Defining it apply "==" to each member (and each
recursively to members of members) makes sense (<OT>Ada does
this</OT>), but it requires the compiler to generate considerable code
for (x == y), which is generally considered to be against the "spirit
of C".


A compiler could use memcmp and ensure that all padding bits/bytes are
always equal to zero.


How could it ensure that all padding is always zero? Consider structs
allocated by malloc(). Consider structs read from a file (which
introduces portability problems anyway, but at least it works when the
same program writes and reads the same file).

Also consider members that are unions, floating-point members that
might be NaNs, and pointer members on an implementation where pointer
equality can't be done as a bitwise comparison.

Even if all this were worked out, the resulting "==" operator wouldn't
necessarily correspond to what the user wants to do. And how often do
you really want to compare structures for equality anyway?

All these things could have been resolved, but I agree with the
committee that it wasn't worthwhile.
It doesn't take considerable code to use "=" on a struct, or to pass or
return it? returning structs was once very messy.


It's not nearly as messy as "==" would be -- and considerably more
useful.

There's always a tradeoff in deciding whether to add a feature to the
language, and it can always be argued that the decision should have
been made differently.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 29 '06 #12
On Wed, 29 Mar 2006 21:19:40 GMT, in comp.lang.c , Keith Thompson
<ks***@mib.org> wrote:
Jordan Abel <ra*******@gmail.com> writes:
On 2006-03-29, Keith Thompson <ks***@mib.org> wrote:[...]
A compiler could use memcmp and ensure that all padding bits/bytes are
always equal to zero.


How could it ensure that all padding is always zero? Consider structs
allocated by malloc().


There are several ways this could be done, but they'd impose a
significant performance penalty. For instance the compiler could
insist that all struct padding bits are set to zero when a struct is
created, or it could copy the struct before comparison, find and zero
any padding bits, then do the compare.
Also consider members that are unions, floating-point members that
might be NaNs, and pointer members on an implementation where pointer
equality can't be done as a bitwise comparison.


These are rather more significant issues, I suspect.

Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Mar 29 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Alatarie | last post by:
Hi all, This is probably a stupid question but I've been out of the c++ thing for a while... I'm trying to make a vector of structs. Each time I create a struct: struct RECORDS { int id;...
8
by: Martin Marcher | last post by:
Hi, I'm working on a program that creates a linear list of structs struct lin_list{ struct lin_list *next; char Name; }; this is what it looks like. And i got (design) problems with the...
18
by: Rick | last post by:
Hi, We all know that Java has classes but how about basic storage objects like structs? C and C++ have Structs, Pascal has Records, Visual Basic has Types etc. How about Java? Greetings, Rick
5
by: Bob Gregory | last post by:
Hi all, I'm utter C# newbie, do be gentle. VS2005 Express refuses point blank to install on my box, so I'm stuck with C# 1.0 unless someone can point me to a C#2.0 compiler elsewhere. I have...
5
by: ma740988 | last post by:
There's a need for me to move around at specified offsets within memory. As as a result - long story short - unsigned char* is the type of choice. At issue: Consider the case ( test code ) where...
19
by: Ole Nielsby | last post by:
How does the GetHashCode() of an array object behave? Does it combine the GetHashCode() of its elements, or does it create a sync block for the object? I want to use readonly arrays as...
61
by: Marty | last post by:
I am new to C# and to structs so this could be easy or just not possible. I have a struct defined called Branch If I use Branch myBranch = new Branch(i); // everything works If I use Branch...
2
by: Zytan | last post by:
I wanted to do something simple like checking my own Color variable against Color.Black, and == returned false, even though their RGB values were all 0! Of course, there's the A (alpha) value, but...
50
by: titan nyquist | last post by:
I wish to compare two structs via == but it does not compile. I can overload and create my own == but am I missing something that c# already has implemented? ~titan
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.