【问题标题】:How does GCC handle variable redefinitionGCC如何处理变量重定义
【发布时间】:2015-05-26 10:27:41
【问题描述】:

我写了一段这样的代码

int a;
int a = 100;
int main()
{
}

GCC编译成功,G++编译不成功。

我猜 GCC 通过忽略变量 a 的第一个定义来处理这个问题。但是我想知道确切的规则,这样我就不会错过任何东西。

谁能帮帮我?

【问题讨论】:

  • 请不要:您应该使用int main(void)。您还应该使用-Wall 进行编译
  • 这不是 gcc 与 g++ 的问题,而是 C 与 C++ 的问题。不同的语言,不同的规则。
  • @Eregrith 我加了-Wall,gcc只提醒我main函数没有return
  • @Mat 因为我觉得 GCC 的这种行为很奇怪,所以我认为它可能只是 GCC 的一个扩展

标签: c++ c gcc g++


【解决方案1】:

在 C 中

int a;  /* Tentative definition */
int a = 100; /* Definition */

来自 C11 规范中的 6.9.2 外部对象定义

具有文件范围的对象的标识符声明 没有初始化器,并且没有存储类说明符或有 存储类说明符 static,构成 暂定 定义。如果一个翻译单元包含一个或多个暂定 标识符的定义,并且翻译单元包含 no 该标识符的外部定义,那么行为就是 好像翻译单元包含该文件的文件范围声明 标识符,与翻译结束时的复合类型 单位,初始化器等于 0。

int i4; // tentative definition, external linkage
static int i5; // tentative definition, internal linkage

在 C++ 中

int a; 是一个定义(不是暂定的),因为一个对象有多个定义是非法的,所以它不会编译。

【讨论】:

  • 非常感谢。规则似乎很复杂。为什么 C 有这个有点令人困惑的特性?你能提供一个我们必须使用它的例子吗?
  • 我记得几年前有一次讨论关于暂定定义有什么好处,但我们得出的结论没有任何用处。所以我不知道有什么好的理由。
  • GCC 10 将默认值更改为 -fno-common,因此暂定定义应与其他定义冲突。 This link 提供更多详细信息。我遇到了一个问题,这为我指明了正确的方向,谢谢!
  • 很高兴看到这很有帮助。
猜你喜欢
  • 2015-07-27
  • 2011-09-02
  • 2021-11-27
  • 1970-01-01
  • 2011-01-14
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多