Pav*_*kin 1 c language-lawyer function-declaration c11 c17
考虑这个代码(t0.c):
typedef int T;
void f(int T);
Run Code Online (Sandbox Code Playgroud)
调用:
gcc -std=c11 -Wall -Wextra -pedantic -c t0.c
<nothing>
clang -std=c11 -Wall -Wextra -pedantic -c t0.c
<nothing>
cl /std:c11 /Za /c t0.c
t0.c(2): warning C4224: nonstandard extension used: formal parameter 'T' was previously defined as a type
Run Code Online (Sandbox Code Playgroud)
问题:
nonstandard extension,那么为什么符合标准的 gcc / clang 什么也没说?
- 哪个 C 规则允许在函数声明器中使用以前定义为类型的标识符?
首先,typedef名称是一个标识符。C 2018 6.2.1 1 说:
标识符可以表示一个对象;一个函数;结构、联合或枚举的标记或成员;一个 typedef 名称;标签名称;宏名称;或宏参数...
同一个段落说我们可以使用相同的标识符来表示不同的实体:
…相同的标识符可以表示程序中不同点的不同实体…
第 4 段告诉我们在T函数原型内部声明的隐藏了之前的T:
… 在内部作用域内,标识符指定在内部作用域中声明的实体;在外部作用域中声明的实体在内部作用域中隐藏(并且不可见)。
- 如果 msvc 说非标准扩展,那么为什么符合标准的 gcc / clang 什么也没说?
GCC 和 Clang 什么也没说,因为根据 C 标准代码是没问题的,而且它们的实现者没有选择发出任何警告。
C 标准允许 MSVC 报告超出标准要求的诊断,因为所有 C 实现都是如此,但声称它是非标准扩展是不正确的。
| 归档时间: |
|
| 查看次数: |
60 次 |
| 最近记录: |