C++: Difference between revisions

From Alliance Doc
Jump to navigation Jump to search
m (fix heading levels)
 
(27 intermediate revisions by 5 users not shown)
Line 1: Line 1:
=C++=
<languages />
<translate>


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 with a number of ISO standards corresponding to the years 1998, 2003 (minor release), 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 it, check out the following Wikipedia links:
<!--T:2-->
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. A number of ISO C++ standards have been released corresponding to the years 1998, 2003, 2011, 2014, 2017, and 2020. These are usually referred to as C++98, C++03, C++11, C++14, C++17, and C++20. The ISO C++ committee is currently releasing its standards on a three-year cycle, i.e., after C++20, the next standard will be in 2023.


# [https://en.wikipedia.org/wiki/C%2B%2B C++], i.e., the language, history, and C++98.
<!--T:4-->
# [https://en.wikipedia.org/wiki/C%2B%2B03 C++03]: Minor release (mostly bug fixes). Mandates that std::vector stores its elements contiguously.
A definitive, up-to-date, free online wiki reference for C++ (and its C Standard Library subset) is [http://en.cppreference.com/w/ cppreference.com].
# [https://en.wikipedia.org/wiki/C%2B%2B11 C++11]: Major release adding many new language and library features including concurrency (e.g., threads, atomics, compare-and-swap). See the link for details.
# [https://en.wikipedia.org/wiki/C%2B%2B14 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).
# [https://en.wikipedia.org/wiki/C%2B%2B17 C++17]: Soon-to-be-major release. Amongst other items, support for parallel STL algorithms will likely be included.


The most definitive, up-to-date, free online (wiki) reference for C++ (and its C Standard Library subset) is [http://en.cppreference.com/w/ cppreference.com]. This site also includes example code and tags definitions with the C++ standards to which they are defined / changed. Should you have a need to refer to the 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 that page's reference section. (If you need the official document, you may purchase it from [http://www.scc.ca/ Standards Council of Canada].)
<!--T:24-->
It is important to understand that the C language is a distinct language from the C++ language. While a lot of C code can be used as-is in C++ there are times when differences will affect compilation and/or program execution due to differences between C and C++. If you are compiling your C code as C++ code, then when asking for help refer to your code as C++ code as it is being compiled as C++ code.


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). For this reason it is useful to be aware of the various C standards that the ISO C++ standards refer to. C++98 relies on C90; C++11 and C++14 was standardized at the same time as C11 to ensure clean and clear definitions with respect to concurrency and memory models.
==Well-defined concurrency and memory models== <!--T:6-->


=Well-Defined Concurrency and Memory Models=
<!--T:7-->
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).'''


It is important to realize that prior to 2011 ISO C++ and ISO C standards these languages had no definitions of concurrency and corresponding memory model behaviour. In pre-C++11 / pre-C11 code, while most of the time the "right" thing is done, understand there are no guarantees with the language specifications (and therefore compiler implementations of such) of the ordering of reads and writes under concurrency. Ideally newly developed C++ and C concurrent code is explicitly compiled under C++11 and/or C11 settings to have and leverage well-defined concurrency and memory models' definitions. All concurrency and memory models in ISO C++ have a corresponding equivalent in ISO C. That said, most persons prefer easier-to-write-and-understand generic/object-based code, and would therefore prefer using C++ over C for concurrent.
<!--T:25-->
Another reason to use the newer compiler and standards possible with C++ code is to take full advantage of optimizations as a result of features such as <tt>constexpr</tt>. With each newer C++ standard, besides additions, there are updates to existing definitions that improve code correctness and/or optimizations that can be applied. Using an old compiler and/or an older standard when newer ones can be used will not be able to take advantage of newer compiler abilities and C++ definitions.


Prior to C++11 and C11, one would have used the pthreads / Windows threading APIs to implement concurrency. Although many compilers will implement C++11 and C11 threads, etc. in terms of pthreads / Windows threading APIs, using the ISO C++11 and ISO C11 definitions is better for two reasons:
==Compiler support== <!--T:8-->
===Language features===
Various compilers implement various language features differently. Compiler releases at times only partially implement a specific ISO C++ standard. This can sometimes be 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 [http://en.cppreference.com/w/cpp/compiler_support 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.


* the code is compiler and platform independent, and,
===Standard library implementation=== <!--T:9-->
* C++11 and C11 have well-defined memory models --continuing to compile code using pre-C++11 and/or pre-C11 compiler language flags implies that no memory models are formally in effect (i.e., one is likely relying on undefined behaviour).
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.


=Compiler Support=
<!--T:10-->
==Language Features==
'''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 administrators to use a specific version of libstdc++ as several versions of GCC (and therefore libstdc++) are typically installed on a 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.


Various compilers implement various language features differently. Unfortunately a number of compilers only partially implement some of the ISO standard language feature requirements with each release of their compilers. This can sometimes make it frustrating when compiling code with a new compiler that does not yet implement a specific language feature. Fortunately there is a wiki page covering virtually all major C++ compilers and [http://en.cppreference.com/w/cpp/compiler_support which compiler versions implement specific language features] at cppreference.com. This page also provide links to each compiler's web site concerning the details of such.
<!--T:11-->
The GCC documentation has a section which details [https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html Standard Library components are supported in libstdc++].


==Standard Library Implementation==
==New to C++ or need an update?== <!--T:12-->


It is important to realize that many C++ compilers under Linux do not actually provide their own implementation of the C++ Standard Library. Instead these compilers use one that is installed on the system. Typically this implies that libstdc++, which is distributed with GCC, is being used. This is important because outside of the C++ language itself nearly everything one uses is in the Standard Library, e.g., containers, algorithms, iostream, threads, random numbers, etc.  
<!--T:13-->
If you are new to C++ or need an update then start by checking out the ISO C++ advocacy site's [https://isocpp.org/get-started Get Started] page --especially its recommended books. All of these books are excellent.


'''NOTE:''' While you need not worry about this, this is the reason C++ compilers other than GCC on systems across Compute Canada must be configured by the  administrators to use the correct version of libstdc++ as several versions of GCC (and therefore libstdc++) are typically installed on the system. If such is set improperly, then there may be issues. This is also a reason why users should '''never''' hard-code explicit paths to administrator-installed libraries to, for example, compile software.
==Pitfalls== <!--T:15-->
===The <tt>volatile</tt> keyword===
The reader should note that <tt>volatile</tt> in C and C++ have very specific meanings, e.g., see [http://en.cppreference.com/w/cpp/language/cv this page]. Needing to use <tt>volatile</tt> in C/C++ code is a rare event. Within high-performance computing code, <tt>volatile</tt> in rare instances might be used to declare a variable in order tell the compiler to not optimize away load/store side-effects from/to that variable. That said, '''never''' use volatile for synchronization: instead, use C11/C++11 atomic operations and locks, etc. Finally, know <tt>volatile</tt> in other programming languages, e.g., Java, is often different than in C/C++. Typically the latter would be implemented in C/C++ using synchronization constructs.


Nicely the GCC documentation has a section which details [https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html Standard Library components are supported in libstdc++].
===Compilers=== <!--T:18-->
====GCC====
=====-O3=====
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., <tt>man g++</tt>) 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.


=Pitfalls=
=====Linking with older previously compiled binaries===== <!--T:21-->
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<ref>Free Software Foundation. The GNU C++ Library, Chapter 3. https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html</ref> 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 <code>-D_GLIBCXX_USE_CXX11_ABI=0</code> to GCC if using GCC v5.1 or higher to link to libraries built using the older ABI.


==The <tt>volatile</tt> Keyword==
<!--T:22-->
An example of how the ABI is affected by various GCC command-line options here: [[GCC C++ Dual ABI]].


Programmers used to or coming from other programming languages writing concurrent code need to be aware that the <tt>volatile</tt> keyword in C and C++ has very specific semantics and should be assumed to be different from other programming language's use of the term 'volatile'. The reader should note that <tt>volatile</tt> in C++ and C has a very specific meaning, e.g., see [http://en.cppreference.com/w/cpp/language/cv this page]. Consequently using <tt>volatile</tt> in C/C++ code is a rare event --typically limited to certain kinds of low-level code.
<!--T:26-->
Generally speaking, the C++ ABI is frequently updated. One should assume each major compiler release might break the C++ ABI enough that older binaries will have trouble linking C++ code. The solution is typically to keep using the same compiler, or, recompile the older binaries from source with the newer compiler. With GCC such options can be controlled, e.g., see [https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html this page] on <tt>-fabi-version</tt>.


Misuse of <tt>volatile</tt> might arise because the Java programming language uses the <tt>volatile</tt> keyword as well. Unfortunately, Java's <tt>volatile</tt> doesn't have the same meaning as <tt>volatile</tt> in C or C++. Specifically, Java's <tt>volatile</tt> keyword in C++ would correspond to using <tt>std::atomic&lt;T&gt;</tt> for some type <tt>T</tt> or <tt>std::atomic_*</tt> (i.e., the C library equivalents where '*' corresponds to a fundamental type name).
====Intel==== <!--T:19-->
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., <tt>man icpc</tt>) and are recommended to use one of two options, <tt>-fp-model precise</tt> or <tt>-fp-model source</tt>, for ANSI/ISO/IEEE standards-compliant floating-point support. For more details, read this Intel slideshow called, [https://software.intel.com/sites/default/files/article/326703/fp-control-2012-08.pdf Floating-point control in the Intel compiler and libraries].


'''NOTE:''' It is unlikely you will ever use the <tt>volatile</tt> keyword in any of your C++ code. In pre-ISO C++11 concurrent code you might need to use <tt>volatile</tt> but that would be a very rare event. Instead of <tt>volatile</tt>, always use the appropriate mutex, atomic, etc. features of the library you are using (e.g., pthreads, the C++ Standard Library).
==References== <!--T:23-->
</translate>
<references/>

Latest revision as of 17:54, 20 March 2024

Other languages:

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. A number of ISO C++ standards have been released corresponding to the years 1998, 2003, 2011, 2014, 2017, and 2020. These are usually referred to as C++98, C++03, C++11, C++14, C++17, and C++20. The ISO C++ committee is currently releasing its standards on a three-year cycle, i.e., after C++20, the next standard will be in 2023.

A definitive, up-to-date, free online wiki reference for C++ (and its C Standard Library subset) is cppreference.com.

It is important to understand that the C language is a distinct language from the C++ language. While a lot of C code can be used as-is in C++ there are times when differences will affect compilation and/or program execution due to differences between C and C++. If you are compiling your C code as C++ code, then when asking for help refer to your code as C++ code as it is being compiled as C++ code.

Well-defined concurrency and memory models[edit]

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).

Another reason to use the newer compiler and standards possible with C++ code is to take full advantage of optimizations as a result of features such as constexpr. With each newer C++ standard, besides additions, there are updates to existing definitions that improve code correctness and/or optimizations that can be applied. Using an old compiler and/or an older standard when newer ones can be used will not be able to take advantage of newer compiler abilities and C++ definitions.

Compiler support[edit]

Language features[edit]

Various compilers implement various language features differently. Compiler releases at times only partially implement a specific ISO C++ standard. This can sometimes be 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[edit]

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 administrators to use a specific version of libstdc++ as several versions of GCC (and therefore libstdc++) are typically installed on a 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?[edit]

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.

Pitfalls[edit]

The volatile keyword[edit]

The reader should note that volatile in C and C++ have very specific meanings, e.g., see this page. Needing to use volatile in C/C++ code is a rare event. Within high-performance computing code, volatile in rare instances might be used to declare a variable in order tell the compiler to not optimize away load/store side-effects from/to that variable. That said, never use volatile for synchronization: instead, use C11/C++11 atomic operations and locks, etc. Finally, know volatile in other programming languages, e.g., Java, is often different than in C/C++. Typically the latter would be implemented in C/C++ using synchronization constructs.

Compilers[edit]

GCC[edit]

-O3[edit]

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[edit]

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[1] 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.

An example of how the ABI is affected by various GCC command-line options here: GCC C++ Dual ABI.

Generally speaking, the C++ ABI is frequently updated. One should assume each major compiler release might break the C++ ABI enough that older binaries will have trouble linking C++ code. The solution is typically to keep using the same compiler, or, recompile the older binaries from source with the newer compiler. With GCC such options can be controlled, e.g., see this page on -fabi-version.

Intel[edit]

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.

References[edit]

  1. Free Software Foundation. The GNU C++ Library, Chapter 3. https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html