使用外部链接(无外部定义)声明的标识符以及在_Generic中使用的标识符是否违反语义?

z9gpfhce  于 2023-02-03  发布在  其他
关注(0)|答案(2)|浏览(103)

从最新的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),有人能对此发表评论吗?

ogq8wdun

ogq8wdun1#

_Generic是在关于定义的语言已经建立的几年后添加到C标准中的,没有在6.9 5中添加关于它的例外是一个疏忽。
显然6.9 5的意图是如果一个程序需要一个对象或函数的定义,因为这个对象或函数是实际使用的,那么就必须有一个定义,但是如果标识符是在一个上下文中使用的,其中只需要它的类型,而不需要它假设引用的对象或函数,那么就不需要定义。
我也搞混了“否则,不应该有超过一个”。
如果使用了对象或函数,就需要有定义,这是逻辑上的必然:没有办法使用不存在的东西。
如果一个对象或函数被声明但没有被使用,那么就不需要定义,这通常会在头文件或源代码的设计上造成松弛:您可以声明可能链接到程序中并使用的内容,也可以声明不链接到程序中并使用的内容,如果声明了这些内容但从未使用或定义它们,则不会出现错误。

oymdgrw7

oymdgrw72#

也许6.9p5错过了_Generic
否,“如果在表达式中使用了用外部链接声明的标识符(而不是作为typeof运算符(其结果不是可变修改类型)或sizeofalignof运算符(其结果是整型常量表达式)的操作数的一部分),则在整个程序中的某个地方,该标识符应该只有一个外部定义;否则,不应超过一个" -因此,如果用作typeof运算符的操作数,则不需要外部定义。
6.5.1.1 Generic selection开始:

  • 3不计算一般选择的控制表达式。如果一般选择具有与控制表达式类型兼容的类型名称的一般关联,则一般选择的结果表达式是该一般关联中的表达式。否则,一般选择的结果表达式是默认一般关联中的表达式。

变量xtypeint是已知的,这就是用来建立正确的泛型关联的全部内容。x是控制表达式,实际上从未被求值。
如果有什么遗漏的话,那就是在typeof和/或_Generic章节中没有提到_Generic使用typeof操作符(未求值)来 as-if 操作。

相关问题