[c] C의 BNF 문법이 빈 init-declarator 시퀀스를 가진 선언을 허용하는 이유는 무엇입니까?

C의 BNF 문법을 살펴볼 때 선언의 생산 규칙이 다음과 같이 이상하다고 생각했습니다 ( https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of% 20C % 20in % 20Backus-Naur % 20form.htm ) :

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;

?에 대해 *수량자를 사용하는 이유 (0 번 이상 발생) init-declarator? 이는 의미 상 유효하지 않지만 구문 과 같은 int;또는 void;구문이 유효한 구문을 허용합니다 . 생산 규칙 +대신 수량 자 (한 번 이상 발생)를 사용할 수 없었 *습니까?

컴파일러가 무엇을 출력하는지 확인하기 위해 간단한 프로그램을 컴파일하려고했는데 경고가 발생했습니다.

입력:

int main(void) {
    int;
}

산출:

test.c: In function main’:
test.c:2:5: warning: useless type name in empty declaration
     int;
     ^~~



답변

declaration-specifier포함 ( type-specifier포함) enum-specifier. 같은 구조

enum stuff {x, y};

declarationno 로 유효합니다 init-declarator.

문법 과 같은 제약 조건에int; 의해 다음 과 같은 구문 이 제외됩니다 .

static_assert 선언 이외의 선언은 최소한 선언자 (함수의 매개 변수 또는 구조체 또는 공용체의 멤버 제외), 태그 또는 열거 형 멤버를 선언해야합니다.

컴파일러 뒤에 경고를 발행하는 호환성 문제가 있다고 생각합니다.


답변

초기화 선언자가없는 선언 :

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;

단일 enum/ struct/ union지정 자가 아닌 선언 지정자 목록에는 무해하며 유용합니다.

원하는 경우, 제시된 문법은 잘못 선언을 일치 int struct foo x;하거나 double _Bool y;(이 같은 일을 일치시키기 위해 여러 지정자를 할 수 있습니다 long long int)하지만, 이러한 모든 의미 론적 점검, 나중에 검출 될 수있다.

BNF 문법 자체가 모든 불법 구문을 제거하지는 않습니다.


답변