19.6.  Standard Expression Conversions

[ fromfile: types.xml id: stdconversion ]

Abstract

This section discusses expression conversions, including implicit type conversions through promotion or demotion, and explicit casting through a variety of casting mechanisms.

Suppose x and y are numeric variables. An expression of the form x op y has both a value and a type. When this expression is evaluated, temporary copies of x and y are used. If x and y have different types, the one with the shorter type may need to be converted (widened) before the operation can be performed.

An implicit conversion of a number that preserves its value is called a promotion.

Automatic Expression Conversion Rules for x op y

  1. Any bool, char, signed char, unsigned char, enum, short int, or unsigned short int is promoted to int. This is called an integral promotion.

  2. If, after the first step, the expression is of mixed type, then the operand of smaller type is promoted to that of the larger type, and the value of the expression has that type.

  3. The hierarchy of types is indicated by the arrows in Figure 19.1.

Figure 19.1. Hierarchy of Basic Types

Hierarchy of Basic Types

The relationship between unsigned and long depends on the implementation. For example, on a system that implements int with the same number of bytes as long, it would not be possible to promote unsigned to long, so the promotion process would bypass long and promote unsigned to unsigned long. Now assume that you have the following declarations:

      double d;
      int i;
    

In general, a promotion such as d = i; will be well behaved. An assignment that causes a demotion such as i = d; can result in a loss of information. Assuming the compiler permits the assignment, the fractional part of d would be discarded. Example 19.8 demonstrates some of the conversions we have discussed.

Example 19.8. src/types/mixed/mixed-types.cpp

#include <iostream>
using namespace std;

int main() {
    int i, j = 88;
    double d = 12314.8723497;
    cout << "initially d = " << d
         << "  and j = " << j << endl;
    cout << "The sum is: " << j + d << endl;
    i = d;
    cout << "after demoting d,  i = " << i << endl;
    d = j;
    cout << "after promoting j,  d = " << d << endl;
}

<include src="src/types/mixed/mixed-types.cpp" href="src/types/mixed/mixed-types.cpp" id="mixedtypescpp" mode="cpp"/>


Here is the compile and run.

      src> g++ mixed-types.cpp
      mixed-types.cpp: In function `int main()':
      mixed-types.cpp:10: warning: converting to `int' from `double'
      src> ./a.out
      initially d = 12314.9  and j = 88
      The sum is: 12402.9
      after demoting d,  i = 12314
      after promoting j,  d = 88
      src>
    

There is another kind of implicit conversion that is made whenever necessary. An expression that evaluates to a pointer or to an integral or floating-point value can be converted to bool. If that value is zero, the result is false; otherwise the result is true. Example 19.9 demonstrates this conversion.

Example 19.9. src/types/convert2bool.cpp

#include <iostream>
using namespace std;

int main() {
   int j(5);
   int* ip(&j);
   int* kp(0);
   double y(3.4);
   if(y)
      cout << "y looks like true to me!" << endl;
   else
      cout << "y looks like false to me!" << endl;
   cout << "ip looks like " << (ip ? "true" : "false") << endl;
   cout << "kp looks like " << (kp ? "true" : "false") << endl;
   while(--j) {
      cout << j << '\t';
   }
   cout << endl;
}

<include src="src/types/convert2bool.cpp" href="src/types/convert2bool.cpp" mode="cpp" id="convert2bool"/>


The output is

      src> ./a.out
      y looks like true to me!
      ip looks like true
      kp looks like false
      4       3       2       1
      src>