bartc said:
Interesting. I developed a pretty much parallel language to C in the
1980's.
That /did/ have struct compares, and it seemed work!
However, my structs didn't have 'holes', as I knew nothing about C's method
of automatic padding (I did this manually as needed.)
Even with holes, I can imagine various schemes to compare two structs that
would not require an arbitrarily large amount of code (such as looping
through a bitmap showing the bytes that need to match, or finding out
exactly what the difficulty is in making sure padding bytes are zero) .
Padding bytes (and padding bits, for bit-fields) mightn't
be the only problem. For example:
struct { char c[100]; }
x = { "Hello" }, y = { "Hello" };
x.c[99] = 'x';
y.c[99] = 'y';
assert (strcmp(x.c, y.c) == 0);
assert (x == y); /* ??? */
The structs x,y are "equal" if their c arrays are thought of
as containing strings, "unequal" if they're thought of as
holding a hundred characters each. A related issue:
char xdata[] = "Hello", ydata[] = "Hello";
struct { char *p; }
x = { xdata }, y = { ydata };
assert (strcmp(x.p, y.p) == 0);
assert (x.p != y.p);
assert (x == y); /* ??? */
It would certainly be possible to define struct equality
as meaning "corresponding elements' values are equal," meaning
that the final assert() in each example would fail. But would
this be useful? Sometimes, perhaps, for "pure value" structs
like `struct point { int x, y; }'. But even for a tiny step
beyond simplicity it seems to me the programmer wants finer
control over which elements do and do not count towards "equal."
In `struct point { int x,y; struct point *next; }', for example,
it's likely that x,y would participate in the test but that the
linked list pointer would not.
How would you compare two union values anyway? Unless the union members are
all the same size, this could just result in a compilation error.
There's trouble even if they're the same size. Just suppose
float and int are the same size (as in a recent thread):
union { float f; int i; } x, y;
x.f = 42;
y.i = 42;
assert (x.f == y.i);
assert (x == y); /* ??? */
The compiler has no way to know which element it should check
for equality, since a union can contain different elements at
different times.
But a substantial stretch of user-code (which must be maintained as the
struct changes) is acceptable...
Since it gives the programmer something of value -- namely,
a way to control which elements participate in the test, and what
notion of "equality" applies to them -- yes, I think so.
I think having a default struct-compare feature in the language would have
been useful.
For self-contained "value" structs, maybe. For others, I'm
not convinced. But try the experiment for yourself: Look through
a pile of code and find the places where structs are tested for
some kind of "equality." See if you think an automatically-
generated test would have worked instead of the hand-coded kind.
(The experiment isn't perfect, of course, but may be informative.)