Modern C++ Features Supported by RAD Studio Clang-enhanced C++ Compilers
Go Up to Modern C++
Contents
- 1 C++17 features supported by the Clang-enhanced compilers
- 2 C++14 features supported by the Clang-enhanced compilers
- 3 C++11 features supported by the Clang-enhanced compilers
- 3.1 Rvalue references description
- 3.2 Initialization of class objects by rvalues
- 3.3 Non-static data member initializers
- 3.4 Variadic templates
- 3.5 Extending variadic template template parameters
- 3.6 Initializer lists
- 3.7 Static assertions
- 3.8 auto-typed Variables
- 3.9 Declared type of an expression
- 3.10 Incomplete return types
- 3.11 Right angle brackets
- 3.12 Default template arguments for function templates
- 3.13 Solving the SFINAE problem for expressions
- 3.14 Alias templates
- 3.15 Extern templates
- 3.16 Null pointer constant
- 3.17 Strongly-typed enums
- 3.18 Forward declarations for enums
- 3.19 Generalized constant expressions
- 3.20 Alignment support
- 3.21 Delegating constructors
- 3.22 Explicit conversion operators
- 3.23 New character types
- 3.24 Unicode string literals
- 3.25 Raw string literals
- 3.26 Universal character names in literals
- 3.27 User-defined literals
- 3.28 Standard Layout Types
- 3.29 Defaulted functions
- 3.30 Deleted functions
- 3.31 Extended friend declarations
- 3.32 Extending sizeof
- 3.33 Inline namespaces
- 3.34 Unrestricted unions
- 3.35 Local and unnamed types as template arguments
- 3.36 Range-based for
- 3.37 Explicit virtual overrides
- 3.38 Allowing move constructors to throw [noexcept]
- 3.39 Defining move special member functions
- 3.40 Atomic operations
- 3.41 Strong Compare and Exchange
- 3.42 Bidirectional Fences
- 3.43 Propagating exceptions
- 3.44 Allow atomics use in signal handlers
- 3.45 __func__ predefined identifier
- 3.46 C99 preprocessor
- 3.47 long long type
- 3.48 Other Features
- 4 See Also
C++17 features supported by the Clang-enhanced compilers
The Clang-enhanced compilers for Win32 and Win64 (bcc32c/bcc32x and bcc64/bcc64x) implement almost all of the ISO C++17 standards.
Some specific features of interest in C++17 include the following:
Constexpr if
- a great addition for compile-time expressions.string_view
- a useful addition for no-copy, i.e., cheap and fast, read-only access to a variety of string types.- If-init (initializing a variable in an if statement).
- Structured bindings.
- Inline variables
For more information on C++17:
- This GitHub document by Tony Van Eerd lists all features, with examples. It’s a great read.
- This very detailed blog post also examines everything new in C++17.
C++14 features supported by the Clang-enhanced compilers
The Clang-enhanced compilers for Win32 and Win64 (bcc32c/bcc32x and bcc64) implement almost all of the ISO C++14 standard.
Some specific features of interest in C++14 include the following:
- Return type deduction with auto.
- Lambdas with generic parameters (via auto).
- Variable templates.
For more information on C++14:
- This Dr. Dobb’s article has a good overview, with code, of new items in C++14.
- This GitHub document by Anthony Calandra has info about what’s new in all modern C++ versions, C++11 onwards.
C++11 features supported by the Clang-enhanced compilers
Here is the list of C++11 features that are supported by the RAD Studio Clang-enhanced C++ Compilers.
- Bcc32c and bcc32x (Clang-enhanced compiler for Win32) implements all of the ISO C++11 standard.
- Older Clang-enhanced C++ compilers partially support the C++11 features:
- Core C++11 features typically work with BCCIOSARM64. This includes variadic templates, static assertions, multi-declarator auto, lambda expressions, and others.
- Standard (Run-time) C++11 features are typically not supported by BCCIOSARM64. This includes the initialization of class objects by rvalues, Atomic operations, and others.
- BCC32 also supports the C++11 features described in C++11 Features in the Classic Compiler.
Rvalue references description
rvalue references is a feature supported by both BCC32 and the Clang-enhanced C++ compilers.
For more information about this feature, see rvalue References.
Rvalue references for *this
rvalue references for *this
is a C++11 feature that is intended to extend the benefits of move semantics to the implicit *this
parameter.
For more information on this feature, see Rvalue references for *this Proposal document.
Initialization of class objects by rvalues
C++11 standard introduces the ability to initialize class objects by rvalues, to write clear, concise, and efficient code.
This means that temporaries are now initialized directly from the entire rvalue object, instead of calling a constructor to copy the object into the temporary.
For more information about this feature, see Initialization of class objects by rvalues Proposal document.
Non-static data member initializers
C++11 introduces the possibility of initializing non-static data members within the class declaration.
The initializers for non-static data members are limited to =initializer-clause
and {initializer-list}
.
For more information on this feature, see the example below or the proposal document at Non-static data member initializers Proposal document.
Non-static data member initializers example
#include <string>
struct B {
B(int, double, double);
};
class A {
int a = 7; // OK
std::string str1 = "member"; // OK
B b = {1, 2, 3.0}; //OK
std::string str2("member"); // ill-formed
};
Variadic templates
Variadic templates refer to class or function templates that can have a variable number of parameters.
In order to achieve this, C++11 introduces parameter packs to represent a list of zero or more parameters.
For more information on this feature, see Variadic templates Proposal document.
Variadic templates example
This is a small example showing the C++ syntax of variadic templates.
template<class ... T>
class A {
// template class body
};
template<char ... T>
class B {
// template class body
};
A<>a1;
A<int, char>a2;
A < B < 'a' >> a3;
B<>b1;
B < 'a', 'b' > b2;
Extending variadic template template parameters
During real-world experimentation with variadic templates, some limitations regarding template template parameters were uncovered.
C++11 standard extends the variadic template template parameters in order to resolve this issue.
For more information on this feature, see Extending Variadic Template Template Parameters Proposal document.
Initializer lists
Initializer lists is a feature that has been extended in C++11 standard.
An initializer list represents a list of ordered arguments, in curly brackets, that is used to initialize structures, classes, and arrays.
Until C++11, only classes that conformed to the Plain Old Data (POD) definition could be initialized using initializer lists. Now, classes like std::vector
can also be initialized using initializer lists.
This is done by using a template named std::initializer_list<>
that can be passed as an argument to constructors or other functions.
Static assertions
Static assertions is a feature supported by both BCC32 and the Clang-enhanced C++ compilers.
For more information about this feature, see Static Assertions (C++11).
auto-typed Variables
auto-typed variables is a C++11 feature that allows the programmer to declare a variable of type auto
, the type itself being deduced from the variable's initializer expression. The auto
keyword is treated as a simple type specifier (that can be used with *
and &
), and its semantics are deduced from the initializer expression.
For more information about this feature, please see the C++11 standard Proposal Document at: auto-typed variables Proposal Document.
auto-typed Variables Examples
int IntFunc() {}
bool BoolFunc() {}
char* CharSFunc() {}
int _tmain(int argc, _TCHAR* argv[]) {
// x is int
auto x = IntFunc();
// y is const bool
const auto y = BoolFunc();
// w is char*
auto w = CharSFunc();
return 0;
}
Another example of the auto
type is here: Generic vector sort (C++).
Multi-declarator auto
The C++11 standard includes the multi-variable form of auto
declarations, such as:
int* func(){}
int _tmain(int argc, _TCHAR* argv[])
{
auto x = 3, * y = func(), z = 4;
return 0;
}
The restriction with multi-declarator auto expressions is that the variables must have the same base type.
For example, the following line of code is well-formed:
auto x = 3, y = new int;
because x and y have the same base type : int
, while the following code:
auto x = 3, y = 3.5;
will generate the error:
[bcc64 Error] File1.cpp(11): 'auto' deduced as 'int' in declaration of 'x' and deduced as 'double' in declaration of 'y'
This feature is supported by the Clang-enhanced C++ compilers.
For more information on this feature, please see the C++11 standard Proposal Document at: Multi-declarator auto
Removal of auto as a storage-class specifier
The C++11 standard removes the use of auto
as a storage class specifier entirely. This feature is supported by the Clang-enhanced C++ compilers.
If your C++ application uses auto
as a storage class specifier, you will receive the following warning from Clang-enhanced C++ compilers:
For more information on this feature, please see the C++11 standard Proposal Document at: Removal of auto as a storage-class specifier.
New function declarator syntax
This C++11 feature changes the semantics of auto
and introduces syntax for function declarators. The auto
type-specifier signifies that the type of a variable being declared shall be deduced from its initializer expression or specified explicitly at the end of a function declarator.
For more information on this feature, please see the C++11 standard Proposal Document at : New function declarator syntax
Declared type of an expression
The declared type of an expression is a feature supported by both BCC32 and the Clang-enhanced C++ compilers.
For more information about this feature, see Type Specifier decltype (C++11).
Incomplete return types
The requirement for a function call expression's type to be complete, when used as a decltype
parameter is not just unnecessary, but harmful too.
In C++11, when the parameter of a decltype
expression is a function call expression returning a class type, the type is not required to be complete. Also, a temporary object is not introduced for the return value, saving storage space, and not invoking the destructor.
For more information on this feature, see Incomplete return types Proposal document.
Right angle brackets
In the Clang-enhanced C++ compilers, two consecutive right angle brackets no longer generate an error, and these constructions are treated according to the C++11 standard.
For more information, see the C++11 proposal document at Right angle brackets Proposal document.
Right angle brackets example
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
#include <vector>
typedef std::vector<std::vector<int> > Table; // OK
typedef std::vector<std::vector<bool>> Flags; // OK
int _tmain(int argc, _TCHAR* argv[]) {
return 0;
}
Default template arguments for function templates
The impossibility of setting default template arguments for function templates has been limiting the programming style for a long time.
In C++11, such default arguments can be used.
For more information on this feature, see Default template arguments for function templates Proposal document.
Default template arguments for function templates example
template<class T = int, class U = char>
void function() {
// function body
}
int _tmain(int argc, _TCHAR* argv[]) {
function<>(); // OK, template arguments are -> int char
function<int>(); // OK, template arguments are -> char
function<char, char>(); // OK, template arguments are -> char char
return 0;
}
Solving the SFINAE problem for expressions
C++11 standard solves the substitution failure is not an error (SFINAE) problem for expressions. This is done by allowing fully general expressions with the condition that most errors generated by these expressions are treated as SFINAE failures instead of errors.
For more information on this feature, see Solving the SFINAE problem for expressions Proposal document.
Alias templates
With the increased use of parameterized types in C++, the need for parameterized type aliases has grown. C++11 adds this feature to the standard.
For more information on this feature, see Alias templates Proposal document.
Extern templates
Extern templates is a feature supported by both BCC32 and the Clang-enhanced C++ compilers.
For more information on this feature, see Extern Templates (C++11).
Null pointer constant
C++11 introduces nullptr
, the null pointer constant, in order to remove the ambiguity between 0 and a null pointer.
Although the NULL
macro exists, it is insufficient because it cannot be distinguished from the integer 0 in a call to a function that has one overload with an int
parameter and another with a char*
parameter.
Therefore, nullptr
is now a reserved word. The integer 0 will not be implicitly converted to any pointer type. The null pointer can only be converted to any pointer type.
See nullptr.
Strongly-typed enums
Strongly-typed enums is a feature supported by both BCC32 and the Clang-enhanced C++ compilers.
For more information about this feature, see Strongly Typed Enums (C++11).
Forward declarations for enums
Forward declarations for enums is a feature supported by both BCC32 and the Clang-enhanced C++ compilers.
For more information about this feature, see Forward Declaration of Enums (C++11).
Generalized constant expressions
C++11 standard generalizes the notion of constant expressions to include calls to simple functions (constexpr functions) and objects of user-defined types that are constructed from simple constructors (constexpr constructors).
A function is a constant-expression function if:
- It returns a value (void type not allowed)
- The function body consists of a single statement, the return statement:
return expr;
- It is declared with the keyword
constexpr
.
A variable or a data member is a constant-expression value if:
- It is declared with the keyword
constexpr
- It is initialized with a constant expression or an rvalue constructed by a constant-expression constructor with constant-expression arguments.
A constructor is a constant-expression constructor if:
- It is declared with the keyword
constexpr
- The member-initializer part involves only potential constant expressions
- Its body is empty.
Generalized constant expressions example
The following example contains a constexpr function, a constexpr variable, and a constexpr constructor:
constexpr int add(int x, int y) {
return x + y;
}
constexpr double var = 2 * add(3, 4);
class A {
constexpr A(int newA, int newB) : a(newA), b(newB) {
}
private:
int a;
int b;
};
Alignment support
C++11 standard intends to extend the standard language and library with alignment-related features.
These alignment features include:
- Alignment specifier (
alignas
) to declarations alignof
expression to retrieve alignment requirements of a type- Alignment arithmetic by library support
- Standard function (
std::align
) for pointer alignment at run time.
For more information on this feature, see Alignment support Proposal document.
Delegating constructors
C++11 introduces the possibility of delegating constructors. This means that class constructors can be invoked within other constructors of the same class.
This is a very useful feature that helps programmers to write less and more expressive code.
For more information about this feature, see Delegating constructors Proposal document.
Delegating constructors example
The following example shows how delegating constructors can be used:
class B {
B(int newA) : a(newA) { /* other initializations */
}
public:
B() : B(15) { /* other initializations */
}
public:
int a;
};
Explicit conversion operators
With C++11, explicit-qualified conversion functions work in the same context as explicit-qualified constructors and produce diagnostics in the same contexts as constructors do. This is done in order to avoid situations when the compiler uncomplainingly accepts code that is not semantically correct.
For more information on these features, see Explicit conversion operators Proposal document.
New character types
C++11 introduces new character types to manipulate Unicode character strings.
For more information on this feature, see Unicode Character Types and Literals (C++11).
Unicode string literals
C++11 introduces new character types to manipulate Unicode string literals.
For more information on this feature, see Unicode Character Types and Literals (C++11).
Raw string literals
Universal character names in literals
In order to make the C++ code less platform-dependent, C++11 lifts the prohibitions regarding control and basic source universal character names within character and string literals. Prohibitions against surrogate values in all universal character names are added.
For more information on this feature, see Universal character names in literals Proposal document.
User-defined literals
C++11 introduces new forms of literals using modified syntax and semantics in order to provide user-defined literals.
Using user-defined literals, user-defined classes can provide new literal syntax.
For more information on this feature, see User-defined literals Proposal document.
Standard Layout Types
C++11 separates trivial special member requirements from layout requirements in order to create a cleaner specification.
POD (Plain Old Data) types are now defined in terms of two new categories: trivial types and standard-layout types. In C++11 standard-layout types are allowed to have base classes. However, the base classes are not allowed to have virtual members or virtual bases. Also, standard-layout types are allowed to have access control.
For more information on this feature, see Standard Layout Types Proposal document.
Defaulted functions
A defaulted function is a function that contains =default;
in its prototype. This construction indicates that the function's default definition should be used.
Defaulted functions are a C++11 specific feature.
For more information on defaulted functions, see Defaulted functions Proposal document.
Defaulted functions example
class A {
A() = default; // OK
A& operator = (A & a) = default; // OK
void f() = default; // ill-formed, only special member function may default
};
Deleted functions
A deleted function is a function that contains =delete;
in its prototype. This construction, introduced with C++11, indicates that the function may not be used.
This construction can be used to forbid the usage of default language facilities (like default constructors or default operators) or problematic conversions.
For more information on this feature, see Deleted functions Proposal document.
Deleted functions example
class A {
A() = delete;
A& operator = (A & a) = delete;
};
Extended friend declarations
C++11 extends the current language to support a wider range of friend
declarations.
For more information on this feature, see Extended friend declarations Proposal document.
Extending sizeof
C++11 extends the functionality of sizeof
so that class members can be sent as parameters even if no object has been instantiated.
For more information on this feature, see Extending sizeof Proposal document.
Extending sizeof example
The following code represents a simple example of how sizeof
can now be used.
#pragma hdrstop
#pragma argsused
#include <tchar.h>
#include <stdio.h>
class A {
public:
int a;
};
int _tmain(int argc, _TCHAR* argv[]) {
// no object of type A has been instantiated
int c = sizeof(A::a);
// well-formed
return 0;
}
Inline namespaces
C++11 standard allows the inline
keyword in a namespace-definition
. This is done in order to specify that members of the namespace can be defined and specialized as though they actually belong to the enclosing namespace.
This construction is called inline namespace and solves the problem where templates could only be specialized in their actual namespace, and not in the namespace they have been imported.
For more information on this feature, see Inline namespaces Proposal document.
Unrestricted unions
The C++11 standard loosens up the restriction regarding members of unions. So, in Clang-enhanced C++ compilers, all types can be union members, except reference types.
For more information on this feature, see Unrestricted unions Proposal document.
Local and unnamed types as template arguments
The C++11 standard allows users to use local and unnamed types as template arguments.
For more information on this feature, see Local and unnamed types as template arguments Proposal document.
Range-based for
Range-based is a feature introduced by the C++11 standard.
In Clang-enhanced C++ compilers, you can create for
loops that iterate through a list or an array without computing the beginning, the end, or using an iterator.
The following example shows the range-based for syntax for a string:
UnicodeString string("C++11");
for (auto character : string) {
std::wcout << character;
}
Explicit virtual overrides
Regarding virtual overrides, C++11 tends to tighten the rules, to detect some problems that often arise.
To achieve this goal C++11 introduces two new contextual keywords:
- final specifies that a method cannot be overridden or a class cannot be derived.
- override specifies that a method overrides a virtual method declared in one of its parent classes.
For more information on this feature, see Explicit virtual overrides Proposal document.
Explicit virtual overrides example
struct base {
virtual void a();
void b();
virtual void c() final;
virtual void d();
};
struct derived : base {
void a() override; // correct
void b() override; // error, an override can only be used for virtual functions
void c() override; // error, cannot override a function marked as final
int d() override; // error, different return type
};
Allowing move constructors to throw [noexcept]
The C++11 standard provides an alternative to std::move
, which is std::move_if_noexcept
, to solve some problematic interactions between move constructors, templates, and certain standard library member functions.
std::move_if_noexcept(x)
grants permission to move x
unless it could throw and the type can be copied.
For more information on this feature, see Allowing move constructors to throw Proposal document.
Defining move special member functions
C++11 provides a way of defining move and copy special member functions.
For more information on this feature, see Defining move special member functions Proposal document.
Atomic operations
C++11 adds atomic types and operations to the standard. Atomic types and operations provide a way of writing multi-threaded applications without using locks.
For more information on this feature, see Atomic operations Proposal document.
Strong Compare and Exchange
C++11 provides both weak and strong compare-and-exchange operations.
Compare-and-exchange operation is an atomic operation used in multi-threaded applications to achieve synchronization.
For more information on this feature, see Strong Compare and Exchange Proposal document.
Bidirectional Fences
A fence is a primitive that enforces ordering between preceding loads or stores and subsequent loads or stores. C++11 improves the support for bidirectional fences.
For more information on this feature, see Bidirectional Fences Proposal document.
Propagating exceptions
The C++11 standard offers the possibility of moving an exception from one thread to another. To do that, some modifications have been made to the <exception>
header.
For more information on this feature, see Propagating exceptions Proposal document.
Allow atomics use in signal handlers
C++11 allows the use of atomics in signal handlers.
For more information on this feature, see Allow atomics use in signal handlers Proposal document.
__func__ predefined identifier
This feature is used to capture function names as string literals and to assist diagnostic libraries.
For more information on this feature, see __func__ predefined identifier Proposal document.
C99 preprocessor
The C++11 standard intends to resynchronize the preprocessor and translation phases of C++ with C99, to make the two standards more compatible.
Predefined macros, pragma operators, and string literal concatenation are some areas in which changes were made.
For more information on this feature, see C99 preprocessor Proposal document.
long long type
To be more compatible with C99, C++11 standard introduces the long long integral type.
For more information on this feature, see long long type Proposal document.