Вы можете использовать любое выражение, которое нуждается в постоянном интегральном выражении и которое затем будет оптимизировано.
#define NPOT(X) \
(1 \
? complex_algorithm(X) \
: sizeof(struct { int needs_constant[1 ? 1 : (X)]; }) \
)
в конце концов вы должны привести результат sizeof
к соответствующему целочисленному типу, поэтомуВозвращаемое выражение относится к типу, который вы ожидаете.
Я использую здесь без тега struct
, чтобы
- имел тип, так что на самом деле временный вывод не производится
- имеют уникальный тип, такой, что выражение может повторяться где угодно в коде, не вызывая конфликтов
- инициирует использование VLA, что недопустимо внутри
struct
с C99:
Член структуры или объединения может иметь любой тип объекта, кроме изменяемого типа.
Я использую троичный ?:
с 1
в качествевыбор выражения, чтобы гарантировать, что :
всегда вычисляется для его типа, но никогда не оценивается как выражение.
Редактировать: Кажется, что gcc принимает VLA внутри struct
как расширениеи делаетдаже не предупреждаю об этом, даже когда я прямо говорю -std=c99
.Это действительно плохая идея для них.
Для такого странного компилятора :) вы можете использовать sizeof((int[X]){ 0 })
вместо этого.Это «запрещено», как и вышеприведенная версия, но к тому же даже gcc жалуется на это.