【问题标题】:Extern variable with different types in CC中具有不同类型的外部变量
【发布时间】:2020-01-25 22:26:23
【问题描述】:

当我遇到这种情况时,我正在测试范围和可见性,但我找不到解释:

我有两个 .c 文件:

F1.c

#include <stdio.h>

void Modify();

int i;
int j;

int main()
{
  i=1;

  printf("i (main 1) = %d\n", i);

  Modify();

  printf("i (main 2) = %d\n", i);

  return 0;
}

F2.c

#include <stdio.h>

extern char i [10];
extern int j;

void Modify()
{
  j=0;
  i[0]='a';
  i[1]= 'b';
  i[4]= 'e';

  printf("i (Modify) = %c\n", i[0]);
  printf("j (Modify) = %d\n", j);
}

当我编译并链接它们以创建我启动的可执行文件时,结果如下:

i (main 1) = 1

i(修改)=a

j(修改)= 0

i (main 2) = 25185

发生了什么?我会改变类型吗?给出一个大小的数组是否会超过 F1.c 中 i 的声明?

谢谢!

【问题讨论】:

  • 这是 UB。一个好的链接器会对此发出警告。
  • @o11c UB 是什么意思?
  • @CSstudZ 你已经破坏了游戏规则,如果你的编译器和链接器确实生成了一个程序,则不能保证它是一个有意义的程序。所有的赌注都取消了。 blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
  • @PSkocik,哦,所以我没有希望找到输出背后的逻辑?大声笑,我刚刚尝试删除行 i[1] = 'b';,现在我得到 i (main2) = 97。我不知道发生了什么

标签: c casting declaration extern linkage


【解决方案1】:

这违反了 C 的规则。外部全局变量需要有一致的声明。 (这就是我们使用标题来保持一致性的原因。)您已授予您的工具集权限,可以将事情弄得一团糟。

话虽如此,在您的情况下发生的事情是对象只是简单地重叠(可能为intchar[10] 分配了足够的存储空间,有点像那里有union。如果仅分配了 4 个字节(仅分配给 int,而不是数组)然后 i[4] 访问将覆盖某些内容或不太可能导致段错误。

251850x6261,假设小端架构对应于{0x61, 0x62, 0x00, 0x00},即{'a', 'b', 0, 0 }'e' 不包含在该数字中,因为您的架构的 ints 有 4 个字节大,而 'e' 放在第 5 个字节。

同样,您处于 UB 领域,所以这些都不是保证行为。

【讨论】:

    猜你喜欢
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 2021-09-28
    • 2011-09-16
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    相关资源
    最近更新 更多