12

I get the following warning:

warning: 'X' is initialized and declared 'extern'

and it looks like it's no big deal and I could disable it. Changing the code is not really a good idea in my case because I have no control over the code, I just need to compile it. So I want to disable the warning.

If it had a -WSomeDefect key next to it then I could use a -Wno-SomeDefect command line switch but it looks like there's no distinct switch for this warning.

How do I disable such warning?

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • Why not simply fix the code? The intent of a warning is to make you change the offending code. Often warnings are emitted for code that, while technically legal, is error prone. I for one always compile my programs with `-Wall -Werror -pedantic`. – datenwolf Sep 16 '19 at 12:53
  • Can you give an example of how to replicate this warning? `extern int i = 0;`? – Fiddling Bits Sep 16 '19 at 12:54
  • Is this external library? If it is a public library provide a link to it. – Marek R Sep 16 '19 at 12:57
  • 6
    If you have no control over the code, is it a library? In that case you could/should include it via `-isystem` instead of `-I` (for GCC and clang) to disable all warnings in it. I also disagree that this warning is “no big deal”: it may be harmless but unlike what the answer says I think it usually points to a mistake in the code as written, and suggests the author doesn’t understand the semantics of the `extern` specifier. So it’s a valid warning that should be heeded. – Konrad Rudolph Sep 16 '19 at 13:01
  • Why just ignoring this warning is not acceptable (it is only a warning after all)? Maybe there is other way to approach this issue? – Marek R Sep 16 '19 at 13:01
  • 4
    @MarekR Because then you can’t use `-Werror`. And you *should* use `-Werror`. – Konrad Rudolph Sep 16 '19 at 13:01
  • 1
    You could disable all warnings with `-w` and call it a day. – cremno Sep 16 '19 at 13:02
  • `-Werror` is cool (I prefer it), but there are many cases where you can't use it. For example new version of compiler reports new type of warnings in lots of places of code. Ones for example I've migrated from 32 bits ti 64 bits and have thousands of warning about conversion from `size_t` to `int` and it was impossible to fix it all immediately. – Marek R Sep 16 '19 at 13:03
  • 1
    @MarekR I disagree. In that case *fix the code* (and don’t use experimental warnings; hence why you shouldn’t use `-Weverything` in production). – Konrad Rudolph Sep 16 '19 at 13:04
  • 1
    @MarekR There're hundreds of instances of this warning and they flood the compiler output. Hard to ignore. – sharptooth Sep 16 '19 at 13:15
  • You can see the relevant [line in the gcc source](https://github.com/gcc-mirror/gcc/blob/b5d1989793d030cedaa0afee81fc5e7bb4021dc9/gcc/c/c-decl.c#L5950) and there is indeed no warning flag that controls it. You could always add one... – Nate Eldredge Sep 16 '19 at 13:30
  • 1
    @KonradRudolph: `-isystem` should never be used as a hack to disable warnings. CMake does this by default and it's a huge bug - it interacts differently with default include path ordering than `-I` does and breaks things. The point of `-isystem` is primarily/only for use with `-nostdinc` to use a different system header set (e.g. an uninstalled libc version you're testing), not hacks based on its side effects. – R.. GitHub STOP HELPING ICE Sep 16 '19 at 13:35
  • @R.. I disagree. It might not have been `-isystem`’s *original* purpose but it’s effectively the *only way* to use library headers that don’t compile cleanly with high warning level, because C and C++ lack proper modularisation. It’s definitely not a hack. – Konrad Rudolph Sep 16 '19 at 14:05
  • @KonradRudolph: It is a hack. If you're upset that there's no non-hack way to do what you want, that's fine, but it's still a hack and it is actively breaking things in the wild when CMake does it. – R.. GitHub STOP HELPING ICE Sep 16 '19 at 14:09
  • *There're hundreds of instances of this warning and they flood the compiler output. Hard to ignore.* Easy to ignore with `grep`. I agree with others that the problem is a problem and ought to be fixed, but if you're bound and determined to just reduce the noise and there's no other way, I'd seriously consider `grep`. – Steve Summit Sep 16 '19 at 15:00

4 Answers4

5

For a direct answer to the posed question:

As can be seen from GCC's source code, there is no (semi-)specific switch to disable this warning. It seems to only be disabled by disabling all warning (-w) or including the offending code as system header via -isystem, both of which are non-specific in the suppressed warnings.

There is a related open bug report on GCC here and an open meta-bug for similar cases of warnings without switches here.

If you don't want to use the two non-specific suppression mechanisms, then you probably will have to patch in an additional flag to GCC or wait for the bugs to be worked on in order to disable this specific warning.

walnut
  • 21,629
  • 4
  • 23
  • 59
3

There're hundreds of instances of this warning and they flood the compiler output. Hard to ignore.

If this is external library there is way to reduce this warning to single warring report. I'm suspecting that you can live with single warning message.

Wrap this library API with your own functions/methods. You can name them 1:1 using different namespace to avoid complex modification of own code where this API is used. This way this warning will be reported only when source including problematic header file is included. Aim is to include problematic header file only once.

Depending how this API looks like it may be harder to do.

Anyway if this is third party library then this approach will make it easier to mock that library and write test for your code.

Marek R
  • 32,568
  • 6
  • 55
  • 140
2

The code producing this warning is not valid C and should be fixed. The C language requires issuing "diagnostics" (warnings or errors) for constraint violations such as this, and does not mandate the existence of any way to disable them. I believed (and I suspect many others do) that extern was a constraint violation with an initializer, since in normal usage extern only provides a declaration, not a definition. However, per 6.9.2 ¶1:

If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.

Being that the grammar seems to allow extern with an initializer, this is indeed a valid definition.

GCC has a -w option that will probably shut the warning off, but at the expense of disabling all warnings with no ability to override and turn some back on. This would make sense if it were a constraint violation and would be a sign to fix the invalid code; however, the code is valid and GCC absolutely should be providing a mechanism not to produce a spurious warning about it.

As noted by Eljay in a comment:

Warnings come in several categories: by the standard required diagnostic message; lint-like static analysis of common accidental language abuse/misuse; well-meaning but still stylistic opinion (e.g., -Weffc++); possibly too pedantic and/or minutia (e.g. -Weverything or -pedantic). The latter categories ought to have "opt-out" ways to disable the specific warning, such as in the OP's case.

GCC generally tries to honor this ought, most of the time, and I think the absence of a way to disable this one would be worth reporting to the GCC bug tracker.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 1
    Excellent answer! Warnings come in several categories: by the standard required diagnostic message; lint-like static analysis of common accidental language abuse/misuse; well-meaning but still stylistic opinion (e.g., `-Weffc++`); possibly too pedantic and/or minutia (e.g. `-Weverything` or `-pedantic`). The latter categories ought to have "opt-out" ways to disable the specific warning, such as in the OP's case. – Eljay Sep 24 '19 at 15:11
  • @Eljay: Thanks. Adding an additional note to the answer. – R.. GitHub STOP HELPING ICE Sep 24 '19 at 15:21
2

There isn't any specific flag to disable this, which is unfortunate, but there is the -w flag that will disable all warnings, with no way to re-enable them.

From the GCC docs:

-w
Inhibit all warning messages.

But the better option here is to remove the extern from the variable declarations/definitions. That way, the compiler knows the variable is defined within the translation unit. You can contact the owners of the code to see if they can change it.

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76