【问题标题】:Why is this code compiled and linked without an error?为什么编译和链接这段代码没有错误?
【发布时间】:2013-09-15 02:20:09
【问题描述】:

extern 关键字不应该简单地“屏蔽”编译器吗?这是我无法理解为什么没有错误的代码。

struct A {
    int a;
};

class B {
    static A x;
public:
    void f() { x.a=0; }
};

extern A B::x; // not allocated.

main() {
    B z;
    z.f();
}

如您所知,静态成员应该手动实例化。但是,我添加了 extern 关键字,这意味着它实际上并未分配。编译的很好,很奇怪!

【问题讨论】:

  • 我认为变量是分配的,它根本没有初始化,这是完全不同的。虽然由于您使用的是类对象,但默认构造函数可能会运行。
  • @ChrisHayes 这怎么可能?你的意思是说extern关键字'可以'分配一个变量吗?
  • @rici 我看不到任何迹象表明B::x 在不同的 CU 中。实际上,这段代码编译的唯一原因似乎是因为它都在一个 CU 中。
  • @rici 它在同一个编译单元中。此外,我通过 z.f() 访问了 B::x。
  • @syam 你的意思是,如果在同一个编译单元中,没有找到声明,extern 关键字可以省略吗?

标签: c++ g++


【解决方案1】:

static 成员变量没有 extern 声明!无论如何,该变量都根据类的定义声明为extern。 gcc 警告您不能将static 成员变量显式声明为extern。但是,gcc 和 clang 都毫不费力地编译和链接代码,显然忽略了extern

当然,使用上面的代码也很明显,您首先使用一些非标准模式进行编译,因为 main() 依赖于隐含的 int 规则,而该规则从来不是 C++ 的一部分。

【讨论】:

  • 我添加了-lstdc++。它只是遵守...我怎样才能使 g++ 更严格?
  • -lstdc++ 选项显然与它无关:这只是显式添加标准 C++ 库。你可能想用-W -Wall -pedantic 编译。如果您想拒绝产生这些警告的程序,您还可以添加-Werror-Werror=pedantic
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 2011-12-27
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多