Краткий ответ - «не».Но если у вас есть к, ради любви всего святого , не делайте это:
#define FOREACH(start, end) \
for (; (start) < (end); (start)++) \
{ \
// do something interesting \
}
Плохое дзю-джи вокруг.Обратите внимание, что start
должно соответствовать lvalue;Вы не сможете назвать это как FOREACH(1,10)
, или FOREACH((a+b), c)
, или FOREACH(x++,y++)
.Все это может привести к ошибке времени компиляции (операнд ++
должен быть l-значением, и ни один из 1
, a+b
или x++
не может быть квалифицирован).Называя его FOREACH(x, y++)
, вы будете делать то, чего вы действительно не хотите.Точно так же вы не хотели бы называть это как FOREACH(x, y())
.
Вы можете в определенной степени защититься от этих проблем, выполнив что-то вроде
#define FOREACH(start, end) \
do { \
int i; \
int j = end; \
for (i = start; i < j; i++) { \
// do something interesting \
} \
} while (0)
По сути, вы создаете локальныйпеременные, соответствующие вашим макро аргументам.Это защищает от start
, не являющегося lvalue, и от end
, имеющего побочный эффект, который применяется, или от функции, которая вызывается при каждой итерации.
Но если вы пытаетесь инкапсулировать цикл, которыйчасто вызывается, помещает его в отдельную функцию .Это безопаснее и легче понять и поддерживать.