【问题标题】:What does C(++) do with values that aren't stored in variables?C(++) 对未存储在变量中的值做了什么?
【发布时间】:2011-01-11 04:51:23
【问题描述】:

我有点好奇 C 和 C++ 如何处理未存储在变量中的数据,例如:

int IE6_Bugs = 12345;
int Win_Bugs = 56789;

是的 - 一切都清楚了。 IE6_Bugs 有 123456 存储在它的特定内存地址。

然后呢..

if ( IE6_Bugs + Win_Bugs > 10000 )
{
  // ...

所以 C 抓取两个变量的值并将它们相加,以便将结果与右侧的 int 进行比较。

但是:

  • IE6_Bugs+Win_Bugs 是否曾经到达 RAM?还是处理器直接通过自己的缓存比较值?

  • 或者,在编译过程中,上面的 if 语句是否转换为机器更“易于理解”的东西? (也许先计算IE6_Bugs+Win_Bugs 并将其存储在某个变量中,...)

【问题讨论】:

  • int your_Bug = 假设 INT_MAX 大于 32768。
  • 所以 Win_Bugs 超过了 INT_MAX - 问题出在哪里? ^^ 如您所见,我选择了 123456789 作为示例数字。

标签: c++ c memory compilation


【解决方案1】:

它将被放置在 CPU 中的一个寄存器中(假设有一个可用)。寄存器是一种内置于 CPU 本身的超快速超小型 RAM,用于存储中间操作的结果。

如果可以确定该值始终等于 xxx,则智能编译器将替换 xxx 的值。

请记住,无论是表达式还是数字,(x+y vs 10)它仍然需要放在一个寄存器中,以便CPU可以访问它并根据其值执行操作。

如需更多信息,请阅读计算机架构。

【讨论】:

  • 如果它不适合寄存器怎么办?
  • 嗯,这取决于 CPU 架构。一些 CPU 只能读/写寄存器,不能访问内存和堆栈。在这种情况下,其他东西从寄存器转移到内存中,并被带到它的位置。 :-)
  • 将值从寄存器移到内存中以便其他内容适合寄存器的过程称为“溢出”。
  • 适用于大多数现代架构——但请记住,标准本身并未指定这一点。
【解决方案2】:

在一般情况下,代码生成器直接在指令中编码这些值(“立即模式寻址”)或将它们存储在程序的数据段中以根据需要加载。

一种称为“常量折叠”的优化在编译时计算常量表达式的值。在您的特定示例中,智能编译器将识别您的条件将始终为真并避免为测试生成代码,因此值 12345、56789 和 10000 可能根本不会在为您的程序生成的机器代码中表示。

您的编译器可能有一个选项来保留为您的程序生成的中间汇编语言,例如g++ -S。稍微了解一下您的处理器的架构和汇编语言,以了解如何从该输出中理解甚至有用的推论。

【讨论】:

    【解决方案3】:

    好吧,一个好的编译器会进行不断的传播和折叠,所以在那个例子中,它会将 IE6_Bugs 替换为 12345,将 Win_Bugs 替换为 56789,然后将其转换为 69134。然后它可能还会将 69134 > 10000 折叠为 ' true' 并在编译时完全删除分支。

    至于如果它不进行常量传播或折叠,它将在哪里存储表达式的结果,无论是内存位置还是寄存器。注册会快得多。

    【讨论】:

      【解决方案4】:

      它将无名临时值放在放置命名变量的任何位置 - 通常在堆栈上。与命名变量一样,编译器可能会选择将值放在 CPU 寄存器中以加快速度。如果你真的对此感兴趣,你应该看看你的编译器生成的汇编器输出。

      【讨论】:

        【解决方案5】:

        绝对没有办法最终回答这个问题。这里的其他答案对于大多数架构来说都是准确的,但这不是 C/C++ 标准所指定的,这些标准与硬件无关。

        评估顺序由标准定义。事情最终如何在内存中处理不是。

        【讨论】:

          【解决方案6】:

          判断的方法是检查生成的汇编代码,或者在调试器中单步执行。不同的编译器可能会以不同的方式执行此操作。它还可能取决于您的编译器选项,例如“DEBUG”。

          如果声明以“const”为前缀,则此处有关常量折叠和“if”测试的消除的 cmets 将适用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-11-17
            • 1970-01-01
            • 2017-02-01
            • 2019-02-07
            • 2010-12-07
            • 1970-01-01
            相关资源
            最近更新 更多