关于c中"非法定"的优化?

Gri*_*han 5 c assembly gcc compiler-optimization logical-operators

虽然学习的编译器优化,我写的代码中CLinuxGCC版本gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5.1)
要understant not a statement(NOP)在C.我写了两码第一y.c第二x.cgenerate their compiled assembly code使用gcc -S选项.

拳头代码yc

desktop:~$ cat y.c
main()
{
int i=0;
}
desktop:~$ gcc -S y.c
desktop:~$ 
Run Code Online (Sandbox Code Playgroud)

第二个代码xc

desktop:~$ cat x.c
main()
{
int i=0;

/* Loops and if*/
while(0);
for(;0;);
if(0);

/* Arithmetic Operations */
i * i;
i / i;
i - i;
i + i;
i % i;
 +i;
 -i;

/* Comparison operators */
i == i;
i != i;
i < i;
i > i;
i >= i;
i <= i;

/* Bitwise Operations*/
i ^ i;
i | i;
i & i;
 ~i;
i << i;
i >> i;

/* Address Operatins*/ 
 &i;
 *(&i);
 (&i)[i];

/* Ternary conditional operation*/
 i? i : i;

/* Other Operations*/ 
 sizeof(i);
 (char)i;

/* Not-Logical Operation*/ 
 !i; 

/* Logical AND , OR Operators */ 
// i && i;  // Commented && operation 
// i || i;  // Commented || operation
}
desktop:~$ gcc -S x.c
Run Code Online (Sandbox Code Playgroud)

注意:此时最后两行x.c被评论.
正如我所期待的那样.它们生成的汇编代码没有区别.我比较x.sy.s使用diff命令.

desktop:~$ diff x.s y.s
1c1
<   .file   "x.c"
---
>   .file   "y.c"
desktop:~$
Run Code Online (Sandbox Code Playgroud)

但当我取消注释最后(或说添加)两行时x.c.

i && i;  
i || i; 
Run Code Online (Sandbox Code Playgroud)

再次使用-S选项编译xc并与ys进行比较

desktop:~$ tail  x.c  
 sizeof(i);
 (char)i;

/* Not-Logical Operation*/ 
 !i; 

/* Logical AND , OR Operators */ 
i && i;  // unCommented && operation 
i || i;  // unCommented || operation
}
desktop:~$ gcc -S x.c
desktop:~$ diff x.s y.s
1c1
<     .file    "x.c"
---
>     .file    "y.c"
10,21d9
<     movl    -4(%ebp), %eax
<     testl    %eax, %eax
<     je    .L3
<     movl    -4(%ebp), %eax
<     testl    %eax, %eax
< .L3:
<     movl    -4(%ebp), %eax
<     testl    %eax, %eax
<     jne    .L8
<     movl    -4(%ebp), %eax
<     testl    %eax, %eax
< .L8:
desktop:~$ 
Run Code Online (Sandbox Code Playgroud)

:
我只是不明白为什么表情i || ii && i不等同于'not a statement'

为什么编译器将这两个语句转换为可执行文件(我们可以用反汇编objdump获取相同的代码).这两个表达有什么特别之处.它们不包括=操作.

它们是否更改(设置/重置)CPU标志寄存器?我觉得不是!

甚至/分割操作被丢弃,可能导致除以零故障.

编辑:添加答案

没有什么特殊i || ii && i表达.两者都相当于NOT A STATEMENT.并且可以通过GCC compiler 一些额外的努力来移除.

要删除此: -o2-o3标志是有用的:
这里是我的尝试!

desktop:~$ gcc -o2 -S y.c 
desktop:~$ gcc -o2 -S x.c 
desktop:~$ diff x.s y.s -y
    .file   "x.c"                         |     .file   "y.c"
    .text                               .text
    .p2align 4,,15                        <
.globl main                         .globl main
    .type   main, @function                     .type   main, @function
main:                               main:
    pushl   %ebp                            pushl   %ebp
    movl    %esp, %ebp                      movl    %esp, %ebp
    popl    %ebp                          |     subl    $16, %esp
                                  >     movl    $0, -4(%ebp)
                                  >     leave
Run Code Online (Sandbox Code Playgroud)

RHS中的额外行是由于文件之间的不对齐.

我也想补充信息JAVAC#编译器丢弃这个表情没有任何标志.

Ale*_*ler 2

使用 启用优化-O2,您应该会看到额外的代码消失。

  • @GrijeshChauhan 是 O(“哦”),而不是 0(“零”)。 (3认同)