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.
Related
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>:
...
>
)
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.
I've been looking around and I can only seem to find the option to omit the frame pointer.
Here are the compile flags that I'm using right now.
-Wall -Wextra -Wconversion -Wctor-dtor-privacy -Wnon-virtual-dtor -Wold-style-cast -g
Can someone tell me how to enable the frame pointer?
Note I'm using g++ version 4.6.6 on RHEL 6.2
Any optimization level (-O, -O2, -O3), enable -fomit-frame-pointer, but you can revert it with -fno-omit-frame-pointer. You can find more details here: http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
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.
-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.