2

I've got this silly program with macros, but I don't know what is the failure:

#include <stdio.h>
#include <stdlib.h>

#define READ_RX  (1 << 1)
#define WRITE_RX (1 << 2)
#define READ_TX  (1 << 3)
#define WRITE_TX (1 << 4)

#define READ_COMMAND(num) (num == 0) ? (READ_RX) : (READ_TX)
#define WRITE_COMMAND(num) (num == 0) ? (WRITE_RX) : (WRITE_TX)

int main(int argc, char **argv)
{

    printf("[DEBUG] 0x%04X\n", (READ_COMMAND(0)) | (WRITE_COMMAND(0))); //works fine
    printf("[DEBUG] 0x%04X\n", READ_COMMAND(0) | WRITE_COMMAND(0)); //doesn't work

    return 0;
}

Result:

$ ./test
[DEBUG] 0x0006 -> works fine
[DEBUG] 0x0002 -> doesn't work

Does anyone know what is the problem?

Best regards.

1
  • 1
    He's missing braces and the operator precidence is messing him up. OP is likely expecting the same output for both printf's. Commented Mar 10, 2017 at 18:59

2 Answers 2

5

Macros just textually replace, what they mean. i.e.

(READ_COMMAND(0)) | (WRITE_COMMAND(0))

becomes

((num == 0) ? (READ_RX) : (READ_TX)) | ((num == 0) ? (READ_RX) : (READ_TX))

whereas

READ_COMMAND(0) | WRITE_COMMAND(0)

becomes

(num == 0) ? (READ_RX) : (READ_TX) | (num == 0) ? (READ_RX) : (READ_TX)

Now using the precedence rules, you can see, that this is the same as

(num == 0) ? (READ_RX) : ( (READ_TX) | (num == 0) ? (READ_RX) : (READ_TX) )
Sign up to request clarification or add additional context in comments.

Comments

3

You need braces around your whole define. The second expands to:

(num == 0) ? (2) : (8) | (num == 0) ? (1) : (4)

notice that the precedence of the | is higher than that of the ? : operator.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.