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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.