cc1plus: unrecognized command line option warning on any other warning - c++

I have a strange behavior of g++ that it shows a warning about unrecognized command line option, when any other warning is shown.
Example:
struct Foo{virtual int bar() = 0;};
struct Bar:public Foo{int bar() {return 0;} };
int main(){}
Compiling with g++-5 -Wsuggest-override -Wno-c99-extensions -std=c++11 a.cpp or even g++-5 -Wsuggest-override -Wno-c99-extensions a.cpp shows:
a.cpp:2:27: warning: ‘virtual int Bar::bar()’ can be marked override [-Wsuggest-override]
struct Bar:public Foo{int bar() {return 0;} };
^
cc1plus: warning: unrecognized command line option ‘-Wno-c99-extensions’
ADDITION: There is no warning/error when I compile with g++-5 -Wno-c99-extensions a.cpp hence that option passes CMAKEs check using CHECK_CXX_COMPILER_FLAG
This bothers me quite a lot, as we use Werror but with exceptions via Wno-error=... It then bails out when any of the (non-error) warnings is shown with the "unrecognized command line option"
Is this known/expected? How can it be prevented?

If you don't want warnings about unrecognised command-line options, don't use unrecognised command-line options: -Wno-c99-extensions has never been a valid GCC option (I believe it's a clangism). Simply remove it from your build command.
As for why the warning is only emitted when you have another warning present, this behaviour seems counter-intuitive but it is actually deliberate and documented:
The warning "unrecognized command-line option" is not given for -Wno-foo
Since GCC 4.4, and as explained in the GCC manual: when an unrecognized warning option is requested (-Wunknown-warning), GCC emits a diagnostic stating that the option is not recognized. However, if the -Wno- form is used, the behavior is slightly different: no diagnostic is produced for -Wno-unknown-warning unless other diagnostics are being produced. This allows the use of new -Wno- options with old compilers, but if something goes wrong, the compiler warns that an unrecognized option is present. (See PR28322 for the history of this change)
This might break configure tests that check for -Wno-foo options. The solution is to either test for the positive form (-Wfoo) or test using a testcase that triggers some other warning.
There are in fact a few results on Google of mailing list threads where software developers have faced this "problem", specifically with CMake, and made trivial fixes to their build scripts to "fix" it.

Related

gcc: suppress [enabled by default] warning from c++ code

We build our project using gcc with -Wall -Werror options.
Warnings from external headers are suppressed by pragmas, like this:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <somelib/component/settings.h>
#pragma GCC diagnostic pop
After upgrading externals to new version we got new type of warnings to suppress:
error: inline function ‘...’ given attribute noinline [-Werror]
Or warning without -Werror:
warning: inline function ‘...’ given attribute noinline [enabled by default]
In seems there is no way to ignore it via #pragma GCC diagnostic ignored.
What can be done in this case under following conditions?
External headers cannot be modified. Patching local copy at build time is acceptable as a last resort.
Problematic header is widely used.
-Werror is on for our code
Finally we have chosen to patch at build time. It's a bit hacky but it allows to leave our project intact.
Patching was added to cmake build:
execute_process(COMMAND "patch" "-N" "header_to_patch.h" "header_to_patch.h.patch")
Patch file was prepared with:
diff -u "original/header_to_patch.h" "fixed/header_to_patch.h" > header_to_patch.h.patch

If you specify conflicting command line arguments to GCC, which one is accepted? [duplicate]

I know that if you execute GCC as such:
gcc -O3 -O2 foo.c
GCC will use the last optimization flag passed (in this case O2). However, is this true for all flags? For example, if I execute GCC like so:
gcc -mno-sse -msse bar.c
Will it support SSE since that was the last flag passed, or would this result in undefined behavior? My initial experimentation seems to indicate that it will support SSE, but I'm not sure if this is true for all cases.
Normally later options on the line override ones passed previously, as you mention in your first example. I haven't personally come across any different behaviour for -m or -f flags, but I don't know of a specific reference in the documentation.
Note that some options don't behave this way:
$ gcc example.c -DABC -DABC=12
<command-line>: warning: "ABC" redefined
<command-line>: warning: this is the location of the previous definition
So there would need to be a -UABC in between there to shut that warning up.
As an aside, clang is particularly good at solving this problem - it will produce a warning if it ignores a command line option, which can help you out.

Can't find Xcode build setting - GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS

I'm using Xcode 6.2 to build a C++ command line application.
The Xcode Build Setting Reference states:
If you develop products using C++, you may need to customize these build settings in your targets:
GCC_WARN_EFFECTIVE_CPLUSPLUS_VIOLATIONS (Effective C++ Violation)
However this option does not appear in the build setting list for any of my targets.
Can anyone tell me where it is?
The setting in question no longer has any effect - if you place it into the pbxproj file, it appears as a user defined setting in the UI.
The setting only applies to the gnu g++ compiler, and xcode doesn't ship with that compiler any more (it ships with clang++ and a g++ wrapper that invokes clang++). a brief test of some conditions that trigger with g++ doesn't trigger with clang++ e.g.:
#include <string>
using std::string;
class foo {
string x;
int y;
void *ptr;
public:
foo() : y(1), ptr(0) {}
};
$ g++-4.9 -c -Weffc++ evil.cpp
evil.cpp:5:7: warning: 'class foo' has pointer data members [-Weffc++]
class foo {
^
evil.cpp:5:7: warning: but does not override 'foo(const foo&)' [-Weffc++]
evil.cpp:5:7: warning: or 'operator=(const foo&)' [-Weffc++]
evil.cpp: In constructor 'foo::foo()':
evil.cpp:11:5: warning: 'foo::x' should be initialized in the member initialization list [-Weffc++]
foo() : y(1), ptr(0) {}
^
$ clang++ -c -Weffc++ evil.cpp
$
There are opinions that it is too noisy to be useful - e.g. the complaint about not initializing x (a std::string) is a pointless warning in this situation, and as such is more trouble than it's worth.
You can manually add the -Weffc++ option to the compilation flags for C++ code, you can add it to the option Other C++ Flags, which is under Apple LLVM X.Y - Custom Compiler Flags (the X.Y depends on your version of XCode), but again the LLVM based compiler doesn't process that option.
It looks like the documentation is out of date for this option - I've logged a radar to have the option removed from the docs to prevent this confusion.

How to make "cc1plus: error: unrecognized command line option" a warnings with -Werror?

I have a project that is using gcc 4.6.3, and am trying to migrate to 4.8.2. However, it needs to compile on 4.6 for a while. It is using -Werror with a few specific errors turned off. To use boost 1.55 with gcc 4.8, i needed to add -Wno-unused-local-typedefs. The problem is that with -Werror, gcc 4.6 emits this error:
cc1plus: error: unrecognized command line option "-Wno-unused-local-typedefs" [-Werror]
The gcc docs on warning options have no indication this particular warning can be treated explicitly as a warnings rather than an error. Is there any way to get 4.6 to treat this as a warning?

why is "cc1plus: warning: unrecognized command line option" for "no-" options only flagged by g++ when there is another warning?

> cat warning.cpp
#pragma foobar
> cat no_warning.cpp
#pragma message "foobar"
> g++ -Wall -Wno-foobar -c warning.cpp
warning.cpp:1:0: warning: ignoring #pragma foobar [-Wunknown-pragmas]
cc1plus: warning: unrecognized command line option "-Wno-foobar" [enabled by default]
> g++ -Wall -Wno-foobar -c no_warning.cpp
no_warning.cpp:1:17: note: #pragma message: foobar
This is by design, explained here:
When an unrecognized warning option is requested (e.g., -Wunknown-warning),
GCC emits a diagnostic stating that the option is not recognized.
However, if the -Wno- form is used, the behavior is slightly different:
no diagnostic is produced for -Wno-unknown-warning unless other diagnostics
are being produced.
This allows the use of new -Wno- options with old compilers, but if something
goes wrong, the compiler warns that an unrecognized option is present.
In other words, suppose you have foo.cc, and GCC-4.9 warns about something (let's call it foobar) in it, but you believe that your use of foobar is safe.
Since you want to treat all warnings as errors (with -Werror), you dutifully add -Wno-foobar to your Makefile.
Now someone else tries to build your code with GCC-4.8. As stated above, this produces no warning and he succeeds.
If this did produce a warning, you'd be unable to both use the foobar construct and have a single Makefile that worked with both GCC-4.8 and GCC-4.9.