QT warning level suggestion - c++

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.

Related

How can you exclude third-party libraries from CppCoreCheck? [duplicate]

I am integrating Guideline Support Library Checkers into a project of mine.
Microsoft.CppCoreCheck
Microsoft.Gsl
When I run it I get a bunch of errors from included libraries like standard libraries, glm, boost, etc.
One concrete example is SDL.h where I get warnings in sdl_stdinc.h.
I made sure that I include SDL only via one header under my control:
ExtSDL.hpp
#pragma once
#pragma warning(disable: 4710)
#pragma warning(push, 0)
#include <SDL.h>
#pragma warning(pop)
I can not find information on how to exclude this library from the static code analysis.
There are multiple ways to suppress CppCoreCheck warnings:
you can suppress CppCoreChecks either using
[[gsl::suppress(chapter)]] attribute, where chapter comes from C++
Core Guidelines, for example, con.4. Please also look at MS docs for information.
you can use #pragma warning to suppress warnings individually or in bulk, as mentioend above.
you can suppress all warnings for "not your code" using CAExcludePath.
The most practical approach I've found so far is to build up #defines like
#define SDL_WARNINGS 4710 26135
and then #include other people's dirty code thusly
#pragma warning(push)
#pragma warning(disable: SDL_WARNINGS)
#include <SDL.h>
#pragma warning(pop)
That will silence warnings for gsl checkers, based on their associated warning codes e.g C26135 above. It silences the compiler exactly where you want it to keep quiet. Note the warning disablement is local to the push/pop scope.
This sort of approach allows one to compile /Wall /WX even if you turn additional checking on, including gsl. Critically it works even when you have dependencies on other people's headers which aren't warning clean. Sadly this includes every C and C++ standard library implementation I've seen plus Boost, LLVM, the Windows SDK etc. etc. i.e. basically everything. Additionally it protects you from evil headers which alter warning pragmas (some standard library implementations used to do this and may still...) This approach allows you to lift your own code to a higher level of cleanliness and quality than the dross you are dependent upon.
One of the good things about the Microsoft C++ Core Check stuff is the way they've tied it into the usual mechanisms used for warnings, so this approach works uniformly for regular warnings and checkers in extra rulesets. Thank goodness they did something like this: some of the gsl checkers are rather questionable and incompatible with many extant coding styles i.e. turn gsl on for code which #includes big standard vendor library and you rapidly need to construct a long list of warning codes to disable before you can dial the noise down so you can focus on your own code. Of course you can globally #pragma warning(disable: GSL_CHECKERS_YOU_DONT_LIKE) for your own code, so you can focus on the aspects of it you find useful.
Alternatively you can pick the rules to apply by selecting rulesets to use and/or making a custom one. That's presumably going to minimise your build times which aren't as quick with Code Analysis enabled.
It would be nice to have a more direct answer to your question which essentially made the dirty headers build quickly because you could disable checkers for "other people's stuff". It's an obvious feature request but I'm not aware of it being supported. Presumably it would be pretty trivial to implement e.g. only run the checkers on source code found in a specified set of directories, so if a #include steps outside that zone the checkers are automatically disabled. Is anyone at Microsoft reading this?

#pragma warning(push) without #pragma warning(pop)

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.

Warnings after enabling -Weffc++ for c++ project using Boost 1.47 [duplicate]

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.

Detecting precompiled headers

Is there a way for the preprocessor to detect if the code in current
translation unit uses(or is creating) precompiled headers?
---
The actual problem I'm facing right now is that I'm on a project that is
abusing PCH by precompiling virtually all header files. That means there is none of
the clear dependency management you can get from #includes and the compile times is awful.
Practically every change will trigger a full rebuild.
The application is way to big to just fix it in one go, and some of the old guys refuses
to belive that precompiling everyting is bad in any way. I will have to prove it first.
So I must do it step by step and make sure my changes does not affect
code that is compiled the old PCH way.
My plan is to do ifdef out the PCH.h and work on the non PCH version whenever I have some time to spare.
#ifdef USES_PCH
#include "PCH.h"
#elif
// include only whats needed
#endif
I would like to avoid defining USES_PCH at command line and manually keep it in
sync with /Y that, besides from not being very elegant, would be a pain. There is a lot of configurations
and modules to juggle with and a lot of files that don't follow project defaults.
If Visual C++ defined a constant to indicate whether precompiled headers were in use, it would probably be listed in Predefined Macros. And it's not documented there, so it probably doesn't exist. (If it does exist, it's probably undocumented and may change in a future version.)
This will not work, when using precompiled headers in Visual C++, you cannot even have any code before including a precompiled header. I was trying to do something similar, when I came across your question. After a little trial and error, I have found that there can be no code prior to the #include directive for the precompiled header when using the /Yu compiler option.
#ifdef USES_PCH
#include "stdafx.h"
#endif
result: fatal error C1020: unexpected #endif
As far as I know, it can't, but there are some heuristics: VC++ uses StdAfx.h, Borland uses #pragma hdrstop, etc.

Handling stdafx.h in cross-platform code

I have a Visual Studio C++ based program that uses pre-compiled headers (stdafx.h). Now we are porting the application to Linux using gcc 4.x.
The question is how to handle pre-compiled header in both environments.
I've googled but can not come to a conclusion.
Obviously I want leave stdafx.h in Visual Studio since the code base is pretty big and pre-compiled headers boost compilation time.
But the question is what to do in Linux. This is what I found:
Leave the stdafx.h as is. gcc compiles code considerable faster than VC++ (or it is just my Linux machine is stronger ... :) ), so I maybe happy with this option.
Use approach from here - make stdafx.h look like (set USE_PRECOMPILED_HEADER for VS only):
#ifdef USE_PRECOMPILED_HEADER
... my stuff
#endif
Use the approach from here - compile VC++ with /FI to implicitly include stdafx.h in each cpp file. Therefore in VS your code can be switched easily to be compiled without pre-compiled headers and no code will have to be changed.
I personally dislike dependencies and the mess stdafx.h is pushing a big code base towards. Therefore the option is appealing to me - on Linux you don't have stdafx.h, while still being able to turn on pre-compiled headers on VS by /FI only.
On Linux compile stdafx.h only as a precompiled header (mimic Visual Studio)
Your opinion? Are there other approaches to treat the issue?
You're best off using precompiled headers still for fastest compilation.
You can use precompiled headers in gcc as well. See here.
The compiled precompiled header will have an extension appended as .gch instead of .pch.
So for example if you precompile stdafx.h you will have a precompiled header that will be automatically searched for called stdafx.h.gch anytime you include stdafx.h
Example:
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
Then compile as:
> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out
Your compilation will work even if you remove stdafx.h after step 1.
I used option 3 last time I needed to do this same thing. My project was pretty small but this worked wonderfully.
I'd either go for option 4 or option 2. I've experimented with precompiled headers on both various VS versions and GCC on Linux (blog posts about this here and here). In my experience, VS is a lot more sensitive to the length of the include paths, number of directories in the include path and the number of include files than G++ is. When I measured build times properly arranged precompiled headers would make a massive difference to the compile time under VS whereas G++ was pretty much unimpressed by this.
Actually, based on the above what I did the last time I worked on a project where this was necessary to rein in the compile time was to precompile the equivalent of stdafx.h under Windows where it made sense and simply used it as a regular file under Linux.
Very simple solution.
Add a dummy file entry for "stdafx.h" in Linux environment.
I would only use option 1 in a big team of developers.
Options 2, 3, and 4 will often halt the productivity of other members of your team, so you can save a few minutes a day in compile time.
Here's why:
Let's assume that half of your developers use VS and half use gcc.
Every now and then some VS developer will forget to include a header in a .cpp file.
He won't notice, because the stdafx.h implicitly includes it. So, he pushes his changes in the version control, and then a few other members of the gcc team will get compiler errors.
So, for every 5 minutes-a-day you gain by using precompiled headers, 5 other people waste by fixing your missing headers.
If you don't share the same code across all of your compilers, you will run into problems like that every day. If you force your VS developers to check for compilation on gcc before pushing changes, then you will throw away all your productivity gains from using precompiled headers.
Option 4 sounds appealing, but what if you want to use another compiler at some point in time ? Option 4 only works if you only use VS and gcc.
Notice that option 1 may make gcc compilation suffer a few seconds. Although it may not be noticeable.
It's simple, really:
Project->Project Settings (Alt + F7)
Project-Settings-Dialog:
C++ -> Category: Precompiled Headers -> Precompiled Headers radio buttons --> disable
Since stdafx.h is by default all the Windows-specific stuff, I've put an empty stdafx.h on my other platform. That way your source code stays identical, while effectively disabling stdafx on Linux without having to remove all the #include "stdafx.h" lines from your code.
If you are using CMake in your project, then there are modules which automate it for you, very convenient, for example see cmake-precompiled-header here. To use it just include the module and call:
include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( ${target} ${header} FORCEINCLUDE SOURCE_CXX ${source} )
Another module called Cotire creates the header file to be precompiled (no need to manually write StdAfx.h) and speeds up builds in other ways - see here.
I've done both option 2 (#ifdef) and option 4 (PCH for gcc) for cross platform code with no issues.
I find gcc compiles much faster than VS so the precompiled headers are generally not that important, unless you are referencing some huge header file.
I have a situation where #2 in particular didn't work for me (There are numerous VS build configs where a #ifdef around #include "stdafx.h" does not work). Other solutions were suboptimal because the files themselves were cross-project as well as being cross-platform. I did not want to force preprocessor macros to be set or force linux or even windows builds to use (or not use) pch, so...
What I did, given a file named notificationEngine.cpp, for example, was removed the #include stdafx.h line entirely, created a new file in the same directory called pchNotificationEngine.cpp with the following contents:
#include "stdafx.h"
#include "notificationEngine.cpp"
Any given project can just include the correct version of the file. This admittedly is probably not the best option for cpp files that are only used by a single project.