First of all, you should fix the macros to be like this:
#define SETBIT(X,Y) ( (X) |= 1ULL << (Y) )
#define UNSETBIT(X,Y) ( (X) &= ~(1ULL << (Y)) ) )
That way code like SETBIT(a, 2) + 1;
would work more like expected and SETBIT(1+a, 2);
would produce error as expected.
You will probably never use the macros that way, but extra parenthesis are free anyway, and solving macro-related issues can be such a PITA, that always put the extra ()
or {}
around macros.
ADDITION: With inline assembly and CPU with bit rotation operation, and assuming Y
is not known at compile time, UNSETBIT can be made faster, avoiding a NOT... Pseudocode:
X = X OR (0xFFFFFFFFFFFFFFFE ROL Y)
Then while those macros are as efficient as it gets (C compiler should optimize them to ideal assembly instructions), you should perhaps provide macros to manipulate several bits, like:
#define SET2BITS(X, B1, B2) ( (X) |= 1ULL << (B1) | 1ULL << (B2) )
Also a function-like macro for using inside expressions might be more efficient in some situations (though compiler optimizations will probably achieve same end result anyway):
#define BITSETVAL(X, B) ( (X) | 1ULL << (B) )