First of all, you should fix the macros this way:
#define SETBIT(X,Y) ( (X) |= 1ULL << (Y) ) #define UNSETBIT(X,Y) ( (X) &= ~(1ULL << (Y)) ) )
Thus, a code of type SETBIT(a, 2) + 1; will work as expected, and SETBIT(1+a, 2); will result in an error as expected.
You will probably never use macros this way, but the extra parentheses are free anyway, and the solution to macros might be a PITA that always adds extra macros () or {} .
ADDITION: With a built-in assembly and a processor with a bit rotation operation and provided that Y not known at compile time, UNSETBIT can be done faster, avoiding NOT ... Pseudo-code:
X = X OR (0xFFFFFFFFFFFFFFFE ROL Y)
Then, when these macros are just as efficient as they are (the C compiler should optimize them to perfect assembly instructions), you should probably provide macros to control multiple bits, for example:
#define SET2BITS(X, B1, B2) ( (X) |= 1ULL << (B1) | 1ULL << (B2) )
Also, in some situations, a function macro for using internal expressions may be more efficient (although optimizing the compiler is likely to achieve the same end result):
#define BITSETVAL(X, B) ( (X) | 1ULL << (B) )