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>:
...
>
)
Related
I have a few files where I'd like to be strict about warnings, and I use GCC to build my project.
I've tried #pragma GCC diagnostic error "-Wall" as per 6.57.10 Diagnostic Pragmas, but it fails to account for some other enabled warning types:
foo.c:666:6: warning: passing argument 2 of 'bar' from incompatible pointer type [-Wincompatible-pointer-types]
Is there a way to enable -Werror for the file like it was supplied from the command line (or, at least, for the implicitly enabled set of warnings), so any warning would trigger an error?
For this case, you can use
#pragma GCC diagnostic error "-Wincompatible-pointer-types"
as for example in
#pragma GCC diagnostic error "-Wincompatible-pointer-types"
void foo(int * a)
{
}
void bar() {
foo("foo");
}
Using -Wall with this pragma is not supported. Only diagnostic options are supported, that are shown with -fdiagnostics-show-option (which is the default today anyway), as in your example warning above.
As a workaround, it turns out the current semantics of the -Wall option are described on the man page. In my case of GCC 8.3.0, it says that it enables the following options that could be used with the pragma afterwards:
-Waddress -Warray-bounds=1 (only with -O2) -Wbool-compare -Wbool-operation -Wc++11-compat -Wc++14-compat -Wcatch-value (C++ and Objective-C++ only) -Wchar-subscripts -Wcomment -Wduplicate-decl-specifier (C and Objective-C
only) -Wenum-compare (in C/ObjC; this is on by default in C++) -Wformat -Wint-in-bool-context -Wimplicit (C and Objective-C only) -Wimplicit-int (C and Objective-C only) -Wimplicit-function-declaration (C and Objective-C
only) -Winit-self (only for C++) -Wlogical-not-parentheses -Wmain (only for C/ObjC and unless -ffreestanding) -Wmaybe-uninitialized -Wmemset-elt-size -Wmemset-transposed-args -Wmisleading-indentation (only for C/C++)
-Wmissing-attributes -Wmissing-braces (only for C/ObjC) -Wmultistatement-macros -Wnarrowing (only for C++) -Wnonnull -Wnonnull-compare -Wopenmp-simd -Wparentheses -Wpointer-sign -Wreorder -Wrestrict -Wreturn-type
-Wsequence-point -Wsign-compare (only in C++) -Wsizeof-pointer-div -Wsizeof-pointer-memaccess -Wstrict-aliasing -Wstrict-overflow=1 -Wstringop-truncation -Wswitch -Wtautological-compare -Wtrigraphs -Wuninitialized
-Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wvolatile-register-var
It's likely that the list may change with time. On the other hand, diagnostic erroring over a version-dependent list may be a bad idea as it may break compilation for users that are likely to use some other versions of the toolchain than developers do (that -Werror is infamous for), so explicitly listing the desired warnings is good for public relations.
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.
I'd like to know what switch you pass to the gcc compiler to turn off unused variable warnings? I'm getting errors out of boost on windows and I do not want to touch the boost code:
C:\boost_1_52_0/boost/system/error_code.hpp: At global scope:
C:\boost_1_52_0/boost/system/error_code.hpp:214:36: error: 'boost::system::posix_category' defined but not used [-Werror=unused-variable]
C:\boost_1_52_0/boost/system/error_code.hpp:215:36: error: 'boost::system::errno_ecat' defined but not used [-Werror=unused-variable]
C:\boost_1_52_0/boost/system/error_code.hpp:216:36: error: 'boost::system::native_ecat' defined but not used [-Werror=unused-variable]
I tried using both -Wunused-value and -Wno-unused-value but neither suppressed the messages above.
What is the right command, here is my compile line:
g++ -g -fno-inline -Wall -Werror -Wextra -Wfloat-equal -Wshadow
-Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Wno-conversion
-Wdisabled-optimization -Wredundant-decls -Wunused-value -Wno-deprecated
-IC:\\boost_1_52_0 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-c -o op.o op.cpp
Perhaps the -Wall overrides my goal?
The -Wno-unused-variable switch usually does the trick. However, that is a very useful warning indeed if you care about these things in your project. It becomes annoying when GCC starts to warn you about things not in your code though.
I would recommend you keeping the warning on, but use -isystem instead of -I for include directories of third-party projects. That flag tells GCC not to warn you about the stuff you have no control over.
For example, instead of -IC:\\boost_1_52_0, say -isystem C:\\boost_1_52_0.
Sometimes you just need to suppress only some warnings and you want to keep other warnings, just to be safe. In your code, you can suppress the warnings for variables and even formal parameters by using GCC's unused attribute. Lets say you have this code snippet:
void func(unsigned number, const int version)
{
unsigned tmp;
std::cout << number << std::endl;
}
There might be a situation, when you need to use this function as a handler - which (imho) is quite common in C++ Boost library. Then you need the second formal parameter version, so the function's signature is the same as the template the handler requires, otherwise the compilation would fail. But you don't really need it in the function itself either...
The solution how to mark variable or the formal parameter to be excluded from warnings is this:
void func(unsigned number, const int version __attribute__((unused)))
{
unsigned tmp __attribute__((unused));
std::cout << number << std::endl;
}
GCC has many other parameters, you can check them in the man pages. This also works for the C programs, not only C++, and I think it can be used in almost every function, not just handlers. Go ahead and try it! ;)
P.S.: Lately I used this to suppress warnings of Boosts' serialization in template like this:
template <typename Archive>
void serialize(Archive &ar, const unsigned int version __attribute__((unused)))
EDIT: Apparently, I didn't answer your question as you needed, drak0sha done it better. It's because I mainly followed the title of the question, my bad. Hopefully, this might help other people, who get here because of that title... :)
If you're using gcc and want to disable the warning for selected code, you can use the #pragma compiler directive:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
( your problematic library includes )
#pragma GCC diagnostic pop
For code you control, you may also use __attribute__((unused)) to instruct the compiler that specific variables are not used.
See man gcc under Warning Options. There you have a whole bunch of unused
Warning Options
... -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wunused-but-set-parameter -Wunused-but-set-variable
If you prefix any of them with no-, it will disable this warning.
Many options have long names starting with -f or with -W---for example, -fmove-loop-invariants, -Wformat and so on. Most of these have both positive and negative forms; the negative form of -ffoo would be -fno-foo. This manual documents only one of these two forms, whichever one is not the default.
More detailed explanation can be found at Options to Request or Suppress Warnings
Use -Wno-unused-variable should work.
You can prefix the variables with '(void)'.
This can be useful if you don't have access to the build framework or you only want to affect a local change in behavior.
IE:
int main()
{
int unused1; //This will print warning
int unused2; //This will not print warning -
// |
(void) unused2; // <----------------------------
}
Output:
$ g++ -Wall test.cc
test.cc: In function ‘int main()’:
test.cc:4:7: warning: unused variable ‘unused1’ [-Wunused-variable]
4 | int unused1;
| ^~~~~~~
How do you disable the unused variable warnings coming out of gcc?
I'm getting errors out of boost on windows and I do not want to touch the boost code...
You visit Boost's Trac and file a bug report against Boost.
Your application is not responsible for clearing library warnings and errors. The library is responsible for clearing its own warnings and errors.
The compiler is already telling you, it's not value but variable. You are looking for -Wno-unused-variable. Also, try g++ --help=warnings to see a list of available options.
-Wall and -Wextra sets the stage in GCC and the subsequent -Wno-unused-variable may not take effect. For example, if you have:
CFLAGS += -std=c99 -pedantic -pedantic-errors -Werror -g0 -Os \
-fno-strict-overflow -fno-strict-aliasing \
-Wall -Wextra \
-pthread \
-Wno-unused-label \
-Wno-unused-function \
-Wno-unused-parameter \
-Wno-unused-variable \
$(INC)
then GCC sees the instruction -Wall -Wextra and seems to ignore -Wno-unused-variable
This can instead look like this below and you get the desired effect of not being stopped in your compile on the unused variable:
CFLAGS += -std=c99 -pedantic -pedantic-errors -Werror -g0 -Os \
-fno-strict-overflow -fno-strict-aliasing \
-pthread \
-Wno-unused-label \
-Wno-unused-function \
$(INC)
There is a good reason it is called a "warning" vs an "error". Failing the compile just because you code is not complete (say you are stubbing the algorithm out) can be defeating.
I recommend neither editing 3rd party code nor suppressing warnings globally. If you are using CMake, you can suppress specific warning only for the external library.
find_package(Boost REQUIRED)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(Boost::boost PUBLIC -Wno-unused-variable)
endif()
...
add_executable(main "main.cpp")
target_link_libraries(main Boost::boost)
See also FindBoost.cmake.
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)
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/