Вътрешна грешка на компилатора - Шаблонен оператор за преобразуване в израз за превключване

Следният код срива компилатора на 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 защо switch очаква 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 Имах предвид изисква изразяване от тип integer, но усетих, че int е по-кратко :). Извинете за неволното подвеждане.   -  person 101010    schedule 31.07.2014
comment
Опитах го в Studio 2013 и също получих срив. Интересното е, че редакторът маркира switch(v) с червено извиване и изскачащият прозорец Error: изразът трябва да има интегрален или 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