最近我重读了Scott Meyers撰写的Effective C ++(第3版)。根据迈耶斯的说法:
"此外,虽然好的编译器不会设置
除了存储整数类型的const对象(除非你创建一个
指针或对象的引用),草率的编译器可能,你可以
不愿意为这些物品留出记忆。"
在我的代码中,我可以打印const变量的地址,但我没有在其上创建指针或引用。我使用Visual Studio 2012。
int main()
{
const int x = 8;
std::cout<<x<<" "<<&x<<std::endl;
}
输出结果为:
8 0015F9F4
有人可以解释我和我的代码之间的不匹配吗?或者我错了?
答案 0 :(得分:3)
通过在变量上使用address-of运算符,实际上是在创建指针。指针是一个临时对象,而不是声明的变量,但它非常适合。
此外,指针类型的声明变量指向您的变量:用于打印指针的重载operator <<
的参数。
答案 1 :(得分:1)
按&x
,您ODR-used变量,这样就可以为x
分配实际存储空间。
答案 2 :(得分:1)
一个好的编译器(当使用优化时)将尝试用代码中的值替换任何编译时常量,以避免进行内存访问。但是,如果你确实请求了一个常量的地址(就像你那样),它就无法优化不为它分配内存。
但是,需要注意的一件重要事情是,它并不意味着您的代码中没有进行研究和替换。由于您不应该更改常量的值,编译器将假定对其进行“研究和替换”是安全的。如果您使用const_cast
更改了值,则会得到未定义的行为。如果在debug中编译它往往会正常工作,但如果编译器优化了代码,通常会失败。
答案 3 :(得分:1)
std::cout<<x<<" "<<&x<<std::endl;
您试图获取变量x
的地址,因此编译器认为有必要为set aside storage for const objects
生成代码。
答案 4 :(得分:1)
在C ++中,对于基本数据类型常量,编译器会将它放在符号表中而不分配存储空间,而ADT(抽象数据类型)/ UDT(用户定义类型)const对象将需要分配存储空间(大对象)。在某些情况下还需要分配存储空间,例如强制声明为外部符号常量或取符号常量的地址等。