Можно ли установить условия препроцессора в макросе? - PullRequest
3 голосов
/ 27 февраля 2011

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

То, что я ищу, выглядит примерно так:

#define MY_MACRO(arg) #if (arg)>0 cout<<((arg)*5.0)<<endl; #else cout<<((arg)/5.0)<<endl; #endif

Идея здесь:
Препроцессор заменяет различные строки кода в зависимости от значения времени компиляции (константы) аргумента макроса.Конечно, я знаю, что этот синтаксис не работает, поскольку # рассматривается как оператор string-ize вместо стандартного #if, но я думаю, что это демонстрирует функциональность препроцессора Iя пытаюсь достичь.

Я знаю, что мог бы просто добавить туда стандартный оператор if, и компилятор / среда выполнения остались бы для проверки значения.Но это ненужная работа для приложения, когда arg всегда будет передаваться постоянное значение, такое как 10.8 или -12.5, которое нужно оценивать только во время компиляции.

Потребность в производительности для этого числаПриложение -crunching требует, чтобы все ненужные условия времени выполнения были по возможности устранены, и для этого было использовано много постоянных значений и макросов (вместо переменных и функций).Возможность продолжить эту тенденцию без необходимости смешивать код препроцессора с реальными условиями if сделает это намного чище - и, конечно же, чистота кода является одной из самых больших проблем при использовании макросов, особенно на этом уровне.

Ответы [ 2 ]

7 голосов
/ 27 февраля 2011

Насколько я знаю, вы не можете иметь #if (или что-то подобное) внутри вашего макроса. Однако, если условие известно во время компиляции, вы можете безопасно использовать обычный оператор if. Компилятор оптимизирует его (при условии, что у вас включены оптимизации).

Это называется " Устранение мертвого кода "

5 голосов
/ 28 февраля 2011

Простой, используйте настоящий C ++:

template <bool B> void foo_impl       (int arg) { cout << arg*5.0 << endl; }
template < >      void foo_impl<false>(int arg) { cout << arg/5.0 << endl; }
template <int I>  void foo            ( )       { foo_impl< (I>0) >(I); }  
...