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_tint16_tint32_tint64_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_tint_fast16_tint_fast32_tint_fast64_t |
fastest signed integer type with width of at least 8, 16, 32 and 64 bits respectively |
int_least8_tint_least16_tint_least32_tint_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_tuint16_tuint32_tuint64_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_tuint_fast16_tuint_fast32_tuint_fast64_t |
fastest unsigned integer type with width of at least 8, 16, 32 and 64 bits respectively |
uint_least8_tuint_least16_tuint_least32_tuint_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.