【问题标题】:const variable in c++C++中的常量变量
【发布时间】:2011-06-27 04:05:37
【问题描述】:

这些是一些愚蠢的问题..我想问..请帮助我理解它

const int i=100;   //1
///some code
long add=(long)&i;  //2

疑问:对于上面的代码..编译器会先遍历整个代码
用于决定是否应该分配内存..或者首先它将存储
变量在只读内存位置,然后在 2 处分配 stroage

疑问:为什么取变量的地址强制编译器将变量存储在内存中..甚至
虽然 rom 或 register 也有地址

【问题讨论】:

  • 是什么让你认为寄存器有地址?
  • const 变量是矛盾的
  • 所以他们(注册)只用他们各自的名字来定义?
  • @user388338:如果您认为 register 可以或不能以 epciffly 方式解决,那么您正在考虑特定的硬件。一些硬件已注册,它们由魔术内存位置表示,从而使它们可寻址,而其他硬件则不能。 C++ 在很多硬件上编译,所以你的想法可能不适用于所有硬件。第 2 行仅意味着编译器必须以具有地址的方式生成(请注意,如果您打开高度优化,实际地址可能会完全消失(这完全取决于))。听到的主要担心是你正在抛弃 const-ness。

标签: c++


【解决方案1】:

在您的代码示例中,add 包含i 的地址,而不是值。我相信您可能认为i 没有存储在正常内存中,除非/直到您获取它的地址。事实并非如此。

const 并不表示该值存储在 ROM 中。它像任何其他变量一样存储在普通内存(通常是堆栈)中。 const 表示编译器会竭尽全力阻止您修改该值。

const 不是,也从未打算成为某种安全机制。如果你获得了内存的地址并想修改它,你可以这样做。当然,这几乎总是一个坏主意,但如果你真的需要这样做,这是可能的。

【讨论】:

  • 您对我的问题的看法是正确的,但我在 bruce eckel 中读到“c++ 编译器避免为 const 创建存储,而是将定义保存在符号表中”
  • 实际上我们不知道i的内存在哪里:如果声明在函数体内,那么它很可能在堆栈上。如果它在文件范围内,它将在其他地方,这是否意味着 ROM 取决于实现。任何将add 的值转换回指针并使用它来修改i 内容的尝试都会产生未定义的结果。
  • 我认为大多数实现默认将i 放在堆栈上,但可以在优化过程中将其移动到其他位置。另见:stackoverflow.com/questions/1576489/…
  • 更改本质上为 const 的变量实际上是未定义的行为。请注意,这与丢弃 const(例如通过将 const& 作为函数参数传递)不同
  • @Nate:我发现在嵌入式系统的编译器上,const 数据要么放入 ROM,要么放入可执行文件。一些编译器可能会将数据从 ROM复制堆栈。如果使用关键字static,编译器直接从ROM 访问数据而不进行复制。这是用汇编语言显示的。
【解决方案2】:

我从未编写过实现此功能的编译器,但我认为将变量作为普通变量处理会很简单,但在使用变量值的地方使用常量值,如果地址是,则使用变量的地址用过。

如果在变量范围的末尾没有人获取地址,那么我可以直接删除它而不是进行真正的分配,因为对于所有其他用途,已使用常量值而不是编译变量加载操作。

【讨论】:

    【解决方案3】:

    常量值(不是const 的唯一用途,而是这里使用的那个)不是“存储在普通内存中”(当然也不存储在 ROM 中)。每当代码使用变量时,编译器就会简单地使用该值(在本例中为 100)。

    当然,如果值没有存储在任何地方,那么常量的地址就没有意义。

    const 的其他用途存储在“普通内存”中,您可以获取它们的地址,但结果是“指向 const 值的指针”,因此(原则上)不能用于修改值。硬转换当然会改变这一点,因此它们会触发令人讨厌的编译器警告。

    另外,请记住,C/C++ 编译器完全在编译时运行(根据定义!),后期的某些使用会影响早期部分的代码生成,这并不罕见。

    一个非常明显的例子是堆栈变量的声明:编译器必须考虑在任何给定级别声明的所有变量才能在块入口处生成堆栈分配。

    【讨论】:

      【解决方案4】:

      我对您的要求有点困惑,但查看您的代码:

      i = 100,地址为 0x?????????????

      add = 无论地址存储为 long int

      【讨论】:

        【解决方案5】:

        此代码中没有(动态)内存分配。这两个局部变量是在堆栈上创建的。取i的地址,粗暴地转换成long,然后赋值给第二个变量。

        【讨论】:

        • 不错的形容词brutally。如果你能更详细地了解为什么粗暴地施放某些东西是一个坏主意,你可以得到我的 +1
        • @Martin 我会尽力在这里提供帮助:-)。使用 C 风格转换将 'const int*' 转换为 'long' 不仅是 const 的问题,而且我们也不知道结果是否适合 long。对我来说太残忍了! :-)
        猜你喜欢
        • 1970-01-01
        • 2021-08-30
        • 1970-01-01
        • 1970-01-01
        • 2011-08-27
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多