【问题标题】:duplicate external static declarations not allowed in visual studio?Visual Studio 中不允许重复的外部静态声明?
【发布时间】:2011-11-16 04:02:38
【问题描述】:

我正在研究声明和定义的概念(链接、范围、持续时间)。

但我发现了一个无法解释的错误:

以下代码在 gcc 和 Visual Studio 2010 中都可以使用

#include <stdio.h>

extern int a = 7;
extern int a;

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

但以下代码在 Visual Studio 中会产生错误,但在 gcc 中没问题:

#include <stdio.h>

static int a = 7;
static int a;

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

error C2370: 'a' : redefinition; different storage class

这只是 Visual Studio 编译器中的一个错误吗?

编辑:这个问题原来是 this 的重复。

【问题讨论】:

  • 我相信 C 和 C++ 在这个问题上有所不同——我认为 C 专门说同一文件中 static 变量的两个定义指的是同一个变量,而 C++ 有这个问题(我可以不记得他们为什么改变它)。确保在 Visual Studio 中编译为 C,而不是 C++。
  • 不是重复的。该问题有一个声明,然后是一个定义,然后是另一个声明。这个没有最初的声明(虽然这看起来像是纯粹的技术性,但它实际上对答案有很大的影响)。
  • hm...为什么定义之前的“额外”声明会产生重大影响?毕竟,“额外”声明将被视为正常声明,因为定义紧随其后。
  • @SHH:嗯,您的第二个 sn-p 本质上是该问题中第一个的副本。但是,您的第一个和他的第二个彼此完全不同——您的指定extern,而他的没有指定任何存储类。对于这些,标准的不同部分是相关的。

标签: c visual-studio gcc static


【解决方案1】:

static int a; 本身没有初始化器是一个“暂定定义”,所以应该没问题。看起来 Microsoft 有某种扩展程序正在吸引您。

编辑 - 它看起来确实是 Microsoft 的问题。看看这个related question。 C规范本身很清楚你的代码很好。从6.9.2 外部对象定义

具有文件范围的对象的标识符声明没有初始化程序,没有存储类说明符或具有存储类说明符static,构成暂定定义。如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,则行为与翻译单元包含该标识符的文件范围声明完全相同,复合类型为翻译单元的末尾,初始化器等于 0。

【讨论】:

  • 哇,我需要提高我的搜索技能。这是重复的。感谢搜索和指出!
  • @SHH - 我通过搜索“暂定定义”找到了骗子。如果您不是在寻找那个确切的短语,它可能会更难找到。
  • 这对自动变量有什么作用?为什么暂定定义不适用于他们?
  • @parminder, no - 正如规范所说,暂定定义是具有文件范围的声明,没有初始化程序和存储类说明符(static 除外,这没关系)。
  • 您给出的报价在这里似乎并不完全适用。根据 §6.9.2/1,static int a = 7; 显然 a 的外部定义,因此(至少)关于 `... 的部分不包含该标识符的外部定义。 ." 显然不能适用。
猜你喜欢
  • 1970-01-01
  • 2018-08-15
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多