This page collects Frequently Asked Questions in gcc-help mailing list. There is also a more official (but seldom updated) FAQ for GCC and there is a FAQ for Wconversion and conversion warnings

Why do I get a warning when passing a pointer to an array to a function that expects a pointer to a constant array?

[ Permalink ]

Short answer: This is how C works.

Long answer: This happens for code like:

typedef int array[3];
void foo (const array* p);
void bar(array *c) {

You get:

test.c:8: warning: passing argument 1 of ‘foo’ from incompatible pointer type [-Wincompatible-pointer-types]

You are passing int (*)[3] to const int (*)[3], which is not correct according to the C standard. You can disable the warning with -Wno-incompatible-pointer-types. Starting with version 5, gcc only warns about this when using -Wpedantic'.

Is -O1 (-O2,-O3 or -Os) equivalent to individual -foptimization options?

[ Permalink ]

No. First, individual optimization options (-f*) do not enable optimization, an option -Os or -Ox with x > 0 is required. Second, the -Ox flags enable many optimizations that are not controlled by any individual -f* option. There are no plans to add individual options for controlling all these optimizations.

What specific flags are enabled by -O1 (-O2, -O3 or -Os)?

[ Permalink ]

This varies by platform and GCC version. GCC will tell you what flags it enables by doing this:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s

Why does my ./configure and make fail?

[ Permalink ]

GCC tends to have problems when configured in the same directory as the GCC source code, or in any subdirectory therein, as stated in the Configuration page in the install documentation.

What should be done is to untar the GCC source code, then in the source directory run ./contrib/download_prerequisites (which will download and untar MPFR, MPC and GMP in the same GCC source code directory as per the prerequisites documentation.)

Then make a peer gcc-build directory next to the GCC source code directory.

Then run the configure either by fully qualified path or by relative path while in the the gcc-build current working directory.

A makefile will be created in the gcc-build directory. Run make in the gcc-build current working directory to begin the build of GCC.

(If building a cross-compiler, there are several more prerequisite steps involved.)

The above steps are atypical of most GNU packages. GCC builds in multiple passes; which, if done within the GCC source code directory, befouls the source code directory itself. Hence the need to build in a separate build directory.

MPFR, MPC and GMP are used by GCC itself, internally. GCC does not use those facilities in the code compiled by GCC.

Configuration fails with ''configure: error: cannot compute suffix of object files: cannot compile''. What is the problem?

[ Permalink ]

Like any of the GNU projects, GCC is using the GNU autotools to commonly configure the compilation for the specifics of the build system. The configure script thereby uses small test programs - usually called conftest.c - to test if certain functions and/or features are available. If the compilation of such a test program fails, you'll see an error message like:

checking for suffix of object files... configure: error: in `/home/manu/gcc/gcc/i686-pc-linux-gnu/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
See `config.log' for more details.
make[2]: *** [configure-stage1-target-libgcc] Error 1
make[2]: Leaving directory `/home/manu/gcc/gcc'

This error message is quite misleading and frequently the problem has nothing to do with the message. You have to check the file 'config.log' in the directory where the error occurred. In the example above, you would have to check the 'config.log' file in the directory '/home/manu/gcc/gcc/i686-pc-linux-gnu/libgcc'. There might be several test programs that failed during the configuration, but some of these failures are non-critical. Check for the last error entry in the file.

Common causes for this error message are:

Build fails with ''fatal error: gnu/stubs-32.h: No such file or directory''. What is the problem?

[ Permalink ]

On x86_64 GNU/Linux the default behaviour is to build GCC so it supports compiling both 64-bit and 32-bit objects. To compile 32-bit versions of the runtime libraries you need to have the 32-bit glibc headers installed, which are not installed by default on many GNU/Linux distributions.

To fix the problem either install the 32-bit glibc package (which your system's package manager probably calls something like libc6-dev, libc6-dev-i386, glibc-devel.i686 or glibc-devel-32bit) or disable 32-bit support by configuring GCC with --disable-multilib.

The compiler optimized away my overflow checks! What is going on?

[ Permalink ]

Signed overflow is undefined behaviour according to the C standard. It should never happen. If it happens, it is an error in the program. So you should check for overflow before it can happen, not afterwards. As a workaround, the options -fwrapv or -fno-strict-overflow make gcc behave as if signed integer overflow were defined but they will probably make your code run slower.

GCC attempts to diagnose some undefined behaviours, but this is not possible in all cases. Try options -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow. If GCC missed a warning and you know how to implement it, please send even a rough working patch. Otherwise, just assume there is no easy/efficient way to diagnose that particular case.

What is the status of adding the UTF-8 support for identifier names in GCC?

[ Permalink ]

Since GCC 5, the option -fextended-identifiers is enabled by default for C++, and for C99 and later C versions. This only supports UCNs in identifiers, not extended characters represented other than with UCNs. Support for actual UTF-8 in identifiers is still pending (please contribute!)

So how do you express UCN in the code? By using the \uNNNN or \UNNNNNNNN syntax. For example, pipe your code through

perl -pe 'BEGIN { binmode STDIN, ":utf8"; } s/(.)/ord($1) < 128 ? $1 : sprintf("\\U%08x", ord($1))/ge;'

or something similar to convert extended characters to UCNs.

A longer example:

//file UCN_almost_UTF8_identifiers.cpp

int main()
       double Δ_电场velocity(0);
       std::cout << "Δ_v电场elocity= " << Δ_电场velocity << "\n";

// with following makefile:

       /home/janek/bin/ UCN_almost_UTF8_identifiers.cpp
       g++ -fextended-identifiers -o UCN_almost_UTF8_identifiers /tmp/UCN_almost_UTF8_identifiers.cpp

//and the helper script:

cat $1 | perl -pe 'BEGIN { binmode STDIN, ":utf8"; } s/(.)/ord($1) < 128 ? $1 : sprintf("\\U%08x", ord($1))/ge;' > /tmp/$1

GCC's default include search paths

[ Permalink ]

When searching for include headers, the GCC C compiler (cc1) and C++ compiler (cc1cplus) look into some default directories after searching the directories specified on the command-line, e.g. via the -I flag. To display the default search directories of GCC, try:

echo "" | gcc -o /tmp/tmp.o -v -x c -

echo "" | g++ -o /tmp/tmp.o -v -x c++ -


touch /tmp/empty.c
gcc -c -o /tmp/tmp.o -v /tmp/empty.c

touch /tmp/empty.cpp
g++ -c -o /tmp/tmp.o -v /tmp/empty.cpp

The continuation character is ignored by C/C++ preprocessor

[ Permalink ]

You have code like:

label: \

and after running gcc -E you expect

label:  fn (args);

but you get:

 fn (args);

First, gcc -E is a C/C++ preprocessor, not a general-purpose text processor. The semantics of both outputs are the same; however, the former better maintains the location information for the rest of the compiler.

Second, you can use gcc -E -P, then it doesn't print  # <lineno> <file>  lines and puts the label and fn on the same line (as without the line notes, locations aren't preserved anyway).

However, if there is no whitespace to separate the two lines, as in:

int foo(){\
return 0;}

GCC will put the return on the same line as the {, and you get:

int foo(){return

return is put on the first line because it appeared immediately after { in the input (line splicings do not count), and GCC does not insert whitespace where there was none. Extra whitespace does get inserted before 0 so that it appears in the same column as in the input.

Is there a list of GCC diagnostics/messages?

[ Permalink ]

There is no list of gcc messages in the documentation. Such a list would rapidly get out of date. The only way to maintain such a list would be to have a dedicated volunteer willing and able to create the list in the first place and keep it up to date as the compiler changes.

Of course, ideally the message should be clear without reference to the documentation. When you find an error message to be particularly perplexing, I would strongly encourage you to file a bug report or send a patch, especially if you can think of a way to phrase it better.

There is an unofficial, incomplete and probably out-of-date list of GCC diagnostics. Feel free to contribute to it.

GCOV/GCC data files are not created

[ Permalink ]

When compiling your projects to determine coverage information (either by using the options [-fprofile-arcs and -ftest-coverage] or [--coverage]) of your programs, you might experience that GCOV data files (newer versions: .gcda, older versions: .da) are not created in your current working directory. This is due to the fact that GCC embeds the absolute file name of the final data file into the executable. The consequence is that the data files are created in the directory where your application was built, but NOT in the directory where you possibly run the application. Here's a short example using a newer version of GCC (4.5.0):

[root@catania test]# pwd
[root@catania test]# gcc test.c --coverage -o test.exe
[root@catania test]# strings test.exe | grep gcda

In order to change the target directory where libgcov will store the data files, please look at the environment variables described in the section ''Data File Relocation to Support Cross-Profiling'' of the manual.

I see many warnings when building GCC, should I report them?

[ Permalink ]

Short answer: No.

Long answer: You are probably seeing warnings like:

warning: unknown conversion type character 'E' in format

GCC is built in stages. The first stage uses the system compiler, which may have bugs or not handle special conversion type characters handled by the GCC version being built (this particular warning). Therefore, warnings produced by the system compiler are often wrong. Please, do not report them.

When building a cross compiler (so not bootstrapped), having the warnings, even if noisy, is a lot better than hiding them all. And if a file fails to build in stage 1 of a bootstrap, having the warnings, again even if noisy, helps identify the problem more than if only actual error messages are present. More generally, warnings from a changed file in stage 1 of a bootstrap give you an early indication of possible problems with a patch without needing to wait for a later stage for a more precise set.

I found a bug in GCC 4.2 for Darwin (Apple System), should I report it?

[ Permalink ]

Short answer: Please no.

Long answer: GCC 4.2 was first released in 2007, and it is not supported any more by the GCC team. Many new versions have been released since them, with significant improvements and thousands of bugfixes. Please, update to a more recent version. Moreover, Apple's version of GCC 4.2 has major modifications that were never shared with the rest of the GCC community, so it is very possible that your bug cannot be reproduced (and, hence, fixed) by GCC developers. You should try to report the bug directly to Apple and/or install a newer version of GCC by yourself.

My program invokes undefined behaviour but...

[ Permalink ]

Sorry, if your program invokes undefined behaviour, then anything can happen. Please:

Neither GCC bugzilla, nor GCC mailing lists are a forum appropriate to debate the above issues. Quoting Steve Summit (maintainer of the C FAQ): "Perhaps we could, but not under the current Standard. [...] But the C Standard is under revision: perhaps, if this is important enough to you, you can convince the committee [...]. Good luck."

My copy constructor doesn't run!

[ Permalink ]

The C++ standard allows compilers to avoid making copies of objects in certain situations, even if copying has observable side effects. This is known as copy elision and is important for performance of C++ programs.

This means C++ programs that rely on side effects of copy constructors will behave differently with different compilers, so it is important not to rely on those side effects for correctness. The G++ option -fno-elide-constructors disables copy elision, but should generally only be used for experimentation to understand the effects of copy elision.

The warning "unrecognized command-line option" is not given for -Wno-foo

[ Permalink ]

Since GCC 4.4, and as explained in the GCC manual: when an unrecognized warning option is requested (-Wunknown-warning), GCC emits a diagnostic stating that the option is not recognized. However, if the -Wno- form is used, the behavior is slightly different: no diagnostic is produced for -Wno-unknown-warning unless other diagnostics are being produced. This allows the use of new -Wno- options with old compilers, but if something goes wrong, the compiler warns that an unrecognized option is present. (See PR28322 for the history of this change)

This might break configure tests that check for -Wno-foo options. The solution is to either test for the positive form (-Wfoo) or test using a testcase that triggers some other warning:

$ gcc -c  -Wno-tautological-compare <<EOF
> const char x = 600;
<stdin>:1:16: warning: overflow in implicit constant conversion [-Woverflow]
cc1: warning: unrecognized command line option "-Wno-tautological-compare"

Why GCC does not warn for mismatch between struct and class (-Wmismatched-tags) ?

[ Permalink ]

Because it is not a bug, hence the warning is just noise. This is a really stupid warning that only exists because the MS compiler has (or had) a bug that treats 'struct' and 'class' differently. GCC (and Clang) correctly implement the C++ standard which says it doesn't matter.

Why floating-point results change with optimization levels or different compiler versions or different target architectures?

[ Permalink ]

See: See also:

In short, the most robust solution (as of GCC 5.0, this is only available in C) is to use -fexcess-precision=standard. For other languages, you may try -ffloat-store or less aggressive optimization levels (like -Og), however, none of those are guaranteed to work and they will probably pessimize your code unnecessarily.

Floating-point results may still depend on the optimization level and target architecture in some cases that are allowed by the ISO C standard. For instance, different sets of instructions may be used for code such as x*y+z depending on the target architecture and the optimization level, and this difference may change the results.

__attribute__((__optimize__(X))) does not work as expected

[ Permalink ]

Currently (2015), this attribute is known to have several critical bugs (PR37565, PR63401, PR60580, PR50782). Using it may produce not effect at all or lead to wrong-code.

Quoting one GCC maintainer: "I consider the optimize attribute code seriously broken and unmaintained (but sometimes useful for debugging - and only that)." source

Unfortunately, the people who added it are either not working on GCC anymore or not interested in fixing it. Do not try to guess how it is supposed to work by trial-and-error. There is not a list of options that are safe to use or known to be broken. Bug reports about the optimize attribute being broken will probably be closed as WONTFIX (59262), thus it is not worth to open new ones. If it works for you for a given version of GCC, it doesn't mean it will work on a different machine or a different version.

The only realistic choices are to not use it, to use it and accept its brokenness (current or future one, since it is unmaintained), or join GCC and fix it (perhaps motivating other people along the way to join your effort).

None: FAQ (last edited 2015-04-29 17:07:45 by ManuelLopezIbanez)