- 1 C++
- 2 Well defined concurrency and memory models
- 3 Compiler support
- 4 New to C++ or need an update?
- 5 Pitfalls
- 6 References
C++ is a general-purpose, high-level, multi-paradigm programming language created by Bjarne Stroustrup at Bell Labs in 1979 by extending the C programming language. C++ is now represented by a number of ISO standards corresponding to the years 1998, 2003, 2011, and 2014 usually referred to as C++98, C++03, C++11, and C++14. (The next C++ standard will likely become official in 2017 and for this reason is usually referred to as C++17.) If you are new to C++ or wish to read an overview of the language and/or how each ISO standard impacted C++, check out the following Wikipedia links:
- C++, i.e., the language, history, and C++98.
- C++03: Minor release (mostly bug fixes). Mandates that std::vector stores its elements contiguously.
- C++11: Major release adding many new language and library features including concurrency (e.g., threads, atomics, compare-and-swap).
- C++14: While mostly bug fixes and small improvements, this version simplifies/generalizes the use of a number of constructs including constexpr, auto, lambdas (e.g., move capture).
- C++17: Soon-to-be-major release. Amongst other items, support for parallel STL algorithms will likely be included.
A definitive, up-to-date, free online wiki reference for C++ (and its C Standard Library subset) is cppreference.com. Should you have a need to refer to an actual ISO standard document for C++, you can obtain a link to the last draft (which may well have errors in it) before each ISO C++ standard release in the aforementioned Wikipedia pages' reference section. (If you need the official document, you may purchase it from Standards Council of Canada.)
ISO standards typically rely on other standards and C++ is no exception. The ISO C++ standards rely on the ISO C standards definitions (per the text, restrictions, etc. in the ISO C++ standard). Consequently, if you require the ISO C++ standard document you will likely also require the ISO C standard document it relies on.
Well defined concurrency and memory models
Prior to 2011 the ISO C++ standards had no definitions of concurrency and memory models in them, thus, in pre-C++11 compiled code there are no guarantees concerning the ordering of memory reads and writes under concurrency, i.e., such is likely undefined behaviour which the compiler vendor may or may not have documented. It is therefore preferable to compile concurrent C++ code as C++11 code (or newer).
Various compilers implement various language features differently. Unfortunately a number of compiler releases only partially implement a specific ISO C++ standard. This can sometimes make it frustrating when compiling code with a compiler that does not yet implement a specific language feature. Fortunately there is a wiki page covering virtually all major C++ compilers and listing the earlier compiler version implementing specific language features at cppreference.com. This page also provides reference links to each compiler's web site concerning the details of such.
Standard library implementation
It is important to realize that many C++ compilers under Linux do not actually provide their own implementation of the C++ Standard Library under certain operating systems (especially Linux). Instead these compilers will use one that is normally installed on the system. Typically this implies that libstdc++, which is distributed with GCC, is used.
NOTE: While you need not worry about this, this is a reason C++ compilers other than GCC on systems across Compute Canada must be configured by the administrators to use a correct version of libstdc++ as several versions of GCC (and therefore libstdc++) are typically installed on any system. If such is set improperly, then there may be issues. This is also a reason why users should never hard-code paths to administrator-installed libraries in order to compile software.
The GCC documentation has a section which details Standard Library components are supported in libstdc++.
New to C++ or need an update?
If you are new to C++ or need an update then start by checking out the ISO C++ advocacy site's Get Started page --especially its recommended books. All of these books are excellent.
A book that specifically and only covers concurrency in C++11 (i.e., threads, atomics, condition variables, etc.) is published by Manning, C++ Concurrency in Action: Practical Multithreading.
The volatile keyword
The reader should note that volatile in C++ has a very specific meaning, e.g., see this page. Consequently needing to use volatile in C++ code is a rare event.
Misuse of volatile might arise from users of the Java programming language which uses the volatile keyword for concurrency. Java's volatile has a totally different meaning from volatile in C++. Java's volatile corresponds to using std::atomic<T> for some type T or std::atomic_* (where '*' corresponds to a fundamental type name such as int) in C++.
NOTE: It is unlikely you will ever use the volatile keyword in any of your C++ code. In pre-ISO C++11 concurrent code you might need to use volatile but that still would be a rare event. Instead of volatile, always use the appropriate mutex, atomic, etc. features of the library you are using (e.g., pthreads, the C++ Standard Library).
The GCC compiler's -O3 option includes possibly unsafe optimizations for some types of code (e.g., code relying on aliasing). If unsure, compile and optimize code using the -O2 option instead. If you've more time, read the man page (e.g., man g++) and unset the appropriate options by searching for "-O3" to see which options are turned on and turn off the settings that are not safe.
Linking with older previously compiled binaries
The transition from GCC version 4.9 to version 5.1 introduced a major change to its ABI. If all source code including all dependent libraries is recompiled using the same version of the compiler then there will be no issues. If different compilers are used, the ABI change may cause linking to fail. The latter is likely to occur if you are linking to precompiled libraries provided in a vendor's product. If this occurs, you can use GCC's Dual ABI feature to tell GCC to use the old ABI in order for your application to link properly with those legacy libraries, e.g., you would pass
-D_GLIBCXX_USE_CXX11_ABI=0 to GCC if using GCC v5.1 or higher to link to libraries built using the older ABI.
We've provided an example of how the ABI is affected by various GCC command-line options here: GCC C++ Dual ABI.
Intel C/C++ compilers may default to using possibly unsafe optimizations for floating-point operations. Users using the Intel compilers should read the Intel man pages (e.g., man icpc) and are recommended to use one of two options, -fp-model precise or -fp-model source, for ANSI/ISO/IEEE standards-compliant floating-point support. For more details, read this Intel slideshow called, Floating-point control in the Intel compiler and libraries.
- Free Software Foundation. The GNU C++ Library, Chapter 3. https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
GNU Compiler Collection, an open source compiler collection