2012-06-15 3 views
2

У меня есть следующий код.if я даю control_word как 6, если условие оценивается как true и входит внутри if block, что именно здесь происходит?Почему такое поведение с MACRO?

#define MACRO1 0x01 
#define MACRO2 0x02 
#define MACRO4 0x04 
#define MACRO3 MACRO1 | MACRO2 
#define MACRO7 MACRO4 | MACRO3 

int main() 
{ 
    if(control_word == MACRO3 || control_word == MACRO7) 
    { 
     /*DO SOME OPERATION*/ 
    } 
    else 
    { 
     /*DO SOMETHING ELSE */ 
    } 

} 
+3

Это не вопрос макросов. Вы можете просто выполнить все подстановки, и вы поймете, почему вы получаете этот результат. –

ответ

2

Выражение

control_word == MACRO3 || control_word == MACRO7 

расширяется

control_word == MACRO1 | MACRO2 || control_word == MACRO4 | MACRO3 

, который в конечном счете расширяется до

control_word == 1 | 2 || control_word == 4 | 1 | 2 

глядя на precedence table, вы видите, что оператор == имеет более высокую precendence чем |, который выше ||, поэтому оценка:

((control_word == 1) | 2) || ((control_word == 4) | 1 | 2) 

, которая вычисляется в

((6 == 1) | 2) || ((6 == 4) | 1 | 2) 

, который (6==1 является false, которая рассматривается как 0 в арифметическом выражении - то же самое для 6==4)

((0 | 2) || (0 | 1 | 2) 

, который является

2 || 3 

который

true 

как 2 и 3 рассматриваются как true (не равно нулю), так что вы вводите if блок, а не else

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

11

Превосходство | и == операторы не так, как вы думаете. Мораль: всегда скопируйте свои макросы!

#define MACRO3 (MACRO1 | MACRO2) 
#define MACRO7 (MACRO4 | MACRO3) 

Так что же происходит выражение расширяется

control_word == 0x01 | 0x02 || control_word == 0x01 | 0x02 | 0x04 

, который в свою очередь формирует

(control_word == 1) | 2 || (control_word == 7) | 6) 

что

0 | 2 || 0 | 6 

так в целом это

2 || 6 

, который интерпретируется как «истина или истина», и это дает истину.

+0

Да, я соглашаюсь на скобки, решает проблему. Не могли бы вы объяснить, как она вступила в блок? Каково точное поведение здесь? – Sandeep

+2

Это не ** проблема с приоритетом между _ | _ и _ || _, это _ == _ и _ | _. См. Этот [график приоритета] (http://www.swansontec.com/sopc.html) и рассмотрите, что происходит при изменении кода на: 'if ((control_word == MACRO3) || (control_word == MACRO7))' – pb2q

+0

Исправлено, см. Обновление. –