Search code examples
cgccpragma

All #pragma GCC diagnostics ignored except the last one


When using #pragma GCC diagnostic push/pop/warning/ignored... it seems that only the last #pragma - line is taken into effect! Why? As an example, I copied and modified the example given for gcc 7.3.0 from here

#include <stdio.h>
#include <stdint.h>

static void foo();
static void bar();
static void car();
static void dar();

int main() {

#pragma GCC diagnostic warning "-Wunused-variable"
    foo();         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
    bar();         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    car();         /* error is given for this one */
#pragma GCC diagnostic pop
    dar();         /* depends on command line options */

    return 0;


}

static void foo() {

    volatile uint32_t testArray[UINT8_MAX] = {0};

}

static void bar() {
    volatile uint32_t testArray[UINT8_MAX] = {0};
}

static void car() {
    volatile uint32_t testArray[UINT8_MAX] = {0};
}

static void dar() {
    volatile uint32_t testArray[UINT8_MAX] = {0};
}

Compiling the code above in two ways

  1. adding -Wall in command line

  2. omitting -Wall in command line

Will result in that 1. raises a warning for all calls to foo(), bar(), car() and dar(), while 2. will not raise a warning for any.. suggesting that the last #pragma GCC diagnostic pop is the only one taken into effect, and which is the one following command line rules. I didn't reach this conclusion only by this example of course, but is the one I'm representing here.

Any ideas on why this is? Am I doing it wrong?

EDIT: The accepted answer led to the following, working, code:

#include <stdio.h>
#include <stdint.h>

static void foo();
static void bar();
static void car();
static void dar();

int main() {


    foo();         /* error is given for this one */


    bar();         /* no diagnostic for this one */

    car();         /* error is given for this one */

    dar();         /* depends on command line options */

    return 0;


}
#pragma GCC diagnostic warning "-Wunused-variable"
static void foo() {

    volatile uint32_t testArray[UINT8_MAX] = {0};

}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
static void bar() {

    volatile uint32_t testArray[UINT8_MAX] = {0};
}
#pragma GCC diagnostic pop
static void car() {

    volatile uint32_t testArray[UINT8_MAX] = {0};
}
#pragma GCC diagnostic pop
static void dar() {

    volatile uint32_t testArray[UINT8_MAX] = {0};
}

Solution

  • The last #pragma is used, because foo and bar are placed in your code after all pragma lines. Try this:

    #pragma GCC diagnostic warning "-Wunused-variable"
    
    static void foo() {
        volatile uint32_t testArray[UINT8_MAX] = {0};
    }
    

    pragma affects the code after this line, and doesn't follow the function calls, as you expect.