|
|
|
@@ -60,7 +60,7 @@
|
|
|
|
|
/// If this attribute is used on a function declaration and a call to such a function is not eliminated through dead code elimination or other optimizations, a warning that includes message is diagnosed. This is useful for compile-time checking
|
|
|
|
|
#define ATTR_WARNING(Message) __attribute__ ((warning(Message)))
|
|
|
|
|
|
|
|
|
|
/** \ingroup Group_GCC
|
|
|
|
|
/**
|
|
|
|
|
* \defgroup Group_VariableAttr Variable Attributes
|
|
|
|
|
* @{
|
|
|
|
|
*/
|
|
|
|
@@ -74,7 +74,7 @@
|
|
|
|
|
#define ATTR_PREPACKED
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
|
|
/** \ingroup Group_GCC
|
|
|
|
|
/**
|
|
|
|
|
* \defgroup Group_FuncAttr Function Attributes
|
|
|
|
|
* @{
|
|
|
|
|
*/
|
|
|
|
@@ -118,6 +118,66 @@
|
|
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \defgroup Group_BuiltinFunc Built-in Functions
|
|
|
|
|
* @{
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/** You can use the built-in function \b __builtin_constant_p to determine if a value 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 value to test. 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. A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the -O option.
|
|
|
|
|
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:
|
|
|
|
|
\code
|
|
|
|
|
#define Scale_Value(X) \
|
|
|
|
|
(__builtin_constant_p (X) ? ((X) * SCALE + OFFSET) : Scale (X))
|
|
|
|
|
\endcode
|
|
|
|
|
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.
|
|
|
|
|
*/
|
|
|
|
|
#define BUILTIN_CONSTANT(exp) __builtin_constant_p(exp)
|
|
|
|
|
|
|
|
|
|
/** You can use the built-in function \b __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 to short **. 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 another enum 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 to enum {hot, dog}.
|
|
|
|
|
You typically use this function in code whose execution varies depending on the arguments' types. For example:
|
|
|
|
|
\code
|
|
|
|
|
#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; \
|
|
|
|
|
})
|
|
|
|
|
\endcode
|
|
|
|
|
*/
|
|
|
|
|
#define BUILTIN_TYPE_COMPATIBLE(type1, type2) __builtin_types_compatible_p(type1, type2)
|
|
|
|
|
|
|
|
|
|
/** You can use the built-in function \b __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.
|
|
|
|
|
This built-in function is analogous to the `? :' operator in C, except that the expression returned has its type unaltered by promotion rules. Also, the built-in function does not evaluate the expression that is not chosen. For example, if const_exp evaluates to true, exp2 is not evaluated even if it has side-effects.
|
|
|
|
|
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:
|
|
|
|
|
\code
|
|
|
|
|
#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))\
|
|
|
|
|
\endcode
|
|
|
|
|
*/
|
|
|
|
|
#define BUILTIN_CHOOSE_EXPR(const_exp, exp1, exp2) __builtin_choose_expr (const_exp, exp1, exp2)
|
|
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|