Clang Language Extensions¶
Introduction¶
This document describes the language extensions provided by Clang. In addition to the language extensions listed here, Clang aims to support a broad range of GCC extensions. Please see the GCC manual for more information on these extensions.
Feature Checking Macros¶
Language extensions can be very useful, but only if you know you can depend on them. In order to allow fine-grain features checks, we support three builtin function-like macros. This allows you to directly test for a feature in your code without having to resort to something like autoconf or fragile “compiler version checks”.
__has_builtin¶
This function-like macro takes a single identifier argument that is the name of a builtin function, a builtin pseudo-function (taking one or more type arguments), or a builtin template. It evaluates to 1 if the builtin is supported or 0 if not. It can be used like this:
#ifndef __has_builtin // Optional of course.
#define __has_builtin(x) 0 // Compatibility with non-clang compilers.
#endif
...
#if __has_builtin(__builtin_trap)
__builtin_trap();
#else
abort();
#endif
...
Note
Prior to Clang 10, __has_builtin could not be used to detect most builtin
pseudo-functions.
__has_builtin should not be used to detect support for a builtin macro;
use #ifdef instead.
__has_constexpr_builtin¶
This function-like macro takes a single identifier argument that is the name of a builtin function, a builtin pseudo-function (taking one or more type arguments), or a builtin template. It evaluates to 1 if the builtin is supported and can be constant evaluated or 0 if not. It can be used for writing conditionally constexpr code like this:
#ifndef __has_constexpr_builtin // Optional of course.
#define __has_constexpr_builtin(x) 0 // Compatibility with non-clang compilers.
#endif
...
#if __has_constexpr_builtin(__builtin_fmax)
constexpr
#endif
double money_fee(double amount) {
return __builtin_fmax(amount * 0.03, 10.0);
}
...
For example, __has_constexpr_builtin is used in libcxx’s implementation of
the <cmath> header file to conditionally make a function constexpr whenever
the constant evaluation of the corresponding builtin (for example,
std::fmax calls __builtin_fmax) is supported in Clang.
__has_feature and __has_extension¶
These function-like macros take a single identifier argument that is the name
of a feature. __has_feature evaluates to 1 if the feature is both
supported by Clang and standardized in the current language standard or 0 if
not (but see below), while
__has_extension evaluates to 1 if the feature is supported by Clang in the
current language (either as a language extension or a standard language
feature) or 0 if not. They can be used like this:
#ifndef __has_feature // Optional of course.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#ifndef __has_extension
#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
#endif
...
#if __has_feature(cxx_rvalue_references)
// This code will only be compiled with the -std=c++11 and -std=gnu++11
// options, because rvalue references are only standardized in C++11.
#endif
#if __has_extension(cxx_rvalue_references)
// This code will be compiled with the -std=c++11, -std=gnu++11, -std=c++98
// and -std=gnu++98 options, because rvalue references are supported as a
// language extension in C++98.
#endif
For backward compatibility, __has_feature can also be used to test
for support for non-standardized features, i.e. features not prefixed c_,
cxx_ or objc_.
Another use of __has_feature is to check for compiler features not related
to the language standard, such as e.g. AddressSanitizer.
If the -pedantic-errors option is given, __has_extension is equivalent
to __has_feature.
The feature tag is described along with the language feature below.
The feature name or extension name can also be specified with a preceding and
following __ (double underscore) to avoid interference from a macro with
the same name. For instance, __cxx_rvalue_references__ can be used instead
of cxx_rvalue_references.
__has_cpp_attribute¶
This function-like macro is available in C++20 by default, and is provided as an extension in earlier language standards. It takes a single argument that is the name of a double-square-bracket-style attribute. The argument can either be a single identifier or a scoped identifier. If the attribute is supported, a nonzero value is returned. If the attribute is a standards-based attribute, this macro returns a nonzero value based on the year and month in which the attribute was voted into the working draft. See WG21 SD-6 for the list of values returned for standards-based attributes. If the attribute is not supported by the current compilation target, this macro evaluates to 0. It can be used like this:
#ifndef __has_cpp_attribute // For backwards compatibility
#define __has_cpp_attribute(x) 0
#endif
...
#if __has_cpp_attribute(clang::fallthrough)
#define FALLTHROUGH [[clang::fallthrough]]
#else
#define FALLTHROUGH
#endif
...
The attribute scope tokens clang and _Clang are interchangeable, as are
the attribute scope tokens gnu and __gnu__. Attribute tokens in either
of these namespaces can be specified with a preceding and following __
(double underscore) to avoid interference from a macro with the same name. For
instance, gnu::__const__ can be used instead of gnu::const.
__has_c_attribute¶
This function-like macro takes a single argument that is the name of an attribute exposed with the double square-bracket syntax in C mode. The argument can either be a single identifier or a scoped identifier. If the attribute is supported, a nonzero value is returned. If the attribute is not supported by the current compilation target, this macro evaluates to 0. It can be used like this:
#ifndef __has_c_attribute // Optional of course.
#define __has_c_attribute(x) 0 // Compatibility with non-clang compilers.
#endif
...
#if __has_c_attribute(fallthrough)
#define FALLTHROUGH [[fallthrough]]
#else
#define FALLTHROUGH
#endif
...
The attribute scope tokens clang and _Clang are interchangeable, as are
the attribute scope tokens gnu and __gnu__. Attribute tokens in either
of these namespaces can be specified with a preceding and following __
(double underscore) to avoid interference from a macro with the same name. For
instance, gnu::__const__ can be used instead of gnu::const.
__has_attribute¶
This function-like macro takes a single identifier argument that is the name of a GNU-style attribute. It evaluates to 1 if the attribute is supported by the current compilation target, or 0 if not. It can be used like this:
#ifndef __has_attribute // Optional of course.
#define __has_attribute(x) 0 // Compatibility with non-clang compilers.
#endif
...
#if __has_attribute(always_inline)
#define ALWAYS_INLINE __attribute__((always_inline))
#else
#define ALWAYS_INLINE
#endif
...
The attribute name can also be specified with a preceding and following __
(double underscore) to avoid interference from a macro with the same name. For
instance, __always_inline__ can be used instead of always_inline.
__has_declspec_attribute¶
This function-like macro takes a single identifier argument that is the name of
an attribute implemented as a Microsoft-style __declspec attribute. It
evaluates to 1 if the attribute is supported by the current compilation target,
or 0 if not. It can be used like this:
#ifndef __has_declspec_attribute // Optional of course.
#define __has_declspec_attribute(x) 0 // Compatibility with non-clang compilers.
#endif
...
#if __has_declspec_attribute(dllexport)
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif
...
The attribute name can also be specified with a preceding and following __
(double underscore) to avoid interference from a macro with the same name. For
instance, __dllexport__ can be used instead of dllexport.
__is_identifier¶
This function-like macro takes a single identifier argument that might be either a reserved word or a regular identifier. It evaluates to 1 if the argument is just a regular identifier and not a reserved word, in the sense that it can then be used as the name of a user-defined function or variable. Otherwise it evaluates to 0. It can be used like this:
...
#ifdef __is_identifier // Compatibility with non-clang compilers.
#if __is_identifier(__wchar_t)
typedef wchar_t __wchar_t;
#endif
#endif
__wchar_t WideCharacter;
...
Include File Checking Macros¶
Not all developments systems have the same include files. The
__has_include and __has_include_next macros allow
you to check for the existence of an include file before doing a possibly
failing #include directive. Include file checking macros must be used
as expressions in #if or #elif preprocessing directives.
__has_include¶
This function-like macro takes a single file name string argument that is the name of an include file. It evaluates to 1 if the file can be found using the include paths, or 0 otherwise:
// Note the two possible file name string formats.
#if __has_include("myinclude.h") && __has_include(<stdint.h>)
# include "myinclude.h"
#endif
To test for this feature, use #if defined(__has_include):
// To avoid problem with non-clang compilers not having this macro.
#if defined(__has_include)
#if __has_include("myinclude.h")
# include "myinclude.h"
#endif
#endif
__has_include_next¶
This function-like macro takes a single file name string argument that is the
name of an include file. It is like __has_include except that it looks for
the second instance of the given file found in the include paths. It evaluates
to 1 if the second instance of the file can be found using the include paths,
or 0 otherwise:
// Note the two possible file name string formats.
#if __has_include_next("myinclude.h") && __has_include_next(<stdint.h>)
# include_next "myinclude.h"
#endif
// To avoid problem with non-clang compilers not having this macro.
#if defined(__has_include_next)
#if __has_include_next("myinclude.h")
# include_next "myinclude.h"
#endif
#endif
Note that __has_include_next, like the GNU extension #include_next
directive, is intended for use in headers only, and will issue a warning if
used in the top-level compilation file. A warning will also be issued if an
absolute path is used in the file argument.
__has_warning¶
This function-like macro takes a string literal that represents a command line option for a warning and returns true if that is a valid warning option.
#if __has_warning("-Wformat")
...
#endif
Builtin Macros¶
__BASE_FILE__Defined to a string that contains the name of the main input file passed to Clang.
__FILE_NAME__Clang-specific extension that functions similar to
__FILE__but only renders the last path component (the filename) instead of an invocation dependent full path to that file.__COUNTER__Defined to an integer value that starts at zero and is incremented each time the
__COUNTER__macro is expanded.__INCLUDE_LEVEL__Defined to an integral value that is the include depth of the file currently being translated. For the main file, this value is zero.
__TIMESTAMP__Defined to the date and time of the last modification of the current source file.
__clang__Defined when compiling with Clang
__clang_major__Defined to the major marketing version number of Clang (e.g., the 2 in 2.0.1). Note that marketing version numbers should not be used to check for language features, as different vendors use different numbering schemes. Instead, use the Feature Checking Macros.
__clang_minor__Defined to the minor version number of Clang (e.g., the 0 in 2.0.1). Note that marketing version numbers should not be used to check for language features, as different vendors use different numbering schemes. Instead, use the Feature Checking Macros.
__clang_patchlevel__Defined to the marketing patch level of Clang (e.g., the 1 in 2.0.1).
__clang_version__Defined to a string that captures the Clang marketing version, including the Subversion tag or revision number, e.g., “
1.5 (trunk 102332)”.__clang_literal_encoding__Defined to a narrow string literal that represents the current encoding of narrow string literals, e.g.,
"hello". This macro typically expands to “UTF-8” (but may change in the future if the-fexec-charset="Encoding-Name"option is implemented.)__clang_wide_literal_encoding__Defined to a narrow string literal that represents the current encoding of wide string literals, e.g.,
L"hello". This macro typically expands to “UTF-16” or “UTF-32” (but may change in the future if the-fwide-exec-charset="Encoding-Name"option is implemented.)
Implementation-defined keywords¶
__datasizeof¶
__datasizeof behaves like sizeof, except that it returns the size of the
type ignoring tail padding.
_BitInt, _ExtInt¶
Clang supports the C23 _BitInt(N) feature as an extension in older C modes
and in C++. This type was previously implemented in Clang with the same
semantics, but spelled _ExtInt(N). This spelling has been deprecated in
favor of the standard type.
Note: the ABI for _BitInt(N) is still in the process of being stabilized,
so this type should not yet be used in interfaces that require ABI stability.
C keywords supported in all language modes¶
Clang supports _Alignas, _Alignof, _Atomic, _Complex,
_Generic, _Imaginary, _Noreturn, _Static_assert,
_Thread_local, and _Float16 in all language modes with the C semantics.
__alignof, __alignof__¶
__alignof and __alignof__ return, in contrast to _Alignof and
alignof, the preferred alignment of a type. This may be larger than the
required alignment for improved performance.
__extension__¶
__extension__ suppresses extension diagnostics in the statement it is
prepended to.
__auto_type¶
__auto_type behaves the same as auto in C++11 but is available in all
language modes.
__imag, __imag__¶
__imag and __imag__ can be used to get the imaginary part of a complex
value.
__real, __real__¶
__real and __real__ can be used to get the real part of a complex value.
__asm, __asm__¶
__asm and __asm__ are alternate spellings for asm, but available in
all language modes.
__complex, __complex__¶
__complex and __complex__ are alternate spellings for _Complex.
__const, __const__, __volatile, __volatile__, __restrict, __restrict__¶
These are alternate spellings for their non-underscore counterparts, but are available in all language modes.
__decltype¶
__decltype is an alternate spelling for decltype, but is also available
in C++ modes before C++11.
__inline, __inline__¶
__inline and __inline__ are alternate spellings for inline, but are
available in all language modes.
__nullptr¶
__nullptr is an alternate spelling for nullptr. It is available in all C and C++ language modes.
__signed, __signed__¶
__signed and __signed__ are alternate spellings for signed.
__unsigned and __unsigned__ are not supported.
__typeof, __typeof__, __typeof_unqual, __typeof_unqual__¶
__typeof and __typeof__ are alternate spellings for typeof, but are
available in all language modes. These spellings result in the operand,
retaining all qualifiers.
__typeof_unqual and __typeof_unqual__ are alternate spellings for the
C23 typeof_unqual type specifier, but are available in all language modes.
These spellings result in the type of the operand, stripping all qualifiers.
__char16_t, __char32_t¶
__char16_t and __char32_t are alternate spellings for char16_t and
char32_t respectively, but are also available in C++ modes before C++11.
They are only supported in C++. __char8_t is not available.
Vectors and Extended Vectors¶
Supports the GCC, OpenCL, AltiVec, NEON and SVE vector extensions.
OpenCL vector types are created using the ext_vector_type attribute. It
supports the V.xyzw syntax and other tidbits as seen in OpenCL. An example
is:
typedef float float4 __attribute__((ext_vector_type(4)));
typedef float float2 __attribute__((ext_vector_type(2)));
float4 foo(float2 a, float2 b) {
float4 c;
c.xz = a;
c.yw = b;
return c;
}
Query for this feature with __has_attribute(ext_vector_type).
Giving -maltivec option to clang enables support for AltiVec vector syntax
and functions. For example:
vector float foo(vector int a) {
vector int b;
b = vec_add(a, a) + a;
return (vector float)b;
}
NEON vector types are created using neon_vector_type and
neon_polyvector_type attributes. For example:
typedef __attribute__((neon_vector_type(8))) int8_t int8x8_t;
typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
int8x8_t foo(int8x8_t a) {
int8x8_t v;
v = a;
return v;
}
GCC vector types are created using the vector_size(N) attribute. The
argument N specifies the number of bytes that will be allocated for an
object of this type. The size has to be multiple of the size of the vector
element type. For example:
// OK: This declares a vector type with four 'int' elements
typedef int int4 __attribute__((vector_size(4 * sizeof(int))));
// ERROR: '11' is not a multiple of sizeof(int)
typedef int int_impossible __attribute__((vector_size(11)));
int4 foo(int4 a) {
int4 v;
v = a;
return v;
}
Boolean Vectors¶
Clang also supports the ext_vector_type attribute with boolean element types in C and C++. For example:
// legal for Clang, error for GCC:
typedef bool bool4 __attribute__((ext_vector_type(4)));
// Objects of bool4 type hold 8 bits, sizeof(bool4) == 1
bool4 foo(bool4 a) {
bool4 v;
v = a;
return v;
}
Boolean vectors are a Clang extension of the ext vector type. Boolean vectors are intended, though not guaranteed, to map to vector mask registers. The size parameter of a boolean vector type is the number of bits in the vector. The boolean vector is dense and each bit in the boolean vector is one vector element.
The semantics of boolean vectors borrows from C bit-fields with the following differences:
Distinct boolean vectors are always distinct memory objects (there is no packing).
Only the operators ?:, !, ~, |, &, ^ and comparison are allowed on boolean vectors.
Casting a scalar bool value to a boolean vector type means broadcasting the scalar value onto all lanes (same as general ext_vector_type).
It is not possible to access or swizzle elements of a boolean vector (different than general ext_vector_type).
The size and alignment are both the number of bits rounded up to the next power of two, but the alignment is at most the maximum vector alignment of the target.
Vector Literals¶
Vector literals can be used to create vectors from a set of scalars, or vectors. Either parentheses or braces form can be used. In the parentheses form the number of literal values specified must be one, i.e. referring to a scalar value, or must match the size of the vector type being created. If a single scalar literal value is specified, the scalar literal value will be replicated to all the components of the vector type. In the brackets form any number of literals can be specified. For example:
typedef int v4si __attribute__((__vector_size__(16)));
typedef float float4 __attribute__((ext_vector_type(4)));
typedef float float2 __attribute__((ext_vector_type(2)));
v4si vsi = (v4si){1, 2, 3, 4};
float4 vf = (float4)(1.0f, 2.0f, 3.0f, 4.0f);
vector int vi1 = (vector int)(1); // vi1 will be (1, 1, 1, 1).
vector int vi2 = (vector int){1}; // vi2 will be (1, 0, 0, 0).
vector int vi3 = (vector int)(1, 2); // error
vector int vi4 = (vector int){1, 2}; // vi4 will be (1, 2, 0, 0).
vector int vi5 = (vector int)(1, 2, 3, 4);
float4 vf = (float4)((float2)(1.0f, 2.0f), (float2)(3.0f, 4.0f));
Vector Operations¶
The table below shows the support for each operation by vector extension. A dash indicates that an operation is not accepted according to a corresponding specification.
Operator |
OpenCL |
AltiVec |
GCC |
NEON |
SVE |
|---|---|---|---|---|---|
[] |
yes |
yes |
yes |
yes |
yes |
unary operators +, – |
yes |
yes |
yes |
yes |
yes |
++, – – |
yes |
yes |
yes |
no |
no |
+,–,*,/,% |
yes |
yes |
yes |
yes |
yes |
bitwise operators &,|,^,~ |
yes |
yes |
yes |
yes |
yes |
>>,<< |
yes |
yes |
yes |
yes |
yes |
!, &&, || |
yes |
– |
yes |
yes |
yes |
==, !=, >, <, >=, <= |
yes |
yes |
yes |
yes |
yes |
= |
yes |
yes |
yes |
yes |
yes |
?: [1] |
yes |
– |
yes |
yes |
yes |
sizeof |
yes |
yes |
yes |
yes |
yes [2] |
C-style cast |
yes |
yes |
yes |
no |
no |
reinterpret_cast |
yes |
no |
yes |
no |
no |
static_cast |
yes |
no |
yes |
no |
no |
const_cast |
no |
no |
no |
no |
no |
address &v[i] |
no |
no |
no [3] |
no |
no |
See also __builtin_shufflevector, __builtin_convertvector.
Vector Builtins¶
Note: The implementation of vector builtins is work-in-progress and incomplete.
In addition to the operators mentioned above, Clang provides a set of builtins to perform additional operations on certain scalar and vector types.
Let T be one of the following types:
an integer type (as in C23 6.2.5p22), but excluding enumerated types and
boolthe standard floating types float or double
a half-precision floating point type, if one is supported on the target
a vector type.
For scalar types, consider the operation applied to a vector with a single element.
Vector Size
To determine the number of elements in a vector, use __builtin_vectorelements().
For fixed-sized vectors, e.g., defined via __attribute__((vector_size(N))) or ARM
NEON’s vector types (e.g., uint16x8_t), this returns the constant number of
elements at compile-time. For scalable vectors, e.g., SVE or RISC-V V, the number of
elements is not known at compile-time and is determined at runtime. This builtin can
be used, e.g., to increment the loop-counter in vector-type agnostic loops.
Elementwise Builtins
Each builtin returns a vector equivalent to applying the specified operation elementwise to the input.
Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±infinity
The integer elementwise intrinsics, including __builtin_elementwise_popcount,
__builtin_elementwise_bitreverse, __builtin_elementwise_add_sat,
__builtin_elementwise_sub_sat can be called in a constexpr context.
No implicit promotion of integer types takes place. The mixing of integer types of different sizes and signs is forbidden in binary and ternary builtins.
Name |
Operation |
Supported element types |
|---|---|---|
T __builtin_elementwise_abs(T x) |
return the absolute value of a number x; the absolute value of the most negative integer remains the most negative integer |
signed integer and floating point types |
T __builtin_elementwise_fma(T x, T y, T z) |
fused multiply add, (x * y) + z. |
floating point types |
T __builtin_elementwise_ceil(T x) |
return the smallest integral value greater than or equal to x |
floating point types |
T __builtin_elementwise_sin(T x) |
return the sine of x interpreted as an angle in radians |
floating point types |
T __builtin_elementwise_cos(T x) |
return the cosine of x interpreted as an angle in radians |
floating point types |
T __builtin_elementwise_tan(T x) |
return the tangent of x interpreted as an angle in radians |
floating point types |
T __builtin_elementwise_asin(T x) |
return the arcsine of x interpreted as an angle in radians |
floating point types |
T __builtin_elementwise_acos(T x) |
return the arccosine of x interpreted as an angle in radians |
floating point types |
T __builtin_elementwise_atan(T x) |
return the arctangent of x interpreted as an angle in radians |
floating point types |
T __builtin_elementwise_atan2(T y, T x) |
return the arctangent of y/x |
floating point types |
T __builtin_elementwise_sinh(T x) |
return the hyperbolic sine of angle x in radians |
floating point types |
T __builtin_elementwise_cosh(T x) |
return the hyperbolic cosine of angle x in radians |
floating point types |
T __builtin_elementwise_tanh(T x) |
return the hyperbolic tangent of angle x in radians |
floating point types |
T __builtin_elementwise_floor(T x) |
return the largest integral value less than or equal to x |
floating point types |
T __builtin_elementwise_log(T x) |
return the natural logarithm of x |
floating point types |
T __builtin_elementwise_log2(T x) |
return the base 2 logarithm of x |
floating point types |
T __builtin_elementwise_log10(T x) |
return the base 10 logarithm of x |
floating point types |
T __builtin_elementwise_popcount(T x) |
return the number of 1 bits in x |
integer types |
T __builtin_elementwise_pow(T x, T y) |
return x raised to the power of y |
floating point types |
T __builtin_elementwise_bitreverse(T x) |
return the integer represented after reversing the bits of x |
integer types |
T __builtin_elementwise_exp(T x) |
returns the base-e exponential, e^x, of the specified value |
floating point types |
T __builtin_elementwise_exp2(T x) |
returns the base-2 exponential, 2^x, of the specified value |
floating point types |
T __builtin_elementwise_exp10(T x) |
returns the base-10 exponential, 10^x, of the specified value |
floating point types |
T __builtin_elementwise_sqrt(T x) |
return the square root of a floating-point number |
floating point types |
T __builtin_elementwise_roundeven(T x) |
round x to the nearest integer value in floating point format, rounding halfway cases to even (that is, to the nearest value that is an even integer), regardless of the current rounding direction. |
floating point types |
T __builtin_elementwise_round(T x) |
round x to the nearest integer value in floating point format, rounding halfway cases away from zero, regardless of the current rounding direction. May raise floating-point exceptions. |
floating point types |
T __builtin_elementwise_trunc(T x) |
return the integral value nearest to but no larger in magnitude than x |
floating point types |
T __builtin_elementwise_nearbyint(T x) |
round x to the nearest integer value in floating point format,
rounding according to the current rounding direction.
May not raise the inexact floating-point exception. This is
treated the same as |
floating point types |
T __builtin_elementwise_rint(T x) |
round x to the nearest integer value in floating point format,
rounding according to the current rounding
direction. May raise floating-point exceptions. This is treated
the same as |
floating point types |
T __builtin_elementwise_canonicalize(T x) |
return the platform specific canonical encoding of a floating-point number |
floating point types |
T __builtin_elementwise_copysign(T x, T y) |
return the magnitude of x with the sign of y. |
floating point types |
T __builtin_elementwise_fmod(T x, T y) |
return The floating-point remainder of (x/y) whose sign matches the sign of x. |
floating point types |
T __builtin_elementwise_max(T x, T y) |
return x or y, whichever is larger For floating point types, follows semantics of maxNum in IEEE 754-2008. See LangRef for the comparison. |
integer and floating point types |
T __builtin_elementwise_min(T x, T y) |
return x or y, whichever is smaller For floating point types, follows semantics of minNum in IEEE 754-2008. See LangRef for the comparison. |
integer and floating point types |
T __builtin_elementwise_maxnum(T x, T y) |
return x or y, whichever is larger. Follows IEEE 754-2008 semantics (maxNum) with +0.0>-0.0. See LangRef for the comparison. |
floating point types |
T __builtin_elementwise_minnum(T x, T y) |
return x or y, whichever is smaller. Follows IEEE 754-2008 semantics (minNum) with +0.0>-0.0. See LangRef for the comparison. |
floating point types |
T __builtin_elementwise_add_sat(T x, T y) |
return the sum of x and y, clamped to the range of representable values for the signed/unsigned integer type. |
integer types |
T __builtin_elementwise_sub_sat(T x, T y) |
return the difference of x and y, clamped to the range of representable values for the signed/unsigned integer type. |
integer types |
T __builtin_elementwise_maximum(T x, T y) |
return x or y, whichever is larger. Follows IEEE 754-2019 semantics, see LangRef for the comparison. |
floating point types |
T __builtin_elementwise_minimum(T x, T y) |
return x or y, whichever is smaller. Follows IEEE 754-2019 semantics, see LangRef for the comparison. |
floating point types |
Reduction Builtins
Each builtin returns a scalar equivalent to applying the specified
operation(x, y) as recursive even-odd pairwise reduction to all vector
elements. operation(x, y) is repeatedly applied to each non-overlapping
even-odd element pair with indices i * 2 and i * 2 + 1 with
i in [0, Number of elements / 2). If the numbers of elements is not a
power of 2, the vector is widened with neutral elements for the reduction
at the end to the next power of 2.
These reductions support both fixed-sized and scalable vector types.
The integer reduction intrinsics, including __builtin_reduce_max,
__builtin_reduce_min, __builtin_reduce_add, __builtin_reduce_mul,
__builtin_reduce_and, __builtin_reduce_or, and __builtin_reduce_xor,
can be called in a constexpr context.
Example:
__builtin_reduce_add([e3, e2, e1, e0]) = __builtin_reduced_add([e3 + e2, e1 + e0])
= (e3 + e2) + (e1 + e0)
Let VT be a vector type and ET the element type of VT.
Name |
Operation |
Supported element types |
|---|---|---|
ET __builtin_reduce_max(VT a) |
return the largest element of the vector. The floating point result will always be a number unless all elements of the vector are NaN. |
integer and floating point types |
ET __builtin_reduce_min(VT a) |
return the smallest element of the vector. The floating point result will always be a number unless all elements of the vector are NaN. |
integer and floating point types |
ET __builtin_reduce_add(VT a) |
+ |
integer types |
ET __builtin_reduce_mul(VT a) |
* |
integer types |
ET __builtin_reduce_and(VT a) |
& |
integer types |
ET __builtin_reduce_or(VT a) |
| |
integer types |
ET __builtin_reduce_xor(VT a) |
^ |
integer types |
ET __builtin_reduce_maximum(VT a) |
return the largest element of the vector. Follows IEEE 754-2019 semantics, see LangRef for the comparison. |
floating point types |
ET __builtin_reduce_minimum(VT a) |
return the smallest element of the vector. Follows IEEE 754-2019 semantics, see LangRef for the comparison. |
floating point types |
Matrix Types¶
Clang provides an extension for matrix types, which is currently being implemented. See the draft specification for more details.
For example, the code below uses the matrix types extension to multiply two 4x4 float matrices and add the result to a third 4x4 matrix.
typedef float m4x4_t __attribute__((matrix_type(4, 4)));
m4x4_t f(m4x4_t a, m4x4_t b, m4x4_t c) {
return a + b * c;
}
The matrix type extension also supports operations on a matrix and a scalar.
typedef float m4x4_t __attribute__((matrix_type(4, 4)));
m4x4_t f(m4x4_t a) {
return (a + 23) * 12;
}
The matrix type extension supports division on a matrix and a scalar but not on a matrix and a matrix.
typedef float m4x4_t __attribute__((matrix_type(4, 4)));
m4x4_t f(m4x4_t a) {
a = a / 3.0;
return a;
}
The matrix type extension supports compound assignments for addition, subtraction, and multiplication on matrices and on a matrix and a scalar, provided their types are consistent.
typedef float m4x4_t __attribute__((matrix_type(4, 4)));
m4x4_t f(m4x4_t a, m4x4_t b) {
a += b;
a -= b;
a *= b;
a += 23;
a -= 12;
return a;
}
The matrix type extension supports explicit casts. Implicit type conversion between matrix types is not allowed.
typedef int ix5x5 __attribute__((matrix_type(5, 5)));
typedef float fx5x5 __attribute__((matrix_type(5, 5)));
fx5x5 f1(ix5x5 i, fx5x5 f) {
return (fx5x5) i;
}
template <typename X>
using matrix_4_4 = X __attribute__((matrix_type(4, 4)));
void f2() {
matrix_5_5<double> d;
matrix_5_5<int> i;
i = (matrix_5_5<int>)d;
i = static_cast<matrix_5_5<int>>(d);
}
Half-Precision Floating Point¶
Clang supports three half-precision (16-bit) floating point types:
__fp16, _Float16 and __bf16. These types are supported
in all language modes, but their support differs between targets.
A target is said to have “native support” for a type if the target
processor offers instructions for directly performing basic arithmetic
on that type. In the absence of native support, a type can still be
supported if the compiler can emulate arithmetic on the type by promoting
to float; see below for more information on this emulation.
__fp16is supported on all targets. The special semantics of this type mean that no arithmetic is ever performed directly on__fp16values; see below._Float16is supported on the following targets:32-bit ARM (natively on some architecture versions)
64-bit ARM (AArch64) (natively on ARMv8.2a and above)
AMDGPU (natively)
NVPTX (natively)
SPIR (natively)
X86 (if SSE2 is available; natively if AVX512-FP16 is also available)
RISC-V (natively if Zfh or Zhinx is available)
SystemZ (emulated)
LoongArch (emulated)
__bf16is supported on the following targets (currently never natively):32-bit ARM
64-bit ARM (AArch64)
RISC-V
X86 (when SSE2 is available)
LoongArch
(For X86, SSE2 is available on 64-bit and all recent 32-bit processors.)
__fp16 and _Float16 both use the binary16 format from IEEE
754-2008, which provides a 5-bit exponent and an 11-bit significand
(counting the implicit leading 1). __bf16 uses the bfloat16 format,
which provides an 8-bit exponent and an 8-bit significand; this is the same
exponent range as float, just with greatly reduced precision.
_Float16 and __bf16 follow the usual rules for arithmetic
floating-point types. Most importantly, this means that arithmetic operations
on operands of these types are formally performed in the type and produce
values of the type. __fp16 does not follow those rules: most operations
immediately promote operands of type __fp16 to float, and so
arithmetic operations are defined to be performed in float and so result in
a value of type float (unless further promoted because of other operands).
See below for more information on the exact specifications of these types.
When compiling arithmetic on _Float16 and __bf16 for a target without
native support, Clang will perform the arithmetic in float, inserting
extensions and truncations as necessary. This can be done in a way that
exactly matches the operation-by-operation behavior of native support,
but that can require many extra truncations and extensions. By default,
when emulating _Float16 and __bf16 arithmetic using float, Clang
does not truncate intermediate operands back to their true type unless the
operand is the result of an explicit cast or assignment. This is generally
much faster but can generate different results from strict operation-by-operation
emulation. Usually the results are more precise. This is permitted by the
C and C++ standards under the rules for excess precision in intermediate operands;
see the discussion of evaluation formats in the C standard and [expr.pre] in
the C++ standard.
The use of excess precision can be independently controlled for these two
types with the -ffloat16-excess-precision= and
-fbfloat16-excess-precision= options. Valid values include:
none: meaning to perform strict operation-by-operation emulationstandard: meaning that excess precision is permitted under the rules described in the standard, i.e. never across explicit casts or statementsfast: meaning that excess precision is permitted whenever the optimizer sees an opportunity to avoid truncations; currently this has no effect beyondstandard
The _Float16 type is an interchange floating type specified in
ISO/IEC TS 18661-3:2015 (“Floating-point extensions for C”). It will
be supported on more targets as they define ABIs for it.
The __bf16 type is a non-standard extension, but it generally follows
the rules for arithmetic interchange floating types from ISO/IEC TS
18661-3:2015. In previous versions of Clang, it was a storage-only type
that forbade arithmetic operations. It will be supported on more targets
as they define ABIs for it.
The __fp16 type was originally an ARM extension and is specified
by the ARM C Language Extensions.
Clang uses the binary16 format from IEEE 754-2008 for __fp16,
not the ARM alternative format. Operators that expect arithmetic operands
immediately promote __fp16 operands to float.
It is recommended that portable code use _Float16 instead of __fp16,
as it has been defined by the C standards committee and has behavior that is
more familiar to most programmers.
Because __fp16 operands are always immediately promoted to float, the
common real type of __fp16 and _Float16 for the purposes of the usual
arithmetic conversions is float.
A literal can be given _Float16 type using the suffix f16. For example,
3.14f16.
Because default argument promotion only applies to the standard floating-point
types, _Float16 values are not promoted to double when passed as variadic
or untyped arguments. As a consequence, some caution must be taken when using
certain library facilities with _Float16; for example, there is no printf format
specifier for _Float16, and (unlike float) it will not be implicitly promoted to
double when passed to printf, so the programmer must explicitly cast it to
double before using it with an %f or similar specifier.
Attributes on Enumerators¶
Clang allows attributes to be written on individual enumerators. This allows enumerators to be deprecated, made unavailable, etc. The attribute must appear after the enumerator name and before any initializer, like so:
enum OperationMode {
OM_Invalid,
OM_Normal,
OM_Terrified __attribute__((deprecated)),
OM_AbortOnError __attribute__((deprecated)) = 4
};
Attributes on the enum declaration do not apply to individual enumerators.
Query for this feature with __has_extension(enumerator_attributes).
C++11 Attributes on using-declarations¶
Clang allows C++-style [[]] attributes to be written on using-declarations.
For instance:
[[clang::using_if_exists]] using foo::bar;
using foo::baz [[clang::using_if_exists]];
You can test for support for this extension with
__has_extension(cxx_attributes_on_using_declarations).
‘User-Specified’ System Frameworks¶
Clang provides a mechanism by which frameworks can be built in such a way that they will always be treated as being “system frameworks”, even if they are not present in a system framework directory. This can be useful to system framework developers who want to be able to test building other applications with development builds of their framework, including the manner in which the compiler changes warning behavior for system headers.
Framework developers can opt-in to this mechanism by creating a
“.system_framework” file at the top-level of their framework. That is, the
framework should have contents like:
.../TestFramework.framework
.../TestFramework.framework/.system_framework
.../TestFramework.framework/Headers
.../TestFramework.framework/Headers/TestFramework.h
...
Clang will treat the presence of this file as an indicator that the framework should be treated as a system framework, regardless of how it was found in the framework search path. For consistency, we recommend that such files never be included in installed versions of the framework.
Checks for Standard Language Features¶
The __has_feature macro can be used to query if certain standard language
features are enabled. The __has_extension macro can be used to query if
language features are available as an extension when compiling for a standard
which does not provide them. The features which can be tested are listed here.
Since Clang 3.4, the C++ SD-6 feature test macros are also supported.
These are macros with names of the form __cpp_<feature_name>, and are
intended to be a portable way to query the supported features of the compiler.
See the C++ status page for
information on the version of SD-6 supported by each Clang release, and the
macros provided by that revision of the recommendations.
C++98¶
The features listed below are part of the C++98 standard. These features are enabled by default when compiling C++ code.
C++ exceptions¶
Use __has_feature(cxx_exceptions) to determine if C++ exceptions have been
enabled. For example, compiling code with -fno-exceptions disables C++
exceptions.
C++ RTTI¶
Use __has_feature(cxx_rtti) to determine if C++ RTTI has been enabled. For
example, compiling code with -fno-rtti disables the use of RTTI.
C++11¶
The features listed below are part of the C++11 standard. As a result, all
these features are enabled with the -std=c++11 or -std=gnu++11 option
when compiling C++ code.
C++11 SFINAE includes access control¶
Use __has_feature(cxx_access_control_sfinae) or
__has_extension(cxx_access_control_sfinae) to determine whether
access-control errors (e.g., calling a private constructor) are considered to
be template argument deduction errors (aka SFINAE errors), per C++ DR1170.
C++11 alias templates¶
Use __has_feature(cxx_alias_templates) or
__has_extension(cxx_alias_templates) to determine if support for C++11’s
alias declarations and alias templates is enabled.
C++11 alignment specifiers¶
Use __has_feature(cxx_alignas) or __has_extension(cxx_alignas) to
determine if support for alignment specifiers using alignas is enabled.
Use __has_feature(cxx_alignof) or __has_extension(cxx_alignof) to
determine if support for the alignof keyword is enabled.
C++11 attributes¶
Use __has_feature(cxx_attributes) or __has_extension(cxx_attributes) to
determine if support for attribute parsing with C++11’s square bracket notation
is enabled.
C++11 generalized constant expressions¶
Use __has_feature(cxx_constexpr) to determine if support for generalized
constant expressions (e.g., constexpr) is enabled.
C++11 decltype()¶
Use __has_feature(cxx_decltype) or __has_extension(cxx_decltype) to
determine if support for the decltype() specifier is enabled. C++11’s
decltype does not require type-completeness of a function call expression.
Use __has_feature(cxx_decltype_incomplete_return_types) or
__has_extension(cxx_decltype_incomplete_return_types) to determine if
support for this feature is enabled.
C++11 default template arguments in function templates¶
Use __has_feature(cxx_default_function_template_args) or
__has_extension(cxx_default_function_template_args) to determine if support
for default template arguments in function templates is enabled.
C++11 defaulted functions¶
Use __has_feature(cxx_defaulted_functions) or
__has_extension(cxx_defaulted_functions) to determine if support for
defaulted function definitions (with = default) is enabled.
C++11 delegating constructors¶
Use __has_feature(cxx_delegating_constructors) to determine if support for
delegating constructors is enabled.
C++11 deleted functions¶
Use __has_feature(cxx_deleted_functions) or
__has_extension(cxx_deleted_functions) to determine if support for deleted
function definitions (with = delete) is enabled.
C++11 explicit conversion functions¶
Use __has_feature(cxx_explicit_conversions) to determine if support for
explicit conversion functions is enabled.
C++11 generalized initializers¶
Use __has_feature(cxx_generalized_initializers) to determine if support for
generalized initializers (using braced lists and std::initializer_list) is
enabled.
C++11 implicit move constructors/assignment operators¶
Use __has_feature(cxx_implicit_moves) to determine if Clang will implicitly
generate move constructors and move assignment operators where needed.
C++11 inheriting constructors¶
Use __has_feature(cxx_inheriting_constructors) to determine if support for
inheriting constructors is enabled.
C++11 inline namespaces¶
Use __has_feature(cxx_inline_namespaces) or
__has_extension(cxx_inline_namespaces) to determine if support for inline
namespaces is enabled.
C++11 lambdas¶
Use __has_feature(cxx_lambdas) or __has_extension(cxx_lambdas) to
determine if support for lambdas is enabled.
C++11 local and unnamed types as template arguments¶
Use __has_feature(cxx_local_type_template_args) or
__has_extension(cxx_local_type_template_args) to determine if support for
local and unnamed types as template arguments is enabled.
C++11 noexcept¶
Use __has_feature(cxx_noexcept) or __has_extension(cxx_noexcept) to
determine if support for noexcept exception specifications is enabled.
C++11 in-class non-static data member initialization¶
Use __has_feature(cxx_nonstatic_member_init) to determine whether in-class
initialization of non-static data members is enabled.
C++11 nullptr¶
Use __has_feature(cxx_nullptr) or __has_extension(cxx_nullptr) to
determine if support for nullptr is enabled.
C++11 override control¶
Use __has_feature(cxx_override_control) or
__has_extension(cxx_override_control) to determine if support for the
override control keywords is enabled.
C++11 reference-qualified functions¶
Use __has_feature(cxx_reference_qualified_functions) or
__has_extension(cxx_reference_qualified_functions) to determine if support
for reference-qualified functions (e.g., member functions with & or &&
applied to *this) is enabled.
C++11 range-based for loop¶
Use __has_feature(cxx_range_for) or __has_extension(cxx_range_for) to
determine if support for the range-based for loop is enabled.
C++11 raw string literals¶
Use __has_feature(cxx_raw_string_literals) to determine if support for raw
string literals (e.g., R"x(foo\bar)x") is enabled.
C++11 rvalue references¶
Use __has_feature(cxx_rvalue_references) or
__has_extension(cxx_rvalue_references) to determine if support for rvalue
references is enabled.
C++11 static_assert()¶
Use __has_feature(cxx_static_assert) or
__has_extension(cxx_static_assert) to determine if support for compile-time
assertions using static_assert is enabled.
C++11 thread_local¶
Use __has_feature(cxx_thread_local) to determine if support for
thread_local variables is enabled.
C++11 type inference¶
Use __has_feature(cxx_auto_type) or __has_extension(cxx_auto_type) to
determine C++11 type inference is supported using the auto specifier. If
this is disabled, auto will instead be a storage class specifier, as in C
or C++98.
C++11 strongly typed enumerations¶
Use __has_feature(cxx_strong_enums) or
__has_extension(cxx_strong_enums) to determine if support for strongly
typed, scoped enumerations is enabled.
C++11 trailing return type¶
Use __has_feature(cxx_trailing_return) or
__has_extension(cxx_trailing_return) to determine if support for the
alternate function declaration syntax with trailing return type is enabled.
C++11 Unicode string literals¶
Use __has_feature(cxx_unicode_literals) to determine if support for Unicode
string literals is enabled.
C++11 unrestricted unions¶
Use __has_feature(cxx_unrestricted_unions) to determine if support for
unrestricted unions is enabled.
C++11 user-defined literals¶
Use __has_feature(cxx_user_literals) to determine if support for
user-defined literals is enabled.
C++11 variadic templates¶
Use __has_feature(cxx_variadic_templates) or
__has_extension(cxx_variadic_templates) to determine if support for
variadic templates is enabled.
C++14¶
The features listed below are part of the C++14 standard. As a result, all
these features are enabled with the -std=C++14 or -std=gnu++14 option
when compiling C++ code.
C++14 binary literals¶
Use __has_feature(cxx_binary_literals) or
__has_extension(cxx_binary_literals) to determine whether
binary literals (for instance, 0b10010) are recognized. Clang supports this
feature as an extension in all language modes.
C++14 contextual conversions¶
Use __has_feature(cxx_contextual_conversions) or
__has_extension(cxx_contextual_conversions) to determine if the C++14 rules
are used when performing an implicit conversion for an array bound in a
new-expression, the operand of a delete-expression, an integral constant
expression, or a condition in a switch statement.
C++14 decltype(auto)¶
Use __has_feature(cxx_decltype_auto) or
__has_extension(cxx_decltype_auto) to determine if support
for the decltype(auto) placeholder type is enabled.
C++14 default initializers for aggregates¶
Use __has_feature(cxx_aggregate_nsdmi) or
__has_extension(cxx_aggregate_nsdmi) to determine if support
for default initializers in aggregate members is enabled.
C++14 digit separators¶
Use __cpp_digit_separators to determine if support for digit separators
using single quotes (for instance, 10'000) is enabled. At this time, there
is no corresponding __has_feature name
C++14 generalized lambda capture¶
Use __has_feature(cxx_init_captures) or
__has_extension(cxx_init_captures) to determine if support for
lambda captures with explicit initializers is enabled
(for instance, [n(0)] { return ++n; }).
C++14 generic lambdas¶
Use __has_feature(cxx_generic_lambdas) or
__has_extension(cxx_generic_lambdas) to determine if support for generic
(polymorphic) lambdas is enabled
(for instance, [] (auto x) { return x + 1; }).
C++14 relaxed constexpr¶
Use __has_feature(cxx_relaxed_constexpr) or
__has_extension(cxx_relaxed_constexpr) to determine if variable
declarations, local variable modification, and control flow constructs
are permitted in constexpr functions.
C++14 return type deduction¶
Use __has_feature(cxx_return_type_deduction) or
__has_extension(cxx_return_type_deduction) to determine if support
for return type deduction for functions (using auto as a return type)
is enabled.
C++14 runtime-sized arrays¶
Use __has_feature(cxx_runtime_array) or
__has_extension(cxx_runtime_array) to determine if support
for arrays of runtime bound (a restricted form of variable-length arrays)
is enabled.
Clang’s implementation of this feature is incomplete.
C++14 variable templates¶
Use __has_feature(cxx_variable_templates) or
__has_extension(cxx_variable_templates) to determine if support for
templated variable declarations is enabled.
C++ type aware allocators¶
Use __has_extension(cxx_type_aware_allocators) to determine the existence of
support for the future C++2d type aware allocator feature. For full details see
C++ Type Aware Allocators for additional details.
C11¶
The features listed below are part of the C11 standard. As a result, all these
features are enabled with the -std=c11 or -std=gnu11 option when
compiling C code. Additionally, because these features are all
backward-compatible, they are available as extensions in all language modes.
C11 alignment specifiers¶
Use __has_feature(c_alignas) or __has_extension(c_alignas) to determine
if support for alignment specifiers using _Alignas is enabled.
Use __has_feature(c_alignof) or __has_extension(c_alignof) to determine
if support for the _Alignof keyword is enabled.
C11 atomic operations¶
Use __has_feature(c_atomic) or __has_extension(c_atomic) to determine
if support for atomic types using _Atomic is enabled. Clang also provides
a set of builtins which can be used to implement
the <stdatomic.h> operations on _Atomic types. Use
__has_include(<stdatomic.h>) to determine if C11’s <stdatomic.h> header
is available.
Clang will use the system’s <stdatomic.h> header when one is available, and
will otherwise use its own. When using its own, implementations of the atomic
operations are provided as macros. In the cases where C11 also requires a real
function, this header provides only the declaration of that function (along
with a shadowing macro implementation), and you must link to a library which
provides a definition of the function if you use it instead of the macro.
C11 generic selections¶
Use __has_feature(c_generic_selections) or
__has_extension(c_generic_selections) to determine if support for generic
selections is enabled.
As an extension, the C11 generic selection expression is available in all languages supported by Clang. The syntax is the same as that given in the C11 standard.
In C, type compatibility is decided according to the rules given in the appropriate standard, but in C++, which lacks the type compatibility rules used in C, types are considered compatible only if they are equivalent.
Clang also supports an extended form of _Generic with a controlling type
rather than a controlling expression. Unlike with a controlling expression, a
controlling type argument does not undergo any conversions and thus is suitable
for use when trying to match qualified types, incomplete types, or function
types. Variable-length array types lack the necessary compile-time information
to resolve which association they match with and thus are not allowed as a
controlling type argument.
Use __has_extension(c_generic_selection_with_controlling_type) to determine
if support for this extension is enabled.
C11 _Static_assert()¶
Use __has_feature(c_static_assert) or __has_extension(c_static_assert)
to determine if support for compile-time assertions using _Static_assert is
enabled.
C11 _Thread_local¶
Use __has_feature(c_thread_local) or __has_extension(c_thread_local)
to determine if support for _Thread_local variables is enabled.
C2y¶
The features listed below are part of the C2y standard. As a result, all these
features are enabled with the -std=c2y or -std=gnu2y option when
compiling C code.
C2y _Countof¶
Use __has_feature(c_countof) (in C2y or later mode) or
__has_extension(c_countof) (in C23 or earlier mode) to determine if support
for the _Countof operator is enabled. This feature is not available in C++
mode.
Modules¶
Use __has_feature(modules) to determine if Modules have been enabled.
For example, compiling code with -fmodules enables the use of Modules.
More information could be found here.
Language Extensions Back-ported to Previous Standards¶
Feature |
Feature Test Macro |
Introduced In |
Backported To |
|---|---|---|---|
variadic templates |
__cpp_variadic_templates |
C++11 |
C++03 |
Alias templates |
__cpp_alias_templates |
C++11 |
C++03 |
Non-static data member initializers |
__cpp_nsdmi |
C++11 |
C++03 |
Range-based |
__cpp_range_based_for |
C++11 |
C++03 |
RValue references |
__cpp_rvalue_references |
C++11 |
C++03 |
Attributes |
__cpp_attributes |
C++11 |
C++03 |
Lambdas |
__cpp_lambdas |
C++11 |
C++03 |
Generalized lambda captures |
__cpp_init_captures |
C++14 |
C++03 |
Generic lambda expressions |
__cpp_generic_lambdas |
C++14 |
C++03 |
variable templates |
__cpp_variable_templates |
C++14 |
C++03 |
Binary literals |
__cpp_binary_literals |
C++14 |
C++03 |
Relaxed constexpr |
__cpp_constexpr |
C++14 |
C++11 |
Static assert with no message |
__cpp_static_assert >= 201411L |
C++17 |
C++11 |
Pack expansion in generalized lambda-capture |
__cpp_init_captures |
C++17 |
C++03 |
|
__cpp_if_constexpr |
C++17 |
C++11 |
fold expressions |
__cpp_fold_expressions |
C++17 |
C++03 |
Lambda capture of *this by value |
__cpp_capture_star_this |
C++17 |
C++03 |
Attributes on enums |
__cpp_enumerator_attributes |
C++17 |
C++03 |
Guaranteed copy elision |
__cpp_guaranteed_copy_elision |
C++17 |
C++03 |
Hexadecimal floating literals |
__cpp_hex_float |
C++17 |
C++03 |
|
__cpp_inline_variables |
C++17 |
C++03 |
Attributes on namespaces |
__cpp_namespace_attributes |
C++17 |
C++11 |
Structured bindings |
__cpp_structured_bindings |
C++17 |
C++03 |
template template arguments |
__cpp_template_template_args |
C++17 |
C++03 |
Familiar template syntax for generic lambdas |
__cpp_generic_lambdas |
C++20 |
C++03 |
|
__cpp_multidimensional_subscript |
C++20 |
C++03 |
Designated initializers |
__cpp_designated_initializers |
C++20 |
C++03 |
Conditional |
__cpp_conditional_explicit |
C++20 |
C++03 |
|
__cpp_using_enum |
C++20 |
C++03 |
|
__cpp_if_consteval |
C++23 |
C++20 |
|
__cpp_static_call_operator |
C++23 |
C++03 |
Attributes on Lambda-Expressions |
C++23 |
C++11 |
|
Attributes on Structured Bindings |
__cpp_structured_bindings |
C++26 |
C++03 |
Packs in Structured Bindings |
__cpp_structured_bindings |
C++26 |
C++03 |
Structured binding declaration as a condition |
__cpp_structured_bindings |
C++26 |
C++98 |
Static assert with user-generated message |
__cpp_static_assert >= 202306L |
C++26 |
C++11 |
Pack Indexing |
__cpp_pack_indexing |
C++26 |
C++03 |
|
__cpp_deleted_function |
C++26 |
C++03 |
Variadic Friends |
__cpp_variadic_friend |
C++26 |
C++03 |
Trivial Relocatability |
__cpp_trivial_relocatability |
C++26 |
C++03 |
Designated initializers (N494) |
C99 |
C89 |
|
Array & element qualification (N2607) |
C23 |
C89 |
|
Attributes (N2335) |
C23 |
C89 |
|
|
C23 |
C89, C++ |
|
Octal literals prefixed with |
C2y |
C89, C++ |
|
|
C2y |
C89 |
Builtin type aliases¶
Clang provides a few builtin aliases to improve the throughput of certain metaprogramming facilities.
__builtin_common_type¶
template <template <class... Args> class BaseTemplate,
template <class TypeMember> class HasTypeMember,
class HasNoTypeMember,
class... Ts>
using __builtin_common_type = ...;
This alias is used for implementing std::common_type. If std::common_type should contain a type member,
it is an alias to HasTypeMember<TheCommonType>. Otherwise it is an alias to HasNoTypeMember. The
BaseTemplate is usually std::common_type. Ts are the arguments to std::common_type.
__type_pack_element¶
template <std::size_t Index, class... Ts>
using __type_pack_element = ...;
This alias returns the type at Index in the parameter pack Ts.
__make_integer_seq¶
template <template <class IntSeqT, IntSeqT... Ints> class IntSeq, class T, T N>
using __make_integer_seq = ...;
This alias returns IntSeq instantiated with IntSeqT = T``and ``Ints being the pack 0, ..., N - 1.
Type Trait Primitives¶
Type trait primitives are special builtin constant expressions that can be used by the standard C++ library to facilitate or simplify the implementation of user-facing type traits in the <type_traits> header.
They are not intended to be used directly by user code because they are implementation-defined and subject to change – as such they’re tied closely to the supported set of system headers, currently:
LLVM’s own libc++
GNU libstdc++
The Microsoft standard C++ library
Clang supports the GNU C++ type traits and a subset of the Microsoft Visual C++ type traits, as well as nearly all of the Embarcadero C++ type traits.
The following type trait primitives are supported by Clang. Those traits marked
(C++) provide implementations for type traits specified by the C++ standard;
__X(...) has the same semantics and constraints as the corresponding
std::X_t<...> or std::X_v<...> type trait.
__array_rank(type)(Embarcadero): Returns the number of levels of array in the typetype:0iftypeis not an array type, and__array_rank(element) + 1iftypeis an array ofelement.__array_extent(type, dim)(Embarcadero): Thedim’th array bound in the typetype, or0ifdim >= __array_rank(type).__builtin_is_implicit_lifetime(C++, GNU, Microsoft)__builtin_is_virtual_base_of(C++, GNU, Microsoft)__can_pass_in_regs(C++) Returns whether a class can be passed in registers under the current ABI. This type can only be applied to unqualified class types. This is not a portable type trait.__has_nothrow_assign(GNU, Microsoft, Embarcadero): Deprecated, use__is_nothrow_assignableinstead.__has_nothrow_move_assign(GNU, Microsoft): Deprecated, use__is_nothrow_assignableinstead.__has_nothrow_copy(GNU, Microsoft): Deprecated, use__is_nothrow_constructibleinstead.__has_nothrow_constructor(GNU, Microsoft): Deprecated, use__is_nothrow_constructibleinstead.__has_trivial_assign(GNU, Microsoft, Embarcadero): Deprecated, use__is_trivially_assignableinstead.__has_trivial_move_assign(GNU, Microsoft): Deprecated, use__is_trivially_assignableinstead.__has_trivial_copy(GNU, Microsoft): Deprecated, use__is_trivially_copyableinstead.__has_trivial_constructor(GNU, Microsoft): Deprecated, use__is_trivially_constructibleinstead.__has_trivial_move_constructor(GNU, Microsoft): Deprecated, use__is_trivially_constructibleinstead.__has_trivial_destructor(GNU, Microsoft, Embarcadero): Deprecated, use__is_trivially_destructibleinstead.__has_unique_object_representations(C++, GNU)__has_virtual_destructor(C++, GNU, Microsoft, Embarcadero)__is_abstract(C++, GNU, Microsoft, Embarcadero)__is_aggregate(C++, GNU, Microsoft)__is_arithmetic(C++, Embarcadero)__is_array(C++, Embarcadero)__is_assignable(C++, MSVC 2015)__is_base_of(C++, GNU, Microsoft, Embarcadero)__is_bounded_array(C++, GNU, Microsoft, Embarcadero)__is_class(C++, GNU, Microsoft, Embarcadero)__is_complete_type(type)(Embarcadero): Returntrueiftypeis a complete type. Warning: this trait is dangerous because it can return different values at different points in the same program.__is_compound(C++, Embarcadero)__is_const(C++, Embarcadero)__is_constructible(C++, MSVC 2013)__is_convertible(C++, Embarcadero)__is_nothrow_convertible(C++, GNU)__is_convertible_to(Microsoft): Synonym for__is_convertible.__is_destructible(C++, MSVC 2013)__is_empty(C++, GNU, Microsoft, Embarcadero)__is_enum(C++, GNU, Microsoft, Embarcadero)__is_final(C++, GNU, Microsoft)__is_floating_point(C++, Embarcadero)__is_function(C++, Embarcadero)__is_fundamental(C++, Embarcadero)__is_integral(C++, Embarcadero)__is_interface_class(Microsoft): Returnsfalse, even for types defined with__interface.__is_layout_compatible(C++, GNU, Microsoft)__is_literal(Clang): Synonym for__is_literal_type.__is_literal_type(C++, GNU, Microsoft): Note, the corresponding standard trait was deprecated in C++17 and removed in C++20.__is_lvalue_reference(C++, Embarcadero)__is_member_object_pointer(C++, Embarcadero)__is_member_function_pointer(C++, Embarcadero)__is_member_pointer(C++, Embarcadero)__is_nothrow_assignable(C++, MSVC 2013)__is_nothrow_constructible(C++, MSVC 2013)__is_nothrow_destructible(C++, MSVC 2013)__is_object(C++, Embarcadero)__is_pod(C++, GNU, Microsoft, Embarcadero): Note, the corresponding standard trait was deprecated in C++20.__is_pointer(C++, Embarcadero)__is_pointer_interconvertible_base_of(C++, GNU, Microsoft)__is_polymorphic(C++, GNU, Microsoft, Embarcadero)__is_reference(C++, Embarcadero)__is_rvalue_reference(C++, Embarcadero)__is_same(C++, Embarcadero)__is_same_as(GCC): Synonym for__is_same.__is_scalar(C++, Embarcadero)__is_scoped_enum(C++, GNU, Microsoft, Embarcadero)__is_sealed(Microsoft): Synonym for__is_final.__is_signed(C++, Embarcadero): Returns false for enumeration types, and returns true for floating-point types. Note, before Clang 10, returned true for enumeration types if the underlying type was signed, and returned false for floating-point types.__is_standard_layout(C++, GNU, Microsoft, Embarcadero)__is_trivial(C++, GNU, Microsoft, Embarcadero)__is_trivially_assignable(C++, GNU, Microsoft)__is_trivially_constructible(C++, GNU, Microsoft)__is_trivially_copyable(C++, GNU, Microsoft)__is_trivially_destructible(C++, MSVC 2013)__is_trivially_relocatable(Clang) (Deprecated, use__builtin_is_cpp_trivially_relocatableinstead). Returns true if moving an object of the given type, and then destroying the source object, is known to be functionally equivalent to copying the underlying bytes and then dropping the source object on the floor. This is true of trivial types, C++26 relocatable types, and types which were made trivially relocatable via theclang::trivial_abiattribute. This trait is deprecated and should be replaced by__builtin_is_cpp_trivially_relocatable. Note however that it is generally unsafe to relocate a C++-relocatable type withmemcpyormemmove; use__builtin_trivially_relocate.__builtin_is_cpp_trivially_relocatable(C++): Returns true if an object is trivially relocatable, as defined by the C++26 standard [meta.unary.prop]. Note that when relocating the caller code should ensure that if the object is polymorphic, the dynamic type is of the most derived type. Padding bytes should not be copied.__builtin_is_replaceable(C++): Returns true if an object is replaceable, as defined by the C++26 standard [meta.unary.prop].__is_trivially_equality_comparable(Clang): Returns true if comparing two objects of the provided type is known to be equivalent to comparing their object representations. Note that types containing padding bytes are never trivially equality comparable.__is_unbounded_array(C++, GNU, Microsoft, Embarcadero)__is_union(C++, GNU, Microsoft, Embarcadero)__is_unsigned(C++, Embarcadero): Returns false for enumeration types. Note, before Clang 13, returned true for enumeration types if the underlying type was unsigned.__is_void(C++, Embarcadero)__is_volatile(C++, Embarcadero)__reference_binds_to_temporary(T, U)(Clang): Determines whether a reference of typeTbound to an expression of typeUwould bind to a materialized temporary object. IfTis not a reference type the result is false. Note this trait will also return false when the initialization ofTfromUis ill-formed. Deprecated, use__reference_constructs_from_temporary.__reference_constructs_from_temporary(T, U)(C++) Returns true if a referenceTcan be direct-initialized from a temporary of type a non-cv-qualifiedU.__reference_converts_from_temporary(T, U)(C++)Returns true if a reference
Tcan be copy-initialized from a temporary of type a non-cv-qualifiedU.
__underlying_type(C++, GNU, Microsoft)
In addition, the following expression traits are supported:
__is_lvalue_expr(e)(Embarcadero): Returns true ifeis an lvalue expression. Deprecated, use__is_lvalue_reference(decltype((e)))instead.__is_rvalue_expr(e)(Embarcadero): Returns true ifeis a prvalue expression. Deprecated, use!__is_reference(decltype((e)))instead.
There are multiple ways to detect support for a type trait __X in the
compiler, depending on the oldest version of Clang you wish to support.
From Clang 10 onwards,
__has_builtin(__X)can be used.From Clang 6 onwards,
!__is_identifier(__X)can be used.From Clang 3 onwards,
__has_feature(X)can be used, but only supports the following traits:__has_nothrow_assign__has_nothrow_copy__has_nothrow_constructor__has_trivial_assign__has_trivial_copy__has_trivial_constructor__has_trivial_destructor__has_virtual_destructor__is_abstract__is_base_of__is_class__is_constructible__is_convertible_to__is_empty__is_enum__is_final__is_literal__is_standard_layout__is_pod__is_polymorphic__is_sealed__is_trivial__is_trivially_assignable__is_trivially_constructible__is_trivially_copyable__is_union__underlying_type
A simplistic usage example as might be seen in standard C++ headers follows:
#if __has_builtin(__is_convertible_to)
template<typename From, typename To>
struct is_convertible_to {
static const bool value = __is_convertible_to(From, To);
};
#else
// Emulate type trait for compatibility with other compilers.
#endif
__builtin_structured_binding_size (C++)¶
The __builtin_structured_binding_size(T) type trait returns
the structured binding size ([dcl.struct.bind]) of type T
This is equivalent to the size of the pack p in auto&& [...p] = declval<T&>();.
If the argument cannot be decomposed, __builtin_structured_binding_size(T)
is not a valid expression (__builtin_structured_binding_size is SFINAE-friendly).
builtin arrays, builtin SIMD vectors, builtin complex types, tuple-like types, and decomposable class types are decomposable types.
A type is considered a valid tuple-like if std::tuple_size_v<T> is a valid expression,
even if there is no valid std::tuple_element specialization or suitable
get function for that type.
template<std::size_t Idx, typename T>
requires (Idx < __builtin_structured_binding_size(T))
decltype(auto) constexpr get_binding(T&& obj) {
auto && [...p] = std::forward<T>(obj);
return p...[Idx];
}
struct S { int a = 0, b = 42; };
static_assert(__builtin_structured_binding_size(S) == 2);
static_assert(get_binding<1>(S{}) == 42);
Blocks¶
The syntax and high level language feature description is in BlockLanguageSpec. Implementation and ABI details for the clang implementation are in Block-ABI-Apple.
Query for this feature with __has_extension(blocks).
ASM Goto with Output Constraints¶
Outputs may be used along any branches from the asm goto whether the
branches are taken or not.
Query for this feature with __has_extension(gnu_asm_goto_with_outputs).
Prior to clang-16, the output may only be used safely when the indirect
branches are not taken. Query for this difference with
__has_extension(gnu_asm_goto_with_outputs_full).
When using tied-outputs (i.e. outputs that are inputs and outputs, not just outputs) with the +r constraint, there is a hidden input that’s created before the label, so numeric references to operands must account for that.
int foo(int x) {
// %0 and %1 both refer to x
// %l2 refers to err
asm goto("# %0 %1 %l2" : "+r"(x) : : : err);
return x;
err:
return -1;
}
This was changed to match GCC in clang-13; for better portability, symbolic references can be used instead of numeric references.
int foo(int x) {
asm goto("# %[x] %l[err]" : [x]"+r"(x) : : : err);
return x;
err:
return -1;
}
ASM Goto versus Branch Target Enforcement¶
Some target architectures implement branch target enforcement, by requiring
indirect (register-controlled) branch instructions to jump only to locations
marked by a special instruction (such as AArch64 bti).
The assembler code inside an asm goto statement is expected not to use a
branch instruction of that kind to transfer control to any of its destination
labels. Therefore, using a label in an asm goto statement does not cause
clang to put a bti or equivalent instruction at the label.
Constexpr strings in GNU ASM statements¶
In C++11 mode (and greater), Clang supports specifying the template, constraints, and clobber strings with a parenthesized constant expression producing an object with the following member functions
constexpr const char* data() const;
constexpr size_t size() const;
such as std::string, std::string_view, std::vector<char>.
This mechanism follow the same rules as static_assert messages in
C++26, see [dcl.pre]/p12.
Query for this feature with __has_extension(gnu_asm_constexpr_strings).
int foo() {
asm((std::string_view("nop")) ::: (std::string_view("memory")));
}
Objective-C Features¶
Automatic reference counting¶
Clang provides support for automated reference counting in Objective-C, which eliminates the need
for manual retain/release/autorelease message sends. There are three
feature macros associated with automatic reference counting:
__has_feature(objc_arc) indicates the availability of automated reference
counting in general, while __has_feature(objc_arc_weak) indicates that
automated reference counting also includes support for __weak pointers to
Objective-C objects. __has_feature(objc_arc_fields) indicates that C structs
are allowed to have fields that are pointers to Objective-C objects managed by
automatic reference counting.
Weak references¶
Clang supports ARC-style weak and unsafe references in Objective-C even
outside of ARC mode. Weak references must be explicitly enabled with
the -fobjc-weak option; use __has_feature((objc_arc_weak))
to test whether they are enabled. Unsafe references are enabled
unconditionally. ARC-style weak and unsafe references cannot be used
when Objective-C garbage collection is enabled.
Except as noted below, the language rules for the __weak and
__unsafe_unretained qualifiers (and the weak and
unsafe_unretained property attributes) are just as laid out
in the ARC specification.
In particular, note that some classes do not support forming weak
references to their instances, and note that special care must be
taken when storing weak references in memory where initialization
and deinitialization are outside the responsibility of the compiler
(such as in malloc-ed memory).
Loading from a __weak variable always implicitly retains the
loaded value. In non-ARC modes, this retain is normally balanced
by an implicit autorelease. This autorelease can be suppressed
by performing the load in the receiver position of a -retain
message send (e.g. [weakReference retain]); note that this performs
only a single retain (the retain done when primitively loading from
the weak reference).
For the most part, __unsafe_unretained in non-ARC modes is just the
default behavior of variables and therefore is not needed. However,
it does have an effect on the semantics of block captures: normally,
copying a block which captures an Objective-C object or block pointer
causes the captured pointer to be retained or copied, respectively,
but that behavior is suppressed when the captured variable is qualified
with __unsafe_unretained.
Note that the __weak qualifier formerly meant the GC qualifier in
all non-ARC modes and was silently ignored outside of GC modes. It now
means the ARC-style qualifier in all non-GC modes and is no longer
allowed if not enabled by either -fobjc-arc or -fobjc-weak.
It is expected that -fobjc-weak will eventually be enabled by default
in all non-GC Objective-C modes.
Enumerations with a fixed underlying type¶
Clang provides support for C++11 enumerations with a fixed underlying type within Objective-C and C prior to C23. For example, one can write an enumeration type as:
typedef enum : unsigned char { Red, Green, Blue } Color;
This specifies that the underlying type, which is used to store the enumeration
value, is unsigned char.
Use __has_feature(objc_fixed_enum) to determine whether support for fixed
underlying types is available in Objective-C.
Use __has_extension(c_fixed_enum) to determine whether support for fixed
underlying types is available in C prior to C23. This will also report true in C23
and later modes as the functionality is available even if it’s not an extension in
those modes.
Use __has_feature(c_fixed_enum) to determine whether support for fixed
underlying types is available in C23 and later.
Interoperability with C++11 lambdas¶
Clang provides interoperability between C++11 lambdas and blocks-based APIs, by
permitting a lambda to be implicitly converted to a block pointer with the
corresponding signature. For example, consider an API such as NSArray’s
array-sorting method:
- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr;
NSComparator is simply a typedef for the block pointer NSComparisonResult
(^)(id, id), and parameters of this type are generally provided with block
literals as arguments. However, one can also use a C++11 lambda so long as it
provides the same signature (in this case, accepting two parameters of type
id and returning an NSComparisonResult):
NSArray *array = @[@"string 1", @"string 21", @"string 12", @"String 11",
@"String 02"];
const NSStringCompareOptions comparisonOptions
= NSCaseInsensitiveSearch | NSNumericSearch |
NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSLocale *currentLocale = [NSLocale currentLocale];
NSArray *sorted
= [array sortedArrayUsingComparator:[=](id s1, id s2) -> NSComparisonResult {
NSRange string1Range = NSMakeRange(0, [s1 length]);
return [s1 compare:s2 options:comparisonOptions
range:string1Range locale:currentLocale];
}];
NSLog(@"sorted: %@", sorted);
This code relies on an implicit conversion from the type of the lambda expression (an unnamed, local class type called the closure type) to the corresponding block pointer type. The conversion itself is expressed by a conversion operator in that closure type that produces a block pointer with the same signature as the lambda itself, e.g.,
operator NSComparisonResult (^)(id, id)() const;
This conversion function returns a new block that simply forwards the two
parameters to the lambda object (which it captures by copy), then returns the
result. The returned block is first copied (with Block_copy) and then
autoreleased. As an optimization, if a lambda expression is immediately
converted to a block pointer (as in the first example, above), then the block
is not copied and autoreleased: rather, it is given the same lifetime as a
block literal written at that point in the program, which avoids the overhead
of copying a block to the heap in the common case.
The conversion from a lambda to a block pointer is only available in Objective-C++, and not in C++ with blocks, due to its use of Objective-C memory management (autorelease).
Object Literals and Subscripting¶
Clang provides support for Object Literals and Subscripting in Objective-C, which simplifies common Objective-C
programming patterns, makes programs more concise, and improves the safety of
container creation. There are several feature macros associated with object
literals and subscripting: __has_feature(objc_array_literals) tests the
availability of array literals; __has_feature(objc_dictionary_literals)
tests the availability of dictionary literals;
__has_feature(objc_subscripting) tests the availability of object
subscripting.
Objective-C Autosynthesis of Properties¶
Clang provides support for autosynthesis of declared properties. Using this
feature, clang provides default synthesis of those properties not declared
@dynamic and not having user provided backing getter and setter methods.
__has_feature(objc_default_synthesize_properties) checks for availability
of this feature in version of clang being used.
Objective-C retaining behavior attributes¶
In Objective-C, functions and methods are generally assumed to follow the
Cocoa Memory Management
conventions for ownership of object arguments and
return values. However, there are exceptions, and so Clang provides attributes
to allow these exceptions to be documented. This are used by ARC and the
static analyzer Some exceptions may be
better described using the objc_method_family attribute instead.
Usage: The ns_returns_retained, ns_returns_not_retained,
ns_returns_autoreleased, cf_returns_retained, and
cf_returns_not_retained attributes can be placed on methods and functions
that return Objective-C or CoreFoundation objects. They are commonly placed at
the end of a function prototype or method declaration:
id foo() __attribute__((ns_returns_retained));
- (NSString *)bar:(int)x __attribute__((ns_returns_retained));
The *_returns_retained attributes specify that the returned object has a +1
retain count. The *_returns_not_retained attributes specify that the return
object has a +0 retain count, even if the normal convention for its selector
would be +1. ns_returns_autoreleased specifies that the returned object is
+0, but is guaranteed to live at least as long as the next flush of an
autorelease pool.
Usage: The ns_consumed and cf_consumed attributes can be placed on
a parameter declaration; they specify that the argument is expected to have a
+1 retain count, which will be balanced in some way by the function or method.
The ns_consumes_self attribute can only be placed on an Objective-C
method; it specifies that the method expects its self parameter to have a
+1 retain count, which it will balance in some way.
void foo(__attribute__((ns_consumed)) NSString *string);
- (void) bar __attribute__((ns_consumes_self));
- (void) baz:(id) __attribute__((ns_consumed)) x;
Further examples of these attributes are available in the static analyzer’s list of annotations for analysis.
Query for these features with __has_attribute(ns_consumed),
__has_attribute(ns_returns_retained), etc.
Objective-C @available¶
It is possible to use the newest SDK but still build a program that can run on
older versions of macOS and iOS by passing -mmacos-version-min= /
-miphoneos-version-min=.
Before LLVM 5.0, when calling a function that exists only in the OS that’s
newer than the target OS (as determined by the minimum deployment version),
programmers had to carefully check if the function exists at runtime, using
null checks for weakly-linked C functions, +class for Objective-C classes,
and -respondsToSelector: or +instancesRespondToSelector: for
Objective-C methods. If such a check was missed, the program would compile
fine, run fine on newer systems, but crash on older systems.
As of LLVM 5.0, -Wunguarded-availability uses the availability attributes together
with the new @available() keyword to assist with this issue.
When a method that’s introduced in the OS newer than the target OS is called, a
-Wunguarded-availability warning is emitted if that call is not guarded:
void my_fun(NSSomeClass* var) {
// If fancyNewMethod was added in e.g. macOS 10.12, but the code is
// built with -mmacos-version-min=10.11, then this unconditional call
// will emit a -Wunguarded-availability warning:
[var fancyNewMethod];
}
To fix the warning and to avoid the crash on macOS 10.11, wrap it in
if(@available()):
void my_fun(NSSomeClass* var) {
if (@available(macOS 10.12, *)) {
[var fancyNewMethod];
} else {
// Put fallback behavior for old macOS versions (and for non-mac
// platforms) here.
}
}
The * is required and means that platforms not explicitly listed will take
the true branch, and the compiler will emit -Wunguarded-availability
warnings for unlisted platforms based on those platform’s deployment target.
More than one platform can be listed in @available():
void my_fun(NSSomeClass* var) {
if (@available(macOS 10.12, iOS 10, *)) {
[var fancyNewMethod];
}
}
If the caller of my_fun() already checks that my_fun() is only called
on 10.12, then add an availability attribute to it,
which will also suppress the warning and require that calls to my_fun() are
checked:
API_AVAILABLE(macos(10.12)) void my_fun(NSSomeClass* var) {
[var fancyNewMethod]; // Now ok.
}
@available() is only available in Objective-C code. To use the feature
in C and C++ code, use the __builtin_available() spelling instead.
If existing code uses null checks or -respondsToSelector:, it should
be changed to use @available() (or __builtin_available) instead.
-Wunguarded-availability is disabled by default, but
-Wunguarded-availability-new, which only emits this warning for APIs
that have been introduced in macOS >= 10.13, iOS >= 11, watchOS >= 4 and
tvOS >= 11, is enabled by default.
Objective-C++ ABI: protocol-qualifier mangling of parameters¶
Starting with LLVM 3.4, Clang produces a new mangling for parameters whose
type is a qualified-id (e.g., id<Foo>). This mangling allows such
parameters to be differentiated from those with the regular unqualified id
type.
This was a non-backward compatible mangling change to the ABI. This change allows proper overloading, and also prevents mangling conflicts with template parameters of protocol-qualified type.
Query the presence of this new mangling with
__has_feature(objc_protocol_qualifier_mangling).
Initializer lists for complex numbers in C¶
clang supports an extension which allows the following in C:
#include <math.h>
#include <complex.h>
complex float x = { 1.0f, INFINITY }; // Init to (1, Inf)
This construct is useful because there is no way to separately initialize the
real and imaginary parts of a complex variable in standard C, given that clang
does not support _Imaginary. (Clang also supports the __real__ and
__imag__ extensions from gcc, which help in some cases, but are not usable
in static initializers.)
Note that this extension does not allow eliding the braces; the meaning of the following two lines is different:
complex float x[] = { { 1.0f, 1.0f } }; // [0] = (1, 1)
complex float x[] = { 1.0f, 1.0f }; // [0] = (1, 0), [1] = (1, 0)
This extension also works in C++ mode, as far as that goes, but does not apply
to the C++ std::complex. (In C++11, list initialization allows the same
syntax to be used with std::complex with the same meaning.)
For GCC compatibility, __builtin_complex(re, im) can also be used to
construct a complex number from the given real and imaginary components.
OpenCL Features¶
Clang supports internal OpenCL extensions documented below.
__cl_clang_bitfields¶
With this extension it is possible to enable bitfields in structs or unions using the OpenCL extension pragma mechanism detailed in the OpenCL Extension Specification, section 1.2.
Use of bitfields in OpenCL kernels can result in reduced portability as struct layout is not guaranteed to be consistent when compiled by different compilers. If structs with bitfields are used as kernel function parameters, it can result in incorrect functionality when the layout is different between the host and device code.
Example of Use:
#pragma OPENCL EXTENSION __cl_clang_bitfields : enable
struct with_bitfield {
unsigned int i : 5; // compiled - no diagnostic generated
};
#pragma OPENCL EXTENSION __cl_clang_bitfields : disable
struct without_bitfield {
unsigned int i : 5; // error - bitfields are not supported
};
__cl_clang_function_pointers¶
With this extension it is possible to enable various language features that are relying on function pointers using regular OpenCL extension pragma mechanism detailed in the OpenCL Extension Specification, section 1.2.
In C++ for OpenCL this also enables:
Use of member function pointers;
Unrestricted use of references to functions;
Virtual member functions.
Such functionality is not conformant and does not guarantee to compile correctly in any circumstances. It can be used if:
the kernel source does not contain call expressions to (member-) function pointers, or virtual functions. For example this extension can be used in metaprogramming algorithms to be able to specify/detect types generically.
the generated kernel binary does not contain indirect calls because they are eliminated using compiler optimizations e.g. devirtualization.
the selected target supports the function pointer like functionality e.g. most CPU targets.
Example of Use:
#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
void foo()
{
void (*fp)(); // compiled - no diagnostic generated
}
#pragma OPENCL EXTENSION __cl_clang_function_pointers : disable
void bar()
{
void (*fp)(); // error - pointers to function are not allowed
}
__cl_clang_variadic_functions¶
With this extension it is possible to enable variadic arguments in functions using regular OpenCL extension pragma mechanism detailed in the OpenCL Extension Specification, section 1.2.
This is not conformant behavior and it can only be used portably when the functions with variadic prototypes do not get generated in binary e.g. the variadic prototype is used to specify a function type with any number of arguments in metaprogramming algorithms in C++ for OpenCL.
This extensions can also be used when the kernel code is intended for targets supporting the variadic arguments e.g. majority of CPU targets.
Example of Use:
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : enable
void foo(int a, ...); // compiled - no diagnostic generated
#pragma OPENCL EXTENSION __cl_clang_variadic_functions : disable
void bar(int a, ...); // error - variadic prototype is not allowed
__cl_clang_non_portable_kernel_param_types¶
With this extension it is possible to enable the use of some restricted types in kernel parameters specified in C++ for OpenCL v1.0 s2.4. The restrictions can be relaxed using regular OpenCL extension pragma mechanism detailed in the OpenCL Extension Specification, section 1.2.
This is not a conformant behavior and it can only be used when the kernel arguments are not accessed on the host side or the data layout/size between the host and device is known to be compatible.
Example of Use:
// Plain Old Data type.
struct Pod {
int a;
int b;
};
// Not POD type because of the constructor.
// Standard layout type because there is only one access control.
struct OnlySL {
int a;
int b;
OnlySL() : a(0), b(0) {}
};
// Not standard layout type because of two different access controls.
struct NotSL {
int a;
private:
int b;
};
#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
kernel void kernel_main(
Pod a,
OnlySL b,
global NotSL *c,
global OnlySL *d
);
#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : disable
Remove address space builtin function¶
__remove_address_space allows to derive types in C++ for OpenCL
that have address space qualifiers removed. This utility only affe