1

cppreference says:

In particular, arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable.

All the major compilers (g++, clang, and msvc) say that decltype(a+b) is int when both a and b are short.

However, the standard says:

Integral promotions [conv.prom]/1
A prvalue of an integer type other than bool, char16_­t, char32_­t, or wchar_­t whose integer conversion rank is less than the rank of int can be converted to a prvalue of type int [...].

Usual arithmetic conversions [expr.arith.conv]/1.5.1
-- If both operands have the same type, no further conversion is needed.

I can only see that "can be converted" and I cannot find where it requires integral promotion for arithmetic operators.
Is the cppreference wrong here?

Community
  • 1
  • 1
Abyx
  • 12,345
  • 5
  • 44
  • 76

1 Answers1

3

You were one line away from it. From [expr]/11 (N4659):

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

...

Otherwise, the integral promotions (7.6) shall be performed on both operands. Then the following rules shall be applied to the promoted operands:

Emphasis added. [conv.prom] says that they can take place and how they work. [expr]/11 specifies one of the times when they will take place.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • That's slightly flimsy wording, if I may say so myself. It says "algorithm A is applied". But once we read the algorithm, it speaks in terms of what "may happen", not what "should happen". – StoryTeller - Unslander Monica Nov 16 '17 at 18:02
  • 1
    @StoryTeller: Right. 7.6 isn't talking about what will happen to every integer everywhere. It's explaining the process of integral promotions, which *can happen*. Someone else decides *when* integer promotions happen. If you use arithmetic on integers, they get promoted. If you *don't* use arithmetic on them, then they *don't* get promoted. That's why it says "can", not "will". – Nicol Bolas Nov 16 '17 at 18:07
  • Yes. And that's the problem. Because for instance, [expr.add]: *"The additive operators + and - group left-to-right. The usual arithmetic conversions are performed for operands of arithmetic or enumeration type."*. Same flimsy wording that points to 7.6 (which is already kinda flimsy). Point being, it's way to subtle a phrasing for a formal specification IMO. – StoryTeller - Unslander Monica Nov 16 '17 at 18:10
  • @StoryTeller: I see nothing flimsy there. "Usual arithmetic conversions" is a techical term, defined explicitly in the standard. "Are performed" means exactly what it says. – Nicol Bolas Nov 16 '17 at 18:12
  • Apparently it's not *quite* as obvious, or the OP wouldn't be confused, and I wouldn't hesitate to bolden the same text myself. – StoryTeller - Unslander Monica Nov 16 '17 at 18:13
  • 1
    @StoryTeller: The fact that one person managed to miss a sentence doesn't mean the sentence was not there nor that it wasn't clear. People make mistakes and misread things. That doesn't mean what they were reading wasn't clear. – Nicol Bolas Nov 16 '17 at 18:14
  • We can argue clarity until the chickens come home to roost. If one persons finds something unclear, it doesn't make them "wrong". I don't appreciate that patronizing attitude to be frank. – StoryTeller - Unslander Monica Nov 16 '17 at 18:15
  • 1
    The [conv.prom] should be written as "1/ Integral promotions are the following conversions: 2/ A prvalue of an integer type other than [...] **is** converted to a prvalue of type int [...]." and there would be no confusion. – Abyx Nov 16 '17 at 18:15
  • @Abyx - To contrast, [the C standard does speak in terms of "**is**" and not "**may**"](https://port70.net/~nsz/c/c11/n1570.html#6.3.1.1p2). – StoryTeller - Unslander Monica Nov 16 '17 at 18:18
  • @Abyx: But *everything* in the standard is written this way. All of these processes use "can be" wording. Look up [basic.lookup.qual] or [basic.stc.static]/3. Or just search for "can be". This is the common way the standard defines processes like this which "can be" invoked by various other constructs. – Nicol Bolas Nov 16 '17 at 18:18
  • @StoryTeller: "The following ***may be used*** in an expression wherever an int or unsigned int may be used:" That's from your C standard link. Just like in C++, it speaks of possibilities here; whether it actually happens is explained elsewhere. – Nicol Bolas Nov 16 '17 at 18:25
  • @NicolBolas - You should continue reading before basing any claim on it. – StoryTeller - Unslander Monica Nov 16 '17 at 18:27
  • @StoryTeller: Now, take the C 6.3.1.1 section and expand it 5-fold (since C++ has more types and cases for integer promotion). Now, instead of doing it as a list, fold the first sentence into each of the list elements. What you'll have is C++'s section 7.6. The "may be" wording in C is applied once, but it still applies to each separate bullet point. The C++ version simply repeats it, since it doesn't use bullet points. – Nicol Bolas Nov 16 '17 at 18:54
  • 1
    @Abyx Uh, no. That wording would be quite bad. [conv.prom] defines conversions that *can be* performed. If you use "is", you're stating that they *are* preformed. Saying "A prvalue of type `bool` **is** converted to a prvalue of type `int`" implies that all bool prvalues are `int`s. The wording is fine as-is. – Barry Nov 16 '17 at 19:02