Suppress warnings from boost includes - c++

I have a c++ application (built under linux with g++ 4.8.3, boost 1.54) that spouts a lot of warnings about boost. Warnings include:
/usr/local/include/boost/math/constants/constants.hpp:314:3: warning: non-standard suffix on floating constant [-Wpedantic]
BOOST_DEFINE_MATH_CONSTANT(rayleigh_skewness, 6.311106578189371381918993515442277798e-01, "6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264e-01")
/usr/local/include/boost/concept/detail/general.hpp:71:20: warning: typedef 'boost_concept_check228' locally defined but not used [-Wunused-local-typedefs]
BOOST_PP_CAT(boost_concept_check,__LINE__)
...
There are so many different ones . It looks like from here that you can suppress particular typedef warnings: https://svn.boost.org/trac/boost/ticket/7242
But I would like to be able to suppress all of these warnings. Any suggestions?

As the commenter T.C. suggests, warnings are suppressed for system headers in gcc. There are (at least) two ways of adding additional system include paths to your gcc build:
-isystem command line option, and
*_INCLUDE_PATH environment variables (where '*' is C, CPLUS, or OBJC).
These mechanisms also work for clang.

Related

Using POSIX feature test macros with C++

When I'm building POSIX C programs, I want to be portable and use only POSIX or standard C library functions. So, for example, with gcc or clang, I build like this:
gcc -std=c99 -D_XOPEN_SOURCE=600
Setting the standard to C99 removes all extensions, then _XOPEN_SOURCE exposes POSIX interfaces. I no longer have the environment polluted with extensions from GNU, BSD, etc.
However, the waters seem murkier with C++. I want to do this:
g++ -std=c++14 -D_XOPEN_SOURCE=600
This has worked fine for me on various operating systems: Linux/glibc, Haiku, MinGW, macOS, at least. But apparently, there are problems with POSIX feature test macros and C++. Oracle docs have this to say:
C++ bindings are not defined for POSIX or SUSv4, so specifying feature test macros such as _POSIX_SOURCE, _POSIX_C_SOURCE, and _XOPEN_SOURCE can result in compilation errors due to conflicting requirements of standard C++ and these specifications.
While I don't have a copy of Oracle Solaris, I am seeing issues with FreeBSD and OpenBSD.
On FreeBSD:
#include <iostream>
int main() { }
$ clang++ -std=c++14 -D_POSIX_C_SOURCE=200112L t.cpp
In file included from t.cpp:1:
In file included from /usr/include/c++/v1/iostream:37:
In file included from /usr/include/c++/v1/ios:215:
/usr/include/c++/v1/__locale:631:16: error: use of undeclared identifier 'isascii'
return isascii(__c) ? (__tab_[static_cast<int>(__c)] & __m) !=0 : false;
...
(This builds fine with _XOPEN_SOURCE=600). C++ headers on FreeBSD use isacii, a non-standard function, so it's not exposed when _POSIX_C_SOURCE is set.
Or on OpenBSD:
#include <fstream>
int main() { }
$ clang++ -std=c++14 -D_XOPEN_SOURCE=600 t.cpp
In file included from t.cpp:1:
In file included from /usr/include/c++/v1/fstream:183:
In file included from /usr/include/c++/v1/ostream:138:
In file included from /usr/include/c++/v1/ios:215:
In file included from /usr/include/c++/v1/__locale:32:
In file included from /usr/include/c++/v1/support/newlib/xlocale.h:25:
/usr/include/c++/v1/support/xlocale/__strtonum_fallback.h:23:64: error: unknown type name 'locale_t'
char **endptr, locale_t) {
Presumably <locale.h> isn't getting included somewhere it “should” be.
The worrisome conclusion I'm drawing is that you can't portably have a POSIX C++ environment that is free of non-POSIX extensions. These examples work fine on OpenBSD and FreeBSD if the feature test macros are removed. That looks to be because the BSD headers expose BSD functions unless in standard C mode, but they do not care about standard C++ mode (they explicitly check whether macros corresponding to C89, C99, or C11 are set). glibc looks to be the same: it still exposes non-standard C functions in standard C++ mode, so perhaps it's only a matter of time before I run into a build error there.
So the actual question is this: can you write portable POSIX C++ code which does not expose platform-specific functionality? Or if I'm targeting POSIX with C++ should I just not set any feature test macros and hope for the best?
EDIT:
I got to thinking about the implications of this (as in, why do I care?), and the following program, I think, illustrates it. This is Linux/glibc:
#include <ctime>
int dysize;
$ g++ -c -std=c++14 t.cpp
t.cpp:2:5: error: ‘int dysize’ redeclared as different kind of entity
2 | int dysize;
| ^~~~~~
In file included from t.cpp:1:
/usr/include/time.h:262:12: note: previous declaration ‘int dysize(int)’
262 | extern int dysize (int __year) __THROW __attribute__ ((__const__));
This is the standard <ctime> header, which is does not include anything called dysize. That's an old SunOS function that glibc includes for compatibility. A C program built with -std=c99 won't expose it, but C++ always does. And there's no real way of knowing which non-reserved identifiers will be used by various implementations. If -std=c++14 caused non-standard identifiers to be hidden, that would avoid this problem, but it doesn't, and I can't see a way around that.
Which might imply that the feature test macro is a red herring: the source of the problem is that, on at least some real-world implementations, C++ compilers are exposing symbols they're not supposed to.
My suggestion is to build a toolchain, and work from that with the libraries, includes, the correct compiler (perhaps a stripped version that can only use POSIX libraries, includes, etc).
To make it portable, generally you would build the application using static linkers. Other linker options may be necessary that point specifically or include your toolchain environment paths.
And if you're using POSIX threads, you may need -pthread.
I see that you are using system-wide headers and libraries, when really, you probably want a specific to your POSIX application toolchain, to avoid contamination.

#pragma(* diagnostic) when mixing Clang analyzers with a GCC compiler

I'm compiling on with GCC on Linux, but CMake is kind enough to produce a Clang compatible compilation database. This means that I can run fancy, modern Clang based tools on my codebase and those tools have perfect knowledge of how each file is to be built (flags, defines, include paths, etc.) So far so good.
But today the Clang based static analysis in my IDE started showing a Clang specific warning. I don't think it particularly matters for my question which warning it is, but it was warning: disabled expansion of recursive macro, generated by -Wdisabled-macro-expansion. This particular macro is provided by a third party, so fixing the warning isn't an option, but I would like to suppress it as it occurs several times in the file in question.
What I'm struggling with is how to suppress the warning in Clang based analysis tools without causing new warnings in the GCC build.
Adding #pragma clang diagnostic ignored "-Wdisabled-macro-expansion" suppresses the warning for Clang tools, but causes GCC to issue warning: ignoring #pragma clang diagnostic [-Wunknown-pragmas].
Similarly, adding #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion" suppresses the Clang warning (because Clang tries to be compatible with GCC diagnostics), but causes GCC to issue warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas].
Wrapping either of the above with #ifdef __clang__ makes GCC happy, but doesn't suppress the Clang warning because the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead.
Is there a way to make a diagnostic #pragma visible to Clang tooling, but not to GCC?
the tooling is smart enough to know that the code isn't compiled with __clang__, but with __GNUC__ instead
If it's reporting a clang-only warning, but does not think that __clang__ is defined, that sounds like a problem with the tooling. If it's trying to be that clever about misrepresenting itself, you may be up a creek... but also you should be complaining to the tool author for creating this situation in the first place.
That said, you could try:
#if defined(__has_warning)
# if __has_warning("-Wdisabled-macro-expansion")
# pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
# endif
#endif
I'm not sure if this will work... it depends on how hard the tooling is pretending to not be clang (__has_warning is a clang-only extension).

Clang: What exactly does the "-stdlib" flag do?

[Mac OS 10.13.2, Xcode9.2]
Clang has a flag -stdlib which, according to both clang++ -cc1 --help (same as clang -cc1 --help) and the LLVM documentation page, allows specification of the C++ standard library to use.
1) How does this flag impact on compilation? I.e. does it change the order of library include paths etc.
2) How does this flag impact linking? I.e. is it just a short-cut/alternative for supplying -lc++?
I am really interested in understanding the details of this flag because I can't find any documentation describing it's precise behaviour and it is causing havoc with our build system since the Xcode9 upgrade. Inclusion of -stdlib=libc++ in our Makefile causes the compilation to fail due to headers problems, yet, when -stdlib=libc++ is omitted, our projects compile fine (presumably because libc++ is the Mac OS default Standard C++ library). The project link against libc++ due to other linker flags -lc++ and -lsupc++.
Some background info about our use-case
We are using Clang to cross-compile to a -march=i686 -target i686-linux-elf target. Prior to the Xcode9 update, our build system was working fine. Since the upgrade we're getting compiler errors, such as:
/usr/local/our-target/sysroot/usr/local/include/c++/v1/stdlib.h:111:82: error: use of undeclared identifier 'labs'; did you mean 'abs'?
inline _LIBCPP_INLINE_VISIBILITY long abs( long __x) _NOEXCEPT {return labs(__x);}
I've now been able to fix this problem by changing the header include paths. Namely I have removed a path reference to the folder that is parent to both the libc++ AND gcc4.8.5 includes.
# -I${STAGING.nao}/usr/local/include/c++ \
-I${STAGING.nao}/usr/local/include/c++/v1
I am still very interested in understanding the details of what the flag does.

Why doesn't -isystem on g++ disable -Wcpp warnings

I am on Ubuntu 16.04, GCC 5.4.
According to here one can disable warnings from external headers by treating them as system headers. However, when I am using VTK I came across a warning that I am unable to disable. Below is the minimum code to reproduce it
#include "vtkVersion.h"
int main(){
return 0;
}
Compile it with g++ main.cpp -isystem /usr/include/vtk-5.10/ return warning message
In file included from /usr/include/c++/5/backward/strstream:50:0,
from /usr/include/vtk-5.10/vtkIOStream.h:108,
from /usr/include/vtk-5.10/vtkSystemIncludes.h:40,
from /usr/include/vtk-5.10/vtkIndent.h:24,
from /usr/include/vtk-5.10/vtkObjectBase.h:43,
from /usr/include/vtk-5.10/vtkObject.h:41,
from /usr/include/vtk-5.10/vtkVersion.h:29,
from Example.cpp:3:
/usr/include/c++/5/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header which may be removed without further notice at a future date. Please use a non-deprecated interface with equivalent functionality instead. For a listing of replacement headers and interfaces, consult the file backward_warning.h. To disable this warning use -Wno-deprecated. [-Wcpp]
#warning \
^
If VTK is not installed you can simply install it with sudo apt-get install libvtk5-dev
Why does the warnings appeared? In my code I have very strict compiler flags and I treat warnings as errors. However, not all external libraries are coded with such strict compiler flags, I am able to get away with including the external headers with the -isystem flag but VTK is giving me problems. My ugly workaround is adding -Wno-deprecated in my own compiler flags to get pass it but obviously this is not the right way to do it. What's the best way to solve this?

silence -Wparentheses-equality error

Im building som software using boost 1.48 on osx 10.8 with gcc version 4.2.1 and i have started getting -Wparentheses-equality warnings for some of the boost source.
equality comparison with extraneous parentheses
[-Werror,-Wparentheses-equality]
else if((state->type == syntax_element_long_set_rep))
I would change the code but i dont want to tinker with the library, how would i silence the warning and make the compiler continue?
From the GCC manual:
Most of these have both positive and negative forms; the negative form of -ffoo would be -fno-foo.
Try -Wno-parentheses-equality.
As an alternative to simply disabling the warning you can also specify certain paths to count as 'system' paths. Warnings are suppressed for system headers, so you can declare that a particular library's headers are 'system' headers and that you don't care about warnings in them.
clang's argument for this is --system-header-prefix=<prefix>
So for example you might say "--system-header-prefix=boost/"
http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-in-system-headers
And judging by the error message you are actually using clang and not gcc.