Attempts to parse the usual C11 rules for arithmetic conversion

I am trying to understand the rules of arithmetic conversion of the C11 standard. The standard defines different integer types with strictly decreasing ranks:

long long int
long int
int
short int
char

      

Also, all other types are signed by default, whereas char is either signed or unsigned depending on the implementation. All types have both signed and unsigned versions. In addition, the standard defines real types as:

long double
double
float

      

The way to read the standard is that if we add, for example,

a + b

      

and a

is a valid type, a b

is any integer type, then b

converted to type a

. In other words, if it a

has a type float

and b

has a type long long int

, do we first convert b

to float

and then do the padding, or am I reading this wrong? In other words, it doesn't matter what the rank of the integer type is, it is the real type, which indicates to which real type the integer type is converted.

Finally, I am having problems with this. Suppose it a

has no sign of a higher rank than the b

one signed, what happens to b

? The standard says we are converting b

to an unsigned version a

. How it's done? I see two logical options for this transformation. Let's say what a

is unsigned long and b

is a signed int, then we can do either:

signed int -> unsigned int -> unsigned long
signed int -> signed long -> unsigned long

      

They can create different values, since in the first case we add UINT_MAX + 1 to b

, and in the second we add ULONG_MAX + 1 to b

if b

negative.

Finally, what should happen if say a

has a signed type of a higher rank than b

, but the range of values b

cannot match the type a

? Seems to be the last possible case the standard is referring to? I assume this is what you get for example. 32-bit architecture where int and long have the same size representation, so a signed long cannot contain all unsigned ints.

Am I getting it right or are there some parts that I am interpreting wrong?

+3


source to share


1 answer


[...] and a

is a real type, a b

is any integer type, then b is converted to a type a

. In other words, if it a

has a type float

and b

has a type long long int

, we first convert b

to float

and then add [...]

Yes.

Finally, I am having problems with this. Suppose it a

has no sign of a higher rank than the b

one signed, what happens to b

? The standard says that we will convert b

to the unsigned version a

. How it's done? [...]



The (arithmetic) value is converted b

, ULONG_MAX

+ 1 is added / subtracted until the value matches the type a

.

The last example uses the last case C11 (n1570) 6.3.1.8 p1, both operands are converted to an unsigned type corresponding long int

to which is unsigned long int

. (I'm not sure about this, but it seems that standard (implicitly?) Requires appropriate unsigned types for all signed integer types, including extended types.)

+2


source







All Articles