6

The unavailability of structs as comparison operands is one of the more obvious things in C that don't make too much sense (to me). structs can be passed by value and copied via assignments but == is not specified for them.

Below are the relevant parts of the C11 standard (draft) that define the constraints of the equality operators (== and !=) and the simple assignment operator (=). Note the lack of structures and unions in the constraints of equality operators. (Apart from the lack of dealing with _Atomic the wording in C99 is the same).

6.5.9 Equality operators

Constraints

One of the following shall hold:

  • both operands have arithmetic type;
  • both operands are pointers to qualified or unqualified versions of compatible types;
  • one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void; or
  • one operand is a pointer and the other is a null pointer constant.

6.5.16.1 Simple assignment

Constraints

One of the following shall hold:

  • the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
  • the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
  • the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.

Can anybody explain why this difference exists (without speculating)?

stefanct
  • 2,503
  • 1
  • 28
  • 32
  • The only person who can answer you without speculating would be Brian Kernighan – M.M Oct 29 '17 at 01:17
  • Well, yes, but he might have explained it sometime ago already... and proof of that might be hard to dig up but that's essentially what I'd like to see. A reasoning by K or someone in the ISO committee if it ever was discussed there (not necessarily *by* them personally on SO :D). Is there anything in K&R about the issue? - Sorry for the duplicate BTW: it did not come up in my search due to the equality/comparison discrepancy (mine is the official wording :P). – stefanct Oct 30 '17 at 08:05
  • 2
    @M.M No need to pester Mr. Kernighan (who wasn't involved in the first creation of C anyway), consulting the C rationale was enough: https://stackoverflow.com/a/47056810/584518 – Lundin Nov 01 '17 at 14:11

1 Answers1

4

Structures and unions cannot be compared for equality, even though assignment for these types is allowed. The gaps in structures and unions caused by alignment restrictions could contain arbitrary values, and compensating for this would impose an unacceptable overhead on the equality comparison or on all operations that modified structure and union types.

From "C: A Reference Manual". Even memcmp can fail when comparing structs, for the same reason (the compiler adding additional buffer space for alignment purposes). I guess they could implement member-by-member comparison; why they haven't is a different issue

Kovalainen
  • 249
  • 1
  • 10
  • Having the code `a == b` potentially generate kilobytes of assembly goes against C's original minimalist nature; although perhaps it is something that will be added in future as the programming landscape evolves – M.M Oct 29 '17 at 01:15
  • Yeah, the reasons why member-by-member comparison and other means of struct comparison havent been implemented can be reasonably guessed. OP said "without speculating" so I just stuck to the facts :) – Kovalainen Oct 29 '17 at 01:24
  • 2
    @M.M: "minimalist" regarding obligations for compiler writers only. Because if the user has to compare the struct then she can't just avoid it but has to write code manually producing "kilobytes of assembly" and the eventual application would potentially be even more bloated than with the autogenerated code (the compiler knows the gaps exactly - the user does not!). But this could very well be the reasoning behind the decision - I just would like to have a more official confirmation than that. – stefanct Oct 30 '17 at 08:02