【问题标题】:Difference between declaration of variable with extern and without it带外部变量和不带外部变量声明的区别
【发布时间】:2020-01-21 16:00:07
【问题描述】:

1.h

extern int a;

1.c

#include <stdio.h>
#include "1.h"

int main(){ 
 printf("%d\n", a);
 return 0;
}

2.c

#include "1.h"

int a = 6;

如果您从1.h 中删除extern 并打印6,这将编译并运行得很好(gcc 1.c 2.c)。 我知道删除它可能会导致在每个翻译单元(目标文件)中定义a,但问题是什么?链接器不会在链接时将其删除,因为它编译时没有错误吗?

【问题讨论】:

  • 如果您删除 extern,您在 1.c 中的 a 将未初始化,printf 将调用未定义的行为。
  • 但在链接过程中没有链接到正确的值?有没有关于这个的 gcc 规则?
  • 实际上你应该在链接时遇到多个定义错误......除非我在这里遗漏了一些东西。
  • 不,我没有收到任何错误。
  • 嗯。也许没有错误,因为 2.c 已完全优化。但是肯定有一个未定义的行为,因为当我尝试重现它时,它会为我打印0。

标签: c linker extern


【解决方案1】:

此技术不符合 C 标准的字母和 “一个定义规则”——这是官方未定义的行为:

J.2 Undefined behavior

使用了带有外部链接的标识符,但在程序中 不存在该标识符的确切一个外部定义,或 该标识符未使用且存在多个外部 标识符的定义 (6.9)。

§6.9 External definitions ¶5

外部定义是一个外部声明,也是一个 函数的定义(内联定义除外)或 目的。 如果使用外部链接声明的标识符用于 表达式(除了作为 sizeof 的操作数的一部分或 _Alignof 运算符,其结果是一个整数常量),在某处 整个程序应该只有一个外部定义 标识符;否则,不得超过 一。161)

161) 因此,如果使用外部链接声明的标识符 不在表达式中使用,不需要外部定义 它。

更多: How do I use extern to share variables between source files?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 2017-11-04
    • 1970-01-01
    • 2013-03-23
    • 1970-01-01
    • 2018-11-24
    相关资源
    最近更新 更多