-
Sanjay Patel authored
This patch depends on r246688 (D12341). The goal is to make LLVM generate different code for these functions for a target that has cheap branches (see PR23827 for more details): int foo(); int normal(int x, int y, int z) { if (x != 0 && y != 0) return foo(); return 1; } int crazy(int x, int y) { if (__builtin_unpredictable(x != 0 && y != 0)) return foo(); return 1; } Differential Revision: http://reviews.llvm.org/D12458 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246699 91177308-0d34-0410-b5e6-96231b3b80d8
Sanjay Patel authoredThis patch depends on r246688 (D12341). The goal is to make LLVM generate different code for these functions for a target that has cheap branches (see PR23827 for more details): int foo(); int normal(int x, int y, int z) { if (x != 0 && y != 0) return foo(); return 1; } int crazy(int x, int y) { if (__builtin_unpredictable(x != 0 && y != 0)) return foo(); return 1; } Differential Revision: http://reviews.llvm.org/D12458 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246699 91177308-0d34-0410-b5e6-96231b3b80d8
Clang Language Extensions
- Introduction
- Feature Checking Macros
- Include File Checking Macros
- Builtin Macros
- Vectors and Extended Vectors
- Messages on
deprecated
andunavailable
Attributes - Attributes on Enumerators
- 'User-Specified' System Frameworks
- Checks for Standard Language Features
- Checks for Type Trait Primitives
- Blocks
- Objective-C Features
- Initializer lists for complex numbers in C
- Builtin Functions
- Non-standard C++11 Attributes
- Target-Specific Extensions
- Extensions for Static Analysis
- Extensions for Dynamic Analysis
- Extensions for selectively disabling optimization
- Extensions for loop hint optimizations
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. 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
...
__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 :ref:`below <langext-has-feature-back-compat>`), 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. :doc:`AddressSanitizer
<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 takes a single argument that is the name of a C++11-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. If the attribute is not supported by the current compliation target, this macro evaluates to 0. It can be used like this:
#ifndef __has_cpp_attribute // Optional of course.
#define __has_cpp_attribute(x) 0 // Compatibility with non-clang compilers.
#endif
...
#if __has_cpp_attribute(clang::fallthrough)
#define FALLTHROUGH [[clang::fallthrough]]
#else
#define FALLTHROUGH
#endif
...
The attribute identifier (but not scope) can also 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
:ref:`langext-__has_include` and :ref:`langext-__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.
__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 :ref:`langext-feature_check`.
__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 :ref:`langext-feature_check`.
__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)
".
Vectors and Extended Vectors
Supports the GCC, OpenCL, AltiVec and NEON vector extensions.
OpenCL vector types are created using ext_vector_type
attribute. It
support for 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_extension(attribute_ext_vector_type)
.
Giving -faltivec
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;
}
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 |
---|---|---|---|---|
[] | yes | yes | yes | -- |
unary operators +, -- | yes | yes | yes | -- |
++, -- -- | yes | yes | yes | -- |
+,--,*,/,% | yes | yes | yes | -- |
bitwise operators &,|,^,~ | yes | yes | yes | -- |
>>,<< | yes | yes | yes | -- |
!, &&, || | yes | -- | -- | -- |
==, !=, >, <, >=, <= | yes | yes | -- | -- |
= | yes | yes | yes | yes |
:? | yes | -- | -- | -- |
sizeof | yes | yes | yes | yes |
C-style cast | yes | yes | yes | no |
reinterpret_cast | yes | no | yes | no |
static_cast | yes | no | yes | no |
const_cast | no | no | no | no |
See also :ref:`langext-__builtin_shufflevector`, :ref:`langext-__builtin_convertvector`.
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)
.
'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 default
ed 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++1y
The features listed below are part of the committee draft for the C++1y
standard. As a result, all these features are enabled with the -std=c++1y
or -std=gnu++1y
option when compiling C++ code.
C++1y 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++1y contextual conversions
Use __has_feature(cxx_contextual_conversions)
or
__has_extension(cxx_contextual_conversions)
to determine if the C++1y 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++1y 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++1y 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++1y 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++1y 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++1y 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++1y 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++1y 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++1y 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++1y variable templates
Use __has_feature(cxx_variable_templates)
or
__has_extension(cxx_variable_templates)
to determine if support for
templated variable declarations is enabled.
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
:ref:`a set of builtins <langext-__c11_atomic>` 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.