GCC 10.2.0 and Clang 11.1.0.
I have the following piece of code:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
uint8_t hour = p[8];
uint8_t min = p[9];
uint8_t sec = p[10];
uint16_t msec = (p[11] * 4);
#pragma GCC diagnostic pop
Clang (which is used by the YouCompleteMe (YCM) Vim plugin) honors these pragmas and doesn't show any warning during file processing. I can confirm that by commenting these pragmas out - YCM diagnostics immediately show me warnings on corresponding lines.
However, GCC ignores them and I get the following in the console log:
packet.c:111:26: warning: unused variable ‘msec’ [-Wunused-variable]
111 | uint16_t msec = (p[11] * 4);
| ^~~~
packet.c:110:25: warning: unused variable ‘sec’ [-Wunused-variable]
110 | uint8_t sec = p[10];
| ^~~
packet.c:109:25: warning: unused variable ‘min’ [-Wunused-variable]
109 | uint8_t min = p[9];
| ^~~
packet.c:108:25: warning: unused variable ‘hour’ [-Wunused-variable]
108 | uint8_t hour = p[8];
| ^~~~
Flags used for build:
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -Wall -pedantic -Werror=format-security" CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -Wall -pedantic -Werror=format-security" LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
What is going on here? It seems like a bug in GCC.
It seems like this is the case even for this simplest program:
int main(int argc, char *argv[]) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
int x;
#pragma GCC diagnostic pop
return 0;
}
Tests:
cd /tmp
clang -Wall main.c
gcc -Wall main.c
main.c: In function ‘main’:
main.c:4:9: warning: unused variable ‘x’ [-Wunused-variable]
4 | int x;
| ^
Some similar bug is described for g++ and still opened for about nine years!
It seems like it's related to the scoping. When I move push/pop #pragma
s outside of a variable's block, GCC behaves well. For example:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
uint8_t hour = p[8];
uint8_t min = p[9];
uint8_t sec = p[10];
uint16_t msec = (p[11] * 4);
#pragma GCC diagnostic pop
should be changed to the:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
{
uint8_t hour = p[8];
uint8_t min = p[9];
uint8_t sec = p[10];
uint16_t msec = (p[11] * 4);
}
#pragma GCC diagnostic pop
Then both Clang and GCC work fine.