从最新的C2x(6.9p5)(着重号是添加的):
外部定义是外部声明,也是函数的定义(内联定义除外)或对象。如果在表达式中使用了使用外部链接声明的标识符(作为其结果不是可变修改类型的typeof运算符的操作数的一部分,或者作为其结果是整数常量表达式的sizeof或alignof运算符的操作数的一部分除外),* 在整个程序中的某个地方,标识符应该有一个外部定义 *;否则,不得超过一名。
考虑这个程序:
extern int x;
int i = _Generic(x, default: 0);
int main(void)
{
}
根据我的理解,在整个程序中的某个地方,标识符x
应该只有一个外部定义,对吗?仅供参考:popular compilers don't complain.
也许6.9p5错过了_Generic
?
我也搞混了"否则,不应该有超过一个"。因此,额外的问题:
1."否则......"与什么相关?与"在整个程序中的某个地方,标识符应该只有一个外部定义"或与"用外部链接声明的标识符用于表达式(而不是......)"相关?
1.如果"otherwise ..."与"在整个程序中的某个地方应该正好有一个标识符的外部定义"相关,那么我将整个引号(6. 9p5)解释为ext_def_cnt == 1 || ext_def_cnt <= 1
,这是多余的(因为它可以折叠为ext_def_cnt <= 1
),有人能对此发表评论吗?
2条答案
按热度按时间ogq8wdun1#
_Generic
是在关于定义的语言已经建立的几年后添加到C标准中的,没有在6.9 5中添加关于它的例外是一个疏忽。显然6.9 5的意图是如果一个程序需要一个对象或函数的定义,因为这个对象或函数是实际使用的,那么就必须有一个定义,但是如果标识符是在一个上下文中使用的,其中只需要它的类型,而不需要它假设引用的对象或函数,那么就不需要定义。
我也搞混了“否则,不应该有超过一个”。
如果使用了对象或函数,就需要有定义,这是逻辑上的必然:没有办法使用不存在的东西。
如果一个对象或函数被声明但没有被使用,那么就不需要定义,这通常会在头文件或源代码的设计上造成松弛:您可以声明可能链接到程序中并使用的内容,也可以声明不链接到程序中并使用的内容,如果声明了这些内容但从未使用或定义它们,则不会出现错误。
oymdgrw72#
也许6.9p5错过了
_Generic
?否,“如果在表达式中使用了用外部链接声明的标识符(而不是作为
typeof
运算符(其结果不是可变修改类型)或sizeof
或alignof
运算符(其结果是整型常量表达式)的操作数的一部分),则在整个程序中的某个地方,该标识符应该只有一个外部定义;否则,不应超过一个" -因此,如果用作typeof
运算符的操作数,则不需要外部定义。从
6.5.1.1 Generic selection
开始:变量
x
的 type,int
是已知的,这就是用来建立正确的泛型关联的全部内容。x
是控制表达式,实际上从未被求值。如果有什么遗漏的话,那就是在
typeof
和/或_Generic
章节中没有提到_Generic
使用typeof
操作符(未求值)来 as-if 操作。