Правило идентификации типа и его нарушение

#c #types #undefined-behavior #linkage

#c #типы #не определено -поведение #связь

Вопрос:

Ниже приведен некоторый код, нарушающий правило идентификации типов (на ideone):

 #include <iostream>

void foo()
{
    typedef int I;
    extern I a; //now a is denoting an entity, which is a member of global scope
    std::cout << a;
}

typedef char I;
I a; //definition of a

int main()
{
    foo();
}
 

Правило идентификации типов (раздел 3.6 / 10 N3797):

После всех корректировок типов (во время которых определения типов (7.1.3) заменяются их определениями) типы, указанные во всех объявлениях, ссылающихся на данную переменную или функцию, должны быть
идентичными, за исключением того, что в объявлениях для объекта array могут указываться типы массивов, которые отличаются наличием или отсутствием основной привязки массива (8.3.4). Нарушение этого правила идентификации типов не
требует диагностики.

Я понимаю, что нарушение этого правила не требует диагностики. Но почему бы и нет?

Ответ №1:

Указанное правило означает, что ваше нарушение вызывает неопределенное поведение.

Причины неполного определения поведения:

  • Простота реализации.
  • Эффективность программы.
  • Удовлетворение различных существующих реализаций.
  • С учетом расширений и будущего развития.

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

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