внешний внутри функции?

Что ж, читая "немного старую" книгу ("Язык программирования C", второе издание, Деннис Ритчи), я наткнулся на следующее:

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

и я такой - что?!

«Переменная также должна быть объявлена ​​в каждой функции, которая хочет получить к ней доступ». Тогда я был потрясен еще раз:

int max; 
/* ... */
int main()
{
    extern int max;
    /* ... */
}

И еще одно - что?!


Насколько я знаю (очевидно, это немного и далеко не достаточно), extern имеет смысл только тогда, когда вы где-то определяете глобальную переменную и хотите получить к ней доступ через другой файл (чтобы не определять ее заново).

So:

  • Какой смысл в этой extern int max внутри main или любой другой функции?
  • Говорит ли стандарт действительно, что это обязательно (что мне нужно объявить, для этого примера, это max в каждой функции, что будешь пользоваться?)
  • Это то же самое для C++ (поэтому я разместил тег C++)? Я впервые вижу что-то подобное.

Примечание: это не то же самое, что Какой смысл объявлять статическую переменную как extern внутри функции?


person Kiril Kirov    schedule 30.08.2012    source источник
comment
Amazon.com говорит, что K&R 2-е изд. был опубликован в 1988 году. Я предполагаю, что с тех пор стандарт немного изменился. :)   -  person dandan78    schedule 30.08.2012
comment
Да, я знаю год издания, я так и думал, но хотел спросить, просто чтобы быть уверенным. Вот почему я попросил подтверждение стандарта ISO.   -  person Kiril Kirov    schedule 30.08.2012
comment
@KirilKirov вам нужны цитаты из стандарта C или C++?   -  person ForEveR    schedule 30.08.2012
comment
Я думаю, что все это было прояснено с помощью ANSI C/C89 еще в тот день.   -  person Clinton Pierce    schedule 30.08.2012
comment
@ Кирил Киров Вы должны прочитать следующие абзацы (и всю главу), которые должны прояснить ваше замешательство. например, если определение внешней переменной происходит в исходном файле до ее использования в конкретной функции, то нет необходимости в объявлении extern в функции. Эта глава предназначена для того, чтобы немного научить вас связыванию и охвату, она делает это с помощью простых примеров, не обязательно лучших практик.   -  person nos    schedule 30.08.2012


Ответы (3)


Ваш пост меня удивил. Я не помнил об этом, и я давно читал K&R. У меня есть только первое издание здесь, и оно есть и там. Однако это еще не все. Из первого выпуска:

Переменная также должна быть объявлена ​​в каждой функции, которая хочет получить к ней доступ; это может быть сделано либо явным объявлением extern, либо неявно контекстом.

Обратите внимание на «неявно по контексту». Далее в тексте:

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

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

person Avi Berger    schedule 30.08.2012

extern int max внутри main или функции говорит компилятору "Я не локальная переменная внутри основной или функции, я глобальная переменная, определенная в другом месте".

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

person Scott Zhu    schedule 30.08.2012

extern — это связь. Это означает, что это имя, max, связано с другими вхождениями этого имени, возможно, в других файлах. (То есть, когда объектные модули связаны вместе для создания исполняемого файла, все связанные ссылки на это имя будут ссылаться на один и тот же объект.)

область действия этого объявления — это оставшаяся часть тела функции, в которой оно находится. Это означает, что другие функции в этом файле не видят имя, объявленное этим объявлением (если только они не объявят его сами).

Масштаб и связь - разные вещи.

person Eric Postpischil    schedule 30.08.2012
comment
Даже в K&R 2ed использование extern в этом примере не требовалось. В определенных обстоятельствах объявление extern можно опустить. Если определение внешней переменной происходит в исходном файле до ее использования в конкретной функции, то нет необходимости в объявлении extern в функции. Первый экземпляр int max будет принят за объявление. - person Clinton Pierce; 30.08.2012
comment
Использование extern int max внутри функции может и не понадобиться, но если int max присутствует внутри функции, то extern необходимо. В противном случае int max сам по себе внутри функции объявляет новый автоматический объект без привязки. Он будет отличаться от внешнего max. - person Eric Postpischil; 30.08.2012