Отключить предупреждение компилятора для операторов switch/case с использованием перечислений

Допустим, у вас есть тип перечисления с более чем 50 элементами для его значения. Были времена, когда я переключал/обрабатывал значение перечисления с таким количеством записей раньше, но только для проверки, скажем, от 2 до 5 записей из этого.

Например, OpenGL привязывает большинство своих перечислений к одному типу перечисления, называемому GLenum. Эти значения варьируются от GL_VERTEX_SHADER до GL_STREAM_DRAW, до GL_TRIANGLES, до GL_ARRAY_BUFFER и т. д.

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

Я сгенерировал предупреждения на MinGW/GCC в Linux, где каждое предупреждение относится к каждому значению перечисления, указанному в его объявлении типа. Я не уверен, что это происходит на VC++, но я решил, что все равно учту это на всякий случай.

Другими словами, количество сгенерированных предупреждений составляет TotalEnumValues - AmountOfCaseStatements для каждого значения перечисления, при условии, что не все перечисления были учтены в самом выражении, что может легко привести к более чем 100 предупреждениям компилятора, если ваш тип перечисления содержит не менее 100 записей.

Я часто использовал if/else, чтобы приспособиться к этому, но при проверке значений перечисления для более чем одной одной записи (что, честно говоря, довольно редко, поскольку цель перечислений в целом требует, чтобы условная логика дополняла ее ), я всегда был склонен к использованию switch/case, так как считаю его более эстетичным (даже если он просто компилируется в оператор if/else;))

Итак, можно ли отключить это предупреждение? Если да, то как?


person zeboidlund    schedule 15.10.2012    source источник


Ответы (1)


Добавьте случай default:, который ничего не делает. Компилятор увидит, что вы «обрабатываете» все возможности (тем самым удаляя предупреждение), но он не изменит сгенерированный код вообще, если вы не укажете для него никаких действий.


Чтобы уточнить: я говорю об этом:

switch(a)
{
case CONSTANT_1:
        ...
    break;
case CONSTANT_2:
        ...
    break;
}

против этого:

switch(a)
{
case CONSTANT_1:
        ...
    break;
case CONSTANT_2:
        ...
    break;
default:
}

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

person Matteo Italia    schedule 15.10.2012
comment
По крайней мере, в VC++ добавление пустого регистра default может повлиять на генерацию кода, но у него есть __assume встроен только для этой цели. - person ildjarn; 15.10.2012
comment
@ildjarn Всегда возможно, что компилятор сделает что-то совершенно бессмысленное и глупое, но значение по умолчанию, которое просто нарушается, семантически эквивалентно отсутствующему значению по умолчанию ... __assume бесполезно в этом случае. - person Jim Balter; 15.10.2012
comment
@JimBalter: Ваше мнение о __assume логически не следует из предпосылки. Это на самом деле полезно здесь; он сообщает компилятору, что переменная не может иметь значений, отличных от тех, что указаны в операторе switch. Это очень полезная информация для современных оптимизаторов. - person MSalters; 15.10.2012
comment
@MSalters Да, это очень полезная информация для компилятора, но это не то, что было указано здесь - случай по умолчанию, который ничего не делает, а не случай по умолчанию, который не может произойти, так что провал логики это все ваше. Я ставлю Маттео +1 за правильное выполнение — сгенерированный код никак не изменится, если вы не укажете для него никаких действий. Если OP хочет неопределенного поведения из-за оптимизации в случае, если значение, не указанное в переключателе, действительно возникает, OP должен был сказать об этом. - person Jim Balter; 16.10.2012
comment
@JimBalter: Вы, вероятно, не знакомы с GL. Случай default здесь должен охватывать перечисление GL_STREAM_DRAW, когда ожидается GL_TRIANGLES. Это не может произойти. - person MSalters; 16.10.2012
comment
@MSalters Неважно, с чем я знаком. Мой комментарий касался этого ответа о добавлении случая по умолчанию, который ничего не делает, и комментария ildjarn о том, что такое добавление повлияет на генерацию кода; это не будет. Конечно, добавление __assume может повлиять на генерацию кода, и никто не говорил иначе. Опять же, вы ошибаетесь в логике. Теперь я закончил с этой болтовней. - person Jim Balter; 16.10.2012