mapbox / cpp

C++ @ Mapbox
108 stars 17 forks source link

Recommendations for enabling more compiler checks #37

Open springmeyer opened 6 years ago

springmeyer commented 6 years ago

Compilers enable by default, a set of warnings they will emit on dodgy or less-than-ideal code. These defaults:

This issue is designed to focus on the problem of c from the perspective of the latest clang++ 4.x versions.

Enabling more warnings than compilers do by default can be an important way of catching bugs early. For example integer truncation bugs can often be detected by enabling -Wconversion, which is not on by default.

Enabling more warnings is very difficult to do after a project is big (e.g. https://github.com/Project-OSRM/osrm-backend/pull/4495 and https://github.com/mapnik/mapnik/issues/2907 and https://github.com/mapnik/mapnik/issues/3204). It is best not to wait and rather to start a project with aggressive warnings from the beginning.

So, the question then becomes: what is a good set of aggressive warnings to enable at the start of a project (or to try to integrate into existing projects)?

In particular:

1) 🍇 Which flags we should always enable for all code no matter what?

2) 🍊 What additional flags may be very useful in some scenarios/some code bases?

3) 🍏 For small projects where it is feasible, can we actually start with clang++s -Weverything? This, when feasible, might be ideal. How to do it?

4) 🍎 What compiler specific flags should we recommend (that only currently work for clang++ or g++)?

springmeyer commented 6 years ago

My proposal for 🍇 is:

Note: all the above flags ARE NOT turned on by default in clang++ (according to https://clang.llvm.org/docs/DiagnosticsReference.html). If they were then there would be no need to list them explicitly.

My proposal for 🍊 is:

My proposal for 🍏 is:

🍎 proposal is:

clang++ only

g++ only

TODO: develop our recommended list based on testing https://kristerw.blogspot.de/2017/09/useful-gcc-warning-options-not-enabled.html

joto commented 6 years ago

One important tip here: All code that is #included from somewhere outside your own code should be included as system library by having the right include path configuration. Use -isystem <DIR> instead of -I <DIR> for this on compiler command lines, in CMake it is include_directories(SYSTEM <DIR>) instead of include_directories(<DIR>). This way warnings are not reported from those libraries. Otherwise you often have to disable warnings for code in libraries you don't have control over. For instance I usually have a copy of catch.hpp in my code for testing, but I put it into its own directory separate from my own headers.

daniel-j-h commented 6 years ago

I want to flag the following:

springmeyer commented 6 years ago

Thanks @joto: Absolutely agree that, to allow more aggressive warnings in your code (and especially -Werror), this must be paired with using -isystem or include_directories(SYSTEM <DIR>) for deps you don't control. As a few examples, I've done this at https://github.com/mapbox/node-cpp-skel/pull/42 and https://github.com/mapbox/hpp-skel/blob/0af4ae29ec83fe12db20963fcd0855dbe7708a57/CMakeLists.txt#L30.

@daniel-j-h - thanks for these links. So far the flags I'm recommending above work in both recent g++ and clang++. Your links raise the issue that it would be useful to also develop recommended lists of additional warnings to enable, per compiler. I will edit inline above to add another section specific to compilers. Then I will plan to PR a doc that will list these and we can iterate on that doc.

springmeyer commented 6 years ago

refs https://github.com/Project-OSRM/osrm-backend/pull/4843