37

I'm getting this warning on a stack variable:

warning: object.member may be used uninitialized in this function

In this case I do not wish to force initialization to just to get rid of the warning as it consumes CPU cycles. The variable is a POD structure so a memset on it is not zero cost. I can verify that the variable is never used uninitialized, so I'd just like to suppress the warning for it.

In general I do want the warning, just not on this particular variable in this particular scenario. How can I suppress the warning?


Looks like the pragma diagnostics are the correct way to go but they require quite a recent version of GCC (4.6)

No acceptable solution prior that version is known.

edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267

5 Answers5

34

Try doing this:

 #pragma GCC diagnostic ignored "-Wuninitialized"
        foo(b);         /* no diagnostic for this one */

This pragma comes in three interesting and helpful flavors : warning, error, ignored. See 6.56.10 Diagnostic Pragmas for their usages. The link says,

GCC allows the user to selectively enable or disable certain types of diagnostics, and change the kind of the diagnostic. For example, a project's policy might require that all sources compile with -Werror but certain files might have exceptions allowing specific types of warnings. Or, a project might selectively enable diagnostics and treat them as errors depending on which preprocessor macros are defined.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • @awoodland: Even I didn't see this before 2009. Looks like it was added after that. – Nawaz Feb 22 '11 at 16:37
  • 3
    It's the first time I have encountered it as well. It'll probably be a couple of years before it's seen out in the wild. What a helpful answer :) – Tim Post Feb 22 '11 at 16:46
  • Makes my collection of "Reduce to NOOP" workarounds for common warnings with -Werror look antiquated! – Flexo Feb 22 '11 at 16:47
  • 2
    This is not allowed to be used inside a function (so says GCC). – edA-qa mort-ora-y Feb 22 '11 at 17:16
  • 2
    Actually this *isn't* what I want. This disables the warning for the entire file, not just a particular function. – edA-qa mort-ora-y Feb 22 '11 at 17:22
  • @edA: Is this mentioned on the same page of the given link? – Nawaz Feb 22 '11 at 17:25
  • @edA-qa mort-ora-y: You're using it incorrectly. After the particular function definition you can write `#pragma GCC diagnostic warning "-Wuninitialized"` to re-enable the warning for rest of the file! – Nawaz Feb 22 '11 at 17:26
  • @edA Disables it for entire file, even when wrapped in push/pop "#pragma GCC diagnostic push #pragma GCC diagnostic pop"? [Documentation gives an explicit example where it should work on a line by line basis](http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html) – Flexo Feb 22 '11 at 17:27
  • Maybe the question is in which version was this local support added. I'm using 4.4.5. – edA-qa mort-ora-y Feb 22 '11 at 17:28
  • 2
    @edA-qa mort-ora-y: I think. it's supported from [GCC 4.6.0](http://gcc.gnu.org/gcc-4.6/changes.html) – Nawaz Feb 22 '11 at 17:33
  • Can you confirm this would work by putting it around the declaration of the variable and not at the point where it is used? – edA-qa mort-ora-y Feb 22 '11 at 17:47
28

The accepted answer has two big problems that requires more than a comment. First, it deactivates the warning for the whole file. If that pragma resides in a header, probably for more. Warnings are useful and if it is indeed a false positive, one should disable the warning for a bunch of code as small as possible.

Then the warning in the OP is "maybe uninitialized" which is deactivated by -Wmaybe-uninitialized, as opposed to -Wuninitialized.

#pragma GCC diagnostic push                             // save the actual diag context
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"  // disable maybe warnings
function() or int variable;                             // impacted section of code
#pragma GCC diagnostic pop                              // restore previous diag context
doom
  • 3,276
  • 4
  • 30
  • 41
MappaM
  • 809
  • 8
  • 15
6

GCC differentiates between uninitalised and self initalized, e.g. compiling:

int main() {
   int i = i;
   return i;
}

With gcc -Wall -Wextra gives no warnings, unless you explicitly added -Winit-self as well, yet it gets completely optimized out by my quick testing.

Flexo
  • 87,323
  • 22
  • 191
  • 272
  • This does not disable my warnings and I do not explicitly add `-Winit-self`. – edA-qa mort-ora-y Feb 22 '11 at 17:24
  • I don't know, I just test in the code where I need to get rid of the warning and it didn't. – edA-qa mort-ora-y Feb 22 '11 at 17:42
  • gcc (4.4.1) does not complain about this, but g++ (same version) does! `$ g++ -Wall -Wextra selfinit.c /home/MICROSOL/agustinf/Work/x.c: In function 'int main()': /home/MICROSOL/agustinf/Work/x.c:2: warning: 'i' is used uninitialized in this function` – gatopeich May 27 '11 at 14:02
6

@Nawaz has answered the question as specifically asked, but have you considered that the fact that you need this may indicate you're declaring your struct too early/at a less nested scope than appropriate? It would generally be much preferred if you could declare your struct at a point where you can actually initialize it rather than declaring it earlier and filling it in various locations.

Also, even though you can verify that it's never used uninitialized right now, what if someone else adds a new code path in the future and it's not initialized properly? If you disable the warning then it'll silently compile and probably break in an unexpected way. Unless you can prove that the initialization is taking a measurable amount of your program's CPU it's probably better to just do the initialization up front.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • 2
    +1 Always code as if the next person to touch the code is dumber than yourself. It might even be you a year from now when you don't remember that you need to worry about that value being initialized. Perhaps if he posts his code we can help him find a relatively efficient way to remove the warning. – Karl Bielefeldt Feb 22 '11 at 17:23
  • 1
    You assume there is a valid default initializer, which there is not. And yes, it takes measurable CPU time. – edA-qa mort-ora-y Feb 22 '11 at 17:44
  • 4
    @edA-qa mort-ora-y If there's no way to validly default construct one of these objects it sounds even more like you shouldn't be creating one uninitialized at all. Are you able to delay construction until you know how to create the object? – Mark B Feb 22 '11 at 18:16
  • 3
    I won't vote this down ;), but I strongly disagree with the sentiment that one should initialize something when you don't know what to initialize it to, just for the sake of initialization. You might initialize it to ANYTHING at this point (it will be overwritten anyway), then later if someone adds code that actually starts to use this ANYTHING - are you really better off? You should just suppress the warning right in front where the variable is used for the first time imho. Use `#pragma GCC diagnostics push/pop` to avoid that the warning is suppressed elsewhere too. – Carlo Wood Oct 15 '18 at 15:03
1

Selectively disable GCC warnings for only part of a translation unit?

Community
  • 1
  • 1
frankc
  • 11,290
  • 4
  • 32
  • 49