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.)

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 C2x 6.2.5p19), 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.

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

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_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_pow(T x, T y)

return x raised to the power of y

floating point 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_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_max(T x, T y)

return x or y, whichever is larger

integer and floating point types

T __builtin_elementwise_min(T x, T y)

return x or y, whichever is smaller

integer and 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

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