pragma GCC诊断随着二进制文件的变化而变化
我添加了一些GCC警告,并希望显式排除一些表达式,并找到了使用的方法。然而,我意识到,根据我把pragma放在哪里,二进制文件可以改变pragma GCC诊断随着二进制文件的变化而变化,c,gcc,pragma,C,Gcc,Pragma,我添加了一些GCC警告,并希望显式排除一些表达式,并找到了使用的方法。然而,我意识到,根据我把pragma放在哪里,二进制文件可以改变 例如,考虑下面的片段: #include <stdio.h> int f(int x, int y, int z); int main() { int x, y, z; scanf("%d%d%d", &x, &y, &z); f(x, y, z); return 0;
例如,考虑下面的片段:
#include <stdio.h>
int f(int x, int y, int z);
int main()
{
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
f(x, y, z);
return 0;
}
f:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
mov DWORD PTR [rbp-12], edx
mov eax, 1
pop rbp
ret
f:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], edi
mov DWORD PTR [rbp-8], esi
mov DWORD PTR [rbp-12], edx
cmp DWORD PTR [rbp-4], 0
jne .L2
cmp DWORD PTR [rbp-8], 0
je .L3
cmp DWORD PTR [rbp-12], 0
je .L3
.L2:
mov eax, 1
jmp .L4
.L3:
mov eax, 0
.L4:
pop rbp
ret
的实现:f
int f(int x, int y, int z) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wparentheses" if (x || y && z) #pragma GCC diagnostic pop { return 1; } return 0; }
int f(int x, int y, int z) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wparentheses" if (x || y && z) { #pragma GCC diagnostic pop return 1; } return 0; }
- 生成的代码:
f: push rbp mov rbp, rsp mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi mov DWORD PTR [rbp-12], edx mov eax, 1 pop rbp ret
f: push rbp mov rbp, rsp mov DWORD PTR [rbp-4], edi mov DWORD PTR [rbp-8], esi mov DWORD PTR [rbp-12], edx cmp DWORD PTR [rbp-4], 0 jne .L2 cmp DWORD PTR [rbp-8], 0 je .L3 cmp DWORD PTR [rbp-12], 0 je .L3 .L2: mov eax, 1 jmp .L4 .L3: mov eax, 0 .L4: pop rbp ret
使用
gcc-std=gnu99-wparenthesses-Werror-O0编译,会产生不同的二进制文件。这是为什么?-O0的设计目的不是为了产生高效的二进制文件,或最佳的二进制文件,或不依赖于代码或编译器选项中的细微更改的二进制文件,或诸如此类的东西。查看生成的二进制文件,除了正确性和可能的可调试性之外,期望任何东西都是没有任何意义的。@n.'degents'm。谢谢,但我不明白你的意思,你是说将二进制文件与-O0进行比较没有意义吗?我的目标是理解带有pragma的代码之间的区别,包括开放的花括号和非开放的花括号。是的,这正是我要说的,我的意思是说,没有更多。你可以试着理解其中的区别,但我认为从中没有什么有价值的东西可以学到。在没有优化的情况下,编译器会生成便于生成的代码,并且无论诊断选项如何,期望同样的事情也会很方便是不合理的。@n.“代词m:-O0
不是以特定方式设计的,这并不意味着检查生成的二进制文件没有任何意义。自然界中没有任何东西是被设计出来的,然而我们通过研究物理学、生物学等学科学到了很多东西,并从中获得了很多价值。从表面上看,忽略警告与代码生成无关,因此存在差异的事实表明存在某种联系。这种表面上看不出的联系令人感兴趣。好奇心是有价值的,应该鼓励而不是阻止它。@n.“代词m:可能需要学习的东西可能是关于编译器是如何构造的一些启发。或者可能是#pragma
指令中的一些语义我们不知道。或者编译器中的一些错误或缺点。OP发现了一些奇怪的东西,调查这些奇怪的东西可能会带来有趣的发现。你看了才知道,阻止好奇心是不好的政策。