Внутренняя ошибка компилятора — шаблонный оператор преобразования в выражении switch

Следующий код приводит к сбою компилятора Microsoft:

class Var
{
public:
    template <typename T>
    operator T () const
    { }
};

int main()
{
    Var v;
    switch (v)
    { }
}

Мой вопрос: правильный ли код или компилятор должен выдавать соответствующую ошибку? Возможно ли однозначное преобразование к целочисленному типу?


person typ1232    schedule 30.07.2014    source источник
comment
Можете ли вы быть более конкретным, когда говорите, что компилятор выходит из строя? Что вы подразумеваете под правильным кодом?   -  person Robert Harvey    schedule 31.07.2014
comment
@RobertHarvey fatal error C1001: An internal error has occurred in the compiler. ... блабла ... пожалуйста, сообщите в Microsoft (я сообщил об ошибке). В строке оператора преобразования.   -  person typ1232    schedule 31.07.2014
comment
Даже если код неверен, он не должен привести к сбою компилятора ... Однако ваш operator T на самом деле ничего не возвращает, так что это UB, даже если он скомпилирован.   -  person T.C.    schedule 31.07.2014
comment
Первый из operator T() должен что-то вернуть. Во-вторых, switch ждет int.   -  person 101010    schedule 31.07.2014
comment
Вы можете использовать class Var в операторе switch только в том случае, если его можно преобразовать в целочисленное значение.   -  person Thomas Matthews    schedule 31.07.2014
comment
@ 40two, почему переключатель ожидает int?   -  person Slava    schedule 31.07.2014
comment
@40two: хуже - switch нужен целочисленный тип, тип перечисления или тип класса, для которого существует единственная неявная функция преобразования в целочисленный тип или тип перечисления (6.4.2/2). Если бы он хотел именно int, он мог бы получить его с v.operator int(). Но v можно преобразовать во что угодно, поэтому утверждение неоднозначно.   -  person Igor Tandetnik    schedule 31.07.2014
comment
@ 40two Неважно, что находится внутри тела функции оператора, компилятор все равно падает. Я просто раздел его, чтобы минимизировать код.   -  person typ1232    schedule 31.07.2014
comment
@ typ1232 ты сделал это слишком минималистично, это должно быть правильно.   -  person Slava    schedule 31.07.2014
comment
@IgorTandetnik Ваш комментарий имеет качество ответа! Спасибо, что нашли цитату.   -  person typ1232    schedule 31.07.2014
comment
Сбой компилятора (ICE), конечно, всегда ошибка. Если код неверный (как здесь), то это просто мелкая неприятность. Но если код правильный, ICE действительно раздражает и требует (часто утомительного) обходного пути.   -  person Walter    schedule 31.07.2014
comment
@Slava Я имел в виду, что требуется выражение целочисленного типа, но мне показалось, что int короче :). Извините за непреднамеренное введение в заблуждение.   -  person 101010    schedule 31.07.2014
comment
Я попробовал это в Studio 2013 и тоже получил сбой. Интересно то, что редактор помечает switch(v) красной волнистой линией, а всплывающее сообщение Ошибка: выражение должно иметь тип integer или enum.   -  person Rob K    schedule 31.07.2014
comment
@RobK Любопытно, что IntelliSense в VS поддерживается компилятор, отличный от MSVC. Обычно они отмечают разные наборы ошибок.   -  person Igor Tandetnik    schedule 31.07.2014


Ответы (1)


Сбой компилятора всегда является ошибкой, этот код не компилируется ни на gcc, ни на clang, но оба выдают ошибку без сбоя. Для clang ошибка:

error: statement requires expression of integer type ('Var' invalid)
switch (v)
^       ~

gcc выдает следующую ошибку:

error: ambiguous default type conversion from 'Var'
 switch (v)
          ^

Также обратите внимание, что вытекание из конца функции, возвращающей значение, является неопределенным поведением в C++.

Обновить

Добавление:

operator int () const
{ return 0; }

к классу приводит к результатам, отличным от clang и gcc.

См. Классы с операторами преобразования как шаблонов, так и нешаблонов в условии оператора switch для обсуждения того, является ли gcc или clang правильный. Моя интерпретация N3323 подразумевает, что clang верен в этом.

Отправленный отчет об ошибке

Я отправил отчет об ошибке для этого ICE, пока нет ответа. Несмотря на то, что это кажется странным, это вызывает внутреннюю ошибку компилятора, которую следует исправить.

person Shafik Yaghmour    schedule 30.07.2014