How to enable _all_ warnings with -fpermissive from g++? - c++

There seem to be cases where the -fpermissive option results in errors being ignored altogether, rather than "downgraded" to warnings, as widely available documentation suggests.
The -Wall option is clearly not enough. What other options are needed in order to have all such downgraded warnings reported by g++?
An example came up with the Nodejs C++ addon library.
In file included from /opt/nodejs/linux64/8.9.4/include/node/node.h:63:0,
from /opt/nan/linux64/2.9.2/include/nan.h:51,
from /build/ndjs/include/blob.h:59,
from /build/ndjs/src/blob.cpp:2:
/opt/nodejs/linux64/8.9.4/include/node/v8.h: In instantiation of ‘v8::Local<T>::Local(v8::Local<S>) [with S = v8::Integer; T = v8::Int32]’:
/build/src/ndjs/blob.cpp:507:1: required from here
/opt/nodejs/linux64/8.9.4/include/node/v8.h:207:5: error: invalid conversion from ‘v8::Integer*’ to ‘v8::Int32*’ [-fpermissive]
TYPE_CHECK(T, S);
^
Recompiling with -fpermissive (and -Wall, of course) results in a clean compile: no warnings at all. What happened? (i.e. Why?)
The TYPE_CHECK() macro tests for type compatibility in pointer assignments:
#define TYPE_CHECK(T, S) \
while (false) { \
*(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \
}
It fails for downcasts (v8::Int32 is derived from v8::Integer), but somehow succeeds without warnings when -fpermissive is in effect. Shouldn't there be a warning about the static downcast?

Related

cc1plus: unrecognized command line option warning on any other warning

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.

How to deal with warnings about tail-padded arrays in C++?

I'm writing a C++ application which uses a C library that defines a tail-padded structure in one of its headers. Without going into too much details, it looks somewhat like this:
struct MyStruct {
// ... other members
// The last member, a tail-padding array
MyType myBuffer[];
}
I use -Wall -Wextra -Wpedantic -Werror with g++ and -std=c++0x.
Unfortunately, g++ gives me a warning about that array:
error: ISO C++ forbids zero-size array 'myBuffer' [-Wpedantic]
What is the right way to deal with this?
I know I can suppress the warning by adding a pragma to the header myself:
#pragma GCC diagnostic ignored "-Wpedantic"
But that doesn't feel right. What do you guys suggest?
You could
Remove the zero-sized array.
Build without -Wpedantic (possibly only for that file).
Build without -Werror and ignore the warning.
Build the code as C.

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

VARIADIC MACRO compile error

I want to learn how to use macro.
I simply write a sample but failed to compile on my local g++4.9
#define P(...) printf("13", ##__VA_ARGS__)
int main() {
// your code goes here
P();
return 0;
}
I will get compile error as below
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:4:42: error: expected primary-expression before ')' token
#define P(...) printf("13", ##__VA_ARGS__)
^
main.cpp:7:5: note: in expansion of macro 'P'
P();
^
But the same code can be compiled on ideone....
http://ideone.com/ucEXXz
and also by VS2015.
Is there any reasonable explanation for this?
How can I write a portable macro for all compiler....
Thanks.
In C, functions that take variable arguments require a prototype declaration, while in C++, all functions require a prototype. The declaration for printf can be found in stdio.h.
#include <stdio.h>
#define P(...) printf("13", ##__VA_ARGS__)
int main() {
P();
return 0;
}
The ##__VA_ARGS__ syntax is non-standard. It is a "swallow comma if the __VA_ARGS__ is empty" extension implemented by GCC, and seems to have been adopted by other compilers.
Regarding the behavior of -std=c++14:
The compiler can accept several base standards, such as ‘c90’ or ‘c++98’, and GNU dialects of those standards, such as ‘gnu90’ or ‘gnu++98’. When a base standard is specified, the compiler accepts all programs following that standard plus those using GNU extensions that do not contradict it. For example, -std=c90 turns off certain features of GCC that are incompatible with ISO C90, such as the asm and typeof keywords, but not other GNU extensions that do not have a meaning in ISO C90, such as omitting the middle term of a ?: expression.
GCC documentation for -std=
The ##__VA_ARGS__ extension does not conflict with the standard. What is causing it to be rejected by the coliru site is that the -pedantic flag is set.
Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the required version of ISO C). However, without this option, certain GNU extensions and traditional C and C++ features are supported as well. With this option, they are rejected.
GCC documentation for -pedantic

Caught set but unused parameters with clang

Is there a way I could catch set but unused variables using clang, something similar to gcc's Werror=unused-but-set-parameter?
I set -Wunused but clang doesn't catch set but unused parameters.
I am not sure if you have tried more than what you have listed, but here is more information on CLANG unused options, using its GCC compatibility:
First, here is what the documentation suggests:
-Wextra -Wunused-but-set-parameter
The following is background reference information:
From HERE:
If you are using the LLVM-GCC or Apple LLVM Compiler build option there are a large number of possible compiler warnings that you can enable/disable. The Clang front end also supports the GCC diagnostic warnings (see http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html) for backwards compatibility.
Following the referenced link in that quote lists several unused options from the GCC family of warnings:
-Wall
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
-Wall turns on the following warning flags:
(there are many more, just listing 'unused')
...
-Wunused-function
-Wunused-label
-Wunused-value
-Wunused-variable
...
And finally, just below the last block:
-Wextra
This enables some extra warning flags that are not enabled by -Wall.
(This option used to be called -W. The older name is still supported, but the newer name is more descriptive.)
(again, there are more, just listing _unused variety)
-Wunused-parameter (only with -Wunused or -Wall)
-Wunused-but-set-parameter (only with -Wunused or -Wall)
There is an equivalent warning generated by clang-tidy, integrated from clang-analyzer:
note: Value stored to 'tmp' is never read
warning: Value stored to 'tmp' is never read [clang-analyzer-deadcode.DeadStores]
It looks like LLVM chose to implement some of the GCC warnings as separate tools.
In this website, if you search for 'unused' you can find some flags that you could use. And I think this one is your flag:
clang -Wunused-variable test.c