В настоящее время я изучаю C, и я столкнулся с этим вопросом, на который не могу найти ответ.
Могу ли я выйти из #ifdef, не проходя через #endif?
Например, я могу сделать это:
char getOS( void ) {
/* Returns the user Operating System
*/
#ifdef _WIN32
return 'w';
#elif TARGET_OS_MAC
return 'm';
#elif __linux__
return 'l';
#else
raiseError( "You cannot play on this OS", true );
#endif
}
Что вы подразумеваете под "выпрыгнуть из"? В цепочке #if...#elif...#else будет выбран только один.
cpp условные операторы (например, #ifdef, #elif) не похожи на операторы C if. Они не генерируют все возможности, как if. Код #ifdef «выбирает» на первом этапе компиляции. Итак, если _WIN32 определено, более поздние этапы компиляции будут видеть [только]: char getOS( void ) { return 'w'; } и компилировать это. Вы можете заменить raiseError( "You cannot play on this OS", true ); на #error You cannot play on this OS, чтобы компиляция не удалась, если вы компилируете в неподдерживаемой системе.





Я считаю, что вы немного неправильно понимаете препроцессор. Помните, препроцессор запускается перед компилятором. Таким образом, эта функция будет выглядеть примерно так, когда попадет в компилятор:
char getOS( void ) {
return 'w';
}
char getOS( void ) {
return 'm';
}
char getOS( void ) {
return 'l';
}
char getOS( void ) {
raiseError( "You cannot play on this OS", true );
}
... и все они действительны. Ну, я не знаю, что делает raiseError, но если это не макрос, который returns или exits, вам нужно будет добавить дополнительный return в конец функции для ветки #else.
Дело в том, что ни один из этих #if, #elif и т. д. все равно не попадет в компилятор, поэтому вы никогда не «выскакиваете». Если вы хотите убедиться сами, вы можете добавить параметр компилятора, чтобы выполнять только предварительную обработку (без компиляции). Я знаю, что для gcc этот вариант -E.
Большое тебе спасибо. Наконец-то я понимаю, что на самом деле делает препроцессор
Кажется, вы путаете препроцессор с поведением во время выполнения: это не одно и то же.
Препроцессор запускается до фактического компилятора (по крайней мере, концептуально; на практике, конечно, это может быть одна и та же программа). Это влияет на источник, который затем видит компилятор.
Вы не можете «пройти» #endif, его нет, когда программа работает. У вас будет либо return, либо звонок raiseError().
И тебе спасибо. Теперь я наконец понял :)
Если под «выпрыгнуть из» вы подразумеваете, что компилятор выдаст ошибку, вы можете сделать это с помощью директивы #error.
#ifdef _WIN32
return 'w';
#elif TARGET_OS_MAC
return 'm';
#elif __linux__
return 'l';
#else
#error "You cannot play on this OS"
#endif
Под «выпрыгнуть из» я имел в виду, что если бы первое условие было истинным, я бы никогда не достиг #endif, и я подумал, что это может быть проблемой. Теперь я лучше понимаю, что на самом деле делает препроцессор. Ваше решение все еще полезно. Спасибо :)
Добавьте (например)
return 0;послеraiseError, чтобы все пути использовали возвратchar. В противном случае ваш код в порядке.