2016-01-24 1 views
0

Рассмотрим это:Как объявить идентификатор с внутренней связью в области блока без предварительного объявления этого идентификатора с видимой видимостью ссылки?

#include <stdio.h> 

static int b; 

int main() 
{ 
    { 
     int b; 

     { 
      extern int b; 

      b = 2; 
     } 
    } 

    printf("%d", b); 
} 

Здесь по определению идентификатор «B», который присваивается значение 2 должен иметь быть один с внешним связыванием. Однако по какой-то причине компилятор «clang» C не жалуется, а выход этого кода равен «2».

Я принимаю это из-за $ 6.2.2.4 точки в стандарте C:

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

И поскольку предыдущее видимое объявление не указывает никакой привязки ('int b').

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

Редактировать: Я вижу, что этот пример UB, но это не меняет мой вопрос.

+0

Могу ли я спросить, за что это было проголосовано? – AnArrayOfFunctions

ответ

1

Ваша программа имеет undefined behaviour. Вы не можете иметь идентификатор с внутренней и внешней связью в той же области.

C11, §6.2.3, 4 говорит

Если в единице трансляции, то же identfier появляется как с внутренней и внешней связи, поведение не определено.

+0

Так как же это может быть не одно? – AnArrayOfFunctions

+0

Они * не могут * быть одним. Наличие внутренней * и * внешней связи для одного и того же идентификатора не имеет смысла (стандарт говорит, что он не определен). 'int b;' (внутри внешнего блока внутри 'main()') не имеет связи. 'extern int b;' объявляет 'b' с внешней связью, которая конфликтует с' static int b; ', которая определяет внутреннюю привязку. –

+0

Нет. Я имел в виду, как может моя программа примера не создавать UB без удаления переменной без привязки. Вы не отвечаете на мой вопрос. – AnArrayOfFunctions

Смежные вопросы