正如我上面所说,这是不好的做法吗?在ASM中,它会是什么样子?我的意思是,我不知道它是否被翻译成这样的东西:
arr[0] = value;
arr[1] = value;
或者像这样:
arr[1] = value;
arr[0] = arr[1];
第二个显然效率更低(imm vs mem)。
提前谢谢。
根据 C 语法赋值运算符从右到左计算。
所以这个说法
arr[0] = arr[1] = value;
相当于
arr[0] = ( arr[1] = value );
来自 C 标准(6.5.16 赋值运算符)
3 赋值运算符将值存储在指定的对象中 左操作数。赋值表达式的值为 left 赋值后的操作数,111),但不是左值。的类型 赋值表达式是左操作数之后的类型 左值转换。更新存储值的副作用 左操作数在左操作数和左操作数的值计算之后排序 正确的操作数。操作数的计算是无序的。
所以根据报价,你可以考虑这个说法
arr[0] = arr[1] = value;
喜欢
arr[1] = value;
arr[0] = arr[1];
至于效率,编译器可以生成一个高效的目标代码,该代码将与您想象中看到的源代码不同。
好吧,我查看了汇编代码,得到了这个:
182 Arr[0] = 0x01;
e357: A601 LDA #0x01
e359: C70100 STA 0x0100
184 Arr[0] = Arr[1] = 0x58;
e35d: A658 LDA #0x58
e35f: C70101 STA 0x0101
e362: C70100 STA 0x0100
因此,如果我执行 Arr[0] = 0x58;并且立即执行 Arr[1] = 0x58; 预期的结果是:
e357: A601 LDA #0x58
e359: C70100 STA 0x0100
e359: C70100 STA 0x0101
(STA:斯托尔蓄能器 |LDA:LoaD蓄能器)
因此,我使用的编译器优化了代码。你们已经说过了,我认为使用以下内容可以更好地练习(或更好的可读性):
Arr[0] = 0x58;
Arr[1] = 0x58;
谢谢大家!
如果你想看asm,你可以使用
objdump -d -M intel binary_name
然后,您将搜索.text
部分,然后搜索main
函数。
这是我使用int arr[2]
和一个简单的printf
在计算机上获得的变量。
优化输出,使用-O3
编译
mov ecx,0x2a
mov edx,0x2a
未优化
对于此代码:
arr[0] = 42;
arr[1] = 42;
输出为:
mov DWORD PTR [rbp-0x10],0x2a
mov DWORD PTR [rbp-0xc],0x2a
对于此代码:
arr[0] = arr[1] = 42;
输出为:
mov DWORD PTR [rbp-0xc],0x2a
mov eax,DWORD PTR [rbp-0xc]
mov DWORD PTR [rbp-0x10],eax
在第二种情况下,还有一个额外的操作。
因此,对于优化的编译,没有区别,但为了代码的可读性,我不会以这种方式编写它。