struct comparison
Badger BA 64810
bbadger at x102c.harris-atd.com
Fri Jul 21 00:59:53 AEST 1989
In article <2261 at auspex.auspex.com> you write:
>>Sure, you _may_ run into special cases, but is this any reason to leave out
>>a useful operation?
>
>Well, it depends on how useful it *really* is; given enough "special
>cases", it may be that the only cases where it *is* useful are special
>cases, in which case you can whip up a macro to do the comparison.
>
>>Other languages, such as Ada (Oh no! The A-word!), provide for comparison
>>of composite objects (records in Ada correspond to structs in C).
>
>So how does Ada define comparison of records?
>From ANSI/MIL-STD-1815A 22 JAN 1983, which is sometimes called the Ada
Language Reference Manual (ALRM), section 4.5.2:
\begin{quote}
[par 1] The equality and inequality operators are predefined for any type
that is not limited.
...
[par 5] For two array values or two record values of the same type,
the left operand is equal to the right operand if and only if
for each component of the left operand there is a {\em matching component}
of the right operand, and vice versa; and the values of the matching
components are equal, as given in the predefined equality operator for
the component type. In particular, two null arrays of the same type are
always equal; two null records of the same type are always equal.
[par 6] For comparing two records of the same type, {\em matching components}
are those which have the same component identifier.
\end{quote}
>
>>Of course there should be caveats about padding data being compared.
>
>I.e., "padding data gets compared"? That doesn't sound like all that
>useful an operation to me; in order to be useful, I'd have to zero out
>structures on e.g. the stack.
>
Right, the component-by-component comparison is much safer, and is the
natural approach for Ada. Given C's low-level approach, though, I did
not want to rule out from discussion a simplistic compare-all-bytes
implementation. That's also why I pointed out some gotcha's.
>>Also unions should only be compared to another union or object
>>which is *actually using* the same representation. (That is, given:
>> union lf_t {long l; float f} lf_a, lf_b;
>> lf_a.l = 10;
>> lf_b.f = 10.0;
>>we should probably not be testing (lf_a == lf_b), but rather
>>(lf_a.l == (long) lf_b.f).)
>
>Fine, so how is the compiler to know to do that? C unions are not
>discriminated unions; there's nothing in the union itself to indicate
>which member is being used.
>
>>However, the fact remains that either simple ``compare all bytes'' or
>>an expansion to compare all struct members recursively, would be a simple
>>extension which could be quite useful.
>
>Simple "compare all bytes" is certainly simple; how useful it is is
>another question, given that comparing padding bytes is simply wrong,
>unless you *guarantee* that they're always going to have some "standard"
>value that gets in the way. You still haven't indicated how unions are
>to be compared, so an expansion to compare all struct members
>recursively would fail if any such members were unions. And, once
>again, I'll point out that pointer comparison may or may not be what you
>want, either.
>
Yes, comparison of unions is not well-defined, so comparison of
structs containing union members would also be not well-defined.
>In other words, comparison might be "simple" in a restricted sense, but
>nobody's proven that in that "simple" sense (i.e., bitwise comparison
>either of all the bits in the structure, or only the "meaningful" bits)
>this would be anywhere near "quite useful".
>
This goes a bit too far, because you throw out the useful comparisons with
the ill-defined ones. It is perfectly well-defined and quite handy
to define a simple member-by-member comparison on structs and arrays.
The only thing you give up are the unions. Comparison of pointers is
defined to be comparison of the pointers themselves, just as always.
char *p, *q;
char a[] = "aa"; char b[] = "bb";
main(){
p = &a[0];q = &b[0];
strcpy(p,"hi"); strcpy(q,"hi");
if (p == p) {printf("Not in C you don't!\n");}
else printf("I thought that's what you meant!\n");
}
Now, I think that given:
typedef struct _pt_t { int x,y,x; } pt_t, * pt_pt;
typedef struct _pt_t polyline_t[3];
pt_t p = { 11, 12, 13};
pt_t q = {21, 22, 23};
polyline_t pl = {{ 11, 12, 13}, { 21, 22, 23}, { 31, 32, 33}};
It would be nice to check things like:
if ( pl[0] == p ) {}
rather than
if ( pl[0].x == p. && pl[0].y == p.y && pl[0].z == p.z ) {}
>If you want abstract data types, you know where to find them....
Well, this doesn't really have anything to do with abstraction, we're not
hiding any implementation. This is just structured data.
I wouldn't cry either if a tagged-union record were added to C. That would
give the compiler a chance to do the union comparisons too, based on the
tags.
Bernard A. Badger Jr. 407/984-6385 |``Use the Source, Luke!''
Secure Computer Products |``Get a LIFE!'' -- J.H. Conway
Harris GISD, Melbourne, FL 32902 |Buddy, can you paradigm?
Internet: bbadger%x102c at trantor.harris-atd.com|'s/./&&/g' Tom sed expansively.
More information about the Comp.std.c
mailing list