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? 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.
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.
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)
>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.
"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.
but the compiler is freeto insert padding between members or after the
last one..
Then How we can prevent the padding from compiler...
"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.
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
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,
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.
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.
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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;...
|
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...
|
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
|
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...
|
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...
|
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...
|
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...
|
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...
|
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
|
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...
|
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...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
|
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...
| |