Почему константы перечисления не имеют связи? - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь понять связь enumeration constant с и не смог найти четкого ответа в Стандарте N1570.6.2.2(p6):

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

Поэтому мне нужно понять, что константы не являются объектами.Объект определяется как 3.15:

область хранения данных в среде выполнения, содержимое которой может представлять значения

Также 6.2.2(p4) (выделите мое):

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

В любом случае 6.4.4.3(p2):

Идентификатор, объявленный как константа перечисления, имеет тип int.

Объединяя все, что я не понимаю, почему

enum test {
    a = 1
};

extern int a; //compile-error. UB?

не компилируется?Я ожидал, что a будет иметь внешнюю связь.

LIVE DEMO

Хорошо ли определено поведение?Можете ли вы дать ссылку на стандарт, объясняющий это?

Ответы [ 3 ]

0 голосов
/ 28 января 2019

Связь здесь не имеет значения.В одной и той же единице компиляции вы пытаетесь использовать два одинаковых идентификатора. Представьте, что код компилируется:

enum test {
    a = 1
};

extern int a; 


int b = a;   // which `a`? a as the external variable or `a` as a constant? How to decide.

enter image description here

0 голосов
/ 28 января 2019

В 6.2.2 4, стандарт намеревается обсудить связь только для идентификаторов объектов и функций, но не может это прояснить.

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

Обратите внимание на объявление extern int a; объявляет a в качестве идентификатора для объекта int.Объект int отличается от значения int, поэтому константа перечисления с именем a не может совпадать с объектом int с именем a.Таким образом, объявление extern int a; недопустимо даже до того, как рассматривается связь.

0 голосов
/ 28 января 2019

Идентификатор, объявленный как константа перечисления, имеет тип int

, что не означает, что это переменная типа int

, но

extern int a;

говорит, что есть переменная типа int с именем a , это конфликт с константой перечисления


Почему константа перечисления не имеет связи

по той же причине, что константа 123 (также имеющая тип int , но независимо от нее) тоже не имеет связи

...