
What Are Your GCC Flags? - fruneau
http://blog.httrack.com/blog/2014/03/09/what-are-your-gcc-flags/
======
ggreer
The compiler flags for Ag[1] are rather strict these days:

    
    
        -Wall -Wextra -Wformat=2 -Wno-format-nonliteral -Wshadow \
        -Wpointer-arith -Wcast-qual -Wmissing-prototypes -Wno-missing-braces \
        -std=gnu89 -D_GNU_SOURCE -O2
    

Note that -Wall and -Wextra do not enable _all_ warnings. To keep backwards
compatibility, -Wall is basically, "All warnings as of 1990." -Wextra covers a
lot of the newer warnings, but still misses a few.

I also use scan-build[2] for static analysis and clang-format[3] to ensure a
consistent style. It was frustrating when I first enabled all these options,
but the warnings helped me discover bugs that had been lurking for years.

1\.
[https://github.com/ggreer/the_silver_searcher](https://github.com/ggreer/the_silver_searcher)

2\. [http://clang-analyzer.llvm.org/scan-build.html](http://clang-
analyzer.llvm.org/scan-build.html)

3\.
[http://clang.llvm.org/docs/ClangFormat.html](http://clang.llvm.org/docs/ClangFormat.html)

~~~
fafner
-pedantic-errors is also a very useful flag.

-Wstrict-aliasing=1/-Wsuggest-attribute= can give good suggestions during development.

Probably not useful for Ag: But I do a lot of numeric stuff so -Wfloat-equal
is handy for me. For code using float this should be mandatory: -Wdouble-
promotion.

~~~
astrange
gcc's -Wstrict-aliasing is _extremely_ inaccurate. It doesn't run inside the
aliasing machinery; it's just a cheap heuristic inside the C parser. I'd call
it a good example of why you shouldn't strive to fix a warning just because it
happens to exist.

I thought there was a better tool, but can't find the name, hmm.

------
jbk
This is probably an unpopular opinion, but:

    
    
      -Werror
    

is fine on your dev machine, but is a _very_ bad idea in the official build
system, notably if you do it for a library that you want people to use.

As soon as you want to compile with various compilers, systems, use cross-
compilation and other funny things that makes it portable, you're going to
have a bad time.

New compilers will make new warnings, old compilers will make new warnings,
clang and gcc have different warnings. Different distributions with gcc
compiled with different flags will make different warnings too!

And of course, I don't mention libraries (or Mingw) that will always warn
because of warnings inside their headers (I'm looking at you Fribidi).

~~~
xroche
Our experience is that it is actually an excellent sanitary decision. We are
using multiple builders with fixed GCC releases (for RHEL5, RHEL6 etc.
flavors), and yes it means fixing additional warnings when we have to
introduce a new architecture. But I can not count the number of serious issues
we avoided by spotting and investigating warnings.

~~~
Spidler
That's fine and dandy. It's not fine when it's an open source project from
three years and four compiler versions ago that you want to compile, and find
-Werror on every line invocation in a Makefile.

What you build with in-house for development/test-farms is not what you should
ship as default to users of your project.

~~~
pjc50
_find -Werror on every line invocation in a Makefile_

If it's on every line and not kept in one place in $(CFLAGS), you have bigger
problems.

~~~
dllthomas
... not to mention that if it _is_ on every line, stripping it out should take
30 seconds with sed.

------
taspeotis

        -fno-exceptions
        I don’t like C++ exceptions. And we don’t use them where I work
    

And none of your code uses the STL nor third party libraries that might throw
exceptions either, right [1]

[1] "Doing without"
[http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_excepti...](http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html)

~~~
xroche
AFAIK, stl (and beyond that, C++) throw exceptions especially in case of
allocation failure (ie. new or push_back() failing to allocate memory), and
more generally in case of programming errors (out_of_range, bad_cast etc.),
and I am 100% okay with the program aborting() in such situation.

~~~
gurkendoktor
Do you use things like the range-checked `std::vector::at` or `dynamic_cast`
with reference types at all then? If so, do you put a breakpoint on `abort`
during development?

------
cpeterso
Firefox's about:buildconfig page will tell you the compiler flags used to
compile your Firefox:

    
    
      clang++ -Qunused-arguments -Qunused-arguments -Wall -Wpointer-arith -Woverloaded-virtual
      -Werror=return-type -Werror=int-to-pointer-cast -Wtype-limits -Wempty-body
      -Wsign-compare -Wno-invalid-offsetof -Wno-c++0x-extensions -Wno-extended-offsetof
      -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-mismatched-tags
      -Wno-error=uninitialized -Wno-error=deprecated-declarations -isysroot /Developer/
      SDKs/MacOSX10.6.sdk -fno-exceptions -fno-strict-aliasing -fno-rtti -ffunction-sections
      -fdata-sections -fno-exceptions -fno-math-errno -std=gnu++0x -pthread -DNO_X11 -pipe
      -DNDEBUG -DTRIMMED -g -O3 -fno-omit-frame-pointer -Qunused-arguments

------
geocar
I start with:

    
    
        -Os
    

I really don't like the stack protector. It adds a lot of space to
executables, so I turn it off:

    
    
        -fno-stack-protector
    

Arthur told me about:

    
    
        -fno-asynchronous-unwind-tables
    

which seems to save a lot of space. I don't know exactly what it does, but the
documentation suggests it does something with debugging, however `-s` doesn't
remove it so I have this here.

I often work without glibc (don't need it) but I like gcc's builtins so I
have:

    
    
        -Dabort=__builtin_trap -Dmemcpy=__builtin_memcpy -Dmemset=__builtin_memset -minline-all-stringops -msse2 -ffreestanding -nostdlib -fno-builtin
    

which seems to do the trick. I don't think all of these are necessary on all
versions of GCC but I keep running into versions that complain about something
so this line keeps getting longer. On x86 I additionally use:

    
    
        -mregparm=3
    

since it saves a lot of space and helps benchmarks.

~~~
astrange
For any benefit you'd get from -mregparm, you'd get a much better one by
switching to amd64 already! Or are you having to support Windows?

~~~
geocar
X32 isn't quite everywhere yet, and the larger words add a lot of space. I try
not to use them if I don't need it, but I'm definitely looking forward to X32.

------
byuu
I go with:

g++ -std=c++11 -O3 -fomit-frame-pointer -fwrapv

fwrapv turns off some "bad" optimizations around signed integer overflow (too
likely to cause harm, too unlikely to make a significant performance
difference in most cases.)

I also use a lot of asserts to verify the behaviors too costly to not rely on
for what I do (low-level CPU simulation and such): linear A-Z, 8-bit char,
twos-complement math, arithmetic shift right on signed types, int > 16-bits,
etc.

I'm sure my views won't be popular, and I'm not encouraging anyone to follow
what I do, just stating my preferences.

I have a love-hate relationship with warnings. My problem is that you end up
with false positives that amount more to "how the compiler authors think you
should style your code" instead of reporting legitimate issues. When combined
with -Werror, it's a show-stopper for no reason.

Clang is much more naggy than GCC. For instance, I frequently switch on
boolean variables. Clang doesn't even have a "-Wno-" intrinsic I can push to
temporarily disable this.

But there's nothing at all illegal about switching on a boolean value. It
annoys me that I need to go back and add unnecessary explicit casting in 100
places in my project to keep Clang quiet, or face real warnings being lost in
a sea of false warnings every single time I build my project. I know you can
do if(var) { ... } else { ... } ... I don't care. I want to use switch, and I
legally am allowed to. Don't bug me about it, Clang.

It also really hates empty statements, eg while(do_something()); warns that
there's nothing inside the while loop. I know, the important part is
do_something() and its return value. Same for if's, for's, etc. It wants me to
put the ; on its own line. Uh, no. That's not my style at all.

And at the same time ... Clang caught a few bugs that GCC overlooked.

So, my current strategy is to build WIPs with GCC at default warnings and
Clang with the sledgehammer of -w; and then before any releases, build with
maximum warnings on both compilers and analyze each one for legitimate issues.
I also run with valgrind to catch many other types of issues, like using
uninitialized variables and memory leaks.

~~~
DannyBee
1\. -fomit-frame-pointer is implied by O3 on most platforms now

2\. "too likely to cause harm, too unlikely to make a significant performance
difference in most cases."

Please define "most cases". Without this, GCC will have significant trouble
being able to derive the bounds of most loops, and in turn, will not be able
to vectorize, unroll, peel, split, etc.

Saying "unlikely to make a significant performance different in most cases" is
probably very very wrong for most people. The last benchmarks I saw across a
wide variety of apps showed the perf difference was 10% in most cases, and a
_lot_ more in others.

~~~
byuu
1\. that's good to know. I'm all for shortening my cflags line since I don't
squelch my Makefile rules.

2\. I always get bitten when I try and generalize. I tested this in all of my
software, and was not able to detect any performance difference with or
without -fwrapv (that is to say, < 1% difference, too small of a difference to
make any conclusions.)

I know you can create extreme edge cases where there's a huge difference, just
as you can probably make up one that's slower without -fwrapv if you really
wanted to.

But yeah, maybe I just don't write code that lends itself to benefiting
heavily from these types of assumptions. I also tend to not really rely on
signed integer overflow following twos-complement. But all the same, I will
take well-defined behavior over the crazy stuff GCC can produce any day, even
at the cost of a bit of performance. Of course, going all the way to -O0 is
way too extreme. So a case where I see no perceptible performance impact and
gain defined behavior? Win-win.

~~~
DannyBee
2\. You must not write software very amenable.

Fun fact btw: GCC and LLVM are the only compilers I know of to assume loops
can overflow _at all_ when optimizations are on.

Compilers like XLC will actually even assume _unsigned_ loop induction
variables will not ovefrlow at O3, unless you give them special flags.

:)

~~~
klodolph
> Compilers like XLC will actually even assume unsigned loop induction
> variables will not ovefrlow at O3

That's not exactly fair. The C standard guarantees that unsigned variables
will overflow by wrapping, so if the compiler assumes such a loop won't
terminate, it is not conformant.

~~~
DannyBee
That's exactly the point: they cheat, because it makes code faster except in
the small percent of code it breaks.

Let us all now bow our heads to the almighty SPEC gods ...

------
sanxiyn
The article does not mention optimization, but standard optimization levels
(-O1, -O2, -O3) are not chosen optimally at all. See
[http://dl.acm.org/citation.cfm?id=1356080](http://dl.acm.org/citation.cfm?id=1356080)

For tuning GCC flags for a particular application, see
[http://opentuner.org/](http://opentuner.org/)

~~~
DannyBee
" are not chosen optimally at all"

Optimally is kind of a non-sensical term for this. There is no optimality to
be found here in any mathematical sense. Even COLE does not generate optimal,
it finds something mildly reasonable.

However, the main problem with things like COLE, is that they mostly discover
phase ordering issues or latent optimization bugs. Those are bugs and problems
that should be fixed.

Most of phase ordering is decided by design and architecture, ie "we want it
to work a certain way for certain reasons". To the degree it doesn't work best
that way, it's usually a problem to be fixed, not a fundamental issue that
COLE has discovered.

------
tenfingers
"-Winit-self" actually disables the common "var x = x" idiom which is used to
silence "uninitialized variable" warnings.

Personally I consider "-Werror" stupid. Warnings are designed to help and be
reviewed, but aiming at "100% warning free" code should not be an "aim". For
instance, I'd rather have "unitialized warnings" than use "i = i", which you
know, might actually be correct code if "i" was available in scope and you
want an additional copy that you can modify (nester for loops come to mind).

I sometimes leave warnings when silencing them "uglifies" the code.

"-fvisibility=hidden" is not so easy to leave on all the time when building
software build by others. What I use is mostly "-fvisibility-inlines-hidden"
in C++ code, even when building OSS projects, for which I never had a problem
so far (in c++ inlines _are_ expected to have hidden visibility).

I also use "-march=native -flto=jobserver" and "-fwhole-program" (when
linking) when I'm targetting my own hardware.

I also noticed that gcc now supports "-Og" to build optimized programs without
impact on debugging, for which I had a very long command line before. "-Og
-g3" gives pretty decent performance and optimal debugging, which is ideal for
beta-testing programs.

gcc supports a pretty infinite list of command line switches. Actually, if you
know what you are doing, you can optimize a program so well it's pretty much
impossible to beat even by hand-crafting assembly. I know I tried several
times, before realizing I could move a function to a separate object and
supply a different set of optimization flags tuned just for that function.

For instance, "-Ofast" is actually safe most of the time for system utilities
(and most other OSS software), and gives quite a boost for programs working
with floats (most image-resizing loops and the like). Very few programs
actually rely on exact IEEE arithmetic. Though I never use it, since finding
issues might be _very_ hard.

~~~
pilif
_> "-Winit-self" actually disables the common "var x = x" idiom which is used
to silence "uninitialized variable" warnings._

so now we have a flag that disables a hack in code that is used to disable a
warning caused by another flag. This is about as ridiculous to my (untrained
in C) mind as it is to have -Wall not in-fact turn on all warnings.

~~~
tenfingers
The number of warnings that GCC can generate can cover some very speculative
grounds, which are sometimes legitimate code. In fact many C idioms that were
considered commonplace are now "warnings" because of the subtle semantics.

Take assignment/evaluation in a condition:

    
    
      if(a = [expr])
    

was not so frowned upon before, because it was sort of implicit that "a" was
also needed in the nested block that followed. Now it's a warning without a
double parenthesis, because it's also common the typo of using = instead of
==.

The list goes on and on. In fact, the level of diagnostics that you get in C
is pretty bit, and probably one of the best in class compared to any other
language thanks to the maturity of the toolchain.

------
fexl
I tend to go with:

    
    
      gcc -c -Wall -Werror -std=c99 -pedantic -O3
    

I use -std=c99 because I use these two features of C:

1\. Mixed declarations and code, e.g.

    
    
      double x = 4.8 * 5.3;
      printf("x = %.15g\n", x);
      double y = 8.7 * x;
      printf("y = %.15g\n", y);
    

2\. Flexible array members, e.g. for my safe string operations:

    
    
      struct str 
          {       
          long len;
          char data[];
          };
    

If I were to use -ansi (same as -std=c89), instead of -std=c99, then -pedantic
would give me these errors:

    
    
      error: ISO C90 forbids mixed declarations and code [-Werror=edantic]
    
      error: ISO C90 does not support flexible array members [-Werror=edantic]
    

(By the way, I have no idea why the error message omits the "p" from pedantic
there. That doesn't smell right. I hope the gcc people fix that.)

I use -O3 for optimization, and I chose level 3 because that enables -finline-
functions. I typically avoid macros, even for simple one-liners like this:

    
    
      /* Increment the reference count. */
      void hold(value f)
          {
          f->N++;
          }
    

With -finline-functions enabled (via -O3), I can see that function being
expanded inline, by examining the assembly output of gcc -S -O3.

~~~
sanxiyn
Why don't you use -O2 -finline-functions then?

~~~
fexl
Good question. I go with -O3 because it does even more optimizations, but to
be quite candid I really don't know what impact -fpredictive-commoning,
-ftree-vectorize, and others have on my resulting machine code, if any.

I did a quick experiment, compiling one C file with -O2 -finline-functions and
another with -O3, using the -S flag so I could see the assembler output.

The only difference I saw was this:

    
    
      .comm	free_list,8,8
    

Versus this:

    
    
      .comm	free_list,8,16
    

Who knows. I guess I'm really using -O3 because "3 is more than 2" \-- in
other words, "Ours goes to 11!" :)

~~~
DannyBee
predictive commoning is a loop optimization that commons cross-loop
redundancies.

It is basically CSE "around loops". You can generalize it to subsume loop
store motion and strength reduction, but most compilers (including GCC) don't
bother.

For example, it transforms

    
    
      for (int i = 0; i < 50; i++)
        a[i+2] = a[i] + a[i+1]
    

into

    
    
      p0 = a[0]
      p1 = a[1]
      for (int i = 0; i < 50; i++) {
         a[i+2]=p2=p0+p1;
         p0=p1;
         p1=p2;
      }
    

Eliminating a whole ton of loads and stores.

It's been a while since i looked at GCC's implementation, but it did pretty
well in the past (whether you can do commoning depends on your ability to
identify and group sequences, etc)

-ftree-vectorize does the obvious thing (turn on vectorization). How effective it is depends on a lot of factors.

------
unwind
Very surprising to not see the -std option to actually clarify which language
standard is being used. Perhaps that isn't as important in C++ as it is in C.

~~~
cliveowen
Is there a way to specify C89 but use the C99 style comments (i.e. //)?

~~~
mpyne
I believe that -std=gnu89 should give you C89 with that particular extension
(and some others).

------
edwintorok
The use of 'bytecode' is strange when refering to gcc and C code, perhaps
'object code', or executable would've been better. Bytecode is usually
reserved for things like the JVM, or other cases where an interpreter/JIT is
needed to run your code.

~~~
npsimons
Couple of points:

\- The GNU Compiler Collection can compile Java, as well as other languages
with "bytecode".

\- GCC actually has a native intermediate language, it's just not very well
advertised.

~~~
rnovak
In real world projects, I have never seen a GNU Compiler not called
explicitly, and in fact this article is advising to be extra explicit in
compiler flags, so referring to any output code, especially -o with a .o
extension, as 'bytecode', is inherently incorrect, regardless of whatever
"intermediate" language GCC actually uses, unless you're outputting that
intermediate code.

------
edwintorok
Since it mentions the Debian hardening wiki, -D_FORTIFY_SOURCE=2 is useful
too. I have mixed feelings about -Wall, sometimes it produces useful warnings,
other times its just too many false positives. I prefer to turn on all
warnings, and then explicitly turn off warnings I don't want to see (-Wno-
pointer-sign for example), as new compiler versions may add new warnings that
could turn out to be useful.

------
jamesdutc
I go overkill on the debugger flags:

    
    
        -g -g3 -ggdb -gdwarf-4
    

Being able to debug C-macros has improved my life!

    
    
        (gdb) info macro Py_TYPE 
        Defined at Include/object.h:117
          included at Include/pytime.h:6
          included at Include/Python.h:65
          included at Parser/myreadline.c:12
        #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)

~~~
xroche
Isn't -g3 sufficient ? ("Level 3 includes extra information, such as all the
macro definitions present in the program. Some debuggers support macro
expansion when you use -g3."). [Note: I found -g3 to be extremely costly, but
I guess everything has a cost...]

~~~
sltkr
Costly in what sense? Compilation time? Binary size?

~~~
xroche
Binary size! (in my base separated .dbg files were HUGE, compared to the .so
files). I don't think it has any impact on performances however (especially as
the debug information is put in a separate ELF section, either in a separate
file, or mapped but "cold" [ie. not live in memory as the runtime does not
touch it])

------
bjerun

        -Wl,-O1 Did you know that you also have an optimization flag for the linker ? Now you know!
    

Ages ago the linker on SUN used to compile templates. What is GCC doing/using
this flag for?

~~~
pja
See this LWN article:
[http://lwn.net/Articles/192624/](http://lwn.net/Articles/192624/)

~~~
bjerun
So it is not really optimizing the code - more like optimizing the symbol
table?

~~~
pja
Yes, looks like it. The default symbol lookup can be really slow in some
situations, especially in large C++ projects with can contain many symbols
that share a long common prefix thanks to C++ name mangling.

------
mahkoh
Not gcc but clang:

    
    
        -Weverything -Werror
    

That's how I roll.

~~~
masklinn
The GCC equivalent being, I believe,

    
    
        -Wall -Wextra -Werror

~~~
mahkoh
GCC has no equivalent of -Weverything. -Wall and -Wextra leave lots of
warnings disabled.

------
npsimons
You mean you people don't have all warnings turned on, with -Werror as well?
Here, how about I list the ones my project _doesn 't_ use, and why:

-Waggregate-return - everything returns an aggregate in C++, and that's not necessarily a bad thing.

-Wlong-long - We use long longs.

-Wmissing-declarations - We don't need to declare every internal function before we use it.

-Wmissing-include-dirs - Sadly necessary; gcc seems to include some on its own.

-Wpadded - Everything's padded.

-Wsystem-headers - I only wish I was in a position where this could be useful :)

As K&R would say, let the machine do the dirty work. If a warning check
exists, there's probably a good reason for it.

------
rescrv
We use quite a few flags to issue warnings for our code[1]. The linked
autoconf macro will detect whether or not the flags are supported on the
detected compiler, and automatically add the flags to the build. It works for
clang, gcc, g++, and helps us spot errors that would otherwise be hard to
detect and fix.

[1]
[https://github.com/rescrv/HyperDex/blob/master/m4/anal_warni...](https://github.com/rescrv/HyperDex/blob/master/m4/anal_warnings.m4)

------
pjmlp
-Wall -Wextra -Wpedantic -Werror -std=c++11

~~~
ninjakeyboard
-Westsieeeede

~~~
logicchains
-WetPsyyyyyyy

~~~
logicchains
Just for reference, the parent is a reference to a lyric from Psy's (the
Korean artist responsible for Gangnam Style) song 'Gentleman', wherein he
parodies the expression 'Westsiiiiiide' (not that this necessarily makes it
any funnier).

------
aDevilInMe
-ansi -pedantic

Because it makes things a lot easier when writing cross platform code besides
when using MSC, as that is the ugly sister.

------
sudokode
Mine are usually some variation of the following, but I find that I can't
always get away with it on projects that are not done solely by myself due to
the strictness :(

    
    
        -Wall -Wextra -pedantic-errors -funroll-loops.info -Weffc++ -Wunreachable-code -fno-exceptions -03 -Werror

------
dllthomas
I recommend -Wswitch-default and -Wswitch-enum. Without these, you're stuck
choosing between foregoing safety when a bug causes an enum to take an
unexpected value, and foregoing safety when you add a new value to an enum
that needs to be handled in many places.

~~~
psquid
Oh hey, that's pretty nice! I'm a big fan of how the functional languages I've
gone further than dabbling in are very pushy about covering all cases for
pattern matches (basically switch on steroids), even if sometimes the correct
answer is to just throw in a catch-all.

Mostly because it forces you upfront to make sure you're considering every
case, and it looks like those warnings ought to give me the same kind of
nagging with C and enums.

------
cammsaul
Most of these are clang specific but I tend to do something like

-pipe

-std=c++11

-gfull # generate correct debugging symbols for dead code stripping

-stdlib=libc++

-Ofast # fast, aggressive optimizations (clang-specific)

-fvectorize # enable loop autovectorizer

-fdiagnostics-show-template-tree (clang: print C++ template error as a tree instead of on a single line)

-Weverything # clang specific: enable every single warning

-Werror

-Wfatal-errors # die after the first error encountered

-Wno-c++98-compat

-Wno-c++98-compat-pedantic

-Wno-global-constructors

-Wno-exit-time-destructors

-ffast-math # enable some floating point optimizations that break IEEE754 compliance but usually work

-funroll-loops # enable loop unrolling

-fstrict-aliasing # make more aggressive assumptions about whether pointers can point to the same objects

-fatal_warnings # treat linker warnings as fatal

-flto # enable link-time optimization

-dead_strip # enable dead code stripping

-Wno-error=deprecated # like being able to put __attribute((deprecated)) in code as a note to self

-Wno-error=#warnings # same thing goes for #warnings

------
__david__
I generally turn everything on and then use

    
    
        -Wno-parentheses
    

because that one _really_ rubs me the wrong way.

Also, speaking of flags, I'm personally in love with -MMD. It makes dependency
generation pretty painless.

------
vijucat

      -Larry -Wall
    

Saw that in the perl6 build long ago :-)

------
userbinator

        -Os
    

Then if any functions are a bottleneck, compile them with function-specific O2
or O3.

~~~
nly
-Os doesn't always produce smaller code than -O2

~~~
joveian
It also unfortunately breaks a lot of things and exposes more gcc bugs than
the commonly used options. I wish "make the output code as small as possible"
was the usual thing compilers tried to do.

------
AsmMAn
I don't do GCC anymore but clang instead of, at all. Does -ansi -pedantic
-fwritable-strings -Weverything -Wno-missing-noreturn -Wno-padded -Wno-nested-
anon-types -Wno-switch-enum count?

------
marinhero
-Wall -Werror -Wextra -ansi -pedantic As a student I think this are very useful flags, it keeps the code in good shape and prevents common pitfalls. Of course sometimes I have to use -g3 ;)

------
danellis
Oh, nice. -fvisibility=internal is what I was about to go looking for. I want
to write an operating system as a static library, so I don't want its internal
symbols visible.

------
gtani
you can learn a lot at the spec.org benchmark site (both c/C++ and java apps),
which many of the heavyweights (Hitachi, Cisco, Intel) use to provide detailed
looks at hardware and software tweaks e.g.
[http://spec.org/cpu2006/results/res2013q4/cpu2006-20130923-2...](http://spec.org/cpu2006/results/res2013q4/cpu2006-20130923-26460.html)

------
shanwang
If you have -Wall, -Winit-self doesn't do anything, just tested with gcc 4.2
on redhat 6, you still have the uninitialized warning

------
tehwalrus
whatever they were to build python[1].

[1] [https://github.com/joe-jordan/complicated_build](https://github.com/joe-
jordan/complicated_build)

------
weishigoname
option -O2 -Wall -std=XXX is very helpful for me

------
gwu78
-static

------
greatsuccess
here's mine:

-u -r -s -t -u -p -i -d

------
chloratine
That's a very easy question. It's usually made of green, white, red and black.
Details here: [http://ncusar.org/email_graphics/images/gcc-
flags.gif](http://ncusar.org/email_graphics/images/gcc-flags.gif)

