We want to add -Werror=conversion to our code base, but the header of the Eigen library will trigger a lot of these error. I am wondering what is the best approach here so that the compilation flag only applies to our code but not for third party header.
One solution we are thinking is to create a wrapper library for Eigen that only contains stuff we need. We will compile the wrapper without the flag. But this is a somewhat big undertaking. I am wondering if there are other solutions.
With gcc you can include Eigen headers via -isystem. They will be treated like system headers and no warnings will be reported. This silences all warnings, though with well tested 3rd party libraries this is usually ok.
You can create a header Eigen.h with this:
#pragma once
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#include <Eigen/Core>
// ...
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
Related
I created a header file. Something simple as follows.
#pragma once
#include <iostream>
template<typename T>
void say(T t) {
std::cout << t << std::endl;
}
and then use g++ to create the gch pre-compiled header with g++ hello.h. It gives me this warning ->
pch.h:2:9: warning: #pragma once in main file
2 | #pragma once
| ^~~~
But the gch file created and the pre-compiled header works fine. This error goes away if I use header guards.
Am I doing something wrong here?
You're not doing anything wrong; this is a quality of implementation issue that has been mentioned on the issue tracker before (but, to my knowledge, there are currently no plans to change the behaviour).
In Clang, you could turn off the warning for that particular compiler invocation (with -Wno-pragma-once-outside-header); in GCC you'll just have to grin and bear it for now.
The main source file used to generate a precompiled header is usually a made-up "indirect" header that contains only a bunch of #include for all the actual real headers you want to precompile.
When you use the machinery this way, there is no need for a #pragma once (nor guard) in the main file, and hence it works as intended with no warning.
This is a known GCC bug:
Pragma once warning when compiling PCH
To my knowledge, there is no good way to disable this warning. One way that retains matching behavior is an additional indirection. In pch.h, use
#include <pch-real.h>
(without #pragma once), and store the actual header contains in pch-real.h. This mostly preserves the include-only-once optimization even if <pch.h> is included multiple times in non-PCH mode.
I have a MSVC C++ project, I am conditionally compiling parts of the source code by passing specifing Preprocessor Defintions in the C++/Preprocessor section of the Project Properties.
What I would also like to do is conditionally link with libraries based on the preprocessor definitions, how do I achieve this?
For example in my project if CLSOPENLDV is defined I want to exclude:
nodetalk32_vcpp.obj
and include:
ldv32.lib
And when it isn't defined I want to do the opposite.
You probably need this:
#ifdef SOME_MACRO
#pragma comment( lib, "ldv32" )
#endif
This is Microsoft specific, it probably won't work with gcc, clang or other compilers.
For excluding nodetalk32_vcpp.obj the only thing you can do that comes into my mind is:
#ifndef SOME_MACRO
// content of nodetalk32_vcpp.cpp
#endif
Quoting from Microsoft documentation, There is no advantage to use of both the #include guard idiom and #pragma once in the same file.
Answers to previous related questions on stackoverflow also confirm that it is pointless to have both. See below, for instance:
Header guards and pragma once
The boost library's vector.hpp file, however, starts thus:
#ifndef BOOST_ASSIGN_STD_VECTOR_HPP
#define BOOST_ASSIGN_STD_VECTOR_HPP
#if defined(_MSC_VER)
# pragma once
#endif
...
#endif
That is, it includes both the guard idiom as well as the pragma once. Is there any reason why boost header files have both?
Technically #pragma once is not standard C++, whereas header guards are. They will not conflict with each other if you have both.
The reason boost likely has both, as alluded to by the #if defined(_MSC_VER) is that if you're not using MSVC then you need something to act as your header guard, so they fall back to the other method.
Since boost strives to be cross-platform they are trying to ensure their code works on compilers that don't support #pragma once, though all of the big modern compilers I can think of do support it, as enumerated on wikipedia.
I have code:
#ifdef Q_OS_LINUX
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcomment"
#include "header.h"
#pragma GCC diagnostic pop
#endif
And I want to supress GCC warning messages related to header.h and all headers included from header.h. But I still have '-Wcomment' warnings related to headers included from header.h. How can I avoid that? Thanks
gcc 4.8.2
edit: The Warning I get looks like this:
/------ Set Analog Output for 8022/8026 --------- /Exp8K WORD
CALLBACK AnalogOutHex_8K(DWORD dwBuf[], float fBuf[], warning: "/"
within comment [-Wcomment] No other pragmas surely. -Wall doesn't work
If you can modify header.h, you could define it to be a system header using #pragma GCC system_header. Otherwise, you could add it to your gcc command line using -isystem.
All warnings, other than those generated by ‘#warning’ (see Diagnostics), are suppressed while GCC is processing a system header.
GCC warnings that are emitted by the preprocessor cannot be suppressed with any pragma when compiling C++, they can only be suppressed by pragmas when compiling C. You're compiling as C++ (and shouldn't have tagged your question as C too). Here's a simple test case:
#pragma GCC diagnostic ignored "-Wcomment"
/* /* */
This warns in C++ mode, but not in C mode.
Given that pragmas just won't work, you should take some other approach. If you can modify the header, just change the comment. If you cannot change the header, you can mark the specific directory the header is in as a system header directory (use the -isystem command-line option).
You have not included your full cpp file. My guess is that an earlier include is already including some of the header files. Those header files will probably have header guards which prevent the header file being included more than once. And therefore the #pragma is not really doing anything.
You best bet is to move the #pragmas and include to the top of your header file before you include anything else. Remember you can also push and pop diagnostic pragmas.
I have a project that uses log4cxx, boost, etc. libraries whose headers generate lots of (repetitive) warnings. Is there a way to suppress warnings from library includes (i.e. #include <some-header.h>) or includes from certain paths? I'd like to use -Wall and/or -Wextra as usual on project code without relevant info being obscured. I currently use grep on make output but I'd like something better.
You may try to include library headers using -isystem instead of -I. This will make them "system headers" and GCC won't report warnings for them.
For those using CMake, you can modify your include_directories directives to include the symbol SYSTEM which suppresses warnings against such headers.
include_directories(SYSTEM "${LIB_DIR}/Include")
^^^^^^
You can use pragmas. For example:
// save diagnostic state
#pragma GCC diagnostic push
// turn off the specific warning. Can also use "-Wall"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
// turn the warnings back on
#pragma GCC diagnostic pop
I found the trick. For library includes, instead of -Idir use -isystem dir in the makefile. GCC then treats boost etc. as system includes and ignores any warnings from them.
#pragma are instructions to the compiler. you can set something before the #include and disable it after.
You can also do it at the command line.
Another GCC page specifically on disabling warnings.
I would go for the option of using #pragma's within the source code, and then providing a
sound reason (as a comment) of why you are disabling the warnings. This would mean reasoning about the headers files.
GCC approaches this by classifying the warning types. You can classify them to be warnings or to be ignored. The previously linked articles will show you which warnings are may be disabled.
Note: you can also massage the source code to prevent certain warnings by using attributes; however, this bind you quite closely to GCC.
Note2: GCC also uses the pop/push interface as used in microsoft's compiler -- Microsoft disables warnings through this interface. I suggest you investigate this further , as I do not know if it is even possible.
Putting the following
#pragma GCC system_header
will turn off GCC warnings for all following code in this file.
You can try using precompiled headers. Warnings won't go away but at least the won't show up in your main compilation.
If you need to explicitly override a system header then you're restricted to pragmas. You can verify which includes you're using via make depend output.
Also see diagnostic push-pop for gcc >= 4.6
Another way to do it is, in the makefile, to tell the compiler to ignore warnings for the specific folder:
$(BUILD_DIR)/libs/%.c.o: CFLAGS += -w
There must be reasons for those warnings. These will either be caused by errors in your code that uses the library, or by errors in the library code itself. In the first case, fix your code. In the second case, either stop using the library or if it is FOSS code, fix it.