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 bool

  • the 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 __builtin_elementwise_rint unless FENV_ACCESS is enabled.

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 __builtin_elementwise_nearbyint unless FENV_ACCESS is enabled.

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.

  • __fp16 is supported on all targets. The special semantics of this type mean that no arithmetic is ever performed directly on __fp16 values; see below.

  • _Float16 is 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)

  • __bf16 is 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 emulation

  • standard: meaning that excess precision is permitted under the rules described in the standard, i.e. never across explicit casts or statements

  • fast: meaning that excess precision is permitted whenever the optimizer sees an opportunity to avoid truncations; currently this has no effect beyond standard

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.

Messages on deprecated and unavailable Attributes

An optional string message can be added to the deprecated and unavailable attributes. For example:

void explode(void) __attribute__((deprecated("extremely unsafe, use 'combust' instead!!!")));

If the deprecated or unavailable declaration is used, the message will be incorporated into the appropriate diagnostic:

harmless.c:4:3: warning: 'explode' is deprecated: extremely unsafe, use 'combust' instead!!!
      [-Wdeprecated-declarations]
  explode();
  ^

Query for this feature with __has_extension(attribute_deprecated_with_message) and __has_extension(attribute_unavailable_with_message).

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 for loop

__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

if constexpr

__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

inline variables

__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

static operator[]

__cpp_multidimensional_subscript

C++20

C++03

Designated initializers

__cpp_designated_initializers

C++20

C++03

Conditional explicit

__cpp_conditional_explicit

C++20

C++03

using enum

__cpp_using_enum

C++20

C++03

if consteval

__cpp_if_consteval

C++23

C++20

static operator()

__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

= delete ("should have a reason");

__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

#embed (N3017)

C23

C89, C++

Octal literals prefixed with 0o or 0O

C2y

C89, C++

_Countof (N3369, N3469)

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 type type: 0 if type is not an array type, and __array_rank(element) + 1 if type is an array of element.

  • __array_extent(type, dim) (Embarcadero): The dim’th array bound in the type type, or 0 if dim >= __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_assignable instead.

  • __has_nothrow_move_assign (GNU, Microsoft): Deprecated, use __is_nothrow_assignable instead.

  • __has_nothrow_copy (GNU, Microsoft): Deprecated, use __is_nothrow_constructible instead.

  • __has_nothrow_constructor (GNU, Microsoft): Deprecated, use __is_nothrow_constructible instead.

  • __has_trivial_assign (GNU, Microsoft, Embarcadero): Deprecated, use __is_trivially_assignable instead.

  • __has_trivial_move_assign (GNU, Microsoft): Deprecated, use __is_trivially_assignable instead.

  • __has_trivial_copy (GNU, Microsoft): Deprecated, use __is_trivially_copyable instead.

  • __has_trivial_constructor (GNU, Microsoft): Deprecated, use __is_trivially_constructible instead.

  • __has_trivial_move_constructor (GNU, Microsoft): Deprecated, use __is_trivially_constructible instead.

  • __has_trivial_destructor (GNU, Microsoft, Embarcadero): Deprecated, use __is_trivially_destructible instead.

  • __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): Return true if type is 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): Returns false, 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_relocatable instead). 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 the clang::trivial_abi attribute. 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 with memcpy or memmove; 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 type T bound to an expression of type U would bind to a materialized temporary object. If T is not a reference type the result is false. Note this trait will also return false when the initialization of T from U is ill-formed. Deprecated, use __reference_constructs_from_temporary.

  • __reference_constructs_from_temporary(T, U) (C++) Returns true if a reference T can be direct-initialized from a temporary of type a non-cv-qualified U.

  • __reference_converts_from_temporary(T, U) (C++)

    Returns true if a reference T can be copy-initialized from a temporary of type a non-cv-qualified U.

  • __underlying_type (C++, GNU, Microsoft)

In addition, the following expression traits are supported:

  • __is_lvalue_expr(e) (Embarcadero): Returns true if e is an lvalue expression. Deprecated, use __is_lvalue_reference(decltype((e))) instead.

  • __is_rvalue_expr(e) (Embarcadero): Returns true if e is 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