C¶
C is a general-purpose, high-level, imperative programming language created by Dennis Ritchie between 1969 and 1973 at Bell Labs. C is now represented as a number of ISO standards corresponding to the years 1989/1990, 1999, and 2011 and are usually referred to as C90 (or C89), C99, and C11. 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:
- C, i.e., the language, history, C90.
- C99: Adds language and Standard Library features.
intis no longer implicitly assumed. - C11: Major release adding memory model and concurrency (e.g., threads, atomics, compare-and-swap) support.
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 the aforementioned Wikipedia pages' reference sections. (If you need the official document, you may purchase it from Standards Council of Canada.)
Well-Defined Concurrency and Memory Models¶
Important
Prior to 2011, the ISO C standard had no definitions of concurrency and memory models. Thus, in pre-C11 compiled code, there are no guarantees concerning the ordering of memory reads and writes under concurrency; such behaviour is likely undefined, and the compiler vendor may or may not have documented it. It is therefore preferable to compile concurrent C code as C11 code (or newer).
Pitfalls¶
The volatile Keyword¶
Understanding volatile in C/C++
The volatile keyword in C and C++ has a very specific meaning. For details, refer to this page. Actually needing to use volatile in C/C++ code is a rare event and is typically limited to certain kinds of low-level code.
Misuse of volatile might arise because the Java programming language also uses the volatile keyword. Java's volatile has a totally different meaning from C's volatile. Specifically, Java's volatile keyword in C corresponds to using atomic_* (i.e., where * corresponds to a fundamental type name such as int).
Compilers¶
GCC¶
GCC Optimization Flags
The GCC compiler's -O3 option includes potentially 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 have more time, read the man page (e.g., man gcc) and unset the appropriate options by searching for "-O3" to see which options are turned on, then turn off the settings that are not safe.
Intel¶
Intel Compiler Floating-Point Optimizations
Intel C/C++ compilers may default to using potentially unsafe optimizations for floating-point operations. Users of Intel compilers should read the Intel man pages (e.g., man icc) 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.