https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83928
Bug ID: 83928
Summary: implicit conversion of literal class type to unscoped
enumeration can not be used as array size
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: smw at gcc dot gnu.org
Target Milestone: ---
[expr.const]/6 says "If an expression of literal class type is used in a
context where an integral constant expression is required, then that expression
is contextually implicitly converted (Clause 4) to an integral or unscoped
enumeration type and the selected conversion function shall be constexpr."
That works great, except when trying to use that constexpr value in an array
declaration.
A code example speaks louder than tortured English can scream.
// Case 1: literal class type with implicit coversion to integral expression
struct LiteralClassTypeInt
{
constexpr LiteralClassTypeInt(int i) : val(i) { }
constexpr operator int() const { return val; }
private:
int val;
};
template<int> struct X { };
constexpr LiteralClassTypeInt lct_int = 42;
X<lct_int> x_int; // OK: implicit conversion to integral expression
int int_index[lct_int]; // OK: implicitly converted to integral expression
// Case 2: Unscoped enumeration
enum E { three = 3 };
int eee[three]; // OK: unscoped enumeration is allowed here
// Case 3: literal class type with implicit conversion to unscoped enum
struct LiteralClassTypeEnum
{
constexpr LiteralClassTypeEnum(E e): val(e) { }
constexpr operator E() const { return val; }
private:
E val;
};
constexpr LiteralClassTypeEnum lct_enum(three);
X<lct_enum> x_enum; // OK!
int enum_index[lct_enum]; // buggerit
All of ICC, LLVM, and MSVC accept the above code as-is. GCC (all versions
tested up to and including 8.0.1 20120117 (experimental)) give the following
error.
32 : <source>:32:24: error: size of array 'enum_index' has non-integral type
'const LiteralClassTypeEnum'
int enum_index[lct_enum]; // buggerit
^
Compiler returned: 1