LINUX.ORG.RU

Как объяснить GCC, что switch полный?

 , ,


0

4

Имеем:

enum class MyEnum
{
   One,
   Two,
}

QString myfunc(const MyEnum e)
{
    switch (e) {
        case MyEnum:One : return "One";
        case MyEnum:Two : return "Two";
    }
}
* код не запускал

GCC 5.4.0 с радостью вещает мне, что:

warning: control reaches end of non-void function [-Wreturn-type]

При том, что clang обрабатывает верно.

Как убрать этот варнинг без глобального флага и без #pragma GCC diagnostic ignored "-Wreturn-type"?

★★★★★

Последнее исправление: RazrFalcon (всего исправлений: 2)
Ответ на: комментарий от reprimand

то, что ты не передаёшь туда мусор не значит что его туда нельзя передать

Я хочу переложить часть забот на компилятор, а он мне не даёт.

RazrFalcon ★★★★★
() автор топика

Поставь в конец

throw Nonsense()
и он заткнётся :-) Лол :-)

anonymous
()
Ответ на: комментарий от Softwayer

Лол, и для этого достаточно static_cast — не перестаю удивляться качеству дизайна этого языка

Лол :-) Да ты много чему удивляешься :-) Например,

  C::~C()
  {
    delete impl_;
    impl_ = nullptr; // твоё удивление :-)
  }
:-) А цепепе - это низкоуровневый и небезопасный язык :-) Всегда таким был и всегда таким будет :-) И никакие *_cast или .get() в смарт-поинтерах не сделают цепепе безопасным :-) Только вот что с того? :-) Лол :-)

anonymous
()
Ответ на: комментарий от sergej
enum class MyEnum : bool {
  One, Two
};

...и никаких сегфолтов.

PS. код из ОП не скомпилится из-за синтаксических ошибок.

anonymous
()
Ответ на: комментарий от Softwayer

И для реализации этих языков выбрали сишечку. И правильно сделали. Си - язык богов и элиты.

anonymous
()
Ответ на: комментарий от a1batross

Поэтому туда может попасть всё что угодно.

Если туда попадет значение, выходящее за пределы отрезка между минимальным и максимальным значением енума, то это UB

annulen ★★★★★
()
Ответ на: комментарий от anonymous

Во-второй раз повторяю: это просто пример.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от Softwayer

и enum class преподносился как попытка их завезти — но если не видно разницы, зачем ещё одна конструкция в языке?

Разница в неявных преобразованиях в int :-) enum class для этого завезли в цепепе, а не для того, чтобы выкрутить ими всем руки настолько, что все бы плюнули и пользовались простыми enum дальше :-)

Во-вторых, если бы для этого был необходим reinterpret_cast, это можно было бы понять: на то он и небезопасный каст, чтобы с его помощью можно было сломать некоторые разумные инварианты, но ведь для каста числа к такому енуму достаточно static_cast, что выглядит совершенно неразумно.

reinterpret_cast - это почти всегда непереносимые между платформами касты :-) Потому что reinterpret_cast подразумевает каст представления данных в памяти :-) Ты конечно же это всё знаешь, но не перестаёшь удивляться, верно? :-) Так вот static_cast числа в число (коим является на самом деле enum) не предполагает каста представления данных, а потому выглядит разумно :-)

anonymous
()
Ответ на: комментарий от jcd

Умные дядьки для этого научили конпеляторы делать проверки на этапе конпеляции.

компилятор должен дать варнинг, что (Q)3 - UB. Если он этого не делает, то это плохой, негодный компилятор.

former_anonymous ★★★
()
Ответ на: комментарий от annulen

Я бы даже сказал, что это устоявшийся паттерн - в конце оставляют MaxUserValue = 1000, и вперед

annulen ★★★★★
()
Ответ на: комментарий от annulen

Хз. Знаю такую фишку используют в Qt.

С одной стороны хорошо, что сделали такую возможность в языке, а с другой - ну дыра же. Сложно мне с С++.

Вон в rust enum вообще по-другому устроен.

RazrFalcon ★★★★★
() автор топика
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от anonymous

impl_ = nullptr; // твоё удивление :-)

Экстрасенс из тебя так себе

static_cast числа в число (коим является на самом деле enum) не предполагает каста представления данных

Он предполагает изменение семантики, что не менее важно. В конце концов, указатель тоже «является на самом деле числом», но ведь важно не это, а то, как ты его интерпретируешь — равно как и с интами и енумами

Softwayer ★★
()
Ответ на: комментарий от RazrFalcon

Поставь в конце функции assert(0). Я думаю и компилятор будет счастлив, и такая страховка лишней не будет.

sergej ★★★★★
()
Ответ на: комментарий от Softwayer

Он предполагает изменение семантики, что не менее важно.

Никакого изменения семантики static_cast не предполагает :-) Семантика в цепепе бывает 2-х видов: значений и указателей :-) static_cast лишь выполняет допустимые касты с т.з. компилятора :-) А т.з. компилятора каста int в enum class : int является валидным :-) И это правильно :-)

В конце концов, указатель тоже «является на самом деле числом», но ведь важно не это, а то, как ты его интерпретируешь — равно как и с интами и енумами

Что это за бред? :-) Указатель - это адрес на данные в памяти, арифметика которого зависит от типа этих данных :-) Указатель _может быть_ представлен как целое (с помощью reinterpret_cast), из-за чего это не является переносимым кастом, поэтому тут reinterpret_cast работает, а static_cast - нет :-) И это правильно :-) Лол :-)

anonymous
()
Ответ на: комментарий от RazrFalcon

Иди Аду потыкай, в ней этого есть (а еще есть типы данных которые могут принимать строго диапазон значений и прочее)

timdorohin ★★★★
()
Ответ на: комментарий от anonymous

impl_ = nullptr; // твоё удивление :-)

А ты, я смотрю, упоротый упорный. Узнал один трюк и теперь везде им хвастаешься?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

А ты, я смотрю, упоротый упорный. Узнал один трюк и теперь везде им хвастаешься?

Лол :-) Ну раз ты ни на что больше не смотришь, то расскажу :-) Тут нет трюка :-) Тут правильная реализация деструктора, которая у некоторых вызывает удивление :-) В частности, этот товарищ некогда удивлялся этому присваиванию нуля после delete :-) Лол :-)

anonymous
()
Ответ на: комментарий от anonymous

Ну да, тебе явно виднее, как правильно в общем случае писать деструкторы.

Softwayer ★★
()
Ответ на: комментарий от anonymous

В частности, этот товарищ некогда удивлялся этому присваиванию нуля после delete :-) Лол :-)

Где, когда?

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

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

Softwayer ★★
()
Ответ на: комментарий от anonymous

И для реализации этих языков выбрали сишечку

О каких языках речь? Не похоже на описание чего-либо, что я имел в виду.

Softwayer ★★
()
Ответ на: комментарий от reprimand

МНИП, стандарт не рекомендует их воспринимать как целое

не рекомендует воспринимать как int. Но в основе лежит целое. Например, int или long.

former_anonymous ★★★
()
Ответ на: комментарий от Softwayer

Ээм... Ну вообще-то это очень полезный трюк для отладки. Например, с Boost.Asio есть немалый шанс словить событие уже после того, как объект разрушен. Вот такой трюк практически гарантирует, что процесс сегфолтнется. Тогда как без зануления указателей обработчик может и успешно отработать. Потом упадёт где-то ещё; разбираться придётся.

i-rinat ★★★★★
()
Ответ на: комментарий от Softwayer

У енума нет, а вот у конкретных байт в памяти которыми енум представлен может быть какое угодно значение.

anonymous
()
Ответ на: комментарий от RazrFalcon

А ну тогда немного забавно. Как написали выше, enum в Си и Си++ не совсем честный enum. Это прежде всего целый тип, для которого просто дополнительно определены символические значения. Поэтому никакого unexhausted case check быть не может, поскольку там может прилететь любое целое значение, да через тот же reinterpret_cast. Может и static_cast хватит

dave ★★★★★
()
Ответ на: комментарий от SZT

И гцц седьмому нужен будет -Wno-fall-through или как-то так.

evilface ★★
()
Ответ на: комментарий от Softwayer

но если не видно разницы, зачем ещё одна конструкция в языке?

Насколько я понимаю, это больше для того, чтобы не засерать родительский scope. Кроме того, полегче делать forward-declare (без обязательного указания размера underlying type). А как, допустим, сделать enum чтобы он не свёлся в итоге к integer? Я вот не сообразил.

d_a ★★★★★
()
Ответ на: комментарий от SZT

Лучше после свитча добавить return NULL — и все будут счастливы. Компилятор не будет ругаться, а этот липовый return так и останется unreached (правда, вполне возможно, что гцц запихнет таки его в результат).

anonymous
()

Как объяснить GCC, что switch полный?

Так а если myfunc скомпилировали с исходным MyEnum, а запустили с другим, в котором в конец добавили ещё Three, Four то что делать? E.g. библиотечка обновилась какая-то, без слома ABI.

d_a ★★★★★
()

Меня больше интересует какого хера он выдает варнинг на неполный свитч, если там есть default.

anonymous
()
Ответ на: комментарий от reprimand

Ну так статически типизированный язык, как ни как. Это же не скриптота какая-то, в которой вообще всё в рантайме проверяется.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

Хочу как в rust - ошибку компиляции.

Мы отдельно скомпилировали библиотеку, в которой в API есть enum class, отдельно пользовательский код. Потом библиотека обновилась и enum расширили. Если myfunc не закрывается return, будет UB. gcc на это намекает, а с -Werror будет желаемая ошибка компиляции (не знаю уж как в расте или не как в расте).

d_a ★★★★★
()
Последнее исправление: d_a (всего исправлений: 1)
Ответ на: комментарий от Softwayer

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

Лол :-) Ну давай, грамотей, расскажи уже почему компилятор имеет полное право выпиливать присваивание impl_ = nullptr :-) Заодно расскажи какие, оказывается, разработчики GCC лохе, что у них в деструкторе ~unique_ptr такое присваивание имеется :-) Видимо они это сделали, чтобы их GCC его выпилил для проверки функции выпиливания из деструторов, да? :-) Лол :-)

anonymous
()
Ответ на: комментарий от d_a

не знаю уж как в расте или не как в расте

Там просто не скомпилируется.

RazrFalcon ★★★★★
() автор топика
Ответ на: комментарий от RazrFalcon

дык кому он нужен гитхаб? на аде реальные посоны высоконадежные системы пишут, а на с++ студентота лабораторные.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.