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

Contents

  1. Configure, Install, Build
    1. Why does my ./configure and make fail?
    2. Configuration fails with ''configure: error: cannot compute suffix of object files: cannot compile''. What is the problem?
    3. Build fails with ''fatal error: gnu/stubs-32.h: No such file or directory''. What is the problem?
    4. I see many warnings when building GCC, should I report them?
    5. configure.ac:4: error: Please use exactly Autoconf 2.64 instead of 2.69
  2. C/C++
    1. Why do I get a warning when passing a pointer to an array to a function that expects a pointer to a constant array?
    2. What is the status of adding the UTF-8 support for identifier names in GCC?
    3. GCC's default include search paths
    4. The continuation character is ignored by C/C++ preprocessor
    5. My program invokes undefined behaviour but...
    6. My copy constructor doesn't run!
    7. Why GCC does not warn for mismatch between struct and class (-Wmismatched-tags) ?
    8. Why does GCC not give an error for some narrowing conversions within list-initializations as required by C++11 (-Wnarrowing) ?
  3. Optimization
    1. Is -O1 (-O2,-O3, -Os or -Og) equivalent to individual -foptimization options?
    2. What specific flags are enabled by -O1 (-O2, -O3, -Os or -Og)?
    3. The compiler optimized away my overflow checks! What is going on?
    4. Why floating-point results change with optimization levels or different compiler versions or different target architectures?
    5. __attribute__((__optimize__(X))) does not work as expected
    6. GCC miscompiles my code when optimizing, how to find whether it is a bug in my code or in GCC ?
  4. Misc: Diagnostics, GCOV, ...
    1. Is there a list of GCC diagnostics/messages?
    2. GCOV/GCC data files are not created
    3. I found a bug in GCC 4.2 for Darwin (Apple System), should I report it?
    4. The warning "unrecognized command-line option" is not given for -Wno-foo

Configure, Install, Build

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. This should be an empty directory before you start.

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. Using make clean or make distclean will not clean up the mess from a failed build, you should start with an empty gcc-build directory if you need to re-configure and try again. Because you've built in a separate directory, not in the source code directory, you can just remove the whole gcc-build directory and create a new one.

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:

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.

configure.ac:4: error: Please use exactly Autoconf 2.64 instead of 2.69

[ Permalink ]

If you modify the GCC sources and need to regenerate the autoconf and automake files, you must use specific versions of the tools, not the latest versions. See Tools/packages necessary for modifying GCC for the required versions. This can be done by installing the right versions of autoconf and automake to a custom location (e.g. under your home directory) and putting them first in your PATH.

The reason for not simply using the latest versions is that they are not always backwards compatible. Ensuring that GCC still works with a newer version takes considerable time and effort. As explained by Jakub Jelinek in https://gcc.gnu.org/ml/gcc/2014-03/msg00410.html:

C/C++

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) {
        foo(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.

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

#include<iostream>
int main()
{
       double Δ_电场velocity(0);
       std::cout << "Δ_v电场elocity= " << Δ_电场velocity << "\n";
}

// with following makefile:

UCN_almost_UTF8_identifiers: UCN_almost_UTF8_identifiers.cpp
       to_UCN.sh UCN_almost_UTF8_identifiers.cpp
       g++ -fextended-identifiers -o UCN_almost_UTF8_identifiers /tmp/UCN_almost_UTF8_identifiers.cpp

//and the helper script: to_UCN.sh:

#!/bin/bash
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++ -

or

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: \
    foo(bar);

and after running gcc -E you expect

label:  fn (args);

but you get:

label:
 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
       0;}

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.

My program invokes undefined behaviour but...

[ Permalink ]

Sorry, if your program invokes undefined behaviour, then:

Please:

The reasons why the above are not reasonable requests are difficult to understand unless you are willing to learn '''in detail''' about how optimizing compilers work internally and the history of the programming languages. Steve Summit briefly discusses only part of the rationale behind undefined behaviors.

Finally, neither GCC bugzilla, nor GCC mailing lists are a forum appropriate to debate the above issues. Undefined behavior is not decided nor defined by GCC, but by the committees that write the language standards. 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"

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.

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 dumb warning that only exists because the MS compiler has a bug that treats struct and class differently in mangled names. GCC (and Clang) correctly implement the C++ standard which says it doesn't matter.

Why does GCC not give an error for some narrowing conversions within list-initializations as required by C++11 (-Wnarrowing) ?

[ Permalink ]

By default, G++ warns about some narrowing conversions, whereas other compilers always give an error. Specifically, G++ gives an error for narrowing conversions from constants, but by default only gives a warning for non-constants.

The standard only requires that "a conforming implementation shall issue at least one diagnostic message" so compiling the program with a warning is allowed, and does not mean G++ fails to conform to the standard. You can use either -Werror=narrowing or -pedantic-errors to make it an error if you want (or -Wno-narrowing to completely disable the warning). Diagnostic Pragmas can be used to set those options for individual functions.

Background:

G++ 4.6 gave an error but it was changed to a warning intentionally for 4.7 because many people found that narrowing conversions were one of the most commonly encountered problems when trying to compile large C++03 codebases as C++11. Previously valid and bug-free code produced errors and failed to compile, despite being perfectly safe. For example, for (int i=0; i < 10; ++i) { char c[] = { i, 0 }; ... } (where i is always within the range of char) caused errors and had to be changed to char c[] = { (char)i, 0 } . People were forced to change code that was provably correct because of the new rule.

As of G++ 5, the behavior is the following: When a later standard is in effect, e.g. when using -std=c++11, narrowing conversions are diagnosed by default, as required by the standard. A narrowing conversion from a constant produces an error, and a narrowing conversion from a non-constant produces a warning, but -Wno-narrowing suppresses the diagnostic. Note that this does not affect the meaning of well-formed code; narrowing conversions are still considered ill-formed in SFINAE contexts. [ -Wnarrowing in the G++ manual ].

Note that what is and isn't a narrowing conversion is specified by the standard, for example int i = { 0.0 };  is a narrowing conversion from double to int.

Optimization

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

[ Permalink ]

No. First, individual optimization options (-f*) do not enable optimization, one of the options -Os, -Og or -Ox with x > 0 is required for any optimization to happen. 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. You may find the output of gcc -help=optimizers helpful here, though it too needs to be interpreted with the above caveat in mind.

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

[ Permalink ]

This varies by platform and GCC version. The status of individual optimization flags corresponding to a given GCC invocation can be queried by appending the -Q --help=optimizers pair of options to it. For example, to see whether the Value Range Propagation optimization controlled by the -ftree-vrp option is enabled either at -O1 or at -O2 invoke GCC like shown below and look for the status in the square brackets.

$ gcc -O1 -Q --help=optimizers -xc - < /dev/null | grep vrp
  -ftree-vrp                            [disabled]
$ gcc -O2 -Q --help=optimizers -xc - < /dev/null | grep vrp
  -ftree-vrp                            [enabled]

To find the flags implicitly enabled and their values for a given compilation command, you could do:

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

As discussed above, however, whether an optimization is actually performed may depend not only on the flag that controls it but also on other optimizations. Unless those are also enabled and actually performed, the optimization pass controlled by the former option may not run. Unfortunately, these implicit dependencies are not documented anywhere and can only be determined by debugging GCC.

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. GCC provides built-in functions to perform arithmetic with overflow checking, which are correct and faster than any custom implementation. As a workaround, the option -fwrapv (In versions earlier than GCC 8, sometimes -fno-strict-overflow is enough but not always, see PR58454) makes gcc behave as if signed integer overflow were defined but these options 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 -fsanitize=undefined. 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.

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

[ Permalink ]

See: https://gcc.gnu.org/bugs/#nonbugs_general See also: https://gcc.gnu.org/ml/gcc-patches/2008-11/msg00105.html

In short, the most robust solution (as of GCC 5.0, this is only available in C) is to use -fexcess-precision=standard (whether this option has effect or not depends on other options, please read the manual entry for -fexcess-precision= carefully). 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 (PR59262), 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).

GCC miscompiles my code when optimizing, how to find whether it is a bug in my code or in GCC ?

[ Permalink ]

  1. Useful warnings "-Wall -Wextra -Wstrict-aliasing=3 -Waggressive-loop-optimizations"

  2. Try adding -fno-strict-aliasing. If it works, your code most probably breaks the strict aliasing rules that the compiler is using for optimization.

  3. Try adding -fwrapv. If it works, your code most probably has undefined behaviour because of integer overflow.

  4. Try adding -fno-aggressive-loop-optimizations. If it works, your code most probably has undefined behaviour because of some loop.

  5. Try adding -fno-delete-null-pointer-checks. GCC removes NULL pointer checks when it can prove that the pointer cannot be NULL (e.g., 'this' in C++ can never be NULL). If the execution path leading to the pointer being NULL triggers undefined behaviour, then the path cannot (should not) happen and the pointer can never be NULL.

  6. Try adding -fno-lifetime-dse. If it works, your code has undefined behaviour according to the C++ standard, probably when using placement new. See also PR71885.

  7. Compile without optimizations and with the -fsanitize= option.

  8. For a locking or race condition issue, you might consider using helgrind to gain an understanding of what's going wrong without having to further reduce the source. Once you have that understanding, it may be possible to show the problem with simpler source or just explain what's going wrong (if indeed it is a compiler issue).

GCC attempts to diagnose some undefined behaviours, but this is not possible in all cases. 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.

Misc: Diagnostics, GCOV, ...

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. If you want such a list, make it happen: Be the change that you want to see in the world. There is an unofficial, incomplete and probably out-of-date list of GCC diagnostics. You could start by contributing to it.

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

Nevertheless, the messages are in the source code itself. Using grep to find them is not trivial, since many different functions may end up generating a diagnostic message. Alternatively, you can view the gcc.pot file generated from the GCC sources by the Translation Project. The file and its translations into various languages are stored in the GCC repository here:

Many of the messages are likely to only make sense in the context of the program they are issued for and the compiler options used to compile it, and not so much on their own.

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
/devel/gcc/build-3.3.6/gcc/test
[root@catania test]# gcc test.c --coverage -o test.exe
[root@catania test]# strings test.exe | grep gcda
/devel/gcc/build-3.3.6/gcc/test/test.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 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.

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;
> EOF
<stdin>:1:16: warning: overflow in implicit constant conversion [-Woverflow]
cc1: warning: unrecognized command line option "-Wno-tautological-compare"

None: FAQ (last edited 2023-12-05 14:48:23 by JonathanWakely)