admin管理员组

文章数量:1123600

I read the c documentation but I couldn't understand it. Could you please answer my questions(Maybe my English is not good.) I have two codes and two question.

Question about first code: Has an integer promotion been made?

I mean, y-->int(integer promotion) --> Double ?

or

y-->Double?(Converted directly to Double. Integer promotions are not made.) ?

which one is true?

//First code
#include <stdio.h>
int main() {
    double x = 11.153;
    short y = 123;
    x - y;
    return 0;
}

Question about second code: Has an integer promotion been made?

I mean, x-->int(integer promotion)-->long.

or

x --> long (Converted directly to long. Integer promotions are not made.) ?

which one?

//Second Code
#include <stdio.h>
int main() {
    short x = 15;
    long y = 12;
    x - y;
    return 0;
}

exact technical answers

I read the c documentation but I couldn't understand it. Could you please answer my questions(Maybe my English is not good.) I have two codes and two question.

Question about first code: Has an integer promotion been made?

I mean, y-->int(integer promotion) --> Double ?

or

y-->Double?(Converted directly to Double. Integer promotions are not made.) ?

which one is true?

//First code
#include <stdio.h>
int main() {
    double x = 11.153;
    short y = 123;
    x - y;
    return 0;
}

Question about second code: Has an integer promotion been made?

I mean, x-->int(integer promotion)-->long.

or

x --> long (Converted directly to long. Integer promotions are not made.) ?

which one?

//Second Code
#include <stdio.h>
int main() {
    short x = 15;
    long y = 12;
    x - y;
    return 0;
}

exact technical answers

Share Improve this question asked 21 hours ago İlker Deveciİlker Deveci 694 bronze badges 7
  • 1 What do you think happens in each scenario and why? Are you aware of "the usual arithmetic conversions"? – Lundin Commented 21 hours ago
  • 1 In both codes, the expressions do not have any effect and are likely optimized away completely. You should assign the result to some variable. This would also improve the question because the way you use the result (assigning it or passing to some function etc.) may add additional conversions depending on types involved. – Gerhardh Commented 21 hours ago
  • 1 Integer to floating point is conversion, not promotion. Promotion is implicit promoting a small integer type to a larger integer type. – Some programmer dude Commented 21 hours ago
  • 2 @Someprogrammerdude: ”Promotion is implicit promoting a small integer type to a larger integer type”: Some promotions convert an integer type to an integer type of the same size but greater rank. – Eric Postpischil Commented 19 hours ago
  • 1 @BoP: Re “It also depends on the relative sizes of the different types… short and long…”: It does not depend on the sizes for this case. The integer promotions convert short to int even if they are the same size, and the usual arithmetic conversions convert a short-long pair to long-long even if short and long are the same size. – Eric Postpischil Commented 19 hours ago
 |  Show 2 more comments

2 Answers 2

Reset to default 4

Start by reading Implicit type promotion rules regarding integer promotion and the usual arithmetic conversions.

Integer promotion often happens independently of the usual arithmetic conversions, but if the usual arithmetic conversions apply, they may involve integer promotion as one of the steps.

This is operator-specific. Your specific case is the binary - operator, which is part of the additive operators. C23 6.5.7 then says:

If both operands have arithmetic type, the usual arithmetic conversions are performed on them.

Now read the quoted steps of the usual arithmetic conversions in the link I posted.

  • Floating point types are checked for first, before integer types.
  • If either operand is of floating point type and the other an integer type, a conversion to the floating point type will happen before the step mentioning integer promotion.
  • Similarly, if neither operand is floating point and both are integer types, we arrive at the step "Otherwise, the integer promotions are performed on both operands." Which only applies for small integer types, not for long etc.

C 2024 (the 2024 edition of the C standard) specifies the binary - operator in clause 6.57. Part of that says:

If both operands have arithmetic type, the usual arithmetic conversions are performed on them.

6.3.2.8 specifies the usual arithmetic conversions with a list of 13 steps, so I will not detail all of them here. The first four apply only when there is a decimal floating-point type, and the fifth only when there is a long double. For your case of double minus short, the sixth step applies:

Otherwise, if the corresponding real type of either operand is double, the other operand is converted, without change of type domain, to a type whose corresponding real type is double.

The real type of double is double,1 so this condition is met, and the short is converted to double. Then the usual arithmetic conversions are done, and the subtraction is performed using double and double.

For your case of short minus long, that sixth step does not apply, and neither does the seventh (about float). The next step says:

Otherwise, if any of the two types is an enumeration, it is converted to its underlying type. Then, the integer promotions are performed on both operands.

Neither short nor long is an enumeration, so that does not apply. Then the integer promotions are performed. 6.3.2.1 specifies the integer promotions. First, the integer promotions apply only to:

An object or expression with an integer type (other than int or unsigned int) whose conversion rank is less than or equal to the rank of int and unsigned int.

A bit-field of type bool, int, signed int, or unsigned int.

Rank is specified in the same clause 12 rules. It is basically an ordering of integer types from narrower to wider. long has greater rank than int and is not a bit-field, so it is not affected by the integer promotions. short has lesser rank than int, so the integer promotions apply to it. The integer promotions are, still in 6.3.2.1:

The value from a bit-field of a bit-precise integer type is converted to the corresponding bit-precise integer type. If the original type is not a bit-precise integer type (6.2.5): if an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

short is not a bit-field, and an int can represent all values of short, so short is converted to int.

Now the integer promotions have left us with a long and an int to subtract, and we return to the usual arithmetic conversions.

The next step applies only if the operands are the same type. After that, we have:

Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.

long and int are both signed integer types, so the lesser-ranked int is converted to the greater-ranked long. This completes the usual arithmetic conversions, and the subtraction is performed using long and long.

Footnote

1 “Real type” and “type domain” refer to complex number types (as in mathematical complex numbers, with real and imaginary parts). “Real type” means the floating-point type that is used for complex numbers. So the real type of complex double is double. The real type of double is double.

本文标签: type conversionInteger Promotion in CStack Overflow