8

Just learned here that -Wsequence-point comiplation flag will pop a warning when the code can invoke UB. I tried it on a statement like

int x = 1;
int y = x+ ++x;

and it worked very nicely. Until now I have compiled with gcc or g++ only using -ansi -pedantic -Wall . Do you have any other helpful flags to make the code more safe and robust?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • `int y = x+ ++x;` -> `int y = 2*x + 1` –  May 14 '17 at 11:20
  • 1
    @InternetAussie This is not what OP's asking, though. – Sergey Kalinichenko May 14 '17 at 11:21
  • @dasblinkenlight I thought that this is UB and because it's UB, it's not 2x+1, at least not by definition. Am I wrong? – CIsForCookies May 14 '17 at 11:22
  • 1
    Did you try reading the documentation of `gcc`, to learn what flags it supports, and which of those would be useful to you? – Algirdas Preidžius May 14 '17 at 11:22
  • `-ansi` does not make your code more safe or more robust, it just makes it use an outdated version of the dialect. Use `-std=` for compliance with a standard of your choosing, for instance `-std=c99` or `-std=c++11`. – spectras May 14 '17 at 11:22
  • @spectras I used _-ansi_ for historical reasons. The new flags are those who I want to make my code robust – CIsForCookies May 14 '17 at 11:23
  • Why don't you have a read through the g++ documentation? Most available warning flags are listed there. – Jesper Juhl May 14 '17 at 11:24
  • @CIsForCookies I think his comment was intended to show you how to rewrite your code with no UB. – Sergey Kalinichenko May 14 '17 at 11:24
  • @dasblinkenlight oh, thanks :) I started doubting my understanding of UB... – CIsForCookies May 14 '17 at 11:24
  • Related: http://stackoverflow.com/a/11720263/3212865 (basically the OP asks how to blanket-enable all warnings and the answer explains why such an option does not exist and would not make sense, and it's up to you to pick what is and isn't an error in your specific project). – spectras May 14 '17 at 11:25
  • @spectras thx! didn't see this one. but still, I wonder what flags are considered good and helpful, and what flags will just overwhelm me with useless data – CIsForCookies May 14 '17 at 11:28
  • For most practical purposes, `-Wall` is more than enough, sometimes `-Wextra` as well. Beyond that, manually picking specific context-dependent warnings _can_ make sense. Consider `-Werror` for dev build as well, if you want to enforce a no-warning policy. – spectras May 14 '17 at 11:31
  • 3
    `-pedantic -Wall -Wextra -Wconversion` helps you, but does not avoid any run-time error, which you probably would never be able to achieve using static code analysis. – alk May 14 '17 at 11:37
  • @alk what do you mean? by telling me _operation on 'x' may be undefined_ I can guess that my run time error was caused by the line touching _x_. – CIsForCookies May 14 '17 at 11:43
  • 2
    These are the compiler flags *I* commonly use with `g++`: `-std=c++14 -O3 -ggdb3 -march=core2 -fno-common -pipe -Werror -Wall -Wextra -Wvla -Wreorder -Wnon-virtual-dtor -Wpacked -Wcast-align -Wenum-compare -Wpointer-arith -Wunused -Wuninitialized -Winit-self -Winvalid-pch -Woverlength-strings -Woverloaded-virtual -Woverflow -Wsequence-point -Wno-unknown-pragmas -Wtrigraphs -finput-charset=UTF-8 -Wpacked-bitfield-compat -Wlogical-op -Wsync-nand -Wstrict-null-sentinel -Wnoexcept` – Jesper Juhl May 14 '17 at 11:46
  • @JesperJuhl that's a nice lid st you've got there! Aren't some of these covered by -Wall or -Wextra? – Jonas May 14 '17 at 11:49
  • @Jonas I don't believe so. Otherwise I wouldn't have added them explicitly ;-) – Jesper Juhl May 14 '17 at 11:51
  • 1
    In general "*run-time error*" refers to an error occurring during .. well: "run-time" of the program, that is not during compilation (or linking time). So if you faced a compilation or linking error, you'd never face a run-time error, as the program would never run, as you faced a compilation or linking error. :-) – alk May 14 '17 at 11:53
  • This surely won't stop the run-time error, but afterwards it may be the best indication I'll have from where to start looking... that's what I meant. And this is only a warning, so I would have a compiler-warning that could turn into a run-time error :) – CIsForCookies May 14 '17 at 11:56
  • 3
    ' +nobugs ' ........:) – ThingyWotsit May 14 '17 at 14:41
  • Some invaluable things are Undefined Behaviour Sanitizer (UBsan) and Address Sanitizer (Asan), available as plugins for GCC and Clang. These can catch types of runtime errors - like buffer/indexing overflows, use of objects before construction or after destruction, etc - that compile-time warnings can't. Why can't they? Well, take your pick: the code is valid as long as it's given valid input, or it's bad but the Standard doesn't mandate a diagnostic, or determining whether an error will occur from the code alone without running it is non-trivial (something-something halting problem something) – underscore_d May 14 '17 at 22:12

1 Answers1

5

As alk summed up, use these flags:

-pedantic -Wall -Wextra -Wconversion


First, I think you don't want to use the -ansi flag, as suggested in Should I use "-ansi" or explicit "-std=..." as compiler flags?

Secondly, -Wextra seems to be quite useful too, as suggested in -Wextra how useful is it really?

Thirdly, -Wconversion seems also useful, as suggested in Can I make GCC warn on passing too-wide types to functions?

Fourthly, -pedantic is also helpul, as suggested in What is the purpose of using -pedantic in GCC/G++ compiler?.

Lastly, enabling -Wall should be fine in this case, so I am pretty doubtful about what you said.

Example with :

Georgioss-MacBook-Pro:~ gsamaras$ cat main.c 
int main(void)
{
    int x = 1;
    int y = x+ ++x;
    return 0;
}
Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
main.c:4:16: warning: unsequenced modification and access to 'x' [-Wunsequenced]
    int y = x+ ++x;
            ~  ^
main.c:4:9: warning: unused variable 'y' [-Wunused-variable]
    int y = x+ ++x;
        ^
2 warnings generated.
Georgioss-MacBook-Pro:~ gsamaras$ gcc -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.38)
Target: x86_64-apple-darwin16.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Example with , same version:

Georgioss-MacBook-Pro:~ gsamaras$ cp main.c main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ g++ -Wall main.cpp 
main.cpp:4:16: warning: unsequenced modification and access to 'x'
      [-Wunsequenced]
    int y = x+ ++x;
            ~  ^
main.cpp:4:9: warning: unused variable 'y' [-Wunused-variable]
    int y = x+ ++x;
        ^
2 warnings generated.

Relevant answer of mine, that Wall saves the day once more with a similar problem.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 5
    Note: `-Wall` does not enable *all* warnings - far from it in fact. Personally I'd always add `-Wextra` as well, at a minimum. But even that still doesn't enable all useful warnings, there are many others that you may want to enable. – Jesper Juhl May 14 '17 at 11:36
  • @JesperJuhl Isn't there something similar to an FAQ concerning the compiler flags from `gcc` ? Seems like a pretty common configuration problem to me.. – clickMe May 14 '17 at 11:40