In the following code, I have defined an unscoped enumeration with long long
type. This program works fine on Clang.
But GCC compiler gives an ambiguity error.
#include <iostream>
enum : long long { Var=5 };
void fun(long long ll)
{
std::cout << "long long : " << ll << std::endl;
}
void fun(int i)
{
std::cout << "int : " << i << std::endl;
}
int main()
{
fun(Var);
}
GCC generated error :
main.cpp: In function 'int main()':
main.cpp:17:12: error: call of overloaded 'fun(<unnamed enum>)' is ambiguous
fun(Var);
^
main.cpp:5:6: note: candidate: void fun(long long int)
void fun(long long ll)
^~~
main.cpp:10:6: note: candidate: void fun(int)
void fun(int i)
^~~
Why does GCC compiler give an ambiguity error?
Automatic type conversions are the main cause of ambiguity. In C++, the type of argument that is used to call the function is converted into the type of parameters defined by the function. Let’s understand ambiguity through a few examples.
prog.cpp:25:11: error: call of overloaded ‘test (char)’ is ambiguous When there is no exact type match, the compiler looks for the closest match. The closest match for “test (‘a’);” will be “void test (int a)”, since it is not present, void test (double d) and void (float f)will cause ambiguity.
To help detect accidental misuses of such arrays GCC issues warnings unless it can prove that the use is safe. See Common Variable Attributes . Warn for cases where adding an attribute may be beneficial.
Enumerated types are considered part of the integer family of types, and it’s up to the compiler to determine how much memory to allocate for an enum variable. The C++ standard says the enum size needs to be large enough to represent all of the enumerator values. Most often, it will make enum variables the same size as a standard int.
GCC is wrong.
Unscoped enumeration type converting to its underlying type is qualified as integral promotion:
an unscoped enumeration type whose underlying type is fixed can be converted to its underlying type, ... (since C++11)
While for Var
converting to int
it requires one more integral conversion (from long long
to int
). Integral promotion has higher ranking than integral conversion in overload resolution:
2) Promotion: integral promotion, floating-point promotion
3) Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base
Then fun(long long ll)
should be better match.
Here's the gcc bug report; it's been fixed at 2017-10-24. LIVE
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With