考虑以下计划:
#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;它们与任何其他变量无关。那么为什么编译器没有对它们进行优化呢?
答案 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的对象并使用它,但是在汇编代码中不会看到它,因为它不需要。编译器经常做的是删除间接,例如,通过直接访问替换引用。