c++编译器如何处理const数组
How const arrays are treated by C++ compilers
这些常量数组是否在内存中分配空间或编译器是否足够聪明并将其分解为文字?
我在这里只提供一个例子:
const int array[] = {
1, 2, 3, 4, 5
};
我只是想知道别的。
简短的回答是:看情况。
长答案是:
如果你编译这个:
const int array[] = {
1, 2, 3, 4, 5
};
int
main()
{
return array[0];
}
你最终在x86/Linux(简化)上得到这个:
.globl main
main:
movl $1, %eax
ret
所以,是的,它不会存储在任何地方,而是作为一个常量在编译时计算。
但是,如果你这样使用:
const int array[] = {
1, 2, 3, 4, 5
};
int
main()
{
return (long)array;
}
它就变成:
.globl main
main:
leal _ZL5array(%rip), %eax
ret
.section .rodata
.align 16
_ZL5array:
.long 1
.long 2
.long 3
.long 4
.long 5
它在section rodata中结束,因为你告诉编译器你实际上需要它作为一个数组。
有一篇关于c++中数据初始化的优秀博文,作者是Qt背后的专家之一Olivier Goffart。
我相信他们可以很容易地优化,如果他们是static
。用一些技巧改变它们的值(比如const_cast
)是未定义的行为,所以编译器不会在意。不管怎样,你可以检查一下。gcc -O2 -S temp.c
.
如果数组是全局的而不是static
,编译器应该保留它,以防其他编译单元需要它。除非你做了整个程序的优化
优化器实际上是非常聪明的生物。例如,下面的代码:
const int array[] = {1, 2, 3, 4, 5};
void show(int i)
{
printf("%dn", i);
}
int main(int argc, char * argv[])
{
show(array[0]);
}
很可能以
结尾void show()
{
printf("%dn", 1);
}
int main(int argc, char * argv[])
{
show();
}
我猜,优化器会注意到,这个show可能很容易内联,所以代码可能会进一步优化:
int main(int argc, char * argv[])
{
printf("%dn", 1);
}
理论上这完全取决于实现。c++标准定义了你得到的行为——如何得到它是不可思议的。
在实践中,我希望每个编译器(平台支持它的地方)在编译时将该数组放在const段中,并从那里直接使用它。随着优化器的发展,前面创建的"const"对象的状态是固定的(标准规定以任何方式改变它们都是未定义的行为),数据流分析器会考虑到这一点。从已知位置的数组中读取值可以,通常用数字代替。
另外,IIRC使用顶级const使对象默认为静态,所以除非你使用'extern',否则它在翻译单元中将是私有的。如果代码中没有真正需要它(读取是按值内联的),则根本不会发出它。
大多数编译器都有发出汇编/机器代码输出的选项,这样你就可以检查它对特定实现做了什么,或者你可以使用对象文件转储器来查看数组的存在。
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么 GCC 在使用类型别名时处理 const reinterpret_cast不同?
- 由非const类处理的数据的const正确性
- 如何处理 const T& 和 T&& 实例化到同一个签名?
- 使用 std::reference_wrapper<const T> 来适当地处理 const T& ?
- C++ 中的文件处理错误 - 调用"std::basic_fstream<char, std::char_traits<char> >::open(const char[8],
- C++1z 处理 == 测试,在自动函数中使用 std::initializer_list<int> 和 w/o const
- Clang和G++在处理const对象时的差异
- 当使用const std::string&作为方法参数类型时,处理nullptr const char*的正确方法是什么?
- 在处理无状态对象时,将它们标记为const是否仍有性能优势
- 处理需要多行初始化'const'对象
- C++如何处理 const double&引用 int?
- 处理C++类中难以避免的大量const成员
- c++编译器如何处理const数组
- 为什么未初始化的const成员在C和c++中的处理方式不同?
- 如何处理带有底层排序向量的映射中的const值
- 我可以有一个返回*this并处理非常量对象的const成员函数吗
- 为什么 const 限定符不处理 const 对象上的指针成员?
- c++从const int*到int*的转换,处理意外结果