在VS2010中,以下代码在.c文件中编译并运行:
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.
}
所以它的表现实际上就像在某处看到的那样:
void F1();
以下代码无法在每个参数的printf行上使用未知标识符错误进行编译:
void F1(,a,b,c,d,e){
printf("%d, %d, %d, %d, %d\n", a, b, c, d, e);
}
这是C标准的一部分吗?知道发生了什么事吗?
答案 0 :(得分:3)
这是非法的C99:参数列表必须指定参数的类型;在C90中,他们默认为int
。
而且,我认为,它在C99中也是非法的,因为the Standard(6.9.1)中的文本使用参数类型列表的“shall”形式和标识符列表。 我认为同样适用于C90也会因为同样的原因使代码非法使用,但我现在无法检查。
<强> 6.9.1 / 5 强> 如果声明符包含参数类型列表,则 声明每个参数必须包含一个标识符, 除了包含参数列表的特殊情况 void类型的单个参数,在这种情况下 不应是标识符。没有声明清单 跟随。
<强> 6.9.1 / 6 强> 如果声明者包含标识符列表,则每个 声明清单中的声明应至少有一个声明 声明者,那些声明者只应声明标识符 来自标识符列表,以及中的每个标识符 标识符列表应声明。声明的标识符 作为typedef名称不得重新声明为参数。 声明清单中的声明应包含否 除寄存器和否之外的存储类说明符 初始化。
答案 1 :(得分:1)
不,这不是标准行为。 File a bug。 C89标准(草案版本here)定义函数定义的语法为(§3.7.1):
3.7.1 Function definitions Syntax function-definition: declaration-specifiers<opt> declarator declaration-list<opt> compound-statement
§3.5.4将声明符定义为:
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
对于定义void F1(,a,b,c,d,e){}
,void
是声明说明符,F1(,a,b,c,d,e)
是(假设)声明符。在 direct-declarator 的5种可能替代方案中,唯一可以匹配的是最后两种。但是,带括号的子表达式,a,b,c,d,e)
与 parameter-type-list 或 identifier-list 不匹配,因此它是一个格式错误的表达式。< / p>