Language Definitions - Discovering Modern C++. An Intensive Course for Scientists, Engineers, and Programmers+ (2016)

Discovering Modern C++. An Intensive Course for Scientists, Engineers, and Programmers(2016)

Appendix C. Language Definitions

This appendix is intended as a reference for definitions relevant to this book.

C.1 Value Categories

C++ distinguishes among different categories of values. The most important are lvalue and rvalue.

Definition C–1 (lvalue). An Lvalue (so called, historically, because lvalues can appear on the left-hand side of an assignment expression) designates a function or an object.

More pragmatically, an lvalue is an entity from which we can get an address. This does not exclude that they may be constant—although this is somewhat inconsistent with the terminology. The reason for this is that early versions of C had no const attribute so all lvalues were allowed on the left side of an assignment.

The counterpart is:

Definition C–2 (rvalue). An Rvalue (so called, historically, because rvalues can appear on the right-hand side of an assignment expression) is an expired value (e.g., an object casted to an rvalue reference), a temporary object or sub-object thereof, or a value that is not associated with an object.

The definitions are adapted from the ISO standard.

C.2 Operator Overview

Image

Image

Image

Table C–1: Operator Summary

The table is taken from [43, §10.3]; we provided the associativity of the binary and ternary operators. Unary operators of the same priority are evaluated from inside out. In expressions with left-associative operators, the left sub-expression is evaluated first; for instance:

a + b + c + d + e // Corresponds to:
((((a + b) + c) + d) + e

Assignments are right-associative; that is:

a= b= c= d= e // Corresponds to:
a= (b= (c= (d= e)))

A noteworthy detail is the definition of sizeof. It can be applied directly to expressions like objects but needs parentheses when applied to a type:

int i;
sizeof i; // Okay: i is an expression
sizeof(i); // Okay as well: extra () do not harm
sizeof int; // Error: parentheses needed for types
sizeof(int); // Okay

If you have doubts about whether parentheses are needed, you can always include extra parentheses.

C.3 Conversion Rules

Integer, floating-point, and bool values can be freely mixed in C++ as each of these types can be converted to any other. Wherever possible, values are converted such that no information is lost. A conversion is Value-Preserving when the conversion back to the original type yields the original value. Otherwise the conversion is Narrowing. This paragraph is the short version of [43, Intro §10.5].

C.3.1 Promotion

An implicit conversion that preserves the value is referred to as Promotion. Short integral or floating-point values can be converted exactly to longer integral or floating-point types respectively. Conversions to int and double are preferred (over longer types) when possible as these are considered to have the “natural” size in arithmetic operations (i.e., being best supported by hardware). The integral promotions are, in detail:

• A char, signed char, unsigned char, short int, or unsigned short int is converted to an int if int can represent all source type values; otherwise, it is converted to unsigned int.

• A char16_t, char32_t, wchar_t, or plain enum is converted to the first of the following types that is able to hold all source type values: int, unsigned int, long, unsigned long, and unsigned long long.

• A bit-field is converted to an int if it can represent all values of the former; otherwise to an unsigned int under the same conditions. Otherwise, no promotion applies.

• A bool is converted to an int: false becomes 0 and true turns into 1.

Promotions are used as part of the usual arithmetic conversions (§C.3.3). Source: [43, §10.5.1].

C.3.2 Other Conversions

C++ performs the following potentially narrowing conversions implicitly:

• Integer and plain enum types can be converted to any integer type. If the target type is shorter, leading bits are cut off.

• Floating-point values can be converted to shorter floating-point types. If the source value lies between two destination values, the result is one of them; otherwise, the behavior is undefined.

• Pointers and references: Any pointer to object types can be converted to void* (evil old-style hacking, though). In contrast, pointers to functions or members cannot be converted to void*. Pointer/references to derived classes can be implicitly converted to pointer/references to (unambiguous) base classes. 0 (or an expression yielding 0) can be converted to any pointer type, resulting in a null pointer. nullptr is preferable. T* can be converted to const T*, likewise T& to const T&.

• bool: Pointers, integral, and floating-point values can be converted to bool: zero values become false, all others true. None of these conversions contributes to understanding programs.

• Integer⇔floating-point: When a floating-point is converted to an integer, the fractional part is discarded (rounding toward 0). If the value is too large to be represented, the behavior is undefined. The conversion from integer to a floating-point type is exact when the former is representable in the target type. Otherwise, the next lower or higher floating-point value is taken (which one is implementation-dependent). In the unlikely case that it is too large for the floating-point type, the behavior is undefined.

Source: [43, §10.5.2] and standard.

C.3.3 Usual Arithmetic Conversions

These conversions are performed on operands of a binary operator to turn them into a common type which is then used as a result type:

1. If either operand is long double, the other is converted to long double;

• Otherwise, if either operand is double, the other is converted to double;

• Otherwise, if either operand is float, the other is converted to float;

• Otherwise, integral promotion from Section C.3.1 is performed on both operands.

2. Otherwise, if either operand is unsigned long long, the other is converted to unsigned long long;

• Otherwise, if one operand is a long long and the other an unsigned long, then the unsigned long is converted to long long if the latter can represent all values of the former; otherwise, both are converted to unsigned long long.

• Otherwise, if one operand is a long and the other an unsigned, then the unsigned is converted to long if the latter can represent all values of the former; otherwise, both are converted to unsigned long.

• Otherwise, if either operand is long, the other is converted to long;

• Otherwise, if either operand is unsigned, the other is converted to unsigned;

• Otherwise, both operands are converted to int.

As a consequence, programs with mixed signed and unsigned integers have platform-dependent behavior since the conversion rules depend on the sizes of integer types. Source: [43, §10.5.3].

C.3.4 Narrowing

A Narrowing Conversion is an implicit conversion:

• From a floating-point type to an integer type; or

• From long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly); or

• From an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type; or

• From an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type.

Source: ISO standard.

Bibliography

[1] D. Abrahams and A. Gurtovoy, C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond. Addison-Wesley, 2004.

[2] D. Adams, “Life, the Universe and Everything.” The Hitchhiker’s Guide to the Galaxy, Pan Macmillan, 1980.

[3] M. H. Austern, Generic Programming and the STL: Using and Extending the C++ Standard Template Library. Professional Computing Series. Addison-Wesley, 1998.

[4] J. J. Barton and L. R. Nackman, Scientific and Engineering C++. Addison-Wesley, 1994.

[5] L. S. Blackford, A. Petitet, R. Pozo, K. Remington, R. C. Whaley, J. Demmel, J. Dongarra, I. Duff, S. Hammarling, G. Henry, et al., “An updated set of basic linear algebra subprograms (blas),” ACM Transactions on Mathematical Software, vol. 28, no. 2, pp. 135–151, 2002.

[6] W. E. Brown, “Three <random>-related proposals, v2,” Tech. Rep. N3742, ISO/IEC JTC 1, Information Technology, Subcommittee SC 22, Programming Language C++, August 2013.

[7] “C++ reference: Implicit cast.” http://en.cppreference.com/w/cpp/language/implicit_cast.

[8] K. Czarnecki and U. W. Eisenecker, Generative Programming: Methods, Tools, and Applications. ACM Press/Addison-Wesley, 2000.

[9] K. Czarnecki and U. Eisenecker, “Meta-control structures for template metaprogramming.” http://home.t-online.de/home/Ulrich.Eisenecker/meta.htm.

[10] I. Danaila, F. Hecht, and O. Pironneau, Simulation Numérique en C++. Dunod, Paris, 2003.

[11] L. Dionne, “Boost.hana.” http://ldionne.com/hana/index.html, 2015.

[12] S. Du Toit, “Hourglass interfaces for c++ apis.” http://de.slideshare.net/StefanusDuToit/cpp-con-2014-hourglass-interfaces-for-c-apis, 2014.

[13] M. A. Ellis and B. Stroustrup, The Annotated C++ Reference Manual. Addison-Wesley, 1990.

[14] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1994.

[15] B. Ganter and R. Wille, Formal Concept Analysis: Mathematical Foundations. Springer Science & Business Media, 2012.

[16] P. Gottschling, “Code reuse in class template specialization,” Tech. Rep. N3596, ISO IEC JTC1/SC22/WG21, 2013. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3596.pdf.

[17] P. Gottschling, Matrix Template Library 4. SimuNova, 2014. mtl4.org.

[18] P. Gottschling, Mixed Complex Arithmetic. SimuNova, 2011. https://simunova.zih.tu-dresden.de/mtl4/docs/mixed__complex.html, Part of Matrix Template Library 4.

[19] P. Gottschling and A. Lumsdaine, “Integrating semantics and compilation: Using c++ concepts to develop robust and efficient reusable libraries,” in GPCE ’08: Proceedings of the 7th International Conference on Generative Programming and Component Engineering, pp. 67–76, ACM, 2008.

[20] P. Gottschling, D. S. Wise, and A. Joshi, “Generic support of algorithmic and structural recursion for scientific computing,” The International Journal of Parallel, Emergent and Distributed Systems (IJPEDS), vol. 24, no. 6, pp. 479–503, December 2009.

[21] D. Gregor, “ConceptGCC,” 2007. http://www.generic-programming.org/software/ConceptGCC/.

[22] A. Gurtovoy and D. Abrahams, The Boost Meta-Programming Library. Boost, 2014. www.boost.org/doc/libs/1_56_0/libs/mpl.

[23] E. Hairer, S. Nørsett, and G. Wanner, Solving Ordinary Differential Equations I: Nonstiff Problems. Springer Series in Computational Mathematics, Springer Berlin Heidelberg, 2008.

[24] M. R. Hestenes and E. Stiefel, “Methods of conjugate gradients for solving linear systems,” J. Res. Nat. Bur. Standards, vol. 49, no. 6, pp. 409–436, December 1952.

[25] R. W. Hockney, The Science of Computer Benchmarking, vol. 2. SIAM, 1996.

[26] N. Josuttis, The C++ Standard Library: A Tutorial and Reference, 2nd Edition. Addison-Wesley, 2012.

[27] B. Karlsson, Beyond the C++ Standard Library. Addison-Wesley, 2005.

[28] KjellKod.cc, “Number crunching: Why you should never, ever, ever use linked-list in your code again.” http://www.codeproject.com/Articles/340797/Number-crunching-Why-you-should-never-ever-EVER-us, August 2012.

[29] K. Meerbergen, Generic Linear Algebra Software. K.U. Leuven, 2014. http://people.cs.kuleuven.be/~karl.meerbergen/glas/.

[30] K. Meerbergen, K. Fresl, and T. Knapen, “C++ bindings to external software libraries with examples from BLAS, LAPACK, UMFPACK, and MUMPS,” ACM Transactions on Mathematical Software (TOMS), vol. 36, no. 4, p. 22, 2009.

[31] S. Meyers, “A concern about the rule of zero.” http://scottmeyers.blogspot.de/2014/03/a-concern-about-rule-of-zero.html.

[32] S. Meyers, Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14. O’Reilly Media, Inc., 2014.

[33] Oracle, “Oracle C++ call interface.” http://www.oracle.com/technetwork/database/features/oci/index-090820.html.

[34] E. Ott, Chaos in Dynamical Systems. Cambridge University Press, 2002.

[35] D. Quinlan, “Rose: Compiler support for object-oriented frameworks,” Parallel Processing Letters, vol. 10, no. 02–03, pp. 215–226, 2000.

[36] J. Rudl, “Skript zur Vorlesung Finanzmathematik,” October 2013.

[37] J. G. Siek, L.-Q. Lee, and A. Lumsdaine, The Boost Graph Library: User Guide and Reference Manual. Addison-Wesley, 2001.

[38] J. G. Siek and A. Lumsdaine, A Language for Generic Programming. PhD thesis, Indiana University, 2005.

[39] M. Skarupke, “The problems with uniform initialization.” http://probablydance.com/2013/02/02/the-problems-with-uniform-initialization, February 2013.

[40] A. Stepanov, “Abstraction penalty benchmark, version 1.2 (kai),” 1992. http://www.open-std.org/jtc1/sc22/wg21/docs/D_3.cpp.

[41] W. Storm, “An in-depth study of the STL deque container.” http://www.codeproject.com/Articles/5425/An-In-Depth-Study-of-the-STL-Deque-Container.

[42] B. Stroustrup, The C++ Programming Language, 3rd Edition. Addison-Wesley, 1997.

[43] B. Stroustrup, The C++ Programming Language, 4th Edition. Addison-Wesley, 2013.

[44] H. Sutter, “Why not specialize function templates?” http://www.gotw.ca/publications/mill17.htm, 2009.

[45] H. Sutter and A. Alexandrescu, C++ Coding Standards. The C++ In-Depth Series, Addison-Wesley, 2005.

[46] A. Sutton, “C++ extensions for concepts,” Tech. Rep. N4377, ISO/IEC JTC 1, Information Technology, Subcommittee SC 22, Programming Language C++, February 2015.

[47] X. Tang and J. Järvi, “Generic flow-sensitive optimizing transformations in C++ with concepts,” in SAC’10: Proceedings of the 2010 ACM Symposium on Applied Computing, Mar. 2010.

[48] G. Teschl, Ordinary Differential Equations and Dynamical Systems, vol. 140. American Mathematical Soc., 2012.

[49] T. Veldhuizen, “C++ templates are Turing complete.” citeseer.ist.psu.edu/581150.html, 2003.

[50] V. Vernon, Implementing Domain-Driven Design. Addison-Wesley, 2013.

[51] R. Whaley, A. Petitet, and J. Dongarra, “Automated empirical optimization of software and the ATLAS project,” Parallel Computing, vol. 27, no. 1–2, pp. 3–35, Jan. 2001.

[52] B. Wicht, “C++ benchmark – std::vector vs std::list vs std::deque.” http://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html, 2012.

[53] A. Williams, C++ Concurrency in Action. Manning, 2012.

[54] P. Wilmott, Paul Wilmott Introduces Quantitative Finance. Wiley, 2007.