Other Builtins (Using the GNU Compiler Collection (GCC)) (original) (raw)
7.12 Other Built-in Functions Provided by GCC ¶
This section documents miscellaneous built-in functions available in GCC.
Built-in Function: bool
__builtin_has_attribute (type-or-expression, attribute)
¶
The __builtin_has_attribute
function evaluates to an integer constant expression equal to true
if the symbol or type referenced by the type-or-expression argument has been declared with the attribute referenced by the second argument. For an type-or-expression argument that does not reference a symbol, since attributes do not apply to expressions the built-in consider the type of the argument. Neither argument is evaluated. The type-or-expression argument is subject to the same restrictions as the argument to typeof
(see Referring to a Type with typeof). Theattribute argument is an attribute name optionally followed by a comma-separated list of arguments enclosed in parentheses. Both forms of attribute names—with and without double leading and trailing underscores—are recognized. See Attribute Syntax, for details. When no attribute arguments are specified for an attribute that expects one or more arguments the function returns true
iftype-or-expression has been declared with the attribute regardless of the attribute argument values. Arguments provided for an attribute that expects some are validated and matched up to the provided number. The function returns true
if all provided arguments match. For example, the first call to the function below evaluates to true
because x
is declared with the aligned
attribute but the second call evaluates to false
because x
is declaredaligned (8)
and not aligned (4)
.
attribute ((aligned (8))) int x; _Static_assert (__builtin_has_attribute (x, aligned), "aligned"); _Static_assert (!__builtin_has_attribute (x, aligned (4)), "aligned (4)");
Due to a limitation the __builtin_has_attribute
function returnsfalse
for the mode
attribute even if the type or variable referenced by the type-or-expression argument was declared with one. The function is also not supported with labels, and in C with enumerators.
Note that unlike the __has_attribute
preprocessor operator which is suitable for use in #if
preprocessing directives__builtin_has_attribute
is an intrinsic function that is not recognized in such contexts.
Built-in Function: type
__builtin_speculation_safe_value (type val, type failval)
¶
This built-in function can be used to help mitigate against unsafe speculative execution. type may be any integral type or any pointer type.
- If the CPU is not speculatively executing the code, then valis returned.
- If the CPU is executing speculatively then either:
- The function may cause execution to pause until it is known that the code is no-longer being executed speculatively (in which caseval can be returned, as above); or
- The function may use target-dependent speculation tracking state to causefailval to be returned when it is known that speculative execution has incorrectly predicted a conditional branch operation.
The second argument, failval, is optional and defaults to zero if omitted.
GCC defines the preprocessor macro__HAVE_BUILTIN_SPECULATION_SAFE_VALUE
for targets that have been updated to support this builtin.
The built-in function can be used where a variable appears to be used in a safe way, but the CPU, due to speculative execution may temporarily ignore the bounds checks. Consider, for example, the following function:
int array[500]; int f (unsigned untrusted_index) { if (untrusted_index < 500) return array[untrusted_index]; return 0; }
If the function is called repeatedly with untrusted_index
less than the limit of 500, then a branch predictor will learn that the block of code that returns a value stored in array
will be executed. If the function is subsequently called with an out-of-range value it will still try to execute that block of code first until the CPU determines that the prediction was incorrect (the CPU will unwind any incorrect operations at that point). However, depending on how the result of the function is used, it might be possible to leave traces in the cache that can reveal what was stored at the out-of-bounds location. The built-in function can be used to provide some protection against leaking data in this way by changing the code to:
int array[500]; int f (unsigned untrusted_index) { if (untrusted_index < 500) return array[__builtin_speculation_safe_value (untrusted_index)]; return 0; }
The built-in function will either cause execution to stall until the conditional branch has been fully resolved, or it may permit speculative execution to continue, but using 0 instead ofuntrusted_value
if that exceeds the limit.
If accessing any memory location is potentially unsafe when speculative execution is incorrect, then the code can be rewritten as
int array[500]; int f (unsigned untrusted_index) { if (untrusted_index < 500) return *__builtin_speculation_safe_value (&array[untrusted_index], NULL); return 0; }
which will cause a NULL
pointer to be used for the unsafe case.
Built-in Function: int
__builtin_types_compatible_p (type1, type2)
¶
You can use the built-in function __builtin_types_compatible_p
to determine whether two types are the same.
This built-in function returns 1 if the unqualified versions of the types type1 and type2 (which are types, not expressions) are compatible, 0 otherwise. The result of this built-in function can be used in integer constant expressions.
This built-in function ignores top level qualifiers (e.g., const
,volatile
). For example, int
is equivalent to const int
.
The type int[]
and int[5]
are compatible. On the other hand, int
and char *
are not compatible, even if the size of their types, on the particular architecture are the same. Also, the amount of pointer indirection is taken into account when determining similarity. Consequently, short *
is not similar toshort **
. Furthermore, two types that are typedefed are considered compatible if their underlying types are compatible.
An enum
type is not considered to be compatible with anotherenum
type even if both are compatible with the same integer type; this is what the C standard specifies. For example, enum {foo, bar}
is not similar toenum {hot, dog}
.
You typically use this function in code whose execution varies depending on the arguments’ types. For example:
#define foo(x)
({
typeof (x) tmp = (x);
if (__builtin_types_compatible_p (typeof (x), long double))
tmp = foo_long_double (tmp);
else if (__builtin_types_compatible_p (typeof (x), double))
tmp = foo_double (tmp);
else if (__builtin_types_compatible_p (typeof (x), float))
tmp = foo_float (tmp);
else
abort ();
tmp;
})
Note: This construct is only available for C.
Built-in Function: type
__builtin_choose_expr (const_exp, exp1, exp2)
¶
You can use the built-in function __builtin_choose_expr
to evaluate code depending on the value of a constant expression. This built-in function returns exp1 if const_exp, which is an integer constant expression, is nonzero. Otherwise it returns exp2.
Like the ‘? :’ operator, this built-in function does not evaluate the expression that is not chosen. For example, if const_exp evaluates totrue
, exp2 is not evaluated even if it has side effects. On the other hand, __builtin_choose_expr
differs from ‘? :’ in that the first operand must be a compile-time constant, and the other operands are not subject to the ‘? :’ type constraints and promotions.
This built-in function can return an lvalue if the chosen argument is an lvalue.
If exp1 is returned, the return type is the same as exp1’s type. Similarly, if exp2 is returned, its return type is the same as exp2.
Example:
#define foo(x)
__builtin_choose_expr (
__builtin_types_compatible_p (typeof (x), double),
foo_double (x),
__builtin_choose_expr (
__builtin_types_compatible_p (typeof (x), float),
foo_float (x),
/* The void expression results in a compile-time error
when assigning the result to something. */
(void)0))
Note: This construct is only available for C. Furthermore, the unused expression (exp1 or exp2 depending on the value ofconst_exp) may still generate syntax errors. This may change in future revisions.
Built-in Function: type
__builtin_tgmath (functions, arguments)
¶
The built-in function __builtin_tgmath
, available only for C and Objective-C, calls a function determined according to the rules of<tgmath.h>
macros. It is intended to be used in implementations of that header, so that expansions of macros from that header only expand each of their arguments once, to avoid problems when calls to such macros are nested inside the arguments of other calls to such macros; in addition, it results in better diagnostics for invalid calls to <tgmath.h>
macros than implementations using other GNU C language features. For example, the pow
type-generic macro might be defined as:
#define pow(a, b) __builtin_tgmath (powf, pow, powl,
cpowf, cpow, cpowl, a, b)
The arguments to __builtin_tgmath
are at least two pointers to functions, followed by the arguments to the type-generic macro (which will be passed as arguments to the selected function). All the pointers to functions must be pointers to prototyped functions, none of which may have variable arguments, and all of which must have the same number of parameters; the number of parameters of the first function determines how many arguments to __builtin_tgmath
are interpreted as function pointers, and how many as the arguments to the called function.
The types of the specified functions must all be different, but related to each other in the same way as a set of functions that may be selected between by a macro in <tgmath.h>
. This means that the functions are parameterized by a floating-point type t, different for each such function. The function return types may all be the same type, or they may be t for each function, or they may be the real type corresponding to t for each function (if some of the types t are complex). Likewise, for each parameter position, the type of the parameter in that position may always be the same type, or may be t for each function (this case must apply for at least one parameter position), or may be the real type corresponding to t for each function.
The standard rules for <tgmath.h>
macros are used to find a common type u from the types of the arguments for parameters whose types vary between the functions; complex integer types (a GNU extension) are treated like the complex type corresponding to the real floating type that would be chosen for the corresponding real integer type. If the function return types vary, or are all the same integer type, the function called is the one for which t is u, and it is an error if there is no such function. If the function return types are all the same floating-point type, the type-generic macro is taken to be one of those from TS 18661 that rounds the result to a narrower type; if there is a function for which t is u, it is called, and otherwise the first function, if any, for which thas at least the range and precision of u is called, and it is an error if there is no such function.
Built-in Function: int
__builtin_constant_p (exp)
¶
You can use the built-in function __builtin_constant_p
to determine if the expression exp is known to be constant at compile time and hence that GCC can perform constant-folding on expressions involving that value. The argument of the function is the expression to test. The expression is not evaluated, side-effects are discarded. The function returns the integer 1 if the argument is known to be a compile-time constant and 0 if it is not known to be a compile-time constant. Any expression that has side-effects makes the function return 0. A return of 0 does not indicate that the expression is not a constant, but merely that GCC cannot prove it is a constant within the constraints of the active set of optimization options.
You typically use this function in an embedded application where memory is a critical resource. If you have some complex calculation, you may want it to be folded if it involves constants, but need to call a function if it does not. For example:
#define Scale_Value(X)
(__builtin_constant_p (X)
? ((X) * SCALE + OFFSET) : Scale (X))
You may use this built-in function in either a macro or an inline function. However, if you use it in an inlined function and pass an argument of the function as the argument to the built-in, GCC never returns 1 when you call the inline function with a string constant or compound literal (see Compound Literals) and does not return 1 when you pass a constant numeric value to the inline function unless you specify the -O option.
You may also use __builtin_constant_p
in initializers for static data. For instance, you can write
static const int table[] = { __builtin_constant_p (EXPRESSION) ? (EXPRESSION) : -1, /* … */ };
This is an acceptable initializer even if EXPRESSION is not a constant expression, including the case where__builtin_constant_p
returns 1 because EXPRESSION can be folded to a constant but EXPRESSION contains operands that are not otherwise permitted in a static initializer (for example,0 && foo ()
). GCC must be more conservative about evaluating the built-in in this case, because it has no opportunity to perform optimization.
Built-in Function: bool
__builtin_is_constant_evaluated (void)
¶
The __builtin_is_constant_evaluated
function is available only in C++. The built-in is intended to be used by implementations of the std::is_constant_evaluated
C++ function. Programs should make use of the latter function rather than invoking the built-in directly.
The main use case of the built-in is to determine whether a constexpr
function is being called in a constexpr
context. A call to the function evaluates to a core constant expression with the valuetrue
if and only if it occurs within the evaluation of an expression or conversion that is manifestly constant-evaluated as defined in the C++ standard. Manifestly constant-evaluated contexts include constant-expressions, the conditions of constexpr if
statements, constraint-expressions, and initializers of variables usable in constant expressions. For more details refer to the latest revision of the C++ standard.
Built-in Function: type
__builtin_counted_by_ref (ptr)
¶
The built-in function __builtin_counted_by_ref
checks whether the array object pointed by the pointer ptr has another object associated with it that represents the number of elements in the array object through thecounted_by
attribute (i.e. the counted-by object). If so, returns a pointer to the corresponding counted-by object. If such counted-by object does not exist, returns a null pointer.
This built-in function is only available in C for now.
The argument ptr must be a pointer to an array. The type of the returned value is a pointer type pointing to the corresponding type of the counted-by object or a void pointer type in case of a null pointer being returned.
For example:
struct foo1 { int counter; struct bar1 array[] attribute((counted_by (counter))); } *p;
struct foo2 { int other; struct bar2 array[]; } *q;
the following call to the built-in
__builtin_counted_by_ref (p->array)
returns:
&p->counter with type int *
.
However, the following call to the built-in
__builtin_counted_by_ref (q->array)
returns a null pointer to void
.
Built-in Function: void
__builtin_clear_padding (ptr)
¶
The built-in function __builtin_clear_padding
function clears padding bits inside of the object representation of object pointed byptr, which has to be a pointer. The value representation of the object is not affected. The type of the object is assumed to be the type the pointer points to. Inside of a union, the only cleared bits are bits that are padding bits for all the union members.
This built-in-function is useful if the padding bits of an object might have indeterminate values and the object representation needs to be bitwise compared to some other object, for example for atomic operations.
For C++, ptr argument type should be pointer to trivially-copyable type, unless the argument is address of a variable or parameter, because otherwise it isn’t known if the type isn’t just a base class whose padding bits are reused or laid out differently in a derived class.
Built-in Function: type
__builtin_bit_cast (type, arg)
¶
The __builtin_bit_cast
function is available only in C++. The built-in is intended to be used by implementations of the std::bit_cast
C++ template function. Programs should make use of the latter function rather than invoking the built-in directly.
This built-in function allows reinterpreting the bits of the argargument as if it had type type. type and the type of thearg argument need to be trivially copyable types with the same size. When manifestly constant-evaluated, it performs extra diagnostics required for std::bit_cast
and returns a constant expression if argis a constant expression. For more details refer to the latest revision of the C++ standard.
Built-in Function: long
__builtin_expect (long exp, long c)
¶
You may use __builtin_expect
to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (-fprofile-arcs), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect.
The return value is the value of exp, which should be an integral expression. The semantics of the built-in are that it is expected thatexp == c. For example:
if (__builtin_expect (x, 0)) foo ();
indicates that we do not expect to call foo
, since we expect x
to be zero. Since you are limited to integral expressions for exp, you should use constructions such as
if (__builtin_expect (ptr != NULL, 1)) foo (*ptr);
when testing pointer or floating-point values.
For the purposes of branch prediction optimizations, the probability that a __builtin_expect
expression is true
is controlled by GCC’sbuiltin-expect-probability
parameter, which defaults to 90%.
You can also use __builtin_expect_with_probability
to explicitly assign a probability value to individual expressions. If the built-in is used in a loop construct, the provided probability will influence the expected number of iterations made by loop optimizations.
Built-in Function: long
__builtin_expect_with_probability ¶
(long exp, long c, double probability)
This function has the same semantics as __builtin_expect
, but the caller provides the expected probability that exp == c. The last argument, probability, is a floating-point value in the range 0.0 to 1.0, inclusive. The probability argument must be a constant floating-point expression.
Built-in Function: void
__builtin_trap (void)
¶
This function causes the program to exit abnormally. GCC implements this function by using a target-dependent mechanism (such as intentionally executing an illegal instruction) or by callingabort
. The mechanism used may vary from release to release so you should not rely on any particular implementation.
Built-in Function: void
__builtin_unreachable (void)
¶
If control flow reaches the point of the __builtin_unreachable
, the program is undefined. It is useful in situations where the compiler cannot deduce the unreachability of the code.
One such case is immediately following an asm
statement that either never terminates, or one that transfers control elsewhere and never returns. In this example, without the__builtin_unreachable
, GCC issues a warning that control reaches the end of a non-void function. It also generates code to return after the asm
.
int f (int c, int v) { if (c) { return v; } else { asm("jmp error_handler"); __builtin_unreachable (); } }
Because the asm
statement unconditionally transfers control out of the function, control never reaches the end of the function body. The __builtin_unreachable
is in fact unreachable and communicates this fact to the compiler.
Another use for __builtin_unreachable
is following a call a function that never returns but that is not declared__attribute__((noreturn))
, as in this example:
void function_that_never_returns (void);
int g (int c) { if (c) { return 1; } else { function_that_never_returns (); __builtin_unreachable (); } }
Built-in Function: type
__builtin_assoc_barrier (type expr)
¶
This built-in inhibits re-association of the floating-point expressionexpr with expressions consuming the return value of the built-in. The expression expr itself can be reordered, and the whole expressionexpr can be reordered with operands after the barrier. The barrier is relevant when -fassociative-math
is active.
float x0 = a + b - b; float x1 = __builtin_assoc_barrier(a + b) - b;
means that, with -fassociative-math
, x0
can be optimized tox0 = a
but x1
cannot.
It is also relevant when -ffp-contract=fast
is active; it will prevent contraction between expressions.
float x0 = a * b + c; float x1 = __builtin_assoc_barrier (a * b) + c;
means that, with -ffp-contract=fast
, x0
may be optimized to use a fused multiply-add instruction but x1
cannot.
Built-in Function: void *
__builtin_assume_aligned (const void *exp, size_t align, ...)
¶
This function returns its first argument, and allows the compiler to assume that the returned pointer is at least align bytes aligned. This built-in can have either two or three arguments, if it has three, the third argument should have integer type, and if it is nonzero means misalignment offset. For example:
void *x = __builtin_assume_aligned (arg, 16);
means that the compiler can assume x
, set to arg
, is at least 16-byte aligned, while:
void *x = __builtin_assume_aligned (arg, 32, 8);
means that the compiler can assume for x
, set to arg
, that(char *) x - 8
is 32-byte aligned.
Built-in Function: int
__builtin_LINE ()
¶
This function is the equivalent of the preprocessor __LINE__
macro and returns a constant integer expression that evaluates to the line number of the invocation of the built-in. When used as a C++ default argument for a function F, it returns the line number of the call to F.
Built-in Function: const char *
__builtin_FUNCTION ()
¶
This function is the equivalent of the __FUNCTION__
symbol and returns an address constant pointing to the name of the function from which the built-in was invoked, or the empty string if the invocation is not at function scope. When used as a C++ default argument for a function F, it returns the name of F’s caller or the empty string if the call was not made at function scope.
Built-in Function: const char *
__builtin_FILE ()
¶
This function is the equivalent of the preprocessor __FILE__
macro and returns an address constant pointing to the file name containing the invocation of the built-in, or the empty string if the invocation is not at function scope. When used as a C++ default argument for a function F, it returns the file name of the call to F or the empty string if the call was not made at function scope.
For example, in the following, each call to function foo
will print a line similar to "file.c:123: foo: message"
with the name of the file and the line number of the printf
call, the name of the function foo
, followed by the word message
.
const char* function (const char *func = __builtin_FUNCTION ()) { return func; }
void foo (void) { printf ("%s:%i: %s: message\n", file (), line (), function ()); }
Built-in Function: void
__builtin___clear_cache (void *begin, void *end)
¶
This function is used to flush the processor’s instruction cache for the region of memory between begin inclusive and endexclusive. Some targets require that the instruction cache be flushed, after modifying memory containing code, in order to obtain deterministic behavior.
If the target does not require instruction cache flushes,__builtin___clear_cache
has no effect. Otherwise either instructions are emitted in-line to clear the instruction cache or a call to the __clear_cache
function in libgcc is made.
Built-in Function: void
__builtin_prefetch (const void *addr, ...)
¶
This function is used to minimize cache-miss latency by moving data into a cache before it is accessed. You can insert calls to __builtin_prefetch
into code for which you know addresses of data in memory that is likely to be accessed soon. If the target supports them, data prefetch instructions are generated. If the prefetch is done early enough before the access then the data will be in the cache by the time it is accessed.
The value of addr is the address of the memory to prefetch. There are two optional arguments, rw and locality. The value of rw is a compile-time constant zero, one or two; one means that the prefetch is preparing for a write to the memory address, two means that the prefetch is preparing for a shared read (expected to be read by at least one other processor before it is written if written at all) and zero, the default, means that the prefetch is preparing for a read. The value locality must be a compile-time constant integer between zero and three. A value of zero means that the data has no temporal locality, so it need not be left in the cache after the access. A value of three means that the data has a high degree of temporal locality and should be left in all levels of cache possible. Values of one and two mean, respectively, a low or moderate degree of temporal locality. The default is three.
for (i = 0; i < n; i++) { a[i] = a[i] + b[i]; __builtin_prefetch (&a[i+j], 1, 1); __builtin_prefetch (&b[i+j], 0, 1); /* … */ }
Data prefetch does not generate faults if addr is invalid, but the address expression itself must be valid. For example, a prefetch of p->next
does not fault if p->next
is not a valid address, but evaluation faults if p
is not a valid address.
If the target does not support data prefetch, the address expression is evaluated if it includes side effects but no other code is generated and GCC does not issue a warning.
Built-in Function: int
__builtin_classify_type (arg)
¶
Built-in Function: int
__builtin_classify_type (type)
¶
The __builtin_classify_type
returns a small integer with a category of arg argument’s type, like void type, integer type, enumeral type, boolean type, pointer type, reference type, offset type, real type, complex type, function type, method type, record type, union type, array type, string type, bit-precise integer type, vector type, etc. When the argument is an expression, for backwards compatibility reason the argument is promoted like arguments passed to ...
in varargs function, so some classes are never returned in certain languages. Alternatively, the argument of the built-in function can be a typename, such as the typeof
specifier.
int a[2]; __builtin_classify_type (a) == __builtin_classify_type (int[5]); __builtin_classify_type (a) == __builtin_classify_type (void*); __builtin_classify_type (typeof (a)) == __builtin_classify_type (int[5]);
The first comparison will never be true, as a is implicitly converted to pointer. The last two comparisons will be true as they classify pointers in the second case and arrays in the last case.
Built-in Function: Pmode
__builtin_extend_pointer (void * x)
¶
On targets where the user visible pointer size is smaller than the size of an actual hardware address this function returns the extended user pointer. Targets where this is true included ILP32 mode on x86_64 or Aarch64. This function is mainly useful when writing inline assembly code.
Built-in Function: int
__builtin_goacc_parlevel_id (int x)
¶
Returns the openacc gang, worker or vector id depending on whether x is 0, 1 or 2.
Built-in Function: int
__builtin_goacc_parlevel_size (int x)
¶
Returns the openacc gang, worker or vector size depending on whether x is 0, 1 or 2.