== operator on struct

I

indigodfw

Greetings from India

I would like to know the rationale on allowing structs to be assigned
(using = operator) and not allowing equality operator ( == operator) on
them.

The compiler when it assigns using = is aware of holes etc and the same
compiler then should be able to generate code to compare the individual
struct fields.

When a new field is added to the struct, all such instances where the
== using individual field is compared need to be modified and is a real
pain. :-(

Thanks in advance,
- Sushil Ramaswamy
 
E

Eric Sosman

Greetings from India

I would like to know the rationale on allowing structs to be assigned
(using = operator) and not allowing equality operator ( == operator) on
them.

If you want to know the rationale, Google for

..

..

..

..

..

..

(wait for it ...)

..

..

..

..

..

..

"C Rationale"!!!!

(Unfortunately, the Rationale doesn't explain why the
committee gave such a counter-intuitive name to the
Rationale. I mean, who in his right mind would use
the word "Rationale" when trying to find a rationale?
It's irrational, that's what.)
 
A

Anonymous 7843

I would like to know the rationale on allowing structs to be assigned
(using = operator) and not allowing equality operator ( == operator) on
them.

The compiler when it assigns using = is aware of holes etc and the same
compiler then should be able to generate code to compare the individual
struct fields.

When a new field is added to the struct, all such instances where the
== using individual field is compared need to be modified and is a real
pain. :-(

Such a feature isn't as useful as it might seem.

- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases.

- the larger the struct, the more likely there are members which
are uninteresting for comparison purposes.

- if there was a struct-equality operator, then eventually some
gmail or yahoo user would come along and ask why there are
no struct-inequality operators, and if those existed, why
can't they be passed to bsearch() and qsort(), and if they
could why can't they be parameterized to give different
weight and ordering to different struct members...

- a complicated equality operator works against the basic C principle
that the basic operation of the language map to very short
(and fast) sequences of cpu instructions.
 
C

CBFalconer

Greetings from India

I would like to know the rationale on allowing structs to be assigned
(using = operator) and not allowing equality operator ( == operator) on
them.
From the C-Rationale:

"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."
 
A

Alan Balmer

Greetings from India

I would like to know the rationale on allowing structs to be assigned
(using = operator) and not allowing equality operator ( == operator) on
them.

The compiler when it assigns using = is aware of holes etc

You're making an unwarranted assumption here. For a simple assignment,
the compiler doesn't need to consider the holes, only the size of the
structure.
 
K

Keith Thompson

CBFalconer said:
"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."

In contrast, struct assignment is very simple; it's just the
equivalent of a memcpy(). The compiler doesn't have to worry about
gaps. It can just copy the whole object, gaps and all.

Structure comparison isn't a completely crazy idea; there are
languages that support it. In fact, I've worked on Ada compiler
support for record (structure) comparison. The initial version
required all record objects to be zero-filled, so equality comparisons
for records with gaps could be done by the equivalent of a memcmp().
A later implementation generated code to do an equality comparison on
each record element in turn (using the appropriate operator for each
element type).
 
I

indigodfw

Several people have replied. Thanks to all.
However I remain unconvinced. (I should have mentioned I'm relatively
new to C).

"- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases."

Does it mean that two floating point numbers may not compare equal (
even if they are equal and they are not part of a struct) - what has
this to do with being a member of struct ??

The remaining points are do not make any logical point to me. It does
not matter how useful this may be or some user from yahoo may ask
something else etc.

Some others have mentioned about holes.
Does it mean that compiler can just take sizeof struct and do a copy
when doing =.
I thought that the compiler may not touch the holes. Does the standard
say it's ok to access holes? The compiler still knows holes when it
extracts members so why is it hard for the compiler to compare the
members it extracted?

I'm really curious why == can not be done by compiler. May be some
compiler writer have some insight or I'm not understanding the reasons
well. :-(

In any case, thanks for everyone's replies. I would appreciate more
crystal clear replies.
With best regards,
-Sushil
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Several people have replied. Thanks to all.
However I remain unconvinced. (I should have mentioned I'm relatively
new to C).

"- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases."

Does it mean that two floating point numbers may not compare equal (
even if they are equal and they are not part of a struct)

Yes. two floating point numbers may not compare equal even if your logic
implies that they should be equal

Think of this:
start a float variable at 2.9
add 0.1 to it
add 0.1 to it
is the variable now equal to 3.1?

Try it

Floatingpoint variables are 'imprecise', in that the variable doesn't always
hold the exact figure that the programmer thinks it does. FP variables are
approximations, in part because they can't express all the digits of a
fraction (how many digits does it take to hold the exact value of 1./3. ?) and
partially because they are sometimes not computed or stored as decimal numbers
(0.3 is 1/4 + 1/32 + ... )

So, in general it is better to compare floatingpoint numbers to a delta
(f1-f2 < allowable_range_for_equal) rather than to each other.

- what has
this to do with being a member of struct ??

Nothing. But because you can't reliably compare as equal two floatingpoint
numbers, you can't reliably compare as equal two structures /that contain/
floatingpoint numbers.
The remaining points are do not make any logical point to me. It does
not matter how useful this may be or some user from yahoo may ask
something else etc.

Some others have mentioned about holes.
Does it mean that compiler can just take sizeof struct and do a copy
when doing =.
Yes

I thought that the compiler may not touch the holes.

Depends on what you mean by "may not touch". the padding isn't directly
referencable, but the mechanism that the compiler implements to perform
assignment /may/ copy the padding without evaluating it's contents.
Does the standard
say it's ok to access holes?

Not AFAIK

[snip stuff I can't speak to]


- --
Lew Pitcher

Master Codewright & JOAT-in-training | GPG public key available on request
Registered Linux User #112576 (http://counter.li.org/)
Slackware - Because I know what I'm doing.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFCxq30agVFX4UWr64RAvS3AKDlW09QN6lbkf6ADidaR0w12jOmigCfU6hb
amxb/Ub/mPfh69/GDBRc+ug=
=v2OT
-----END PGP SIGNATURE-----
 
C

CBFalconer

Several people have replied. Thanks to all. However I remain
unconvinced. (I should have mentioned I'm relatively new to C).

"- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases."

Does it mean that two floating point numbers may not compare equal (
even if they are equal and they are not part of a struct) - what has
this to do with being a member of struct ??

Yes. The result being that, if a member of a struct, you can't
trust any equality comparison involving that structure. Any time
you do an equality comparison between floats you have a potential
problem. gcc can be told to warn you on that. I routinely enable
that warning. I think it is -Wfloat-equal.
 
K

Keith Thompson

Several people have replied. Thanks to all.
However I remain unconvinced. (I should have mentioned I'm relatively
new to C).

"- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases."

Does it mean that two floating point numbers may not compare equal (
even if they are equal and they are not part of a struct) - what has
this to do with being a member of struct ??

Nothing directly, except it means that floating-point equality
comparisons would be hidden behind a struct comparison. If you
compare floating-point numbers directly, it's more obvious (or it
should be) that you're doing something questionable.

Another issue is struct members that happen to be unions. There's no
way to determine which member of the union should be compared. If
struct comparison were added to the language, this would have to be
resolved, either by making an arbitrary choice (compare the first
declared union member), making it undefined behavior (something the
language doesn't need any more of), or disallowing struct comparison
for structs that contain unions.

[...]
Some others have mentioned about holes.
Does it mean that compiler can just take sizeof struct and do a copy
when doing =.
Yes.

I thought that the compiler may not touch the holes. Does the standard
say it's ok to access holes?

It doesn't say it isn't ok, so as long as it doesn't affect the
visible behavior of the program there's nothing wrong with it.
The compiler still knows holes when it
extracts members so why is it hard for the compiler to compare the
members it extracted?

To extract a member, the compiler has to know the offset and size of
the member. It doesn't have to worry about any gaps between the
member and any adjacent members. It doesn't matter whether the byte
following a member is a gap or another member (the compiler *might*
use this information for optimization in some cases, but it doesn't
have to).

For an equality comparison, the compiler would have to analyze the
entire layout of the structure, including where the gaps are and, on
many systems, the types of the members -- and this would have to be
done recursively for any nested structures.
I'm really curious why == can not be done by compiler. May be some
compiler writer have some insight or I'm not understanding the reasons
well. :-(

It *could* be done by the compiler. It's just not considered to be
worth the trouble. Most operations in C map more or less directly to
machine-level operations (part of what's known as the "spirit of C").
Struct equality comparison would be an exception to this general
principle.

And, in my experience, structure equality comparison just isn't used
that often. It's more common to want to know whether two structures
represent the same *logical* value. For example, if I have a
structure type that represents a dynamic string, I'll want to know
whether two objects represent the same string value. A
member-by-member comparison of the structures is unlikely to tell me
this; I need to write a separate function.

That's not to say that it wouldn't sometimes be uesful, but there's
always a tradeoff between complexity and usefulness. In this case,
you seem to be on the losing end of that tradeoff. Sorry, but it
happens to all of us.

Note that this was a design choice made by the authors of the
standard. The decision could have gone the other way. You're
obviously one of those who wish it had. No language is perfect; there
are plenty of things in C that I disagree with (though this isn't one
of them).
 
L

Lawrence Kirby

Several people have replied. Thanks to all.
However I remain unconvinced. (I should have mentioned I'm relatively
new to C).

"- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases."

Does it mean that two floating point numbers may not compare equal (
even if they are equal and they are not part of a struct) - what has
this to do with being a member of struct ??

Floating point calculations are in most cases inexact i.e. the results are
approximations. Comparing approximate results for equality (i.e.
exactness) is potentially a logical flaw. Doing this in a struct is
dangerous because strucure comparison effectively hides the fact that
floating point comparisons are involved. Besides there are lots of
different ways you coul compare the members of a struct and very often you
don't want to involve all structure members in such a comparison. For
example in a linked list you might want to compare the data held in a node
but it would be an error to include the link pointer in the comparison.

In short structure comparison isn't a trivial operation to implement to
give reqsonable results and even then typically doesn't implement what you
need in practice. It is better to code the comparison you need explicitly.
The remaining points are do not make any logical point to me. It does
not matter how useful this may be or some user from yahoo may ask
something else etc.

Usefulness is important. A simple language is better than a complex
language in many ways, it is easier to learn, easier to read, easier to
implement. So unless a feature provides a real, significant benefit to a
language you are often better off leaving it out.
Some others have mentioned about holes. Does it mean that compiler can
just take sizeof struct and do a copy when doing =. I thought that the
compiler may not touch the holes. Does the standard say it's ok to
access holes? The compiler still knows holes when it extracts members so
why is it hard for the compiler to compare the members it extracted?

The compiler can copy padding bytes if it wants to since they don't
contribute to the value of the struct.
I'm really curious why == can not be done by compiler. May be some
compiler writer have some insight or I'm not understanding the reasons
well. :-(

We're not saying that it can't be done, just that supporting this would
add little if any utility to the language, but it would create a whole
can of worms.

Lawrence
 
W

websnarf

Several people have replied. Thanks to all.
However I remain unconvinced. (I should have mentioned I'm relatively
new to C).

"- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases."

Does it mean that two floating point numbers may not compare equal (
even if they are equal and they are not part of a struct) - what has
this to do with being a member of struct ??

Yes, 0 and -0 are the same number but can be represented in two
different ways in the IEEE-754 standard.

But there are worse problems -- NaN != x is true for *every* value of x
*including* NaN. Furthermore there are multiple representations of NaN
which are all assumed to normalize to the canonical NaN value. So even
if you wanted to subvert the IEEE-754 mechanics, and say that NaNs are
equal to each other you are screwed.

The real problem with struct comparing has, IMHO, not been addressed.
The C Rationale has been quoted here and it underscores just how short
sighted and bad the C committee's thinking is. Fortunately they seem
to have made the correct choice even if for the wrong reason.

The *REAL* reason why you can't sanely do struct comparison is because
a struct may contain a char array[] entry:

struct test1 {
char name[256];
} x, y;

Ok, so if you "struct compared" the variables x and y, what do you
expect to happen? If the name[] entry is supposed to be a
256-character array buffer, then memcmp() semantics is just fine. If
you intend that entry to be a '\0' terminated string (which you've
provided "more than adequate" space for) then what you want is strcmp()
semantics.

Worse yet, it doesn't follow the semantics when you remove the wrapping
struct declaration, if you just declare two such arrays:

char name1[256], name2[256];

Then comparing name1 and name2 compares the *pointers* and is going to
always be false, BTW.

If you were to change it to pointer comparison for the structs, then
that would just be equivalent to comparing the struct base pointers,
which you can already do today (but comparing the & of the struct
variables.)
 
I

indigodfw

Keith, Lawrence and Paul

That was quite useful piece of information.

Thank you,
CLC rocks! This is a great mailing list.

-Sushil
 
C

Coos Haak

Op 4 Jul 2005 09:30:52 -0700 schreef (e-mail address removed):
Keith, Lawrence and Paul

That was quite useful piece of information.

Thank you,
CLC rocks! This is a great mailing list.

-Sushil

This isn't a mailing list. It's a newsgroup
 
K

Kenneth Brody

Anonymous said:
Such a feature isn't as useful as it might seem.

- structs containing floating point numbers cannot be guaranteed
to ever compare as equal, except in trivial cases.

- the larger the struct, the more likely there are members which
are uninteresting for comparison purposes.

- if there was a struct-equality operator, then eventually some
gmail or yahoo user would come along and ask why there are
no struct-inequality operators, and if those existed, why
can't they be passed to bsearch() and qsort(), and if they
could why can't they be parameterized to give different
weight and ordering to different struct members...

- a complicated equality operator works against the basic C principle
that the basic operation of the language map to very short
(and fast) sequences of cpu instructions.

To take it a step further, someone would then ask "why does the
equality fail when the char* entry points to separate, yet identical,
strings?" Should this new equality operator require that pointers
point to the same object, or is it okay to point to two distinct
objects, as long as those objects themselves will compare equal?

And so on...

If the OP is many places he needs to compare structs, and is afraid
of modifying all of these places when the struct is modified in the
future, then simply write a function to do the comparison. (Not to
mention that this allows the user to define "less than" and "greater
than", which is something that the compiler can't do anything useful
with even on a simple "int month,day,year;" struct.)

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top