Грамматика модуля перевода C ++ - PullRequest
8 голосов
/ 02 декабря 2010

В течение длительного времени я понимал, что единица перевода C ++ после запуска препроцессора - это последовательность объявлений (напомню, что любое определение также декларация).

Многие люди спорили с этим утверждением, но никто никогда не давал контрпример. Но я сам нашел этот пример, который меня беспокоит:

int x;       //declaration

;            // ??? EMPTY DECLARATION?

int main()   //dec
{            //la
}            //ration

Прекрасно сочетается с MSVC и онлайн-комедиями. Я знаю, что стандарт определяет пустое утверждение , но я никогда не слышал о пустом объявлении. Итак, я вижу три варианта:

  • Мое понимание верно, и стандарт определяет пустую декларацию
  • Мое понимание правильное, но стандарт не определяет пустые объявления, и приведенный выше перевод неверен
  • Мое понимание неверно, т. Е. C ++ TU не является последовательностью объявлений

Пожалуйста, помогите мне развеять мои сомнения. Спасибо

Ответы [ 2 ]

6 голосов
/ 02 декабря 2010

Ваше понимание верно, и стандарт (или, по крайней мере, Страуструп) определяет пустую декларацию .

РЕДАКТИРОВАТЬ : Кажется, этот ответ неправильный (естьсемантическое правило для стандарта - но, насколько я могу судить, не для книги - которое запрещает как decl-specified-seq, так и init-declarator-list быть пустыми одновременно).См. Ответ Чарльза Бейли.


n "Язык программирования C ++", приложение A, раздел A.4:

Программа - это набор translation-unit s (...).translation-unit, часто называемый исходным файлом , представляет собой последовательность declaration s:

translation-unit:
   declaration-seq_opt

opt означает, что производство является необязательным.В этом правиле это означает, что действительна пустая единица перевода.

Раздел A.7:

declaration-seq:
    declaration
    declaration-seq declaration

declaration:
    block-declaration
    (...)

block-declaration:
    simple-declaration
    (...)

simple-declaration:
    decl-specified-seq_opt init-declarator-list_opt ;

Таким образом, declaration-seq является последовательностью по крайней мере из одного declaration.declaration может, помимо прочего, быть block-declaration, что, в свою очередь, дает simple-declaration.Поскольку не-литерал decl-specified-seq и init-declarator-list являются необязательными, ; является допустимым объявлением.

5 голосов
/ 02 декабря 2010

пустое объявление разрешено в (текущем черновике) C ++ 0x в области видимости файла (и в области пространства имен и в других местах, где разрешено объявление), и это просто точка с запятой.Это отдельная грамматическая сущность.

В C ++ 03 не допускается одиночная точка с запятой, если ожидается только объявление.Хотя может показаться, что simple-объявление может сократить до точки с запятой, явное правило запрещает это.

7 [dcl.dcl] / 3

В простом объявлении необязательный список инициализации-объявления может быть опущен только при объявлении класса (пункт 9) или перечисления (7.2), то есть когда decl-Спецификатор-seq содержит либо спецификатор класса , уточненный спецификатор типа с ключом класса (9.1) или enum-спецификатор .

Короче говоря, это означает, что список инициализации-декларатора может быть опущен только тогда, когда decl-specier-seq не опущено.

...