GCC diagnostic pragma: targeted warning suppression in embedded C builds
0 reputation · 11 Apr 2020, 15:37 UTC
0 reputation · 11 Apr 2020, 15:37 UTC
In a large embedded C codebase compiled with -Wall -Werror, developers often need to silence harmless -Wunused-variable warnings that arise in legacy or third‑party headers, while preserving the strict error‑on‑warning behavior for all other diagnostics.
The suppression must be local—affecting only the code following a #pragma GCC diagnostic push and preceding the matching #pragma GCC diagnostic pop. It must not lower the global warning level, must interact correctly with -Werror, and ideally should be portable or at least conditionally compiled across other embedded compilers.
1. Does placing #pragma GCC diagnostic ignored "-Wunused-variable" inside a push/pop pair prevent the warning from being treated as an error when -Werror is active, while leaving other warnings in the same file still subject to -Werror?
2. If a warning is emitted before the push but after the pop, does it still trigger a build error, confirming the localized scope of the suppression?
3. What is the most reliable way to wrap these pragmas in a header so that they are ignored by non‑GCC compilers without breaking compilation on IAR, Keil, or Clang?
Yes, placing #pragma GCC diagnostic ignored "-Wunused-variable" within a push/pop pair prevents that specific warning from being promoted to an error by -Werror, while ensuring all other warnings in the file remain subject to the global error-on-warning policy.
The GCC diagnostic stack operates as a state machine. When #pragma GCC diagnostic push is called, the current diagnostic state is saved. The subsequent ignored pragma modifies the active state for the current translation unit. Because -Werror acts on the result of the diagnostic check, a warning that is explicitly ignored is never triggered, and therefore cannot be promoted to an error.
Regarding scope: any warning emitted before the push or after the matching pop is processed using the global compiler flags. If -Werror is active, a warning emitted after the pop will trigger a build error, confirming that the suppression is strictly localized to the block.
To maintain compatibility across different embedded compilers (such as IAR or Keil) and to support Clang (which shares GCC's pragma syntax), wrap the pragmas in a guarded header. This prevents non-GCC compilers from attempting to process unknown pragmas.
/* diag_utils.h */
#if defined(__GNUC__) || defined(__clang__)
#define DIAG_PUSH() _Pragma("GCC diagnostic push")
#define DIAG_POP() _Pragma("GCC diagnostic pop")
#define DIAG_IGNORE_UNUSED() _Pragma("GCC diagnostic ignored \"-Wunused-variable\"")
#else
#define DIAG_PUSH()
#define DIAG_POP()
#define DIAG_IGNORE_UNUSED()
#endif
Usage Pattern:
#include "diag_utils.h"
DIAG_PUSH();
DIAG_IGNORE_UNUSED();
#include "legacy_third_party_header.h"
DIAG_POP();
To verify the localized scope and -Werror interaction, use the following test case:
gcc -Wall -Werror test.c.-Werror._Pragma is used in the macros instead of #pragma because _Pragma can be defined within a macro, whereas #pragma must appear at the start of a line.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.