Соединение блока прицела стандарт C

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

{
    static int a; //no linkage
}

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

{
    static int a; //no linkage
    extern int a; //a should get external linkage, no?
}

Ошибка GCC: объявление extern следующего объявления без привязки

Может кто-нибудь объяснить мне, почему я получаю эту ошибку?

Спасибо


person mindless    schedule 30.08.2011    source источник
comment
Может быть семантикой, указывает отсутствие привязки или указывает «без привязки». Автоматическое продвижение в этом случае звучит безумно.   -  person Steve-o    schedule 30.08.2011
comment
Я не понимаю разницы. Не могли бы вы уточнить?   -  person mindless    schedule 30.08.2011


Ответы (2)


Ваше предположение верно: второе объявление a имеет внешнюю связь. Однако вы получите сообщение об ошибке, потому что ваш код нарушает ограничение в §6.7:

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

То есть, если вы объявили a не имеющим связи, вы не можете повторно объявить его в той же области.


Допустимый пример применения этого правила:

int a = 10;  /* External linkage */

void foo(void)
{
    int a = 5;  /* No linkage */

    printf("%d\n", a);    /* Prints 5 */

    {
        extern int a;  /* External linkage */

        printf("%d\n", a);    /* Prints 10 */
    }
}
person caf    schedule 30.08.2011
comment
Не могли бы вы привести мне допустимый пример: если предыдущее объявление не указывает никакой связи, тогда идентификатор имеет внешнюю связь. Я не могу ни о чем думать. - person mindless; 30.08.2011

если в предыдущем объявлении не указано никакой связи

означает

если в предыдущем заявлении указано, что не является признаком связи

и не

если в предыдущем объявлении указано, что у него нет связи

Это сбивает с толку и неоднозначно; не обычный способ написать стандарт ...

person glglgl    schedule 30.08.2011
comment
Вы можете удалить статику, ошибка все равно будет. Статика в области видимости блока не меняет связи, только продолжительность хранения. В области файлов изменяется привязка, но не продолжительность хранения (всегда статическая). Еще одна двусмысленность в c. - person mindless; 30.08.2011
comment
Ты неправ; подразумеваемое значение является последним, в точности так, как оно написано. Во всяком случае, это не имеет отношения к вопросу. - person caf; 30.08.2011