I was adding some GCC warning, and wanted to explicitly exclude some expressions and found a way by using #pragma diagnostic. However, I realized that depending where I put the pragma, the binaries can change.
For instance, consider the following snippet:
#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;
}
and the following two implementations of f(...)
:
https://godbolt.org/z/hxWcf6h9s
Implementation of
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; }
Generated code:
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
https://godbolt.org/z/qdnhhKMjP
Implementation of
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; }
Generated code:
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
Compiled with gcc -std=gnu99 -Wparentheses -Werror -O0
, result in different binaries. Why is that?