In Visual C++, it's possible to use #pragma warning (disable: ...)
. Also I found that in GCC you can override per file compiler flags. How can I do this for "next line", or with push/pop semantics around areas of code using GCC?

- 112,946
- 110
- 377
- 526
-
1possible duplicate of [disable specific warnings in gcc](http://stackoverflow.com/questions/1079997/disable-specific-warnings-in-gcc) - Oops, actually that question itself is a dupe (but not closed). That just happens to be the one that showed up under "Related". Anyway, this has been asked and answered several times on SO. – Tyler McHenry Jul 31 '10 at 14:49
-
4@paxdiablo: I'm doign the reverse. I've jacked up the warning level very high, and want to squash warnings line by line that I've verified to be okay. – Matt Joiner Jul 31 '10 at 16:28
-
7@Tyler McHenry: If you checked more carefully you might note that the linked question contains a per-file solution, precisely the one I mentioned in my own question as being unsatisfactory (I even stole the link). – Matt Joiner Jul 31 '10 at 16:30
-
9@paxdiablo, compilers give false positives, sometimes you want to compile with -Werror but not have these false positives block a build. so disabling spesific cases and commenting why - makes sense in some cases. There are other cases too where this could be handy - like auto-generating code that produces harmless warnings that are not so easy to go in and change (since the code is generated), though in that case disabling per file is more likely to be the solution. – ideasman42 Nov 04 '12 at 06:56
9 Answers
It appears this can be done. I'm unable to determine the version of GCC that it was added, but it was sometime before June 2010.
Here's an example:
#pragma GCC diagnostic error "-Wuninitialized"
foo(a); /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
#pragma GCC diagnostic pop
foo(c); /* error is given for this one */
#pragma GCC diagnostic pop
foo(d); /* depends on command line options */

- 7,611
- 5
- 39
- 71

- 112,946
- 110
- 377
- 526
-
28one `push` and two `pop`s - may be another `push` at the beginning is missing? – abyss.7 Nov 17 '12 at 14:03
-
@abyss.7: From memory this is verbatim from the GCC manual. If the exampe is good enough for them, I'm happy to use it, even if it's an erroneous snippet :P – Matt Joiner Dec 15 '12 at 10:39
-
48"#pragma GCC diagnostic push #pragma GCC diagnostic pop Causes GCC to remember the state of the diagnostics as of each push, and restore to that point at each pop. If a pop has no matching push, the command-line options are restored." -- from the GCC manual: http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html – bobpaul Jan 11 '13 at 18:43
-
11For reference, gcc version 4.4.3 supports error/warning/ignored, but not push/pop – frankster Feb 12 '13 at 14:21
-
16The first version of GCC that had diagnostic push/pop is [GCC 4.6.4](https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas). I determined this by looking at the Diagnostic-Pragmas.html#Diagnostic-Pragmas section for each GCC version at [GCC Documentation](https://gcc.gnu.org/onlinedocs/) – Alex Bitek Aug 20 '14 at 15:48
-
*"I'm unable to determine the version of GCC that it was added..."* - yeah, I could not locate it either. I learned `GCC diagnostic optimize` has been available since 4.7, so maybe around that time? Also see [When did 'pragma diagnostic' become available?](https://gcc.gnu.org/ml/gcc-help/2015-07/msg00062.html) on the GCC-Help mailing list. – jww Jul 20 '15 at 07:03
-
6Its a shame this does not work in practice. In some cases, it produces more warnings. Or maybe, more correctly, it does not work in practice for GCC 4.7 through 5.1. See, for example, [GCC does not honor 'pragma GCC diagnostic' to silence warnings](http://stackoverflow.com/q/31509434). – jww Jul 20 '15 at 07:05
-
Nor apparently does the latest release of GCC honor -Wconversion. What's a guy to do? – Matt Joiner Jul 20 '15 at 13:18
-
I've always had trouble with push/pop, and it is a shame it doesn't work... I was aiming to turn diagnostics on for a short chunk of code... #pragma GCC diagnostic push #pragma GCC diagnostic error "-Wpadded" #pragma GCC diagnostic pop ... This causes padded WARNINGS thereafter instead of ignoring them (-Wpadded was not enabled anywhere else or on the command line). gcc version 4.9.4 – Jetski S-type Oct 14 '16 at 05:03
-
1
-
Well the reason why 1-push-but-2-pops is good for their example is that they're explicitly demonstrating a change from the command-line options and how a final push reverts to that without an explicit pop prior, and they're implicitly in the context of code which is well within its rights to erase whatever diagnostic pragma state was configured by any code *before* this example code. This is one of those things that's usually going to be fine, until you paste it in the middle of code which wasn't written with the expectation that its diagnostic pragmas will get unset partway through. – mtraceur Sep 08 '22 at 05:53
To net everything out, this is an example of temporarily disabling a warning:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
write(foo, bar, baz);
#pragma GCC diagnostic pop
You can check the GCC documentation on diagnostic pragmas for more details.

- 14,379
- 2
- 32
- 61

- 1,539
- 1
- 9
- 3
-
3Should work, but my `gcc-4.9` just ignores this line completely. – Aleksei Petrenko Sep 18 '17 at 13:42
TL;DR: If it works, avoid, or use specifiers like _Noreturn
, [[nodiscard]]
, __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 five things you could do:
- Improve the source code, if possible
- Use an attribute, like
[[maybe_unused]]
- Use a declaration specifier, like
__attribute__
- Use
_Pragma
- Use
#pragma
- Use a command line option.
Improving the source
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).
Using an attribute, like [[maybe_unused]]
#include <stdio.h>
int main([[maybe_unused]] int argc, const char *argv[])
{
while (*++argv) puts(*argv);
return 0;
}
If you're lucky, the standard provides an attribute for your situation, like [[maybe_unused]]
. Attributes are a new feature of C2x. So far, C2x defines four attributes, [[deprecated]]
, [[fallthrough]]
, [[maybe_unused]]
, and [[nodiscard]]
.
Using a declaration specifier, like __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.
Suppressing the warning on the command line for a single file
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 readers who are in similar situations.

- 17,035
- 5
- 40
- 47
-
3re: `improving the source` it would also work to change the declaration of main to `int main(int, const char* argv[]) { ... }` by not giving the argument a name, you tell the compiler it will be unused. – Jesse Chisholm Aug 09 '18 at 18:05
-
2@JesseChisholm omitting the parameter name at the function definition is not possible. See 6.9.1 Function definintions of ISO/IEC9899, §5 "If the declarator includes a parameter type list, the declaration of each parameter shall include an identifier […]" And correctly so the code would be rejected by `gcc` as well as `clang`. – Christian Hujer Nov 29 '18 at 17:33
-
4Another pattern is to just do a cast of the variable to void. In fact, I have seen in a project the following macro: `#define UNUSED(x) ((void)x)` used to silence warnings. I think it was in ReactOS? – Paul Stelian Apr 13 '19 at 15:11
-
2They way `__attribute__` syntax works, it cleverly uses double parentheses `((` `))`, so, if your compiler doesn't understand it, you can `#define __attribute__(x)` and they all disappear. – doug65536 Jun 15 '21 at 04:14
-
Thank you! I have wondered for a couple years when I will need the `_Pragma()` style over the `#pragma` style, and I just found it! You might want to add this to your answer: you **must** use the `_Pragma()` style if you want to put these calls inside of a macro definition! This is because you can't do preprocessor calls that begin with `#` from within macro definitions since the `#` character means something special inside macro definitions (is is the stringization character) and it cannot be used like that. – Gabriel Staples Apr 17 '22 at 04:23
I know the question is about GCC, but for people looking for how to do this in other and/or multiple compilers…
TL;DR
You might want to take a look at Hedley, which is a public-domain single C/C++ header I wrote which does a lot of this stuff for you. I'll put a quick section about how to use Hedley for all this at the end of this post.
Disabling the warning
#pragma warning (disable: …)
has equivalents in most compilers:
- MSVC:
#pragma warning(disable:4996)
- GCC:
#pragma GCC diagnostic ignored "-W…"
where the ellipsis is the name of the warning; e.g.,#pragma GCC diagnostic ignored "-Wdeprecated-declarations
. - Clang:
#pragma clang diagnostic ignored "-W…"
. The syntax is basically the same as GCC's, and many of the warning names are the same (though many aren't). - Intel C++ Compiler (ICC): Use the MSVC syntax, but keep in mind that warning numbers are totally different. Example:
#pragma warning(disable:1478 1786)
. - PGI/Nvidia: There is a
diag_suppress
pragma:#pragma diag_suppress 1215,1444
. Note that all warning numbers increased by one in 20.7 (the first Nvidia HPC release). - TI (CCS): There is a
diag_suppress
pragma with the same syntax (but different warning numbers!) as PGI:pragma diag_suppress 1291,1718
- Oracle Developer Studio (ODS) (suncc): there is an
error_messages
pragma. Annoyingly, the warnings are different for the C and C++ compilers. Both of these disable basically the same warnings:- C:
#pragma error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)
- C++:
#pragma error_messages(off,symdeprecated,symdeprecated2)
- C:
- IAR: also uses
diag_suppress
like PGI and TI, but the syntax is different. Some of the warning numbers are the same, but I others have diverged:#pragma diag_suppress=Pe1444,Pe1215
- Pelles C: similar to MSVC, though again the numbers are different
#pragma warn(disable:2241)
For most compilers it is often a good idea to check the compiler version before trying to disable it, otherwise you'll just end up triggering another warning. For example, GCC 7 added support for the -Wimplicit-fallthrough
warning, so if you care about GCC before 7 you should do something like
#if defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
For Clang and compilers based on Clang, such as newer versions of XL C/C++ and armclang, you can check to see if the compiler knows about a particular warning using the __has_warning()
macro.
#if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#endif
Of course you also have to check to see if the __has_warning()
macro exists:
#if defined(__has_warning)
# if __has_warning("-Wimplicit-fallthrough")
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
# endif
#endif
You may be tempted to do something like
#if !defined(__has_warning)
# define __has_warning(warning)
#endif
So you can use __has_warning
a bit more easily. Clang even suggests something similar for the __has_builtin()
macro in their manual. Do not do this. Other code may check for __has_warning
and fall back on checking compiler versions if it doesn't exist, and if you define __has_warning
you'll break their code. The right way to do this is to create a macro in your namespace. For example:
#if defined(__has_warning)
# define MY_HAS_WARNING(warning) __has_warning(warning)
#else
# define MY_HAS_WARNING(warning) (0)
#endif
Then you can do stuff like
#if MY_HAS_WARNING(warning)
# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
#elif defined(__GNUC__) && (__GNUC__ >= 7)
# pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#endif
Pushing and popping
Many compilers also support a way to push and pop warnings onto a stack. For example, this will disable a warning on GCC for one line of code, then return it to its previous state:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
call_deprecated_function();
#pragma GCC diagnostic pop
Of course there isn't a lot of agreement across compilers about the syntax:
- GCC 4.6+:
#pragma GCC diagnostic push
/#pragma GCC diagnostic pop
- Clang:
#pragma clang diagnostic push
/#pragma clang diagnostic pop
- Intel 13+ (and probably earlier):
#pragma warning(push)
/#pragma warning(pop)
- MSVC 15+ (Visual Studio 9.0 / 2008):
#pragma warning(push)
/#pragma warning(pop)
- ARM 5.6+:
#pragma push
/#pragma pop
- TI 8.1+:
#pragma diag_push
/#pragma diag_pop
- Pelles C 2.90+ (and probably earlier):
#pragma warning(push)
/#pragma warning(pop)
If memory serves, for some very old versions of GCC (like 3.x, IIRC) the push/pop pragmas had to be outside of the function.
Hiding the gory details
For most compilers it's possible to hide the logic behind macros using _Pragma
, which was introduced in C99. Even in non-C99 mode, most compilers support _Pragma
; the big exception is MSVC, which has its own __pragma
keyword with a different syntax. The standard _Pragma
takes a string, Microsoft's version doesn't:
#if defined(_MSC_VER)
# define PRAGMA_FOO __pragma(foo)
#else
# define PRAGMA_FOO _Pragma("foo")
#endif
PRAGMA_FOO
Is roughly equivalent, once preprocessed, to
#pragma foo
This let’s us create macros so we can write code like
MY_DIAGNOSTIC_PUSH
MY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated_function();
MY_DIAGNOSTIC_POP
And hide away all the ugly version checks in the macro definitions.
The easy way: Hedley
Now that you understand the mechanics of how to do stuff like this portably while keeping your code clean, you understand what one of my projects, Hedley does. Instead of digging through tons of documentation and/or installing as many versions of as many compilers as you can to test with, you can just include Hedley (it is a single public domain C/C++ header) and be done with it. For example:
#include "hedley.h"
HEDLEY_DIAGNOSTIC_PUSH
HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
call_deprecated();
HEDLEY_DIAGNOSTIC_POP
Will disable the warning about calling a deprecated function on GCC, Clang, ICC, PGI, MSVC, TI, IAR, ODS, Pelles C, and possibly others (I probably won't bother updating this answer as I update Hedley). And, on compilers which aren't known to work, the macros will be preprocessed away to nothing, so your code will continue to work with any compiler. Of course HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED
isn't the only warning Hedley knows about, nor is disabling warnings all Hedley can do, but hopefully you get the idea.

- 16,623
- 1
- 43
- 62
Use:
#define DIAG_STR(s) #s
#define DIAG_JOINSTR(x,y) DIAG_STR(x ## y)
#ifdef _MSC_VER
#define DIAG_DO_PRAGMA(x) __pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(warning(x))
#else
#define DIAG_DO_PRAGMA(x) _Pragma (#x)
#define DIAG_PRAGMA(compiler,x) DIAG_DO_PRAGMA(compiler diagnostic x)
#endif
#if defined(__clang__)
# define DISABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,push) DIAG_PRAGMA(clang,ignored DIAG_JOINSTR(-W,clang_option))
# define ENABLE_WARNING(gcc_unused,clang_option,msvc_unused) DIAG_PRAGMA(clang,pop)
#elif defined(_MSC_VER)
# define DISABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,push) DIAG_DO_PRAGMA(warning(disable:##msvc_errorcode))
# define ENABLE_WARNING(gcc_unused,clang_unused,msvc_errorcode) DIAG_PRAGMA(msvc,pop)
#elif defined(__GNUC__)
#if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,push) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,pop)
#else
# define DISABLE_WARNING(gcc_option,clang_unused,msvc_unused) DIAG_PRAGMA(GCC,ignored DIAG_JOINSTR(-W,gcc_option))
# define ENABLE_WARNING(gcc_option,clang_option,msvc_unused) DIAG_PRAGMA(GCC,warning DIAG_JOINSTR(-W,gcc_option))
#endif
#endif
This should do the trick for GCC, Clang and MSVC.
It can be called with e.g.:
DISABLE_WARNING(unused-variable,unused-variable,42)
[.... some code with warnings in here ....]
ENABLE_WARNING(unused-variable,unused-variable,42)
See 7 Pragmas, Controlling Diagnostics via Pragmas and Pragma directives and the __pragma and _Pragma keywords for more details.
You need at least version 4.02 to use these kind of pragmas for GCC, and I am not sure about MSVC and Clang about the versions.
It looks like the push pop pragma handling for GCC is a little bit broken. If you enable the warning again, you still get the warning for the block that was inside the DISABLE_WARNING/ENABLE_WARNING block. For some versions of GCC it works, and for some it doesn't.

- 30,738
- 21
- 105
- 131

- 1,860
- 22
- 13
#pragma GCC diagnostic ignored "-Wformat"
Replace "-Wformat" with the name of your warning flag.
AFAIK there is no way to use push/pop semantics for this option.

- 2,855
- 2
- 31
- 25
-
6Its a shame this does not work in practice. In some cases, it produces more warnings. Or maybe, more correctly, it does not work in practice for GCC 4.7 through 5.1. See, for example, [GCC does not honor 'pragma GCC diagnostic' to silence warnings](http://stackoverflow.com/q/31509434). – jww Jul 20 '15 at 07:01
I had same issue with external libraries like ROS headers. I like to use following options in CMakeLists.txt for stricter compilation:
set(CMAKE_CXX_FLAGS "-std=c++0x -Wall -Wextra -Wstrict-aliasing -pedantic -Werror -Wunreachable-code ${CMAKE_CXX_FLAGS}")
However, doing this causes all kind of pedantic errors in externally included libraries as well. The solution is to disable all pedantic warnings before you include external libraries and re-enable them like this:
// Save compiler switches
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
// Bad headers with a problem goes here
#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>
// Restore compiler switches
#pragma GCC diagnostic pop

- 30,738
- 21
- 105
- 131

- 63,284
- 17
- 238
- 185
-
2Shouldn't this better be handled by with gcc's [system](https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html) [directories](https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html)? – Red XIII Jan 17 '17 at 10:19
-
1@RedXIII - yes, that's an option if you can make list of such directories and specify in gcc command line. However many times compiler gets invoked deep in pipeline or you have not much control over how someone else should compile your code. In those cases above is probably a better solution. – Shital Shah Dec 02 '19 at 11:15
Here is a way to do this in IAR. Try this:
#pragma diag_suppress=Pe177
void foo1(void)
{
/* The following line of code would normally provoke diagnostic
message #177-D: variable "x" was declared but never referenced.
Instead, we have suppressed this warning throughout the entire
scope of foo1().
*/
int x;
}
#pragma diag_default=Pe177
See official documentation for reference.

- 167
- 8
Rather than silencing the warnings, GCC style is usually to use either standard C constructs or the __attribute__
extension to tell the compiler more about your intention.
For instance, the warning about assignment used as a condition is suppressed by putting the assignment in parentheses, i.e. if ((p=malloc(cnt)))
instead of if (p=malloc(cnt))
.
Warnings about unused function arguments can be suppressed by some odd __attribute__
I can never remember, or by self-assignment, etc.
But generally I prefer just globally disabling any warning option that generates warnings for things that will occur in correct code.

- 30,738
- 21
- 105
- 131

- 208,859
- 35
- 376
- 711
-
2Maybe so. My intent is not to prove any general case pattern, rather an observation about what gcc's philosophy on warning suppression seems to be. – R.. GitHub STOP HELPING ICE Jul 31 '10 at 20:12
-
compiler behaves differently w/r/t warnings with added parentheses?!?!??!!!! WOW! That is unexpected. – Jason S Dec 10 '14 at 17:05
-
2@JasonS the parens doesn't change the compiler's behavior wrt warnings, what it does is change the semantics of the statement. The extra parens make the compiler finish the assignment and keep its final value as an expression, which deserves no warning. If you want clarity, you could say `if ((p=malloc(cnt)) != NULL) ...` as that is what the compiler is doing behind the scenes. – Jesse Chisholm Aug 09 '18 at 18:10
-
1@JesseChisholm: I don't think your explanation is accurate. – R.. GitHub STOP HELPING ICE Nov 01 '18 at 20:32
-
What is that *"[ICE](https://pmortensen.eu/world/EditOverflow.php?LookUpTerm=ICE)"* you speak of? Perhaps elaborate somewhat in your profile text? – Peter Mortensen Oct 21 '22 at 23:24
-
1ICE = U.S. [Immigration and Customs Enforcement](https://en.wikipedia.org/wiki/U.S._Immigration_and_Customs_Enforcement) – Peter Mortensen Nov 08 '22 at 21:37