В дополнение к ответу Тома, который объясняет, что происходит, вот пример того, как вы можете определить макрос для безопасного возведения в квадрат числа:
#define SQR(x) ( \
{ \
__auto_type x_ = (x); \
\
x_ * x_; \
} \
)
Он имеет только вид x
и поэтому он не оценивает его дважды.Вместо этого используется копия x_
.Обратите внимание, что переменные, созданные в макросе, могут конфликтовать с другими переменными, созданными в функции, которая вызывает макрос.Чтобы избежать конфликтов имен, вы используете специальные имена, которые не должны использоваться в обычном коде, такие как конечный _
.
С этим макросом это:
a = SQR(b++);
будет эквивалентноthis:
a = SQR(b);
b++;
Предупреждение: на некоторых компиляторах это работает как расширение (например, GCC), но это не стандартная C.
Другой вариант, если вы хотите стандартную C, этоиспользовать встроенную функцию.Это нормально, если вы хотите, чтобы он работал только с одним типом (в C11 есть _Generic
, но я никогда не использовал его, так что понятия не имею).