In my C++ project, I use precompiled headers as a compile time optimization. However, when I enable /Wall option in the compiler settings, I am not able to suppress any of warnings in the precompiled header file.
Header File:
#ifndef _PRECOMPILED_H
#define _PRECOMPILED_H
#pragma warning(push, 0)
#pragma warning(disable: 4514)
#include <vector>
#pragma warning(pop)
#endif /* _PRECOMPILED_H */
Source File:
#include "precompiled.h"
I end up with tons of warnings in vector.
When I do the same, but in a regular file, everything works as expected.
Any solutions for this problem?
I am using Visual Studio 2013 community edition update 4.
Don't use /Wall with Visual C++. It doesn't mean the same as -Wall with g++. Use /W4 (rough equivalence with g++ -Wall).
I did not get a 4514 warning from including vector.
You have only disabled 4514, and only in the vector header. I think this is happening in other code that happens to use vector, and the warning message (which you did not post) refers to the vector header since that's where the function being removed by the optimizer was declared.
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 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.
Using C++ Native solution in Visual Studio 2010.
#pragma warning (push) is used in the beginning of the cpp file, after all the includes. After that there are couple of disabled warning by #pragma warning(disable : XXXX).
What are possible consequences of omitting #pragma warning(pop) at the end of the file?
Thanks
If you have any other source files that #include that cpp file, then the warning state when compiling the outer file will be messed up -- it could fail to give warnings when the warnings were warranted.
Note, however, that #includeing a cpp file is considered bad form and a code smell; there are certain, rare, situations where it might be the right thing to do (such as a build system that #includes many source files into one to reduce compilation times, sort of like precompiled headers), but almost always it's the wrong thing to do, even if it manages to compile and link without errors.
If that source file is never #included anywhere else, then failing to have a #pragma warning(pop) will not have any adverse consequences, assuming the compiler doesn't complain about that mismatch in the first place.
Since this is a compiler only setting, it won't have any impact on the program itself. It may though screw up warnings for external includes.
What is the warning level you use while compiling QT projects?
When I compiled with W4, I'm getting a lot of warnings such as:
C4127: conditional expression is constant
Should I compile at W3, or find other ways to handle warnings at W4, such as: adding a new header file and using pragma's(mentioned here C++ Coding Standards: 101 Rules, Guidelines, and Best Practices).
What are your practices?
Thanks.
I ran into the exact same problem you have a couple of years ago, that of setting the compiler to level 4 warnings to catch as many potiential problems as possible. At the time, I had a support contract with Qt and asked them why their code generated so many warnings. Their response was that they never gaurenteed that their code would compile without any warnings. Only that their code would run correctly.
After several attemps, I started surrounding the Qt header files with pragmas to disable the warnings as shown below -
#pragma warning(push,3) // drop compiler to level 3 and save current level
#include <QString>
#include <QVariant>
#include <QStack>
#include <QLabel>
#include <QtGui/QTableWidget>
#pragma warning(pop) // restore compiler warning level
By doing it this way, you only compile the Qt header files at the lower warning level. Or whatever level it takes to get rid of the warnings. You may have some individual warnings that still show up, so you could raise the warning level or disable individual warnings with
#pragma warning(disable: 4700)
Some Boost library files also have this problem.
Personally I just use the Makefiles that qmake generates by default... on the presumption that I can trust the guys at Nokia to have it generate Makefiles that do the right thing for the current build environment.
I do see that qmake will take some optional arguments regarding warnings, though:
The level of warning information can be fine-tuned to help you find problems in your project file:
-Wall
qmake will report all known warnings.
-Wnone
No warning information will be generated by qmake.
-Wparser
qmake will only generate parser warnings. This will alert you to common pitfalls and potential problems in the parsing of your project files.
-Wlogic
qmake will warn of common pitfalls and potential problems in your project file. For example, qmake will report whether a file is placed into a list of files multiple times, or if a file cannot be found.
Use CONFIG += warn_on in your .pro file.
See the documentation.
Option
warn_on
The compiler should output as many warnings as possible.
This is ignored if warn_off is specified.
warn_off
The compiler should output as few warnings as possible.
If you're fighting with Q_ASSERT in Visual studio, all that warning push/pop stuff won't work, since macros are "instantiated" in place, far behind you headers.
So I would suggest to redefine Q_ASSERT:
#ifdef NDEBUG
#undef Q_ASSERT
#define Q_ASSERT(x) __noop
#endif
Based on user2846246's answer, I found that adding the following early on in the compilation of whichever library uses Qt did the trick (in my case that library uses a precompiled header file in Visual Studio so I just added the code to that header file):
#ifndef _DEBUG
#undef Q_ASSERT
#define Q_ASSERT(x) __noop
#undef Q_ASSERT_X
#define Q_ASSERT_X(cond, where, what) __noop
#endif
Which is great as I dislike dropping the warning level of a whole library.
I've tried placing the following in my C++ code:
#ifdef _WIN32
#include "stdafx.h"
#endif
but I getan error:
PCH warning: header stop cannot be in a macro of #if block. An IntelliSense PCH file was not generated.
I'm trying to let my code work both on windows and linux, stdafx.h does not work on linux where it's a must on visual studio.
Is there another way to use the include with ifdef?
Unfortunately you can not do that with precompiled header and using Microsoft MSVC. The MSVC totally ignores all code (and whatever garbage) lines that precede that #include "stdafx.h" line. As result the #endif will be unexpected to it.
Put that #ifdef _WIN32 and what not inside of stdafx.h.
I have just created an empty stdafx.h. With follow content for solutions without pre-compiled headers
#pragma once
//this is only for using Common modules with Precompiled headers. We can't disable it using a preprocessor(
//https://stackoverflow.com/a/36271896/6160632