^= 是否在内存中创建一个临时变量?
Does ^= create a temporary variable in memory?
按位运算符^=
在使用时会在内存中创建一个临时变量吗?
举个例子,如果我有:
a ^= b;
它是否在内存中创建一个 a
的副本,然后检查它然后分配?或者它只是直接检查然后分配而不创建临时变量?
这是一个特定于编译器的问题,但我用 g++ -O2
和 clang++ -O2
试过了。它编译了这个:
int main (int argc, char** argv) {
int a = argc, b = argc * 3;
a ^= b;
return a;
}
到
leal (%rdi,%rdi,2), %eax
xorl %edi, %eax
ret
a ^= b
部分响应 xorl
行,如您所见,它是一条指令。所以gcc并没有创建然后赋值一个新的变量,而是直接把操作交给了CPU.
请注意,您应该纯粹因为觉得它有趣而看它。从性能的角度来看,您应该 不 关心这些事情并将其留给您的编译器。优化这些东西非常好,所以把你的时间和知识集中在编写正确和可读的代码上!
这里发生的事情如下:
read a
read b
xor the previously variables
store result in a
变量是大多数编程语言(但不是全部)中使用的高级结构。这里没有创建变量。
变量与内存不同。当上面的代码在 CPU 上执行时,CPU 必须从 ram 加载操作数,如果它还没有存储在寄存器中的话。这种操作的输入或输出是否存储在 RAM(又名 "memory")或寄存器中取决于之前和之后的操作。
简而言之:没有变量,数据在使用前最有可能被复制,但不一定存储在 RAM 中。
它可能发生在处理器的一个通用寄存器中,而不是内存中,但它取决于很多因素:CPU 体系结构、编译器优化标志、周围代码。
可能的情况是:
- 将
a
的值加载到寄存器中(假设 eax
f.e);
- 将
b
的值加载到另一个寄存器(比方说 ebx
);
- xor 存储在两个寄存器中的值,结果去其中一个(
eax
, f.e.);
- 将
eax
寄存器中的值存储到内存中,地址为 a
。
如果变量 a
和 b
是用常量值初始化的局部变量,它们本身可能不会在内存中占有一席之地并且只在处理器寄存器中度过它们的生命周期,它们的寿命很短并且编译器认为将它们存储在这里是浪费时间和内存,只是为了在以后的几条指令中忽略并丢弃它们(当函数 returns)。
在极端情况下,如果a
是一个局部变量并且在赋值后没有使用a
的值,那么给出的代码可能根本不会生成CPU指令, f.e.
按位运算符^=
在使用时会在内存中创建一个临时变量吗?
举个例子,如果我有:
a ^= b;
它是否在内存中创建一个 a
的副本,然后检查它然后分配?或者它只是直接检查然后分配而不创建临时变量?
这是一个特定于编译器的问题,但我用 g++ -O2
和 clang++ -O2
试过了。它编译了这个:
int main (int argc, char** argv) {
int a = argc, b = argc * 3;
a ^= b;
return a;
}
到
leal (%rdi,%rdi,2), %eax
xorl %edi, %eax
ret
a ^= b
部分响应 xorl
行,如您所见,它是一条指令。所以gcc并没有创建然后赋值一个新的变量,而是直接把操作交给了CPU.
请注意,您应该纯粹因为觉得它有趣而看它。从性能的角度来看,您应该 不 关心这些事情并将其留给您的编译器。优化这些东西非常好,所以把你的时间和知识集中在编写正确和可读的代码上!
这里发生的事情如下:
read a
read b
xor the previously variables
store result in a
变量是大多数编程语言(但不是全部)中使用的高级结构。这里没有创建变量。
变量与内存不同。当上面的代码在 CPU 上执行时,CPU 必须从 ram 加载操作数,如果它还没有存储在寄存器中的话。这种操作的输入或输出是否存储在 RAM(又名 "memory")或寄存器中取决于之前和之后的操作。
简而言之:没有变量,数据在使用前最有可能被复制,但不一定存储在 RAM 中。
它可能发生在处理器的一个通用寄存器中,而不是内存中,但它取决于很多因素:CPU 体系结构、编译器优化标志、周围代码。
可能的情况是:
- 将
a
的值加载到寄存器中(假设eax
f.e); - 将
b
的值加载到另一个寄存器(比方说ebx
); - xor 存储在两个寄存器中的值,结果去其中一个(
eax
, f.e.); - 将
eax
寄存器中的值存储到内存中,地址为a
。
如果变量 a
和 b
是用常量值初始化的局部变量,它们本身可能不会在内存中占有一席之地并且只在处理器寄存器中度过它们的生命周期,它们的寿命很短并且编译器认为将它们存储在这里是浪费时间和内存,只是为了在以后的几条指令中忽略并丢弃它们(当函数 returns)。
在极端情况下,如果a
是一个局部变量并且在赋值后没有使用a
的值,那么给出的代码可能根本不会生成CPU指令, f.e.