Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does C treat char sums?

Tags:

c++

c

char

int

When I'm in C++, and I call an overloaded function foo, like so:

foo('e' - (char) 5)

it can output "this is a char" or "this is an int" based on the type result. I get "this is an int" from my program, like this:

#include <iostream>

void foo(char x)
{
    std::cout << "output is a char" << std::endl;
}
void foo(int x)
{
    std::cout << "output is an int" << std::endl;
}
int main()
{
    foo('a' + (char) 5);
}

My instructor says that in C, the expression above, ('a' + (char) 5), evaluates as a char. I see in the C99 standard that chars are promoted to ints to find the sum, but does C recast them back to chars when it's done? I can't find any references that seem credible saying one way or another what C actually does after the promotion is completed, and the sum is found.

Is the sum left as an int, or given as a char? How can I prove this in C, or is there a reference I'm not understanding/finding?

like image 272
MagnaVis Avatar asked Dec 11 '22 23:12

MagnaVis


2 Answers

From the C Standard, 6.3.1.8 Usual arithmetic conversions, emphasis mine:

Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is the type domain of the operands if they are the same, and complex otherwise. This pattern is called the usual arithmetic conversions:

  • First, if the correspeonding real type of either operand is long double...
  • Otherwise, if the corresponding real type of either operand is double...
  • Otherwise, if the corresponding real type of either operand is float...
  • Otherwise, the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
    • If both operands have the same type, then no further conversion is needed.

So you are exactly correct. The type of the expression 'a' + (char) 5 is int. There is no recasting back to char, unless explicitly asked for by the user. Note that 'a' here has type int, so it's only the (char)5 that needs to be promoted. This is stipulated in 6.4.4.4 Character Constants:

An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'.
...
An integer character constant has type int.

There is an example demonstrating the explicit recasting to char:

In executing the fragment

char c1, c2;
/* ... */
c1 = c1 + c2

the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to int size and then add the two ints and truncate the sum. Provided the addition of two chars can be done without overflow, or with overflow wrapping silently to produce the correct result, the actual execution need only produce the same result, possibly omitting the promotions.

The truncation here only happens because we assign back to a char.

like image 98
Barry Avatar answered Dec 26 '22 11:12

Barry


No, C does not recast them back to chars.

The standard (ISO/IEC 9899:1999) says (6.3.1.8 Usual arithmetic conversions):

Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result. For the specified operands, each operand is converted, without change of type domain, to a type whose corresponding real type is the common real type. Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result, whose type domain is determined by the operator.

like image 32
Arkanosis Avatar answered Dec 26 '22 11:12

Arkanosis