不好的做法是 arr[0] = arr[1] = C 中的值吗?



正如我上面所说,这是不好的做法吗?在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

在第二种情况下,还有一个额外的操作。

因此,对于优化的编译,没有区别,但为了代码的可读性,我不会以这种方式编写它。

相关内容

  • 没有找到相关文章

最新更新