C++可以通过编译器在类外优化常量类数据吗?

Cpp*_*s 1 3 c++ memory-layout compiler-optimization object-layout

我知道类之外的常量变量可以直接优化到编译器的函数调用中,但编译器对常量类变量执行相同操作是否合法?

如果有一个类声明如下:

class A {
public:
const int constVar;
    //other, modifiable variables

A(int val): constVar(val) {
         //code to initialize modifiable variables

}
};
Run Code Online (Sandbox Code Playgroud)

我创建一个A的实例并调用这样的函数:

A obj(-2);
int absoluteVal = std::abs(A.constVar);
Run Code Online (Sandbox Code Playgroud)

是否允许编译器执行此操作并使类sizeof(int)更小?:

A obj();
int absoluteVal = std::abs(-2);
Run Code Online (Sandbox Code Playgroud)

bol*_*lov 9

编译器可以自由地发出任何保留程序"可观察行为"的代码(复制构造函数有一个例外,即使它有可观察的行为也可以省略,但这里不适用).这称为规则

struct X { int x; };

auto foo()
{
  X x{24};

  return x.x;
}
Run Code Online (Sandbox Code Playgroud)

任何体面的编译器都会优化以上内容:

foo():                                # @foo()
        mov     eax, 24
        ret
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,它与constness(好吧,差不多)没有任何关系,只是与可观察的行为有关.您可以尝试使用代码添加复杂性,并了解编译器在确定它可以删除与类实例相关的代码时有多聪明.提示:它很聪明.


我不清楚你的意思是:

是否允许编译器执行此操作并使类的sizeof(int)更小?:

我可以告诉你的是:对于类型X和对象x等类型的sizeof(x)永远是= sizeof(X)不管类的实例化.换句话说,类的大小是在定义类时确定的,因此它不受可能的实例化或缺乏的影响.类的大小是其非静态数据成员的所有大小加上填充的总和.填充是实现定义的并且通常可以在某种程度上受到控制(例如,打包的结构).所以不,类的大小永远不会小于所有非静态非引用数据成员的大小总和.

  • @ user2079303我想你会发现这很有趣:[了解编译器优化 - Chandler Carruth - 开幕主题演讲C++ 2015](https://youtu.be/FnGCDLhaxKU) - 我想你会发现他不同意你的意见; `const`对优化器基本上是*无用的*. (3认同)