Why does gcc complain about my loops? - c++

I have some fairly trivial code, still gcc complains (in -O3 -march=native) about loop unrolling:
cannot optimize loop, the loop counter may overflow [-Wunsafe-loop-optimizations]
for(auto& plan : fw)
^
Here is a (stripped of all fftw stuff, else it would be quite long) version of my code
class FFTWManager
{
public:
void setChannels(unsigned int n)
{
fw.resize(n);
bw.resize(n);
//some fftw-specific stuff comes here
}
void forward()
{
for(auto& plan : fw)
fftw_execute(plan);
}
void backward()
{
for(auto& plan : bw)
fftw_execute(plan);
}
private:
std::vector<fftw_plan> fw = {};
std::vector<fftw_plan> bw = {};
};
The vectors never exceed a size of 2 in my code.
Edits according to comments :
I use a lot of flags.
-pedantic -Wextra -Weffc++ -Wall -Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment -Wconversion -Wdisabled-optimization -Wformat -Wformat=1 -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimport -Winit-self -Winline -Winvalid-pch -Wunsafe-loop-optimizations -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wpacked -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wstack-protector -Wstrict-aliasing=3 -Wswitch -Wswitch-default -Wswitch-enum -Wtrigraphs -Wuninitialized -Wunknown-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvolatile-register-var -Wwrite-strings
I don't see the point of speaking of putting infos about fftw_execute here but if you want to see the whole code (that I judged too long for a SO post), it's here :
https://github.com/jcelerier/watermarking/blob/master/src/libwatermark/transform/FFTWManager.h
GCC : gcc version 4.8.2 (Debian 4.8.2-10)
I don't see why changing from unsigned int to size_type would change anything since I don't get any warning in my setChannels method (even if I think it's long unsigned int on my platform) and once the size is set, the original type of the variable that was used to set it seems quite irrelevant to me.
There is no warning with the basic for(int i = 0; i < bw.size(); i++) or with the iterator version for(auto i = bw.begin(); i != bw.end(); i++).
I also tried with clang, which seems to recognize the warning swich so I guess they also implemented the optimization, and I don't get any warnings (but much quicker compile times \o)
Sorry about long feedback, I was out.

From gcc manual:
-funsafe-loop-optimizations
This option tells the loop optimizer to assume that loop indices do not overflow, and that loops with nontrivial exit condition are not infinite. This enables a wider range of loop optimizations even if the loop optimizer itself cannot prove that these assumptions are valid. If you use -Wunsafe-loop-optimizations, the compiler warns you if it finds this kind of loop.
Thus, apparently, the implementation of range-for loop in the compiler is somehow broken in that it triggers this warning. You could either disable this particular warning or disable this particular optimization... I would advise the latter as it is unclear to me whether the optimization is actually done or not when the warning is triggered.

Related

how to turn on icc/icpc warnings?

I installed Intel Compiler composer_xe_2013_sp1.3.174 on Linux. I am confused about the icc warnings. Feed icc with a simple program main.c as below:
int main(int argc, char **argv) {
int a = 1;
unsigned int b = -22;
if (b = a) {
}
}
I compiled the file with the command: icc -Wall main.c. Surprisingly, the command works silently without any warnings. Do I have to turn on the warnings switch on icc? Thanks
The Intel compiler doesn't really have good presets for warnings the way that gcc does (at least on Linux). The main warning option is -wn where n can be 0 to 5. The default is 1, and 4 & 5 have no meaning on Linux. It also supports some gcc options like -Wall and -Wextra. However:
-Wall is very minimalistic compared to gcc, as you found
-w2 and -w3 enable some useful diagnostics, but also a lot of spam remarks
-diag-disable:remark removes that spam but also a lot of useful diagnostics
In the end -w3 -diag-disable:remark is the best preset that icc has but it is still more minimalistic than gcc -Wall. Instead you need to either start with a minimal set of warnings and build up your own, or start with maximum diagnostics and disable any that get annoying using -wd.
Build Up
The main downside to the first approach is that Intel doesn't really document most of its warnings, so it is hard to know what is available to enable. However, it does support many of the GCC command line flags, so the GCC documentation is a good place to start. For example, here are settings that are relatively close to g++ -Wall, which is convenient if you want to develop with one and have a good chance of a clean build with the other:
icpc -Wall -Warray-bounds -Wchar-subscripts -Wcomment -Wenum-compare -Wformat -Wuninitialized -Wmaybe-uninitialized -Wmain -Wnarrowing -Wnonnull -Wparentheses -Wpointer-sign -Wreorder -Wreturn-type -Wsign-compare -Wsequence-point -Wtrigraphs -Wunused-function -Wunused-but-set-variable -Wunused-variable -Wwrite-strings
This isn't an exact match for gcc -Wall. There are differences between GCC's and ICC's implementation of the above warnings. I was also unable to find ICC options to match these GCC warnings:
-Wformat-contains-nul
-Wunused-label
-Wstrict-overflow
-Wvolatile-register-var
And I intentionally left these out, because the ICC version was much more spammy than GCC:
-Wstrict-aliasing So broad that any use of polymophism will cause this warning
-Wswitch Requires a default even if you have cases for all enumeration values
Trim Down
If GCC parity isn't a concern then the easiest way to learn what warnings ICC has is to enable them all, and then decide whether you like them or not. If you don't like a warning, you can disable it using it's diagnostics number, which often has more granularity that GCC's options do.
icpc -w3 -wd1418,2259
Here are some diagnostics that I have seen disabled in the past:
383: value copied to temporary, reference to temporary used
869: parameter "*" was never referenced
981: operands are evaluated in unspecified order
1418: external function definition with no prior declaration
1572: floating-point equality and inequality comparisons are unreliable
2259: non-pointer conversion may loose significant bits
11074: Inlining inhibited by limit max-size (or max-total-size)
11076: To get full report use -qopt-report=4 -qopt-report-phase ipo
161: disable warning for unrecognized pragmas
But I encourage you to start with them all on and pare down just the ones that are problematic for your code base.
Generally speaking, the best compilation options for a small program your developing is
-Wall -Wextra -std=c11 -pedantic
Contrary to the warning switch's name, Wall does not actually activate all warnings; you use both Wall and Wextra to get the majority of the important warnings.
-std switch sets the standard that the code uses; the most recent one is C11 therefore std=c11. Pedantic is a way to signal to the compiler that you want to write a program that doesn't use compiler-specific extensions. Pedantic requires the std switch and will emit warnings for any syntax, ect. that does not conform to the standard specified by std. Finally, if you want errors instead of warnings for usage of compiler-extension, use -pedantic-errors instead.*
(* - pedantic does not warn about the usage of non-standard libraries like conio.h)
Now if you compile the program with Wall Wextra std=c11 pedantic, you should get 1 warnings:
Warning: Line 4 - Suggest Parenthesis around truthy value (9 out of 10, this means you used = instead == in a comparison context).
If you fix that warning, you'll receive another warning:
Warning: Line 4 - Comparison between Signed and Unsigned Integer without a cast.
Adding an explicit cast or changing b to a normal int will solve this warning.
These days I am pretty happy using this target_options in CMake with icpc 2021.6.0 20220226, I collected them from several sources.
Any additions are welcome.
target_compile_options(
${TEST_EXE}
PRIVATE
$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:
...
>
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<NOT:$<CUDA_COMPILER_ID:NVIDIA>>,$<NOT:$<CUDA_COMPILER_ID:Clang>>>:
...
>
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CUDA_COMPILER_ID:Clang>>:
...
>
$<$<CXX_COMPILER_ID:Intel>: # also IntelLLVM, XL (ibm), XLClang (ibm)
-Werror
-Wall
-Wextra
-diag-disable=remark
-diag-error:3846
-diag-disable=1011 # disables warning missing return at the end of non-void function
-wd161
-Wabi
-Warray-bounds
-Wcast-qual
-Wchar-subscripts
-Wcomment
-Wdeprecated
-Wenum-compare
-Wextra-tokens
-Wformat
-Wformat=2
-Wformat-security
-Wic-pointer
-Wnarrowing
-Wno-return-type
-Wnon-virtual-dtor
-Wnonnull
-Wmaybe-uninitialized
-Wmain
-Wmissing-declarations
-Wmissing-prototypes
-Wmultichar
-Woverloaded-virtual
-Woverflow
-Wparentheses
-Wpointer-arith
-Wpointer-sign
-Wreorder
-Wreturn-type
-Wsequence-point
-Wshadow
-Wsign-compare
-Wshorten-64-to-32
-Wno-strict-aliasing
-Wstrict-prototypes
-Wtrigraphs
-Wtype-limits
-Wuninitialized
-Wunused
-Wunused-but-set-variable
-Wunused-function
-Wunused-parameter
-Wunused-variable
-Wwrite-strings
>
$<$<OR:$<CXX_COMPILER_ID:PGI>,$<CXX_COMPILER_ID:NVHPC>>:
...
>
$<$<CXX_COMPILER_ID:MSVC>:
...
>
)

There is no "may be used uninitialized" when optimization is disabled

In simple short words:
I need to show "may be used uninitialized" for -O0 optimization
I have problem with cause warning "may be used uninitialized in this function" when optimization is turned off.
I have in code something like this:
int i = i;
Which is obviously wrong. And if compiler optimization is turned off - there is no warning but if I turn optimization to -O1 warring appears.
I need to show this warning when optimizations by -O option are disabled.
Ofcourse there are gcc warning options:
-Wall -Wextra -Winit-self -Wuninitialized -Werror
I read chapter 3.10 Options That Control Optimization, turn off optimization and manually add all -f flags which should be turned on for -O1 level:
-fauto-inc-dec
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fguess-branch-probability
-fif-conversion2
-fif-conversion
-fipa-pure-const
-fipa-reference
-fmerge-constants
-fsplit-wide-types
-ftree-builtin-call-dce
-ftree-ccp
-ftree-ch
-ftree-copyrename
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-forwprop
-ftree-fre
-ftree-phiprop
-ftree-sra
-ftree-pta
-ftree-ter
-funit-at-a-time
and additional:
-fdefer-pop
-fthread-jumps
-fcprop-registers
-fomit-frame-pointer
There is no warning.
Please, could you tell me which flag I missed?
Compiler which I must use is gcc-4.5.4
I think you need:
-Wuninitialized -Winit-self
for that one. Even with -O0, that still generates a warning about self initialisation (at least for gcc 4.7.2):
pax> cat x.c
#include <stdio.h>
int main (void) {
int i = i;
return 0;
}
pax> gcc -O0 -Wuninitialized -Winit-self -o x x.c
x.c: In function ‘main’:
x.c:4:6: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
If you can't get this happening for your version of gcc, there may be another way. You could change the way you build things so that checks are done first at -O1 and only if they pass do you proceed to do the -O0 build. A Makefile like this should be a good start:
x: x.c
gcc -O1 -Wuninitialized -Winit-self -Werror -o x x.c
gcc -O0 -o x x.c
The first compilation will treat warnings as errors so, if it finds self initialisation, the make process will stop completely.
If there are no warnings, you carry on and build the executable again but with -O0.
That may need tuning to make it so only self initialisation stops the process and they may be a little trickier. But it's something to keep in mind if you need the behaviour and you can't convince your current compiler to give it to you at that optimisation level.
One way would be to simply not use -Werror but instead capture the output of the compiler and search specifically for the string is used uninitialized, returning an error code to your make process. That's a bit of a kludge but you may end up having to do something of that description.

How to enable the highest warning level in GCC compiler(Boost is heavily used)

I just read a book which recommends enable the highest warning level in GCC. I just check the doc online, and found there are too much parameters. I want to enable the highest warning level, which parameter should I use?
And we use Boost heavily in our project.
Contrary to cl which has 4 levels, gcc only has a set of options that you can turn on or off.
As mentioned by others, the -Wall is the default, which turns on many warnings already. The -pedantic option adds a few more. And -Wextra yet another group...
But to really capture many warnings, you'll have to add many manually.
There is a set I like to use, although someone told me that some of those were contradictory, I find that list rather good for my development work:
-Werror -Wall -Wextra -pedantic -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-variadic-macros -Wno-parentheses -fdiagnostics-show-option
Note that I make use of -Werror because otherwise you get warnings and tend to ignore them. With -Werror, no more ignoring anything! Write pristine code and your software is much more likely to work as expected.
I guess you can use the -Wallswitch

Flags to enable thorough and verbose g++ warnings

Often in C under gcc, I will start with the following set of warning flags (painfully assembled from multiple sources):
-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \
-Wfloat-equal -pedantic -ansi
I will build (at least my debug versions) with this set of warnings and fix everything I possibly can (usually everything), and then only remove flags if they are either not relevant or not fixable (almost never the case). Sometimes, I'll also add -Werror if I have to step away while compiling.
I'm just picking up C++ (yes, I'm 15 years behind the times), and I'd like to start off on the right foot.
My question is: Does someone have a precompiled similar set of complete warning flags for C++ under g++? (I know many of them will be the same.)
I went through and found the minimal set of includes that should get the maximum level of warning. I then removed from that list the set of warnings that I feel do not actually indicate something bad is happening, or else have too many false positives to be used in a real build. I commented as to why each of the ones I excluded were excluded. This is my final set of suggested warnings:
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused
Questionable warnings that are present:
I include -Wno-unused because I often have variables that I know I
will use later, but do not yet have the functionality written for.
Removing warnings about that allows me to write in my preferred style
of occasionally deferring the implementation of things. It is useful
to turn that off every once in a while to make sure nothing slipped
through the cracks.
-Wdisabled-optimization seems like a strong user-preference
setting. I just added this one to my build (only for optimized builds
for obvious reasons) and it didn't turn anything up, so it doesn't
seem to be an especially chatty warning, at least for the way I code.
I include it (even though code that triggers this warning isn't
necessarily wrong) because I believe in working with my tools instead
of against them. If gcc is telling me that it cannot optimize code
for the way I wrote it, then I should look at rewriting it. I suspect
that code that triggers this warning could benefit from being more
modular, regardless, so although the code is not technically wrong
(probably), stylistically it likely is.
-Wfloat-equal warns for safe equality comparisons (in particular,
comparison with a non-computed value of -1). An example in my code
where I use this is that I have a vector of float. I go through this
vector, and there are some elements I cannot evaluate yet what they
should be, so I set them to -1.0f (since my problem only uses
positive numbers, -1 is out of the domain). I later go through and
update -1.0f values. It does not easily lend itself to a different
method of operation. I suspect that most people don't have this
problem, and comparison of an exact number in floating point is
probably an error, so I'm including it in the default list.
-Wold-style-cast has a lot of false positives in library code I'm using. In particular, the htonl family of functions used in networking, as well as a Rijndael (AES) encryption implementation I'm using has old-style casts that it warns me about. I intend to replace both of these, but I'm not sure if there is anything else in my code that it will complain about. Most users should probably have this on by default, though.
-Wsign-conversion was a tough one (and almost didn't make the
list). Turning it on in my code generated a huge amount of warnings
(100+). Almost all of them were innocent. However, I have been
careful to use signed integers wherever I wasn't sure, although for
my particular problem domain, I would usually get a slight efficiency
increase using unsigned values due to the large amount of integer
division I do. I sacrificed this efficiency because I was concerned
about accidentally promoting a signed integer to an unsigned and then
dividing (which is not safe, unlike addition, subtraction, and
multiplication). Turning on this warning allowed me to safely change
most of my variables to unsigned types and add a few casts in some
other places. It's currently a little hard to use because the warning
isn't that smart. For instance, if you do unsigned short + (integral
constant expression), that result is implicitly promoted to int. It
then warns about a potential sign problem if you assign that value to
unsigned or unsigned short, even though it's safe. This is
definitely the most optional warning for almost all users.
-Wsign-promo: see -Wsign-conversion.
-Wswitch-default seems pointless (you don't always want a default
case if you've enumerated all possibilities explicitly). However,
turning on this warning can enforce something that is probably a good
idea. For cases where you explicitly want to ignore everything except
the listed possibilities (but other numbers are possible), then put
in default: break; to make it explicit. If you explicitly enumerate
all possibilities, then turning on this warning will help ensure that
you put something like assert (false) to make sure that you've
actually covered all possible options. It lets you be explicit in
what the domain of your problem is and programatically enforces that.
However, you'll have to be careful in just sticking assert (false)
everywhere. It's better than doing nothing with the default case, but
as usual with assert, it won't work in release builds. In other
words, you cannot rely on it to validate numbers that you get from,
say, a network connection or a database that you do not have absolute
control over. Exceptions or returning early are the best way to
handle that (but still require you to have a default case!).
-Werror is an important one for me. When compiling large amounts of
code in a multi-threaded build with multiple targets, it's easy for a
warning to slip by. Turning warnings into errors ensures that I
notice them.
Then there is a set of warnings that are not included in the above list because I did not find them to be useful. These are the warnings and my comments on why I'm not including them in the default list:
Warnings that are absent:
-Wabi is not needed because I'm not combining binaries from different compilers. I tried compiling with it anyway, and it didn't trigger, so it doesn't seem needlessly verbose.
-Waggregate-return is not something that I consider an error. For
instance, it triggers when using a range-based for loop on a vector
of classes. Return value optimization should take care of any
negative effects of this.
-Wconversion triggers on this code: short n = 0; n += 2; The
implicit conversion to int causes a warning when it's then converted
back to its target type.
-Weffc++ includes a warning if all data members are not initialized
in the initializer list. I intentionally do not do this in many
cases, so the set of warnings is too cluttered to be useful. It's
helpful to turn on every once in a while and scan for other warnings,
though (such as non-virtual destructors of base classes). This would
be more useful as a collection of warnings (like -Wall) instead of
a single warning on its own.
-Winline is absent because I don't use the inline keyword for
optimization purposes, just to define functions inline in headers. I
don't care if the optimizer actually inlines it. This warning also
complains if it can't inline a function declared in a class body
(such as an empty virtual destructor).
-Winvalid-pch is missing because I don't use precompiled headers.
-Wmissing-format-attribute is not used because I do not use gnu
extensions. Same for -Wsuggest-attribute and several others
Potentially notable for its absence is -Wno-long-long, which I have
no need for. I compile with -std=c++0x (-std=c++11 in GCC 4.7),
which includes long long integer types. Those stuck back on C++98 /
C++03 may consider adding that exclusion from the warning list.
-Wnormalized=nfc is already the default option, and looks to be the
best.
-Wpadded is turned on occasionally to optimize the layout of
classes, but it is not left on because not all classes have enough
elements to remove padding at the end. In theory I could get some
extra variables for 'free', but it's not worth the extra effort of
maintaining that (if my class size changes, it's not easy to remove
those previously free variables).
-Wstack-protector is not used because I do not use -fstack-protector
-Wstrict-aliasing=3 is turned on by -Wall and is the most
accurate, but it looks like level 1 and 2 give more warnings. In
theory a lower level is a 'stronger' warning, but it's at the cost of
more false positives. My own test code compiled cleanly under all 3
levels.
-Wswitch-enum isn't behavior that I want. I don't want to handle
every switch statement explicitly. It would be useful if the language
had some mechanism to activate this on specified switch statements
(to ensure that future changes to the enum are handled everywhere
that they need to be), but it's overkill for an "all-or-nothing"
setting.
-Wunsafe-loop-optimizations causes too many spurious warnings. It
may be useful to apply this one periodically and manually verify the
results. As an example, it generated this warning in my code when I
looped over all elements in a vector to apply a set of functions to
them (using the range-based for loop). It is also warning for the
constructor of a const array of const std::string (where this is no
loop in user code).
-Wzero-as-null-pointer-constant and -Wuseless-cast are
GCC-4.7-only warnings, which I will add when I transition to GCC 4.7.
I've filed a few bug reports / enhancement requests at gcc as a result of some of this research, so hopefully I'll be able to eventually add more of the warnings from the "do not include" list to the "include" list. This list includes all warnings mentioned in this thread (plus I think a few extra). Many of the warnings not explicitly mentioned in this post are included as part of another warning I do mention. If anyone notices any warnings that are excluded from this post entirely, let me know.
edit: It looks like I had missed several (which I have now added in). There is actually a second page at http://gcc.gnu.org that is quite well hidden. General warning options and C++ options (scroll down to the bottom for warnings)
D'oh, all of my original searches turned up 99% of posts on how to suppress warnings (scarily enough), but I just ran across this comment, which has this lovely set of flags (some less relevant):
Cross checked with:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
-g -O -Wall -Weffc++ -pedantic \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security \
-Wformat-y2k \
-Wimplicit -Wimport -Winit-self -Winline \
-Winvalid-pch \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings
So, I think that's a good starting point. Didn't realize this was a dupe, but at least it was deeply buried. :-)
Some of those are already included in -Wall or -Wextra.
A good base setup for C is:
-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror
and for C++
-ansi -pedantic -Wall -Wextra -Weffc++
(skipping -Werror for C++ since -Weffc++ has some annoyances)
Try
export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' |
sort | uniq` -pedantic -fdiagnostics-show-option -Werror"
That's a quick and dirty start which will definitely need some tuning; for one thing, even if you call the compiler by the appropriate name for your language (e.g. g++ for C++), you will get warnings that don't apply to that language (and the compiler will throw up its hands and refuse to continue until you remove the warning).
Another thing is that I added in -Werror, because if you aren't fixing the warnings, why do you care about turning them on? You can also take warnings out of the list. (For example, I almost never use -Waggregate-return with C++.)
Some warnings won't do anything without other performance related options (-Wstack-protector). -fdiagnostics-show-option and the GCC manual are your friends.
By the way, some warnings are mutually exclusive; in particular using -Wtraditional and -Wold-style-definition along with -Werror, will not compile.
In my Clion's CmakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(cpp17)
set(CMAKE_CXX_STANDARD 17)
set(GCC_COVERAGE_COMPILE_FLAGS "-std=c++17 -Wall -Weffc++ -Wno-error=effc++ -pedantic \
-Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-newline-eof \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security \
-Wformat-y2k \
-Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
add_executable(cpp17 main.cpp)

What does "-Wall" in "g++ -Wall test.cpp -o test" do?

-o changes the output filename (I found that using --help)
But I can't find out what -Wall does?
It's short for "warn all" -- it turns on (almost) all the warnings that g++ can tell you about. Typically a good idea, especially if you're a beginner, because understanding and fixing those warnings can help you fix lots of different kinds of problems in your code.
See man gcc.
-Wall turns on these warnings:
-Waddress -Warray-bounds (only with -O2) -Wc++0x-compat -Wchar-subscripts
-Wenum-compare (in C/Objc; this is on by default in C++) -Wimplicit-int (C and
Objective-C only) -Wimplicit-function-declaration (C and Objective-C only)
-Wcomment -Wformat -Wmain (only for C/ObjC and unless -ffreestanding)
-Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreorder -Wreturn-type
-Wsequence-point -Wsign-compare (only in C++) -Wstrict-aliasing
-Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas
-Wunused-function -Wunused-label -Wunused-value -Wunused-variable
-Wvolatile-register-var
-Wextra contains:
-Wclobbered -Wempty-body -Wignored-qualifiers -Wmissing-field-initializers
-Wmissing-parameter-type (C only) -Wold-style-declaration (C only) -Woverride-init
-Wsign-compare -Wtype-limits -Wuninitialized -Wunused-parameter (only with -Wunused
or -Wall) -Wunused-but-set-parameter (only with -Wunused or -Wall)
There are many more warnings which you have to turn on explicitly.
E.g. for our C code we use:
-Wall -Wextra -Waggregate-return -Wcast-align -Wcast-qual -Wdisabled-optimization -Wdiv-by-zero -Wendif-labels -Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wimplicit -Wimport -Winit-self -Winline -Winvalid-pch -Wjump-misses-init -Wlogical-op -Werror=missing-braces -Wmissing-declarations -Wno-missing-format-attribute -Wmissing-include-dirs -Wmultichar -Wpacked -Wpointer-arith -Wreturn-type -Wsequence-point -Wsign-compare -Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch -Wswitch-default -Werror=undef -Wno-unused -Wvariadic-macros -Wwrite-strings -Wc++-compat -Werror=declaration-after-statement -Werror=implicit-function-declaration -Wmissing-prototypes -Werror=nested-externs -Werror=old-style-definition -Werror=strict-prototypes
or just the set of warnings with https://www.gnu.org/software/autoconf-archive/ax_compiler_flags.html
Sadly enough none of the answers is quoting the actually relevant part of manual, which really brings it to a point:
This enables all the warnings about constructions that some users consider
questionable, and that are easy to avoid (or modify to prevent the warning),
even in conjunction with macros.
[...]
Note that some warning flags are not implied by -Wall. Some of them warn
about constructions that users generally do not consider questionable, but which
occasionally you might wish to check for; others warn about constructions that
are necessary or hard to avoid in some cases, and there is no simple way to
modify the code to suppress the warning. Some of them are enabled by -Wextra
but many of them must be enabled individually.
Ergo:
-Wall does not mean "all warnings".
It does also not mean "(almost) all", not by a long shot.
It does mean a set of individual options that is bound to change.
Bottom line, it is about the absolute minimum of warnings you should set. While -Wall -Wextra is better, it's still not making use of all the error checking your compiler can do for you.
Personally I wouldn't go for less than -Wall -Wextra -Wfloat-equal -Wundef -Wcast-align -Wwrite-strings -Wlogical-op -Wmissing-declarations -Wredundant-decls -Wshadow -Woverloaded-virtual. All my current projects actually use a list of warnings longer than that (without triggering any of them). And I do check the manual on every major release for new options. The compiler is your friend. Use whatever diagnostics it can offer you.
It enables warnings which are deemed useful and easy to avoid at the source by gcc writers. There is also -W (-Wextra in newer releases) which are deemed useful but for which work-arounding false positives can be difficult or result in clumsy code.
gcc has also a bunch of other warnings, generally less useful. See http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Warning-Options.html#Warning-Options
It enables most warning messages.
You can find out more if you use g++ --help=warnings.
It enables all warnings. (reads as "Warning All")
It shows all warnings. I'd recommend also use -pedantic to warn about some non-conformant parts of code.