TL;DR: If it works, avoid, or use specifiers like __attribute__
, otherwise _Pragma
.
This is a short version of my blog article Suppressing Warnings in GCC and Clang.
Consider the following Makefile
CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
.PHONY: all
all: puts
for building the following puts.c
source code
#include <stdio.h>
int main(int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
It will not compile because argc
is unused, and the settings are hardcore (-W -Wall -pedantic -Werror
).
There are 5 things you could do:
__attribute__
_Pragma
#pragma
The first attempt should be checking if the source code can be improved to get rid of the warning. In this case we don't want to change the algorithm just because of that, as argc
is redundant with !*argv
(NULL
after last element).
__attribute__
#include <stdio.h>
int main(__attribute__((unused)) int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
If you're lucky, the standard provides a specifier for your situation, like _Noreturn
.
__attribute__
is proprietary GCC extension (supported by Clang and some other compilers like armcc
as well) and will not be understood by many other compilers. Put __attribute__((unused))
inside a macro if you want portable code.
_Pragma
operator_Pragma
can be used as an alternative to #pragma
.
#include <stdio.h>
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
int main(int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
_Pragma("GCC diagnostic pop")
The main advantage of the _Pragma
operator is that you could put it inside macros, which is not possible with the #pragma
directive.
Downside: It's almost a tactical nuke, as it works line-based instead of declaration-based.
The _Pragma
operator was introduced in C99.
#pragma
directive.We could change the source code to suppress the warning for a region of code, typically an entire function:
#include <stdio.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
int main(int argc, const char *argv[])
{
while (*++argc) puts(*argv);
return 0;
}
#pragma GCC diagnostic pop
Downside: It's almost a tactical nuke, as it works line-based instead of declaration-based.
Note that a similar syntax exists in clang.
We could add the following line to the Makefile
to suppress the warning specifically for puts:
CPPFLAGS:=-std=c11 -W -Wall -pedantic -Werror
.PHONY: all
all: puts
puts.o: CPPFLAGS+=-Wno-unused-parameter
This is probably not want you want in your particular case, but it may help other reads who are in similar situations.