In 2011, a new standard for the C++ programming language has been published, which is commonly referred to as C++11. This new standard introduces many new language features and standard library functions. Many of these new features have been introduced to make C++ more flexible and to make C++ more easy to use. Bjarne Stroustrup (the creator of C++) even thinks «C++11 feels like a new language: The pieces just fit together better than they used to and I find a higher-level style of programming more natural than before and as efficient as ever.» This year another new version of C++ (C++14) has been defined, which brings some minor enhancements and clarifications compared to C++11. As C++ is a general purpose programing language the new features of the revised versions are not specifically designed for the needs of scientific computing. Nevertheless, C++11/14 adds several new tools to the computational scientist’s toolbox. In the following I will present some of them.
New integer types
C++ does not define which are the minimal and maximal values that the integer types int
and long
can hold. The language standard requires only lower/upper bounds on these values. As a consequence int
may be a 16-bit, 32-bit or a 64-bit integer or even something different. In C++11/14 the standard header file cstdint
defines several new integer types with specific bit-width.
int8_t int16_t int32_t int64_t |
signed integer type with width of exactly 8, 16, 32 and 64 bits respectively with no padding bits and using 2’s complement for negative values (provided only if the implementation directly supports the type) |
int_fast8_t int_fast16_t int_fast32_t int_fast64_t |
fastest signed integer type with width of at least 8, 16, 32 and 64 bits respectively |
int_least8_t int_least16_t int_least32_t int_least64_t |
smallest signed integer type with width of at least 8, 16, 32 and 64 bits respectively |
intmax_t |
maximum width integer type |
intptr_t |
integer type capable of holding a pointer |
uint8_t uint16_t uint32_t uint64_t |
unsigned integer type with width of exactly 8, 16, 32 and 64 bits respectively (provided only if the implementation directly supports the type) |
uint_fast8_t uint_fast16_t uint_fast32_t uint_fast64_t |
fastest unsigned integer type with width of at least 8, 16, 32 and 64 bits respectively |
uint_least8_t uint_least16_t uint_least32_t uint_least64_t |
smallest unsigned integer type with width of at least 8, 16, 32 and 64 bits respectively |
uintmax_t |
maximum width unsigned integer type |
uintptr_t |
unsigned integer type capable of holding a pointer |
The header file cstdint
defines also several macros for the maximal and minimal values of the integer types shown above. These values, however, are more conveniently accessed through the template class std::numeric_limits
.
Numeric limits
The class template std::numeric_limits
, which is defined in the header file limits
provides a standardized way to query various properties of arithmetic types (e.g., the largest possible value for type int
is std::numeric_limits<int>::max
). This information is provided via specializations of the numeric_limits
template. Since C++1 the members of std::numeric_limits
are declared as static
constexpr
. Thus, their return values can be consumed by operations that require constant expressions, such as an integer template argument. Furthermore, the new members max_digits10
and lowest
have been introduced in C++11, which give the number of decimal digits necessary to differentiate all values of this type and the lowest finite value of the given type.