Подтвердить что ты не робот

Действительно ли "&" и "&&" действительно имеют значение для флагов времени компиляции?

У меня есть привычка использовать следующий синтаксис во временных флагах компиляции:

#if (defined(A) & defined(B))

Обычно я предлагал сделать это с помощью && следующим образом:

#if (defined(A) && defined(B))

Я знаю разницу между двумя операторами и что в нормальном коде && будет короткое замыкание. Тем не менее, все это обрабатывается компилятором. Неважно, что я использую? Это влияет на время компиляции на некоторую бесконечно малое количество, потому что оно не оценивает второй define()?

4b9b3361

Ответ 1

Так как defined(SOMETHING) дает 0 или 1, так что вам гарантировано 0 или 1 с обеих сторон, это не означает, что вы используете & или &&.

В основном это касается хороших привычек (использование & может переноситься в какую-то ситуацию, когда это было бы неправильно) и о написании кода, который легко понять простым сопоставлением шаблонов. A & там вызывает паузу в миллисекунду, тогда как можно подумать, может ли это быть бит-уровень.

С третьей стороны вы не можете использовать ключевое слово and, которое вы можете использовать в обычном С++-коде.

Примечания:
¹ С Visual С++ вы можете использовать and с помощью принудительного включения <iso646.h>.

Ответ 2

В соответствии со стандартом C99 выражения, используемые в препроцессоре, являются постоянными выражениями, определяемыми самим языком C, и оцениваются с использованием одного и того же движка. Следовательно, && является логическим и оператором, что короткие замыкания на основе его LHS, а & - побитовый оператор без предопределенного порядка оценки.

В практическом плане, когда вы используете с defined() как есть, между ними нет никакой разницы. Однако следующее может показаться разным:

#define A 2
#define B 5
#if (A && B)
printf("A && B\n");
#endif
#if (A & B)
printf("A & B"\n);
#endif

В этом случае выводится A && B, но не A & B (так как результат этого поразрядного и 0)

Ответ 3

Я хотел бы добавить к предыдущим ответам, что это может иметь большое значение в такой ситуации:

#define A 0
#define B 21
#if (A != 0) && (42 / A == B)
/* ... */
#endif

Здесь, если A == 0, компилятор не сломается. Запись (A != 0) & (42 / A == B) заставит компилятор жаловаться на деление на ноль.