gpt4 book ai didi

编译器代码生成比较

转载 作者:太空狗 更新时间:2023-10-29 15:17:58 25 4
gpt4 key购买 nike

好的,所以一切从这里开始:Unsigned integer and unsigned char holding same value yet behaving differently why?

我编写了以下应用程序以了解幕后发生的事情(即编译器如何处理此问题)。

#include <stdio.h>

int main()
{
{
unsigned char k=-1;
if(k==-1)
{
puts("uc ok\n");
}
}

{
unsigned int k=-1;
if(k==-1)
{
puts("ui ok");
}
}
}

在使用 GCC 编译时,如下所示:

gcc -O0 -S -masm=intel h.c 

我得到以下程序集文件:

    .file   "h.c"
.intel_syntax noprefix
.section .rodata
.LC0:
.string "ui ok"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 16
mov BYTE PTR [rbp-1], -1
mov DWORD PTR [rbp-8], -1
cmp DWORD PTR [rbp-8], -1
jne .L3
mov edi, OFFSET FLAT:.LC0
call puts
.L3:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits

令我大吃一惊的是,第一张支票竟然不存在。

但是,如果我用 Microsoft Visual C++ (2010) 编译同样的东西,我会得到(我已经从这个列表中删除了很多垃圾,这就是它不是那么有效的原因):

00B81780  push        ebp  
00B81781 mov ebp,esp
00B81783 sub esp,0D8h
00B81789 push ebx
00B8178A push esi
00B8178B push edi
00B8178C lea edi,[ebp-0D8h]
00B81792 mov ecx,36h
00B81797 mov eax,0CCCCCCCCh
00B8179C rep stos dword ptr es:[edi]
00B8179E mov byte ptr [k],0FFh
00B817A2 movzx eax,byte ptr [k]
00B817A6 cmp eax,0FFFFFFFFh
00B817A9 jne wmain+42h (0B817C2h)
00B817AB mov esi,esp
00B817AD push offset string "uc ok\n" (0B857A8h)
00B817B2 call dword ptr [__imp__puts (0B882ACh)]
00B817B8 add esp,4
00B817BB cmp esi,esp
00B817BD call @ILT+435(__RTC_CheckEsp) (0B811B8h)
00B817C2 mov dword ptr [k],0FFFFFFFFh
00B817C9 cmp dword ptr [k],0FFFFFFFFh
00B817CD jne wmain+66h (0B817E6h)
00B817CF mov esi,esp
00B817D1 push offset string "ui ok" (0B857A0h)
00B817D6 call dword ptr [__imp__puts (0B882ACh)]
00B817DC add esp,4
00B817DF cmp esi,esp
00B817E1 call @ILT+435(__RTC_CheckEsp) (0B811B8h)

问题是:为什么会这样?为什么 GCC 会“跳过”第一个 IF,我怎样才能强制 GCC 不跳过它?优化被禁用,但它似乎仍然优化了一些东西......

最佳答案

我的猜测(我不是 GCC 开发人员)是它做了足够多的静态分析来向自己证明第一个 if 的测试永远不会为真。

这不应该难,因为在初始化和测试之间没有代码,任何副作用或外部实体都不可能改变变量。

出于好奇,尝试将变量设为 static 和/或 volatile 以查看是否有任何变化。

关于编译器代码生成比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16772763/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com