为什么C++编译器没有优化未使用的引用变量?

Why C++ compiler isn't optimizing unused reference variables?

本文关键字:引用 变量 未使用 优化 C++ 编译器 为什么      更新时间:2023-10-16

考虑以下程序:

#include <iostream>
struct Test
{
    int& ref1;
    int& ref2;
    int& ref3;
};
int main()
{
    std::cout<<sizeof(Test)<<'n';
}

我知道c++编译器可以完全优化引用变量,这样它们就不会占用任何内存空间。

我测试了上面的演示程序来查看输出。但是当我编译&在g++ 4.8.1上运行它会给我输出12。看起来编译器没有优化引用变量。我期望测试结构体的大小为1。我也使用了-Os命令行选项,但它仍然给我输出12。我也在msvs2010上试用了这个程序使用/Ox命令行选项编译,但看起来微软编译器根本没有执行任何优化。

三个引用变量未使用&它们不与任何其他变量相关联。那么为什么编译器不优化它们呢?

结构体的大小保持不变,没有什么可优化的。如果您想创建一个Test数组,它应该为每个Test分配正确的大小。编译器无法知道将使用或不使用哪个。这就是为什么没有这样的优化。

例如,未使用的变量在主函数中是一个新的int& int

理论上,如果世界只由简单程序组成,编译器可以将这个结构体的sizeof优化为1,因为结构体的sizeof是未指定的。

但是在我们的现实世界中,我们有单独的编译共享库,编译器在编译你的代码时没有任何提示(例如你可以LoadLibrarydlopen),碰巧也定义了你的struct,其中sizeof应该与你的程序中的sizeof一致。

所以实际上编译器最好不要把sizeof优化为1:)

在c++标准的8.3.2.4中,说

未指定引用是否需要存储

因此,标准将如何实现引用的问题留给了实现。这意味着struct的大小可以是非零的。

如果编译器将从结构体中删除引用,则无法链接使用不同编译器设置编译的代码。假设您编译了一个带有优化的翻译单元,而另一个没有,并将它们连接在一起,并将对象从一个TU传递到另一个TU。代码的大小应该是多少?tu1中的函数在堆栈上分配12个字节,而tu2中的函数在堆栈上分配一些其他空间。

编译器可以优化你的程序,例如删除临时对象,赋值等。您可能会在源代码的某个地方创建结构的对象并使用它,但在汇编代码中不会看到它,因为不需要它。编译器还经常删除间接访问,例如用直接访问代替引用。