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

-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.

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>:
...
>
)

Why does gcc complain about my loops?

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.

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

How can I turn on (literally) ALL of GCC's warnings?

I would like to enable—literally—all of the warnings that GCC has. (You'd think it would be easy...)
You'd think -Wall might do the trick, but nope! You still need -Wextra.
You'd think -Wextra might do the trick, but nope! Not all of the warnings listed here (for example, -Wshadow) are enabled by this. And I still don't have any idea if this list is comprehensive.
How do I tell GCC to enable (no if's, and's, or but's!) all the warnings it has?
You can't.
The manual for GCC 4.4.0 is only comprehensive for that version, but it does list all the possible warnings for 4.4.0. They're not all on the page you link to though. For instance, some language-specific options are on the pages for C++ options or Objective-C options. To find them all, you're better off looking at the Options Summary
Turning on everything would include -Wdouble-promotion which is only relevant on CPUs with a 32-bit single-precision floating-point unit which implements float in hardware, but emulates double in software. Doing calculations as double would use the software emulation and be slower. That's relevant for some embedded CPUs, but completely irrelevant for modern desktop CPUs with hardware support for 64-bit floating-point.
Another warning that's not usually useful is -Wtraditional, which warns about perfectly well formed code that has a different meaning (or doesn't work) in traditional C, e.g., "string " "concatenation", or ISO C function definitions! Do you really care about compatibility with 30 year old compilers? Do you really want a warning for writing int inc(int i) { return i+1; }?
I think -Weffc++ is too noisy to be useful. It's based on the outdated first edition of Effective C++ and warns about constructs which are perfectly valid C++ (and for which the guidelines changed in later editions of the book). I don't want to be warned that I haven't initialized a std::string member in my constructor; it has a default constructor that does exactly what I want. Why should I write m_str() to call it? The -Weffc++ warnings that would be helpful are too difficult for the compiler to detect accurately (giving false negatives), and the ones that aren't useful, such as initializing all members explicitly, just produce too much noise, giving false positives.
Luc Danton provided a great example of useless warnings from -Waggregate-return that almost certainly never makes sense for C++ code.
I.e., you don't really want all warnings; you just think you do.
Go through the manual, read about them, decide which you might want to enable, and try them. Reading your compiler's manual is a Good ThingTM anyway, taking a shortcut and enabling warnings you don't understand is not a very good idea, especially if it's to avoid having to RTFM.
Anyone who just turns on everything is probably either doing so because they're clueless because or a pointy-haired boss said "no warnings."
Some warnings are important, and some aren't. You have to be discriminating or you mess up your program. Consider, for instance, -Wdouble-promotion. If you're working on an embedded system you might want this; if you're working on a desktop system you probably don't. And do you want -Wtraditional? I doubt it.
See also -Wall-all to enable all warnings which is closed as WONTFIX.
In response to DevSolar's complaint about makefiles needing to use different warnings depending on compiler version, if -Wall -Wextra isn't suitable then it's not difficult to use compiler-specific and version-specific CFLAGS:
compiler_name := $(notdir $(CC))
ifeq ($(compiler_name),gcc)
compiler_version := $(basename $(shell $(CC) -dumpversion))
endif
ifeq ($(compile_name),clang)
compiler_version := $(shell $(CC) --version | awk 'NR==1{print $$3}')
endif
# ...
wflags.gcc.base := -Wall -Wextra
wflags.gcc.4.7 := -Wzero-as-null-pointer-constant
wflags.gcc.4.8 := $(wflags.gcc.4.7)
wflags.clang.base := -Wall -Wextra
wflags.clang.3.2 := -Weverything
CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))
I would agree with the previous answers that it is probably not beneficial to enable literally all warnings, however GCC does provide a reasonably convenient way to achieve this. The command
gcc -Q --help=warning
provides a list of all supported warning options with information on whether they are active. This can by the way be used to find out which options are (not) enabled by e.g. -Wall and -Wextra
gcc -Wall -Wextra -Q --help=warning
To enable all the warnings you can use some regex to extract the command line parameters
gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n'
For my current GCC this gives:
-Wabi -Wabi-tag -Waddress -Waggregate-return -Waggressive-loop-optimizations -Waliasing -Walign-commons -Wampersand -Warray-bounds -Warray-temporaries -Wassign-intercept -Wattributes -Wbad-function-cast -Wbool-compare -Wbuiltin-macro-redefined -Wc++-compat -Wc++0x-compat -Wc++14-compat -Wc-binding-type -Wc90-c99-compat -Wc99-c11-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wcharacter-truncation -Wchkp -Wclobbered -Wcomment -Wcompare-reals -Wconditionally-supported -Wconversion -Wconversion-extra -Wconversion-null -Wcoverage-mismatch -Wcpp -Wctor-dtor-privacy -Wdate-time -Wdeclaration-after-statement -Wdelete-incomplete -Wdelete-non-virtual-dtor -Wdeprecated -Wdeprecated-declarations -Wdesignated-init -Wdisabled-optimization -Wdiscarded-array-qualifiers -Wdiscarded-qualifiers -Wdiv-by-zero -Wdouble-promotion -Weffc++ -Wempty-body -Wendif-labels -Wenum-compare -Wextra -Wfloat-equal -Wformat-contains-nul -Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-signedness -Wformat-y2k -Wformat-zero-length -Wfree-nonheap-object -Wfunction-elimination -Wignored-qualifiers -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wimplicit-interface -Wimplicit-procedure -Wincompatible-pointer-types -Winherited-variadic-ctor -Winit-self -Winline -Wint-conversion -Wint-to-pointer-cast -Wintrinsic-shadow -Wintrinsics-std -Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch -Wjump-misses-init -Wline-truncation -Wliteral-suffix -Wlogical-not-parentheses -Wlogical-op -Wlong-long -Wmain -Wmaybe-uninitialized -Wmemset-transposed-args -Wmissing-braces -Wmissing-declarations -Wmissing-field-initializers -Wmissing-include-dirs -Wmissing-parameter-type -Wmissing-prototypes -Wmultichar -Wnarrowing -Wnested-externs -Wnoexcept -Wnon-template-friend -Wnon-virtual-dtor -Wnonnull -Wodr -Wold-style-cast -Wold-style-declaration -Wold-style-definition -Wopenmp-simd -Woverflow -Woverlength-strings -Woverloaded-virtual -Woverride-init -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpedantic -Wpmf-conversions -Wpointer-arith -Wpointer-sign -Wpointer-to-int-cast -Wpragmas -Wproperty-assign-default -Wprotocol -Wreal-q-constant -Wrealloc-lhs -Wrealloc-lhs-all -Wredundant-decls -Wreorder -Wreturn-local-addr -Wreturn-type -Wselector -Wsequence-point -Wshadow -Wshadow-ivar -Wshift-count-negative -Wshift-count-overflow -Wsign-compare -Wsign-promo -Wsized-deallocation -Wsizeof-array-argument -Wsizeof-pointer-memaccess -Wstack-protector -Wstrict-null-sentinel -Wstrict-prototypes -Wstrict-selector-match -Wsuggest-attribute=const -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wsuggest-attribute=pure -Wsuggest-final-methods -Wsuggest-final-types -Wsuggest-override -Wsurprising -Wswitch -Wswitch-bool -Wswitch-default -Wswitch-enum -Wsync-nand -Wsynth -Wsystem-headers -Wtabs -Wtarget-lifetime -Wtraditional -Wtraditional-conversion -Wtrampolines -Wtrigraphs -Wtype-limits -Wundeclared-selector -Wundef -Wunderflow -Wuninitialized -Wunknown-pragmas -Wunsafe-loop-optimizations -Wunsuffixed-float-constants -Wunused -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-dummy-argument -Wunused-function -Wunused-label -Wunused-local-typedefs -Wunused-macros -Wunused-parameter -Wunused-result -Wunused-value -Wunused-variable -Wuse-without-only -Wuseless-cast -Wvarargs -Wvariadic-macros -Wvector-operation-performance -Wvirtual-move-assign -Wvla -Wvolatile-register-var -Wwrite-strings -Wzero-as-null-pointer-constant -Wzerotrip -frequire-return-statement
This can now be used to call the GCC, i.e.
gcc $(gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n')
Note however that this results in warnings due to some warning options only being available for certain languages (e.g., C++). These could be avoided by using some more regex to only include the options allowed for the current language or by adding an appropriate -Wno-whatever at the end of the call.
It's simply impossible to program with all warnings enabled (unless you are going to ignore them, but then, why bother?). For example, let's assume you use following set of flags: -Wstrict-prototypes -Wtraditional.
Even with two warnings enabled, the following program would complain.
/tmp $ cat main.c
int main(int argc, char **argv) {
return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c
main.c: In function ‘main’:
main.c:1:5: warning: traditional C rejects ISO C style function definitions [-Wtraditional]
int main(int argc, char **argv) {
^
You may think "well, I'm going to use old style prototypes then". Nope, this won't work.
/tmp $ cat main.c
int main(argc, argv)
int argc;
char **argv;
{
return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
int main(argc, argv)
^
And no, not specifying any prototype is also wrong, as the compiler will also complain.
/tmp $ cat main.c
int main() {
return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
int main() {
^
If you define any functions inside your program, you cannot use all flags, because the compiler will complain about any imaginable function definition.
For C++, this is possible (the -Wtraditional flag doesn't exist), and very simple programs can be compiled. To enable all warnings, use following list of warnings (probably some warnings are duplicated, because I didn't bother to filter warnings enabled by -Wall).
-Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo -Wextra -Wall -Waddress -Waggregate-return -Warray-bounds -Wno-attributes -Wno-builtin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Winline -Wno-int-to-pointer-cast -Wno-invalid-offsetof -Winvalid-pch -Wunsafe-loop-optimizations -Wlogical-op -Wlong-long -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wno-mudflap -Wno-multichar -Wnonnull -Wno-overflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-aliasing=1 -Wstrict-overflow=5 -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas -Wno-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings
Someone has created a set of tools for determining the complete set of warnings for a given GCC or Clang version.
For GCC, copying from the full list of warnings provided by this tool for your compiler version appears to be the only way to ensure that all warnings are turned on, since (unlike Clang) GCC does not provide -Weverything.
The tool appears to parse the actual c.opt file in the GCC source code, so its results should be definitive.
The repository also contains text files with the warning lists generated for most GCC and Clang versions (currently Clang 3.2 through 3.7 and GCC 3.4 through 5.3).
GCC 4.3+ now has -Q --help=warnings, and you can even specify --help=warnings,C to just print out the C related warnings.
I just wrote an m4 module to take advantage of this (it also supports Clang's -Weverything); see wget_manywarnings.m4.
How to use it is pretty simple. Basically, the module turns every warn flag on. And you remove warnings as needed—some are really very verbose.
Example: configure.ac
If you don't use autotools, you'll find the code to turn on all disabled warnings in the m4 module, which basically is the GCC call piped through AWK:
flags="-Wall -Wextra -Wformat=2 "$(gcc -Wall -Wextra -Wformat=2 -Q --help=warning,C|awk '{ if (($2 == "[disabled]" || $2 == "") && $1!~/=/ && $1~/^-W/&& $1!="-Wall") print $1 }'
From this page:
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.
I guess the question is which ones? Perhaps you could grep that page for all lines beginning with -W, and get a complete list of warning flags. Then compare those with the lists under -Wall and -Wextra. There is also -Wpedantic, though you are obviously wanting to be even more pedantic still =)
And I still have no idea if this list is comprehensive.
It probably is, but the only list that is 100% comprehensive is the actual source for the compiler. However, GCC is big! And I don't know if all command-line parameters are collected in one place or spread out over several source files. Also note that some warnings are for the pre-processor, some for the actual compiler and some for the linker (which is a completely separate program, and found in the binutils package) so they most likely are spread out.
EDIT 2023: refreshed for GCC 12.
I gathered information from the other postings and one-by-one tested the warnings in the test for a C++ library.
Using the list from Haatschii and his/her method of getting the full list for GCC 11:
gcc -Wall -Wextra -Wpedantic -Q --help=warning
Of all these warnings some do not apply to C++, so here it is a list of warnings and some minimal comments that work for the tests of my C++ project.
Take into account, that:
Some of these warnings are by default already turned on without adding any option.
I don't claim to know what some warnings actually mean.
I don't recommend using or not using any particular warning.
Some are commented, and that doesn't mean anything. Comment or uncomment them as you need. (I commented the ones that were not useful for my project.)
Some will not work on GCC 10.
The list is given as-is, it may contain errors or typos.
The list is basically in alphabetical order, with some minimal bunching to save vertical space. As a bonus, it is formatted for use in a CMake project.
Now the list:
target_compile_options(
target
PRIVATE
$<$<AND:$<CXX_COMPILER_ID:GNU>,$<NOT:$<CUDA_COMPILER_ID:NVIDIA>>,$<NOT:$<CUDA_COMPILER_ID:Clang>>>:
-Werror
-Wall
-Wextra # (activates -Wunknown-pragmas)
-Wpedantic
-WNSObject-attribute # (gcc 12, not in 11)
# -Wabi=13 -Wabi-tag (maybe important when linking with very old libraries)
# -Wabsolute-value # C/ObjC only (gcc 12, not in 11)
-Waddress
# -Waddress-of-packed-member (gcc 11, not in gcc 8)
# -Waggregate-return (disallow return classes or structs, seems a C-compatibility warning)
-Waggressive-loop-optimizations
# -Waligned-new=all (gcc 12, not in 11)
# -Walloc-size-larger-than=<bytes> (gcc 12, not in 11)
-Walloc-zero # -Walloc-size-larger-than=<bytes>
-Walloca # -Walloca-larger-than=<number>
# -Wanalyzer-double-fclose -Wanalyzer-double-free -Wanalyzer-exposure-through-output-file -Wanalyzer-file-leak -Wanalyzer-free-of-non-heap -Wanalyzer-malloc-leak (gcc 11, not in gcc 9)
# -Wanalyzer-mismatching-deallocation (gcc 11, not in gcc 10)
# -Wanalyzer-null-argument -Wanalyzer-possible-null-argument -Wanalyzer-null-dereference (gcc 11, not in gcc 9)
# -Wanalyzer-possible-null-dereference (gcc 11, not in gcc 9)
# -Wanalyzer-shift-count-negative -Wanalyzer-shift-count-overflow (gcc 11, not in gcc 10)
# -Wanalyzer-stale-setjmp-buffer
# -Wanalyzer-tainted-allocation-size (gcc 12, not in 11)
# -Wanalyzer-tainted-array-index (gcc 11, not in gcc 9)
# -Wanalyzer-tainted-divisor -Wanalyzer-tainted-offset -Wanalyzer-tainted-size -Wanalyzer-too-complex -Wanalyzer-unsafe-call-within-signal-handler (gcc 12, not in 11)
# -Wanalyzer-unsafe-call-within-signal-handler -Wanalyzer-use-after-free -Wanalyzer-use-of-pointer-in-stale-stack-frame
# -Wanalyzer-write-to-const -Wanalyzer-write-to-string-literal (gcc 11, not in gcc 10)
# -Warith-conversion (gcc 11, not in gcc 9)
-Warray-bounds
# -Warray-bounds=<0,2> -Warray-compare (gcc 12, not in gcc 9)
# -Warray-parameter -Warray-parameter=<0,2> (gcc 11, not in gcc 10)
# -Wattribute-alias -Wattribute-alias=<0,2> (gcc 12, not in 11)
# -Wattribute-warning (gcc 9, not in 8)
-Wattributes
# -Wbad-function-cast (gcc 12, not in 11)
-Wbool-compare -Wbool-operation
# -Wbidi-chars -Wbidi-chars=any (gcc 12, not in 11)
-Wbuiltin-declaration-mismatch -Wbuiltin-macro-redefined
#-Wc++-compat
-Wc++0x-compat -Wc++11-compat -Wc++14-compat -Wc++17-compat -Wc++17-extensions -Wc++1z-compat
# -Wc++20-compat -Wc++20-extensions -Wc++23-extensions -Wc++2a-compat (gcc 11, not in gcc 9)
# -Wcannot-profile (gcc 9, not in gcc 8)
-Wcast-align=strict -Wcast-function-type
-Wcast-qual
-Wcatch-value #=<0, 3>
-Wchar-subscripts
# -Wchkp -Wclass-conversion -Wclass-memaccess (gcc 12, not in 11)
# -Wclobbered
# -Wcomma-subscript (gcc 12, not in 11)
# -Wcomment # (same as -Wcomments)
# -Wcompare-reals (gcc 12, not in 11)
-Wconditionally-supported
-Wconversion -Wconversion-null
-Wcoverage-mismatch -Wcpp
# -Wctad-maybe-unsupported # TODO(correaa) add ctad explicitly as necessary
-Wctor-dtor-privacy
-Wdangling-else
# -Wdangling-pointer (gcc 12, not in 11)
-Wdate-time
# -Wdeclaration-after-statement (gcc 12, not in 11)
-Wdelete-incomplete -Wdelete-non-virtual-dtor
-Wdeprecated
# -Wdeprecated-copy -Wdeprecated-copy-dtor (gcc 11, not in gcc 8)
-Wdeprecated-declarations
# -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion (gcc 11, not in gcc 10)
# -Wdesignated-init (gcc 12, not in 11)
-Wdisabled-optimization
# -Wdiscarded-array-qualifiers (gcc 12, not in 11)
-Wdiv-by-zero -Wdouble-promotion
# -Wduplicate-decl-specifier (gcc 12, not in 11)
-Wduplicated-branches -Wduplicated-cond
# -Weffc++ (doesn't allow some advanced techniques, such as CRTP)
-Wempty-body -Wendif-labels
-Wenum-compare
# -Wenum-conversion (gcc 11, not in gcc 10)
-Wexpansion-to-defined
# -Werror-implicit-function-declaration not for C++ (gcc 12, not in 11)
# -Wexceptions (gcc 11, not in gcc 10)
# -Wextra
-Wextra-semi
-Wfloat-conversion # -Wfloat-equal (disallows float equality)
-Wformat=2
# -Wformat-contains-nul (gcc 12, not in 11)
# -Wformat-diag (gcc 10, not in gcc 9)
-Wformat-extra-args -Wformat-nonliteral
# -Wformat-overflow=1
-Wformat-security -Wformat-signedness -Wformat-truncation -Wformat-y2k -Wformat-zero-length
-Wframe-address # -Wframe-larger-than=<byte-size>
-Wfree-nonheap-object -Whsa
-Wif-not-aligned
-Wignored-attributes -Wignored-qualifiers
# -Wimplicit (gcc 12, not in 11)
-Wimplicit-fallthrough#=3 # -Wimplicit-fallthrough=<0,5>
# -Wimplicit-function-declaration -Wimplicit-int (gcc 12, not in 11)
# -Winaccessible-base (gcc 12, not in 11)
# -Wincompatible-pointer-types -Winfinite-recursion -Winherited-variadic-ctor -Winit-list-lifetime (gcc 12, not in 11)
-Winit-self
# -Winline
# -Wint-conversion (gcc 12, not in 11)
-Wint-in-bool-context -Wint-to-pointer-cast
# -Winterference-size (gcc 12, not in 11)
# -Winvalid-imported-macros (gcc 11, not in gcc 10)
-Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch
# -Wjump-misses-init (gcc 12, not in 11)
# -Wlarger-than=<byte-size> # (disallow large objects types? in executable)
-Wliteral-suffix
-Wlogical-not-parentheses -Wlogical-op
# -Wlong-long (C++98 warning)
-Wlto-type-mismatch -Wmain -Wmaybe-uninitialized
-Wmemset-elt-size -Wmemset-transposed-args
-Wmisleading-indentation
# -Wmismatched-dealloc -Wmismatched-new-delete (gcc 11, not in gcc 10)
# -Wmismatched-tags (gcc 11, not in gcc 9)
-Wmissing-attributes
-Wmissing-braces -Wmissing-declarations -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn
# -Wmissing-parameter-type (gcc 12, not in 11)
# -Wmissing-profile (gcc 11, not in gcc 8)
# -Wmissing-prototypes -Wmissing-requires -Wmissing-template-keyword (gcc 12, not in 11)
-Wmultichar
# -Wmultiple-inheritance (disallows composition by inheritance)
-Wmultistatement-macros
# -Wnamespaces (disallows use of namespaces, seems a C-tool)
-Wnarrowing
# -Wnested-externs (gcc 12, not in 11)
# -Wno-alloc-size-larger-than=<bytes> -Wframe-larger-than=<bytes> -Wno-larger-than<bytes> -Wstack-usage=<bytes> (gcc 112, not in 11)
-Wnoexcept -Wnoexcept-type
-Wnon-template-friend -Wnon-virtual-dtor
-Wnonnull -Wnonnull-compare
-Wnormalized #=nfc -Wnormalized=[none|id|nfc|nfkc]
-Wnull-dereference
-Wodr -Wold-style-cast
# -Wold-style-declaration -Wold-style-definition (gcc 12, not in 11)
# -Wopenacc-parallelism (gcc 12, not in 11)
-Wopenmp-simd -Woverflow
-Woverlength-strings -Woverloaded-virtual
# -Woverride-init -Woverride-init-side-effects (gcc 12, not in 11)
-Wpacked -Wpacked-bitfield-compat -Wpacked-not-aligned
# -Wpadded (disallows structs that need padding for alignment)
-Wparentheses
# -Wpedantic (see above)
# -Wpessimizing-move (gcc 11, not in gcc 8)
-Wplacement-new #=1 -Wplacement-new=<0,2>
-Wpmf-conversions
-Wpointer-arith -Wpointer-compare
# -Wpointer-sign -Wpointer-to-int-cast (gcc 12, not in 11)
-Wpragmas
# -Wprio-ctor-dtor (gcc 11, not in gcc 8)
-Wpsabi
# -Wrange-loop-construct (gcc 11, not in gcc 10)
-Wredundant-decls
# -Wredundant-move (gcc 11, not in gcc 8)
# -Wredundant-tags (gcc 11, not in gcc 9)
-Wregister
# -Wreorder (gcc 12, not in 11)
-Wreturn-local-addr -Wreturn-type
-Wrestrict -Wreorder
-Wscalar-storage-order -Wsequence-point
-Wshadow -Wshadow-compatible-local -Wshadow-local -Wshadow=compatible-local -Wshadow=local
-Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value -Wshift-overflow #=1 -Wshift-overflow=<0,2>
-Wsign-compare -Wsign-conversion -Wsign-promo
-Wsized-deallocation
-Wsizeof-array-argument
# -Wsizeof-array-div (gcc 11, not in gcc 10)
-Wsizeof-pointer-div
-Wsizeof-pointer-memaccess
-Wstack-protector # -Wstack-usage=<byte-size>
-Wstrict-aliasing #=3 -Wstrict-aliasing=<0,3>
-Wstrict-null-sentinel #=1 -Wstrict-overflow=<0,5>
-Wstrict-overflow #=1 -Wstrict-overflow=<0,5>
# -Wstrict-prototypes (gcc 12, not in gcc 11)
# -Wstring-compare (gcc 11, not in gcc 9)
-Wstringop-overflow #=2 -Wstringop-overflow=<0,4>
# -Wstringop-overread (gcc 11, not in gcc 10)
-Wstringop-truncation
-Wsubobject-linkage
# -Wsuggest-attribute=cold (gcc 12, not in 11)
-Wsuggest-attribute=const -Wsuggest-attribute=format -Wsuggest-attribute=malloc -Wsuggest-attribute=noreturn
# -Wsuggest-attribute=pure
-Wsuggest-final-methods -Wsuggest-final-types
# -Wsuggest-override (gcc 12, not in gcc 11)
-Wswitch -Wswitch-bool -Wswitch-default -Wswitch-enum
# -Wswitch-outside-range (gcc 11, not in gcc 9)
-Wswitch-unreachable
-Wsync-nand -Wsynth
# -Wsystem-headers (expects system headers to be warning-compliant which they are not)
-Wtautological-compare
# -Wtemplates (disallows templates, C-tool)
# -Wterminate -Wtraditional -Wtraditional-conversion (gcc 12, not in 11)
-Wtrampolines -Wtrigraphs
# -Wtrivial-auto-var-init (gcc 12, not in 11)
# -Wtsan (gcc 11, not in 10)
-Wtype-limits -Wundef -Wuninitialized
-Wno-unknown-pragmas # (see above) -Wunknown-pragmas (other compilers need their own pragmas for their warnings)
-Wunreachable-code -Wunsafe-loop-optimizations
# -Wunsuffixed-float-constants (gcc 12, not in 11)
-Wunused -Wunused-but-set-parameter -Wunused-but-set-variable
# -Wunused-const-variable #=2 TODO(correaa) add [[maybe_unused]] to niebloids
-Wunused-function -Wunused-label -Wunused-local-typedefs -Wunused-macros -Wunused-parameter -Wunused-result -Wunused-value -Wunused-variable
# -Wuse-after-free # =<0,3> (gcc 12, not in 11)
-Wuseless-cast
-Wvarargs -Wvariadic-macros -Wvector-operation-performance
# -Wvexing-parse (gcc 11, not in gcc 10)
-Wvirtual-inheritance -Wvirtual-move-assign
-Wvla
# -Wvla-larger-than=<number> (gcc 12, not in 11)
# -Wvla-parameter (gcc 11, not in gcc 10)
# -Wvolatile (gcc 11, not in gcc 9)
-Wvolatile-register-var
-Wwrite-strings
-Wzero-as-null-pointer-constant
# -Wzero-length-bounds (gcc 12, not in 11)
>
)

Making GCC and other C++ compilers very strict

I'm working on a large collaborative C++ project that is both developed and run on various flavors of Linux, OS X and Windows. We compile across these platforms with GCC, Visual Studio C++ and the Intel C++ compiler. As more and more people start developing code for the project, we're starting to see weird errors in compilation and runtime that are specific to particular compilers on particular operating systems. An example of this is implicit inclusion of headers that certain OS/compiler pairs seem to find for you, accidentally overloading a function from a base class in a derived class.
My goal is to make compilation on GCC more strict and catch more errors across all platforms so that we don't keep running into these problems. Here's my list of flags that I'm thinking about trying out for GCC that I've found via Google and the GCC man pages:
-Wall
-Wextra
-Winit-self
-Wold-style-cast
-Woverloaded-virtual
-Wuninitialized
-Wmissing-declarations
-Winit-self
-ansi
-pedantic
What are the other flags that people use to make GCC (and less importantly Visual Studio C++ and the Intel C++ Compiler) obey a stricter standard of the C++ language? Be specific about which compiler and version you're talking about, as some of these might not be implemented in all versions of all compilers.
Beside the pedantic-error that everyone else suggested, IMO, it's always good to run lint as part of your compile process.
There are some tools out there:
cpplint (free)
gimple lint
coverity
They will save a lot of your time.
You can make pedantic warnings into errors with -pedantic-errors. This will prevent developers from ignoring it. For that matter you could make all warnings into errors as well with -Werror although that can be counter productive in some cases (maybe not in yours though).
Overall, I think, as far as adhering to a strict standard goes, the -pedantic options are the most helpful.
Copy and paste the below line into your master CMake file. The below line comprises almost most useful compiler flags in order to test yourself stricter.
set(CMAKE_CXX_FLAGS "-O0 -fno-elide-constructors -pedantic-errors -ansi -Wextra -Wall -Winit-self -Wold-style-cast -Woverloaded-virtual -Wuninitialized -Wmissing-declarations -Winit-self -std=c++98")
If you don’t use CMake, just copy the flags in double quotes and send them to your compiler.
-pedantic-errors.
See more on gcc(1).
As well as -pendantic, you should also provide a -std switch. If you need a stricter compile then you should know what standard you are trying to conform to. Typically for current C++ this would be -std=c++98. (-ansi performs a similar function in C++ mode, but -std= is more explicit.)
In a similar situation we gave up and moved to the ACE framework, hiding the difference between platforms.
I wrote a blog post on this topic after researching several options. You also need to handle the cases where you are using other libraries, but they are not following strict compilation. Fortunately, there is an easy way to handle them as well. I have been using this extensively in all my projects.
In short, use the following compiler options to turn on very strict mode (below is what I put in CMakeLists.txt):
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wstrict-aliasing -pedantic -fmax-errors=5 -Werror -Wunreachable-code -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 -Wswitch-default -Wundef -Wno-unused -Wno-variadic-macros -Wno-parentheses -fdiagnostics-show-option ${CMAKE_CXX_FLAGS}")
You can read more about how to turn on and off this strict mode for specific portions of code here: http://shitalshah.com/p/how-to-enable-and-use-gcc-strict-mode-compilation/