Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy does a value of an enum with a fixed underlying type of char resolve to fct(int) instead of fct(char)?
    primarykey
    data
    text
    <p>This problem came up when answering <a href="https://stackoverflow.com/questions/14185352/underlying-type-of-weak-typed-enum-in-c11">this question about overload resolution with enums</a>.</p> <p>While the case for <code>long long</code> was definitely a bug in MSVC2012NovCTP (according to the standard text and a test with gcc 4.7.1), I cannot figure out why the following behavior occurs:</p> <pre><code>#include &lt;iostream&gt; enum charEnum : char { A = 'A' }; void fct(char) { std::cout &lt;&lt; "fct(char)" &lt;&lt; std::endl; } void fct(int) { std::cout &lt;&lt; "fct(int)" &lt;&lt; std::endl; } void fct(long long) { std::cout &lt;&lt; "fct(long long)" &lt;&lt; std::endl; } int main() { fct('A'); fct(A); } </code></pre> <p>Both MSVC2012NovCTP and gcc 4.7.1 agree on this output: </p> <blockquote> <p>fct(char)<br> fct(int) </p> </blockquote> <p>Shouldn't <code>A</code> be converted from <code>charEnum</code> to <code>char</code>? Why is <code>A</code> being converted to <code>int</code>?</p> <p>EDIT: clang complains that the call is ambiguous, which agrees with my interpretation below; that said, I would still find it much more intuitive if it were only considered to be the underlying type.</p> <hr> <p>Two relevant standard excerpts are §7.2/9:</p> <blockquote> <p>The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion (4.5)</p> </blockquote> <p>And §4.5/4:</p> <blockquote> <p>A prvalue of an unscoped enumeration type whose underlying type is fixed (7.2) can be converted to a prvalue of its underlying type. Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type. </p> </blockquote> <p>So <code>charEnum</code> can either be converted to <code>char</code>, or any integral promotion of <code>char</code>, such as <code>int</code>.</p> <p>But this is vague to me because "can" doesn't quite say which will actually be chosen. If anything, this should be ambiguous with this wording because no preference is given between <code>char</code> or any of its promotions. If you comment out <code>fct(int)</code>, then the call <em>is</em> ambiguous. Why is <code>int</code> special?</p> <p>The only thing I can think of is that integral promotions are applied recursively, but nothing I see mandates it.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. COJust guessing: To keep old code working, because before C++11, an enum casts to `int`. Now with the type specifier (`char` in your case, I don't know how it is called correctly), we just want to say what type should be used to represent it, not how it is treated in conversions.
      singulars
    2. CO@leemes: Eh, kind of. An "old-style" enum casts to its underlying type, which is either `int`, `unsigned int`, `long`, etc. until one correctly holds all the enumerator values. So this one would cast to `unsigned int`: `enum foo { X = 0, Y = UINT_MAX };`. Regardless though your point still stands: it was never "less" than `int`. But since the entire concept of a fixed underlying type is new, it's strange the break the intuitiveness for no compatability reasons.
      singulars
    3. COSounds like a defect in the Standard's description of integral promotions to me. Every other type mentioned is described as being able to promote to zero or one exactly specified promoted type. So when other parts of the Standard say "integral promotion", everyone knows exactly what that does. But here it sounds like there are two possible promoted types??
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload