gpt4 book ai didi

c - 您需要使用 extern 来处理不完整的类型吗?

转载 作者:行者123 更新时间:2023-12-02 09:03:43 26 4
gpt4 key购买 nike

您是否绝对需要使用带有不完整类型的 extern 例如 int a[];让它使用链接文件中的数组定义?我的逻辑是,它不保留内存,因此它不是定义而是声明(就像函数原型(prototype)一样,它也不需要编译器将其隐式留给链接器的 extern )。我会自己测试,但目前还不能。

最佳答案

既然您问是否绝对需要使用 extern 来声明名义上不完整类型的标识符,那么技术上答案是“不”,原因有两个:

  • C 标准是自愿性的。没有什么需要你服从。
  • 如果您使用 C 标准,并且在一个翻译单元中外部(任何函数之外)声明 int a[];,并且 int a[5] = { 3, - 7, 24, 5, 7 }; 在另一个翻译单元内,并且您在程序中使用 a,该行为不是由 C 标准定义的。也就是说,C 标准“允许”您这样做,但没有定义结果。

我会回来解释为什么后者没有被定义。首先,让我们看看为什么您真正想问的问题的答案是"is"。

如果您问是否需要使用 extern 来获得定义的结果,并且可能是您想要的结果,那么答案是"is"。如果您在翻译单元中声明 int a[];,则它是按照 C 2018 6.9.2 2 的暂定定义:

A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

这意味着,如果您在外部声明 int a[]; 并且不在同一个翻译单元(包含所有包含文件的源文件)中以其他方式定义它,则就好像您编写了int a[] = { 0 };,它定义它是一个只有一个元素的数组。所以它实际上是一个定义,而不仅仅是一个声明。

为了防止它成为暂定定义并成为定义,需要将其声明为 extern int a[];

如果不这样做,那么您将在一个源文件中拥有该定义,并在链接的另一文件中拥有该定义。那么,如果在程序中使用a,就会违反C 2018 6.9 5:

… If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof or _Alignof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.

这个“应该”是外部定义语义的一部分,而不是约束的一部分,因此它受 4 2 的约束:

If a “shall” or “shall not” requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined…

这解释了我上面的第二个要点。

除此之外,这是 C 标准的“未定义行为”实际上在某些常见用途中的一个例子。在常见的 Unix 工具中,一个翻译单元中的暂定定义根据需要与其他翻译单元中的非暂定定义进行解析。因此,只要您使用支持此问题的工具,“否”也是您想要的问题的答案。

关于c - 您需要使用 extern 来处理不完整的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60759025/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com