leading comma in param list implies empty parens?
In VS2010, the following code compiles and runs in a .c file:
void F1(,a,b,c,d,e){} // Note the leading comma.
void F2(void){
int x = 10;
void* y = 0;
F1(x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, y); // Compiles fine.
}
So it's effectively acting like this had been seen somewhere:
void F1();
The following code fails to compile with an unknown identifier error on the printf line for each param:
void F1(,a,b,c,d,e){
printf("%d, %d, %d, %d, %d\n", a, b, c, d, e);
}
Is this part 开发者_如何转开发of the C standard? Any idea what's going on?
This is illegal C99: the parameter list must specify the types of the parameters; in C90 they default to int
.
And, I think, it's also illegal in C99 because the text in the Standard (6.9.1) uses the "shall" form for parameter type list, and identifier list. I assume the same is valid for C90 making the code illegal with that language too, for the same reason, but I can't check that now.
6.9.1/5 If the declarator includes a parameter type list, the declaration of each parameter shall include an identifier, except for the special case of a parameter list consisting of a single parameter of type void, in which case there shall not be an identifier. No declaration list shall follow.
6.9.1/6 If the declarator includes an identifier list, each declaration in the declaration list shall have at least one declarator, those declarators shall declare only identifiers from the identifier list, and every identifier in the identifier list shall be declared. An identifier declared as a typedef name shall not be redeclared as a parameter. The declarations in the declaration list shall contain no storage-class specifier other than register and no initializations.
No, that is not standard behavior. File a bug. The C89 standard (draft version available here) defines the syntax for a function definition to be (§3.7.1):
3.7.1 Function definitions Syntax function-definition: declaration-specifiers<opt> declarator declaration-list<opt> compound-statement
And §3.5.4 defines a declarator to be:
3.5.4 Declarators Syntax declarator: pointer<opt> direct-declarator direct-declarator: identifier ( declarator ) direct-declarator [ constant-expression<opt> ] direct-declarator ( parameter-type-list ) direct-declarator ( identifier-list<opt> ) pointer: * type-qualifier-list<opt> * type-qualifier-list<opt> pointer type-qualifier-list: type-qualifier type-qualifier-list type-qualifier parameter-type-list: parameter-list parameter-list , ... parameter-list: parameter-declaration parameter-list , parameter-declaration parameter-declaration: declaration-specifiers declarator declaration-specifiers abstract-declarator<opt> identifier-list: identifier identifier-list , identifier
In the case of the definition void F1(,a,b,c,d,e){}
, void
is a declaration-specifier and F1(,a,b,c,d,e)
is (supposedly) the declarator. Of the 5 possible alternatives for a direct-declarator, the only ones it can match are the last two. But, the parenthesized subexpression ,a,b,c,d,e)
does not match either a parameter-type-list or a identifier-list, so it is an ill-formed expression.
精彩评论