我对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
是否会达到内存?或者处理器是否通过自己的缓存直接比较值?
或者,在编译过程中,上面的if语句转换为机器更“理解”的东西? (也许首先计算IE6_Bugs+Win_Bugs
并将其存储在某个变量中,...)
答案 0 :(得分:18)
它将被放置在CPU的寄存器中(假设有一个可用)。寄存器是一种超快的超小型RAM,内置于CPU本身,用于存储中间操作的结果。
如果可以确定该值始终等于xxx,则智能编译器将替换xxx的值。
请记住,无论是表达式还是数字(x + y vs 10),仍然需要放在一个寄存器中,以便CPU可以访问它并根据其值执行操作。
有关详细信息,请阅读计算机体系结构。
答案 1 :(得分:8)
在一般情况下,代码生成器直接在指令中编码这些值(“立即模式寻址”)或将它们存储在程序的数据段中,以便根据需要加载。
称为“常量折叠”的优化在编译时计算常量表达式的值。在您的特定示例中,智能编译器将识别您的条件将始终为真并避免为测试生成代码,因此在为您的程序生成的机器代码中可能根本不会显示值12345,56789和10000。 / p>
您的编译器可能有一个选项来保留为您的程序生成的中间汇编语言,例如,,g++ -S
。了解一下处理器的体系结构和汇编语言,以便从这个输出中学习理解甚至是有用的推论。
答案 2 :(得分:4)
它将无名的临时值放在命名变量的任何地方 - 通常在堆栈上。与命名变量一样,编译器可以选择将值放在CPU寄存器中以加快速度。如果您真的对此感兴趣,那么您应该查看编译器生成的汇编器输出。
答案 3 :(得分:4)
好吧,一个好的编译器会做常量传播和折叠,所以在这个例子中,它用12345替换IE6_Bugs,用56789替换Win_Bugs,然后将其转换为69134.然后它可能还会折叠69134> 10000到'true'并在编译时完全删除分支。
如果它不进行常量传播或折叠,无论是内存位置还是寄存器,它将存储表达式结果的位置。寄存器会快得多。
答案 4 :(得分:2)
绝对没有办法最终回答这个问题。这里的其他答案对于大多数体系结构都是准确的,但这并不是C / C ++标准所规定的,这些标准与硬件无关。
评估顺序由标准定义。最终如何在内存中处理事情不是。
答案 5 :(得分:0)
告诉我们的方法是检查生成的汇编代码,或者在调试器中逐步执行它。不同的编译器可以以不同的方式进行。它可能还取决于您的编译器选项,例如“DEBUG。”
如果声明的前缀为“const”,那么关于常量折叠和消除“if”测试的注释将适用。