Проблема не в теории: при условии, что вы по какой-то причине хотите иметь макрос, который расширяется по-разному в зависимости от значения переданного ему параметра, и этот параметр является константой, известной препроцессору макроса нет никаких причин, по которым это не могло бы работать ... для универсального макропроцессора ... Но cpp, к несчастью, не позволяет присутствию других "команд" макропроцессора в определении макроса ...
Итак, ваш
#define foo(x) \
#if x>32 \
x \
#else \
2*x \
#endif
не расширяется до
#if X>32
X
#else
2*X
#endif
где X - известный параметр (поэтому измените X, например, на 31), что требует еще одного прохода препроцессором.
Более того, новые строки игнорируются, хотя они важны для такого использования; в противном случае следующее может быть рассмотрено как уловка (для которой требуется еще один этап предварительной обработки)
#define foo(x,y) \
y if x>32 \
x \
y else \
2*x \
y endif
, что с foo(20,#)
производит
# if 20>32 20 # else 2*20 # endif
, который бы работал, если бы он был
# if 20>32
20
# else
2*20
# endif
... но это не так (и, как уже было сказано, выход препроцессора должен быть снова передан препроцессору ...)
Итак, мой ответ: если вам нужны эти вещи, вы не можете использовать препроцессор C; вам следует использовать необычный (не стандартный?) препроцессор C или просто другой макропроцессор, и если вам нужны такие вещи, которые "cpp" должен "интегрировать" сам с C, то вы не можете использовать универсальный ( как M4) так легко ...