Он собирает по той же причине, что 1;
, "----";
или 1 + 2 + 3 + 4;
бы компилировать: потому что выражение, за которым следует точка с запятой, является действительным заявление.
Включение выражений в операторы с точкой с запятой необходимо для работы множества частей C. Например:
do_stuff_to(x);
вызов функции, которая имеет значение, но может быть полезным в качестве оператора в своем собственном праве.
Даже что-то вроде
x = y;
(то есть, уступка) фактически является выражением. Это особенно полезно в позиции оператора.
Соответствующие части C grammar являются:
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
то есть statement
может быть одна из многих вещей, в том числе expression_statement
; и
expression_statement
: ';'
| expression ';'
;
то есть, expression_statement
является либо точкой с запятой или expression
, а затем точкой с запятой.
Что эта программа компилирует, зависит от реализации. Компилятор может свободно компилировать строку в сегмент данных программы или просто просто игнорировать ее. На моей машине GCC даже не помещает строку в скомпилированный исполняемый файл вообще, даже без уровня оптимизации.
Составители также не обязаны предупреждать об этой конструкции, но GCC делает, когда задан флаг -Wunused-value
. Это предупреждение может быть полезно иногда, потому что эта конкретная конструкция вообще не полезна.
test.c: In function ‘main’:
test.c:2:5: warning: statement with no effect [-Wunused-value]
("----");
^
Почему это ошибка? Это допустимое выражение. В скобках просто сообщается компилятору, чтобы он не предупреждал об отсутствии какого-либо задания. Я бы предположил, что он скомпилирует пустую программу со строкой в сегменте данных. – Myst