Strange diagnostic pragma behavior in GCC 4.6
Asked Answered
R

1

9

I have a C program with a couple of static functions that are not (yet) used. I want to disable warnings for those specific functions. I do not want to disable all -Wunused-function warnings. I am using GCC 4.6. Specifically:

gcc --version

gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

I am following the advice in the documentation (to use push and pop), but I have not been able to get it to work.

I have created some simplified source code to investigate the problem. I am compiling them with gcc -Wall -o pragma pragma.c (where pragma.c). My first version of pragma.c looks like this:

void foo(int i) { }
static void bar() { }
int main() { return 0; }

As expected, I get this when I compile it:

pragma.c:3:13: warning: ‘bar’ defined but not used [-Wunused-function]

Also as expected, I am able to disable the warning like this (then the compile succeeds silently):

#pragma GCC diagnostic ignored "-Wunused-function"
void foo(int i) { }
static void bar() { }
int main() { return 0; }

But then, I tried this:

void foo(int i) { }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void bar() { }
#pragma GCC diagnostic pop
int main() { return 0; }

When I compiled that, I got the original warning:

pragma.c:4:13: warning: ‘bar’ defined but not used [-Wunused-function]

Removing the pop gets rid of the warning:

void foo(int i) { }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static void bar() { }
int main() { return 0; }

But I need a way to disable the warning just for a specific section of code. I have not been able to do that.

It is hard for me to imagine how this could be intended behavior...but many others have used this version of GCC and it seems unlikely that, if this were a bug, it would make it into the release version.

Still, I have trouble seeing how this behavior is consistent with the documentation, which says that "pragmas occurring after a line do not affect diagnostics caused by that line."

What am I doing wrong? Is there more information about the problem, such as a bug report and/or information about possible workarounds?

Ruhnke answered 23/3, 2012 at 0:46 Comment(4)
I suspect that GCC doesn't run its test for unused functions until after parsing the entirety of the source file, so any instruction to pop its warning state before EOF would therefore take effect before that check.Shorttempered
This is very localized question, better to be asked on other SO sites.Vociferance
@Vociferance As the answer shows, this appears to apply to every remotely recent GCC suite, on any operating system, and the problem in my question speaks directly to what might be considered a basic conceptual misunderstanding (i.e., a check that happens after processing the whole file cannot generally occur locally within an opening and closing pragma, see Adam Rosenfield's comment). I have trouble seeing how this question is even a little bit localized. Furthermore, coming from AU, I can tell you we'd probably close this OT there and migrate here.Ruhnke
For posterity, this problem still exists in GCC 5.4...Ur
D
16

This works (GCC version 4.6.1):

#ifdef __GNUC__
#define SUPPRESS_NOT_USED_WARN __attribute__ ((unused))
#else
#define SUPPRESS_NOT_USED_WARN
#endif

void foo() {  }
SUPPRESS_NOT_USED_WARN static void bar() { }
int main() { return 0; }

/* or
static void SUPPRESS_NOT_USED_WARN bar() { }
 etc. */

/* but not, undefined declarations:
SUPPRESS_NOT_USED_WARN static void bar();
*/

GCC v4.2.4 doc. 5.32 Specifying Attributes of Variables:

unused
        This attribute, attached to a variable, means that the variable is meant to be possibly unused. GCC will not produce a warning for this variable.

GCC v4.2.4 doc. 5.25 Declaring Attributes of Functions (a more correct link, functions, sorry about that.)

unused
        This attribute, attached to a function, means that the function is meant to be possibly unused. GCC will not produce a warning for this function.


When it comes to pragma push, pop, etc,, the documentation say:

GCC doc. 6.57.10 Diagnostic Pragmas:

Modifies the disposition of a diagnostic. Note that not all diagnostics are modifiable; at the moment only warnings (normally controlled by `-W...') can be controlled, and not all of them. Use -fdiagnostics-show-option to determine which diagnostics are controllable and which option controls them.

It states; "and not all of them", -Wunused-function seems to be one of the ones not willing to be suppressed. The option fdiagnostics-show-option seems to be enabled by default. (Gives the flag from which the error/warning enabled.).

Using -Wno-unused-function at command line disables it, but then of course for all, not just the ones directly specified in the code.

If you say:

gcc -Wunused-function -o o mycode.c

You'll still get the warning, - so it does not have anything to do with, e.g., the -Wall setting for the compile process in an special state where it won't work.


As an example, this works:

int foo(int i) { return i; }

int main() {
    int a;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(a);
#pragma GCC diagnostic pop

    return 0;
}
Digitize answered 23/3, 2012 at 1:19 Comment(2)
Thanks. Using the unused attribute is more elegant, and less visually distracting, too. I think that when the documentation says not all warnings can be controlled, it means that not all warnings have -W... syntax, not that some warnings that do have -W... syntax still cannot be turned off. So I suspect the explanation Adam Rosenfield provided (in his comment) explains why my approach was not going to work. As you say, other GCC diagnostic ignored ... pragmas work with push and pop--I am able to disable -Wuninitialized as in your example. Thanks again!Ruhnke
Yes, Mr. Rosenfield's explanation sounds good. Had a quick peek at the gcc source code and it seems, tho I've easily can have overlooked something ;), that this is the case. Guess, perhaps, using a #ifdef SILENCE_WARN_FN_UNUSED, or similar could be wise, - to force one to add / make aware / remember etc. at compile-time.Digitize

© 2022 - 2024 — McMap. All rights reserved.