C(++)对未存储在变量中的值有什么作用?

我对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并将其存储在某个变量中,……)

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

如果可以确定该值始终等于xxx,那么智能编译器将在其位置替换xxx的值。

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

有关详细信息,请阅读计算机体系结构。

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

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

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

好吧,一个好的编译器会做常量传播和折叠,所以在这个例子中,它用12345替换IE6_Bugs,用56789替换Win_Bugs,然后将其转换为69134.然后它可能还将69134> 10000折叠为’true’并且在编译时完全删除分支。

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

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

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

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

告诉我们的方法是检查生成的汇编代码,或者在调试器中逐步执行它。 不同的编译器可以以不同的方式进行。 它可能还取决于您的编译器选项,例如“DEBUG”。

如果声明以“const”为前缀,那么关于常量折叠和消除“if”测试的注释将适用。