2009-05-19 2 views
4

Я только что узнал об ошибке, которую я представил, что меня удивило в том, что она скомпилирована, законно ли включать постоянную?Можно ли включить константу в C++?

Visual Studio 8 и Comeau оба принимают его (без предупреждений).

switch(42) { // simplified version, this wasn't a literal in real life 
    case 1: 
     std::cout << "This is of course, imposible" << std::endl; 
} 
+4

попробуйте компилировать с/W4, он должен выплюнуть предупреждение. Я также рекомендую всегда компилировать с помощью W4;) –

+0

Вы должны были поставить это в ответ, так как он отвечает на реальный вопрос (почему он не был пойман). –

+1

Есть некоторые проблемы с составлением 15-летней базы кода с W4, которая не была скомпилирована с W4 в течение 15 лет. –

ответ

18

Не исключено, что включение константы имеет смысл. Рассмотрение:

void f(const int x) { 
    switch(x) { 
    ... 
    } 
} 

Включение постоянной константы редко имеет смысл. Но это законно.

Edit: Думая об этом, есть случай, когда переключение на буквальном делает совершенного смысл:

int main() { 
    switch(CONFIG) { 
      ... 
    } 
} 

, где программа была составлена ​​с:

g++ -DCONFIG=42 foo.cpp 
+0

+1 фантастический пример – dubnde

+1

+1, хороший пример. Также код шаблона или сгенерированный код могут легко создать такую ​​конструкцию. –

2

Да, вполне законно включать любое целочисленное выражение. Это то же самое, что и switch ing на целочисленное значение, возвращаемое функцией - это довольно часто используемая конструкция.

16

Не все, что имеет смысл для компилятора, имеет смысл!

Ниже также будет собирать, но не имеет никакого смысла:

if (false) 
{ 
    std::cout << "This is of course, imposible" << std::endl; 
} 

Это до нас, как разработчиков, чтобы обнаружить их.

+0

@Chris: #define DEBUG false ... и позже ... if (DEBUG) {fprintf (stderr, "DEBUG: Вы тоже не можете попасть, поэтому хороший оптимизирующий компилятор удалит весь этот блок."} – corlettk

+0

Я видел, как такой код подвергался насилию следующим образом: for (....) {if (false) {end: ....;} .... if (stuff) goto end;} –

2

Да, но почему вы хотите (если не отлаживать) другое дело.

Это похоже на if (0) или while (true).

+4

Но while (true) с разрывом - довольно обычная конструкция. – ChrisF

+0

while (true) не настолько сумасшедший, как может показаться, и составляет основу нескольких конструкций, но, вероятно, есть более эффективные подходы, но он используется. if (0) или if (false) действительно попадают прямо в лагерь «Почему !?» :) – Lazarus

+0

Я просто демонстрировал, что литералы/константы в операторах включения/выключения не были необычными. –

3

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

E.g. Вы могли бы использовать что-то вроде этого для отладки материал:

int glyphIndex; 
... 
#if CHECK_INVALID_GLYPH 
glyphIndex = -1; 
#endif 

switch (glyphIndex) 
    ... 

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

#if CHECK_INVALID_GLYPH 
const int glyphIndex = -1; 
#else 
int glyphIndex = GetGlyph(); 
#endif 

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

 Смежные вопросы

  • Нет связанных вопросов^_^