【问题标题】:The address of const variable, C++const 变量的地址,C++
【发布时间】:2015-04-27 02:17:48
【问题描述】:

最近我在重读 Scott Meyers 的 Effective C++(第 3 版)。根据迈耶斯的说法:
“另外,虽然好的编译器不会设置 为整数类型的 const 对象留出存储空间(除非您创建一个 对象的指针或引用),草率的编译器可能,你可能 不愿意为此类对象留出内存。”
在我的代码中,我可以打印 const 变量的地址,但我没有在其上创建指针或引用。我使用 Visual Studio 2012。

int main()
{
    const int x = 8;
    std::cout<<x<<" "<<&x<<std::endl;
}

输出是:
8 0015F9F4

谁能解释我这本书和我的代码不匹配的地方?还是我哪里弄错了?

【问题讨论】:

  • 你能告诉我们你得到了什么吗?通常,如果您在调试模式下编译,代码中的常量不会被替换
  • 您仍然可以获取 const 对象的地址。通过获取地址,您很可能会强制编译器在可执行文件中为其留出一些存储空间。
  • 当您获取地址时,您会创建一个临时指针。

标签: c++ constants


【解决方案1】:

通过在变量上使用地址运算符,您实际上是在创建一个指针。指针是一个临时对象,不是声明的变量,但它就在那里。

此外,还有一个声明的指针类型变量指向您的变量:您用来打印指针的重载operator &lt;&lt; 的参数。

【讨论】:

    【解决方案2】:
         std::cout<<x<<" "<<&x<<std::endl;
    

    你试图获取变量x的地址,所以编译器认为有必要生成set aside storage for const objects的代码。

    【讨论】:

      【解决方案3】:

      通过&amp;x,您是ODR-used 变量,这使得为x 分配实际存储空间是必要的。

      【讨论】:

        【解决方案4】:

        一个好的编译器(在使用优化时)会尝试用代码中的值替换任何编译时常量,以避免进行内存访问。但是,如果您确实请求了一个常量的地址(就像您一样),它无法进行不为其分配内存的优化。

        但是,需要注意的重要一点是,这并不意味着您的代码中没有进行研究和替换。由于您不应该更改常量的值,因此编译器将假定对其进行“研究和替换”是安全的。如果您使用 const_cast 更改值,您将获得未定义的行为。如果您在调试中编译它往往可以正常工作,但如果您的编译器优化代码通常会失败。

        【讨论】:

          【解决方案5】:

          在C++中,对于基本数据类型常量,编译器会将其放入符号表中,不分配存储空间,而ADT(Abstract Data Type)/UDT(User Defined Type) const对象需要分配存储空间(大对象)。还有一些情况也需要分配存储空间,比如强制声明为extern符号常量或者取符号常量的地址等。

          【讨论】:

            猜你喜欢
            • 2015-03-28
            • 1970-01-01
            • 1970-01-01
            • 2014-09-24
            • 1970-01-01
            • 2011-05-20
            • 2010-10-09
            • 1970-01-01
            • 2019-01-06
            相关资源
            最近更新 更多