These machine-independent options control the interface conventions used in code generation.
Most of them have both positive and negative forms; the negative form of -ffoo
is -fno-foo
. In the table below, only one of the forms is listed—the one that is not the default. You can figure out the other form by either removing ‘no-
’ or adding it.
-fstack-reuse=
reuse-level
all
’, ‘named_vars
’, or ‘none
’. ‘all
’ enables stack reuse for all local variables and temporaries, ‘named_vars
’ enables the reuse only for user defined local variables with names, and ‘none
’ disables stack reuse completely. The default value is ‘all
’. The option is needed when the program extends the lifetime of a scoped local variable or a compiler generated temporary beyond the end point defined by the language. When a lifetime of a variable ends, and if the variable lives in memory, the optimizing compiler has the freedom to reuse its stack space with other temporaries or scoped local variables whose live range does not overlap with it. Legacy code extending local lifetime is likely to break with the stack reuse optimization. For example,
int *p; { int local1; p = &local1; local1 = 10; .... } { int local2; local2 = 20; ... } if (*p == 10) // out of scope use of local1 { }
Another example:
struct A { A(int k) : i(k), j(k) { } int i; int j; }; A *ap; void foo(const A& ar) { ap = &ar; } void bar() { foo(A(10)); // temp object's lifetime ends when foo returns { A a(20); .... } ap->i+= 10; // ap references out of scope temp whose space // is reused with a. What is the value of ap->i? }
The lifetime of a compiler generated temporary is well defined by the C++ standard. When a lifetime of a temporary ends, and if the temporary lives in memory, the optimizing compiler has the freedom to reuse its stack space with other temporaries or scoped local variables whose live range does not overlap with it. However some of the legacy code relies on the behavior of older compilers in which temporaries' stack space is not reused, the aggressive stack reuse can lead to runtime errors. This option is used to control the temporary stack reuse optimization.
-ftrapv
-ftrapv
and -fwrapv
override each other, so using -ftrapv
-fwrapv
on the command-line results in -fwrapv
being effective. Note that only active options override, so using -ftrapv
-fwrapv
-fno-wrapv
on the command-line results in -ftrapv
being effective. -fwrapv
-ftrapv
and -fwrapv
override each other, so using -ftrapv
-fwrapv
on the command-line results in -fwrapv
being effective. Note that only active options override, so using -ftrapv
-fwrapv
-fno-wrapv
on the command-line results in -ftrapv
being effective. -fexceptions
-fnon-call-exceptions
SIGALRM
. -fdelete-dead-exceptions
-funwind-tables
-fexceptions
, except that it just generates any needed static data, but does not affect the generated code in any other way. You normally do not need to enable this option; instead, a language processor that needs this handling enables it on your behalf. -fasynchronous-unwind-tables
-fno-gnu-unique
STB_GNU_UNIQUE
binding to make sure that definitions of template static data members and static local variables in inline functions are unique even in the presence of RTLD_LOCAL
; this is necessary to avoid problems with a library used by two different RTLD_LOCAL
plugins depending on a definition in one of them and therefore disagreeing with the other one about the binding of the symbol. But this causes dlclose
to be ignored for affected DSOs; if your program relies on reinitialization of a DSO via dlclose
and dlopen
, you can use -fno-gnu-unique
. -fpcc-struct-return
struct
and union
values in memory like longer ones, rather than in registers. This convention is less efficient, but it has the advantage of allowing intercallability between GCC-compiled files and files compiled with other compilers, particularly the Portable C Compiler (pcc). The precise convention for returning structures in memory depends on the target configuration macros.
Short structures and unions are those whose size and alignment match that of some integer type.
Warning: code compiled with the -fpcc-struct-return
switch is not binary compatible with code compiled with the -freg-struct-return
switch. Use it to conform to a non-default application binary interface.
-freg-struct-return
struct
and union
values in registers when possible. This is more efficient for small structures than -fpcc-struct-return
. If you specify neither -fpcc-struct-return
nor -freg-struct-return
, GCC defaults to whichever convention is standard for the target. If there is no standard convention, GCC defaults to -fpcc-struct-return
, except on targets where GCC is the principal compiler. In those cases, we can choose the standard, and we chose the more efficient register return alternative.
Warning: code compiled with the -freg-struct-return
switch is not binary compatible with code compiled with the -fpcc-struct-return
switch. Use it to conform to a non-default application binary interface.
-fshort-enums
enum
type only as many bytes as it needs for the declared range of possible values. Specifically, the enum
type is equivalent to the smallest integer type that has enough room. Warning: the -fshort-enums
switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.
-fshort-wchar
wchar_t
to be short
unsigned int
instead of the default for the target. This option is useful for building programs to run under WINE. Warning: the -fshort-wchar
switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface.
-fno-common
-fcommon
, and is the default for GCC on most targets. On the other hand, this behavior is not required by ISO C, and on some targets may carry a speed or code size penalty on variable references. The -fno-common
option specifies that the compiler should place uninitialized global variables in the data section of the object file, rather than generating them as common blocks. This has the effect that if the same variable is declared (without extern
) in two different compilations, you get a multiple-definition error when you link them. In this case, you must compile with -fcommon
instead. Compiling with -fno-common
is useful on targets for which it provides better performance, or if you wish to verify that the program will work on other systems that always treat uninitialized variable declarations this way. -fno-ident
#ident
directive. -finhibit-size-directive
.size
assembler directive, or anything else that would cause trouble if the function is split in the middle, and the two halves are placed at locations far apart in memory. This option is used when compiling crtstuff.c
; you should not need to use it for anything else. -fverbose-asm
-fno-verbose-asm
, the default, causes the extra information to be omitted and is useful when comparing two assembler files.
-frecord-gcc-switches
-fverbose-asm
switch, but that switch only records information in the assembler output file as comments, so it never reaches the object file. See also -grecord-gcc-switches
for another way of storing compiler options into the object file. -fpic
-fpic
does not work; in that case, recompile with -fPIC
instead. (These maximums are 8k on the SPARC, 28k on AArch64 and 32k on the m68k and RS/6000. The x86 has no such limit.) Position-independent code requires special support, and therefore works only on certain machines. For the x86, GCC supports PIC for System V but not for the Sun 386i. Code generated for the IBM RS/6000 is always position-independent.
When this flag is set, the macros __pic__
and __PIC__
are defined to 1.
-fPIC
Position-independent code requires special support, and therefore works only on certain machines.
When this flag is set, the macros __pic__
and __PIC__
are defined to 2.
-fpie
-fPIE
-fpic
and -fPIC
, but generated position independent code can be only linked into executables. Usually these options are used when -pie
GCC option is used during linking. -fpie
and -fPIE
both define the macros __pie__
and __PIE__
. The macros have the value 1 for -fpie
and 2 for -fPIE
.
-fno-plt
-fno-plt
all external symbols are resolved at load time. Alternatively, the function attribute noplt
can be used to avoid calls through the PLT for specific external functions.
In position-dependent code, a few targets also convert calls to functions that are marked to not use the PLT to use the GOT instead.
-fno-jump-tables
-fpic
or -fPIC
for building code that forms part of a dynamic linker and cannot reference the address of a jump table. On some targets, jump tables do not require a GOT and this option is not needed. -ffixed-
reg
reg must be the name of a register. The register names accepted are machine-specific and are defined in the REGISTER_NAMES
macro in the machine description macro file.
This flag does not have a negative form, because it specifies a three-way choice.
-fcall-used-
reg
It is an error to use this flag with the frame pointer or stack pointer. Use of this flag for other registers that have fixed pervasive roles in the machine's execution model produces disastrous results.
This flag does not have a negative form, because it specifies a three-way choice.
-fcall-saved-
reg
It is an error to use this flag with the frame pointer or stack pointer. Use of this flag for other registers that have fixed pervasive roles in the machine's execution model produces disastrous results.
A different sort of disaster results from the use of this flag for a register in which function values may be returned.
This flag does not have a negative form, because it specifies a three-way choice.
-fpack-struct[=
n]
Warning: the -fpack-struct
switch causes GCC to generate code that is not binary compatible with code generated without that switch. Additionally, it makes the code suboptimal. Use it to conform to a non-default application binary interface.
-fleading-underscore
-fno-leading-underscore
, forcibly change the way C symbols are represented in the object file. One use is to help link with legacy assembly code. Warning: the -fleading-underscore
switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface. Not all targets provide complete support for this switch.
-ftls-model=
model
global-dynamic
’, ‘local-dynamic
’, ‘initial-exec
’ or ‘local-exec
’. Note that the choice is subject to optimization: the compiler may use a more efficient model for symbols not visible outside of the translation unit, or if -fpic
is not given on the command line. The default without -fpic
is ‘initial-exec
’; with -fpic
the default is ‘global-dynamic
’.
-fvisibility=
[default
|internal
|hidden
|protected
]
Despite the nomenclature, ‘default
’ always means public; i.e., available to be linked against from outside the shared object. ‘protected
’ and ‘internal
’ are pretty useless in real-world usage so the only other commonly used option is ‘hidden
’. The default if -fvisibility
isn't specified is ‘default
’, i.e., make every symbol public.
A good explanation of the benefits offered by ensuring ELF symbols have the correct visibility is given by “How To Write Shared Libraries” by Ulrich Drepper (which can be found at http://www.akkadia.org/drepper/)—however a superior solution made possible by this option to marking things hidden when the default is public is to make the default hidden and mark things public. This is the norm with DLLs on Windows and with -fvisibility=hidden
and __attribute__ ((visibility("default")))
instead of __declspec(dllexport)
you get almost identical semantics with identical syntax. This is a great boon to those working with cross-platform projects.
For those adding visibility support to existing code, you may find #pragma GCC visibility
of use. This works by you enclosing the declarations you wish to set visibility for with (for example) #pragma GCC visibility push(hidden)
and #pragma GCC visibility pop
. Bear in mind that symbol visibility should be viewed as part of the API interface contract and thus all new code should always specify visibility when it is not the default; i.e., declarations only for use within the local DSO should always be marked explicitly as hidden as so to avoid PLT indirection overheads—making this abundantly clear also aids readability and self-documentation of the code. Note that due to ISO C++ specification requirements, operator new
and operator delete
must always be of default visibility.
Be aware that headers from outside your project, in particular system headers and headers from any other library you use, may not be expecting to be compiled with visibility other than the default. You may need to explicitly say #pragma GCC visibility push(default)
before including any such headers.
extern
declarations are not affected by -fvisibility
, so a lot of code can be recompiled with -fvisibility=hidden
with no modifications. However, this means that calls to extern
functions with no explicit visibility use the PLT, so it is more effective to use __attribute ((visibility))
and/or #pragma GCC visibility
to tell the compiler which extern
declarations should be treated as hidden.
Note that -fvisibility
does affect C++ vague linkage entities. This means that, for instance, an exception class that is be thrown between DSOs must be explicitly marked with default visibility so that the ‘type_info
’ nodes are unified between the DSOs.
An overview of these techniques, their benefits and how to use them is at http://gcc.gnu.org/wiki/Visibility.
-fstrict-volatile-bitfields
unsigned short
(assuming short is 16 bits on these targets) to force GCC to use 16-bit accesses instead of, perhaps, a more efficient 32-bit access. If this option is disabled, the compiler uses the most efficient instruction. In the previous example, that might be a 32-bit load instruction, even though that accesses bytes that do not contain any portion of the bit-field, or memory-mapped registers unrelated to the one being updated.
In some cases, such as when the packed
attribute is applied to a structure field, it may not be possible to access the field with a single read or write that is correctly aligned for the target machine. In this case GCC falls back to generating multiple accesses rather than code that will fault or truncate the result at run time.
Note: Due to restrictions of the C/C++11 memory model, write accesses are not allowed to touch non bit-field members. It is therefore recommended to define all bits of the field's type as bit-field members.
The default value of this option is determined by the application binary interface for the target processor.
-fsync-libcalls
__sync
family of functions may be used to implement the C++11 __atomic
family of functions. The default value of this option is enabled, thus the only useful form of the option is -fno-sync-libcalls
. This option is used in the implementation of the libatomic
runtime library.
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Code-Gen-Options.html