Reputation: 117
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.
Upvotes: 2
Views: 47
Reputation: 1825
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.
Upvotes: 3
Reputation: 1916
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) )
Upvotes: 5