Почему структуры не допускаются в выражениях равенства в C?

Недоступность структур как опций сравнения является одной из наиболее очевидных вещей в C, которые не имеют слишком большого смысла (для меня). structs могут передаваться по значению и копироваться через назначения, но == для них не указывается.

Ниже приведены соответствующие части стандарта C11 (черновик), которые определяют ограничения операторов равенства (== и !=) и простой оператор присваивания (=). Обратите внимание на отсутствие структур и союзов в ограничениях операторов равенства. (Помимо отсутствия контакта с _Atomic, формулировка на C99 такая же).

6.5.9 Операторы равенства

Ограничения

Одно из следующего:

  • оба операнда имеют арифметический тип;
  • оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимых типов;
  • один операнд является указателем на тип объекта, а другой - указателем на квалифицированную или неквалифицированную версию void; или
  • один операнд является указателем, а другой - константой нулевого указателя.

6.5.16.1 Простое назначение

Ограничения

Одно из следующего:

  • левый операнд имеет атомный, квалифицированный или неквалифицированный арифметический тип, а правый имеет арифметический тип;
  • левый операнд имеет атомную, квалифицированную или неквалифицированную версию структуры или типа объединения, совместимой с типом права;
  • левый операнд имеет атомный, квалифицированный или неквалифицированный тип указателя и (учитывая тип, который левый операнд имел бы после преобразования lvalue), оба операнда являются указателями на квалифицированные или неквалифицированные версии совместимых типов и тип, на который указывает left имеет все квалификаторы типа, на которые указывает справа;
  • левый операнд имеет атомный, квалифицированный или неквалифицированный тип указателя и (учитывая тип, который левый операнд имел бы после преобразования lvalue), один операнд является указателем на тип объекта, а другой - указателем на квалифицированный или неквалифицированная версия void, а тип, на который указывает левый, имеет все квалификаторы типа, на который указывает правый;
  • левый операнд является атомарным, квалифицированным или неквалифицированным указателем, а справа - константа нулевого указателя; или
  • левый операнд имеет тип атомный, квалифицированный или неквалифицированный _Bool, а правый - указатель.

Может ли кто-нибудь объяснить, почему эта разница существует (без спекуляции)?

Ответ 1

Структуры и объединения не могут сравниваться для равенства, даже если назначение для этих типов разрешено. Разрывы в структурах и объединениях, вызванные ограничениями выравнивания, могут содержать произвольные значения, и компенсация за это налагает неприемлемые накладные расходы на сравнение равенства или на все операции, которые изменяют структуру и типы профсоюзов.

Из "C: Справочное руководство". Даже memcmp может сбой при сравнении структур, по той же причине (компилятор добавляет дополнительное пространство буфера для целей выравнивания). Я предполагаю, что они могут реализовывать поэтапное сравнение; почему у них нет другой проблемы.