Мой совет - игнорировать любые предложения о том, как исправить этот макрос, проблема real в том, что вы используете макрос вообще.
Существует почти нет причин использовать макросы (которые на самом деле являются просто немного менее чем глупыми текстовыми подстановками) в современном C для чего-либо, кроме условной компиляции.
- Макросы типа значения обычно следует заменять перечислениями, поскольку они лучше сохраняют информацию типа.
- Макросы типа функции должны просто быть функциями, так как современные компиляторы имеют очень мало проблем, делая их встроенными, если им это нужно.
Использование реальных функций также решает все эти причудливые крайние случаи, такие как:
#define calc(x) x * x
:
int a = 7;
int b = calc(a + 1); // a + (1 * a) + 1, NOT (a + 1) * (a + 1)
Если вы хотите, чтобы это работало надежно, вам нужно, чтобы макрос был что-то вроде ((x) * (x))
, но даже , что потерпит неудачу с большей сложностью, например b = calc(a++)
.
Короче говоря, то, что вы должны иметь в своем коде:
void foo(int x) {
if (x > 0)
printf("Ouch\n");
}
Если вам do необходимо иметь возможность использовать макросы функций в любом месте (голый оператор, оператор внутри фигурного блока if, оператор в свободном блоке if, фигурный и неразблокированный операторы while и т. д.) приходится прибегать к причудливым макросам, таким как (конечно, #include <stdbool.h>
для доступа к false
, конечно):
#define XYZZY(s) do {plugh(s);} while (false)
Однако я бы настоятельно предложил бы просто заставить их функционировать.