我想知道如果我在 K&R 函数定义中省略参数声明会发生什么,所以我尝试了以下操作:
#include <stdio.h>
void f(a)
// int a; <--- omitting `declaration-list` causes warning in gcc, but nothing in clang
{
printf("%d", 9);
}
int main()
{
f(9);
return 0;
}
当我用 gcc 11
编译它时,诊断以警告的形式发出(即 warning: type of 'a' defaults to 'int'
) .但是,当我用 clang 14
编译它时,没有发出任何诊断消息。
这让我感到困惑,因为在标准中,省略 declaration-list
(其中包含参数声明)是违反约束的(根据 C11 6.9.1(6) ),这需要符合标准的实现才能发出诊断(根据 C11 5.1.1.3 )。 那么,为什么clang没有发出警告呢?我是不是误解了什么?
编辑: 如果编译器可以应用标准中的某些其他条款“修复”约束违规,是否必须发布诊断?
例如,上面代码中的空声明列表一直是约束违规(since C89)。然而,在 C99 之前,该标准还有一个隐式的 int
规则(参见 C90 6.5.2 ),这将允许编译器将任何未声明的参数假定为 int
从而从 no-empty-declaration-list 约束违规中恢复过来。
那么,在这种情况下,1999 年之前符合 ANSI 标准的编译器是否仍会发出诊断?我的第一印象是它会因为约束优先于隐式 int
规则,但是 pg. Harbison 和 Steele 的 287 说(强调):
In the pre-Standard traditional form, the parameter names are listed in the declarator and the types are specified (in any order) in the declaration-list opt following the declarator. All parameters should be declared in the declaration-list, but prior to C99 omitted parameter declarations defaulted to type int.
粗体字看起来像是允许空声明列表,因为隐式 int
规则会“修复”任何 no-empty-declaration-list 约束违规。
最佳答案
如果使用 -pedantic
标志编译,clang 将生成警告。
<source>:3:8: warning: parameter 'a' was not declared, defaulting to type 'int' [-Wpedantic]
void f(a)
^
1 warning generated.
ASM generation compiler returned: 0
<source>:3:8: warning: parameter 'a' was not declared, defaulting to type 'int' [-Wpedantic]
void f(a)
^
1 warning generated.
Execution build compiler returned: 0
Program returned: 0
9
关于c - 违反约束是否总是导致诊断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74663869/