繁体   English   中英

内联成员函数使用的静态全局变量

[英]Static global variable used by inline member function

当您在C ++头文件中有一个静态全局变量时,包含头文件的每个翻译单元最终都会有自己的变量副本。

但是,如果我在同一个头文件中声明一个类,并创建该类的成员函数,在类声明中实现内联,它使用静态全局变量,例如:

#include <iostream>

static int n = 10;

class Foo {
 public:
   void print() { std::cout << n << std::endl; }
};

然后我看到gcc 4.4下的一些奇怪的行为:

  1. 如果我在没有优化的情况下编译,则成员函数的所有使用都使用来自其中一个翻译单元(g ++命令行中提到的第一个)的变量副本。

  2. 如果我使用-O2编译,则每次使用成员函数都会使用来自翻译单元的变量副本。

显然这是一个非常糟糕的设计,所以这个问题只是出于好奇。 但是,我的问题是,C ++标准对此案例的说法是什么? 通过在启用和不启用优化的情况下提供不同的行为,g ++是否正常运行?

标准说(3.2 / 5):

可以有多个类类型的定义(第9节),......如果定义满足以下要求......在D的每个定义中,根据3.4查找的相应名称应引用定义的实体在D的定义内,或应指同一实体

这是您的代码丢失的地方。 Foo的不同定义中使用n不是指同一个对象。 游戏结束,未定义的行为,所以是的,gcc有权在不同的优化级别做不同的事情。

3.2 / 5继续:

如果对象在D的所有定义中具有相同的整数或枚举类型,并且该对象使用常量表达式(5.19)初始化,并且值(但不是),则名称可以引用具有内部链接或无链接的const对象使用对象的地址),并且对象在D的所有定义中具有相同的值

因此,在您的示例代码中,您可以将n转换为static const int并且所有内容都很可爱。 这个子句描述了不同的TU是否“引用”相同的对象或不同的对象没有区别的条件并不是巧合 - 他们使用的只是编译时常量值,并且它们都使用相同的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM