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

时间:2015-10-03 09:10:02

标签: c++ optimization reference

考虑以下计划:

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

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

我测试了一个上面的演示程序来查看输出。 但是当我编译&amp;在g ++ 4.8.1上运行它给我输出12。 看起来编译器没有优化引用变量。我期待Test结构的大小为1。 我还使用了-Os命令行选项,但它仍然给我输出12.我也在MSVS 2010上尝试过这个程序 使用/Ox命令行选项编译,但看起来Microsoft编译器根本没有执行任何优化。

三个参考变量未使用&amp;它们与任何其他变量无关。那么为什么编译器没有对它们进行优化呢?

3 个答案:

答案 0 :(得分:2)

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

未使用的变量例如是主函数中的新int& int。如果未使用,优化程序将对其进行优化。

答案 1 :(得分:2)

理论上,如果世界只包含简单的程序,编译器可以优化此结构的sizeof为1,因为结构的sizeof未指定。

但在我们的现实世界中,我们对共享库进行了单独的编译,编译器在编译代码时没有任何线索(例如,您可以/(\d+) (?:entry|entries)/LoadLibrary),这也恰好定义了您的dlopen以及sizeof应该更好地与您的计划中的内容一致。

所以实际上编译器最好不要将sizeof设置为1:)

答案 2 :(得分:1)

在C ++标准的8.3.2.4中,有人说

  

未指明引用是否需要存储

因此,该标准使实现如何实现引用。这意味着结构的大小可以为非零。

如果编译器将从结构中删除引用,则无法链接使用不同编译器设置编译的代码。想象一下,您使用优化编译一个翻译单元,另一个没有并将它们链接在一起并将一个对象从一个TU传递到另一个。代码应该采用哪种尺寸? TU 1中的函数在堆栈上分配12个字节,而TU 2中的函数分配一些其他空间。

编译器可以优化您的程序,例如删除临时对象,赋值等。可能是在源代码的某处创建了struct的对象并使用它,但是在汇编代码中不会看到它,因为它不需要。编译器经常做的是删除间接,例如,通过直接访问替换引用。