我阅读了c++11 faq并找到了这句话:
通常我们想要全局或命名空间对象的编译时评估保证,通常是我们想要放置在只读存储中的对象。
我想看看我的编译器(gcc 版本 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) )是如何工作的,所以我在下面编写代码:
#include <iostream>
using namespace std;
constexpr int add5(int i){
return i+5;
}
int main(int argc,char*argv[])
{
constexpr int read_only = add5(10);
cout << &read_only <<endl;
return 0;
}
我以为read-only
会出现在 .rodata 部分,但它没有出现。显然人们可能认为编译器做了优化。在这种观点下,我认为几乎每个常量表达式都可以存储在编译器的表中,但不能省略到目标代码中。如果存在退出,则目标代码中应该存在一些常量表达式,以便更好地进行只读存储。
~$: ./constexpr
0x7fff622addec
~$: cat /proc/3051/maps
7fff6228e000-7fff622af000 rw-p 00000000 00:00 0 [stack]
更新:
我不太明白我特别引用粗体部分的句子。
正如下面的评论,read_only
是一个局部变量,它将作为上面的结果出现在堆栈中。如果我们不谈论全局数据或命名空间中的内容,那是没有意义的:
#include <iostream>
using namespace std;
constexpr int add5(int i){
return i+5;
}
constexpr int read_only = add5(10);
int global_int = add5(10);
int main(int argc,char*argv[])
{
cout << &read_only <<endl;
cout << &global_int <<endl;
getchar();
return 0;
}
~$: ./constexpr
0x4009b8
0x601068
~$: cat /proc/3157/maps
00400000-00401000 r-xp 00000000 08:09 1200603 /home/shia/constexpr
00600000-00601000 r--p 00000000 08:09 1200603 /home/shia/constexpr
00601000-00602000 rw-p 00001000 08:09 1200603 /home/shia/constexpr
它按我的预期工作。关于用前缀声明的全局变量const
:
使用 constexpr 声明的变量或数据成员的行为与使用 const 声明一样,只是它需要在使用前进行初始化,并且其初始化程序必须是常量表达式。因此 constexpr 变量始终可以用作常量表达式的一部分
因此,它也应该出现在.rodata
部分中。