Swammerdami
Squadron Leader
First a brief note on C macros. Never mind that the macro is a silly triviality: we just use it to review syntax.
Consider the following code:
Please answer this before reading on.
Since x is 10; and x+5 is 15; TIMES3(x+5) should yield 3*15=45; so y = TIMES3(x+5)/5 should set y to the value 45/5 = 9.
But does it? Not in the C language.
Expanding the macro in
Let's add some parentheses in the macro definition:
Try again with even more parentheses:
Because of these problems (or "ambiguities"), practiced C coders will add parentheses around all instances of arguments in the macro definition, AND around the entire macro definition. (Out of habit or "good taste", the coder usually provides the parentheses even when they appear unnecessary.)
It MIGHT seem wrong or ill-advised that C macros work as they do. But C programmers code in the C language, and NOT in the language they wish C were!
{ *, / , % } all have higher precedence than { + , -}. Precedence is left-to-right within THESE equal-precedence groups.
As explained above, the useless-looking parentheses are supplied -- whether needed in a specific invocation or not -- if only out of habit.
The weird macro does nothing useful with 0xF0F0F. It works only with a k-bit all-ones mask, i.e. 1 less than a power of two. This is implied by the test program I supplied, but I should have been much more explicit about that. (But note that the weird macro wasn't even used by the rest of my code; it was just an example of a "weird one-liner." I'd hoped it might elicit smiles, but I'm afraid every part of the posts earned only frowns. :-( )
You're welcome to try to simplify or understand the weird macro. But I do NOT think its arithmetic is deliberately over-complicated. It's just "magic arithmetic" ! I'd try to explain what I mean by this but by now we have ample evidence that I am unable to explain things.
Consider the following code:
#define TIMES3(p) 3*p // return the macro argument times 3 [sic]
x = 10;
y = TIMES3(x + 5) / 5;
What should y now equal? What does the coder probably want it to equal?Please answer this before reading on.
Since x is 10; and x+5 is 15; TIMES3(x+5) should yield 3*15=45; so y = TIMES3(x+5)/5 should set y to the value 45/5 = 9.
But does it? Not in the C language.
Expanding the macro in
y = TIMES3(x + 5) / 5;
yieldsy = 3*x + 5 / 5;
which is (3*10) + (5/5) or 31.Let's add some parentheses in the macro definition:
#define TIMES3(p) (3*p) // return the macro argument times 3 [sic]
x = 10;
y = TIMES3(x + 5) / 5;
Now we get y = (3*x + 5) / 5 which is 7. Different from 31, but still not what was intended.Try again with even more parentheses:
#define TIMES3(p) (3*(p)) // return the macro argument times 3 [works correctly!]
x = 10;
y = TIMES3(x + 5) / 5;
Now we get y = (3*(x + 5)) / 5 which is 9.Because of these problems (or "ambiguities"), practiced C coders will add parentheses around all instances of arguments in the macro definition, AND around the entire macro definition. (Out of habit or "good taste", the coder usually provides the parentheses even when they appear unnecessary.)
It MIGHT seem wrong or ill-advised that C macros work as they do. But C programmers code in the C language, and NOT in the language they wish C were!
Yes that's the one. BTW I suspect that...
You're right that NB was "number of bits." And M was "mask." I do pick poor overly-short names. Guilty as charged.
((m) / ((m) % 255 + 1) / 255 % 255 * 8 + 7 - 100 / ((m) % 255 + 14))
could be simplified a bit but I'm not sure the precedence of all of the operators (e.g. maybe * is done before +), etc. It really needs lots of brackets - though I think some are unnecessary... like the ones around m.... (unless you had a long expression using M_TO_NB(m))? I wonder how it handles something like a 0xF0F0F etc mask?
{ *, / , % } all have higher precedence than { + , -}. Precedence is left-to-right within THESE equal-precedence groups.
As explained above, the useless-looking parentheses are supplied -- whether needed in a specific invocation or not -- if only out of habit.
The weird macro does nothing useful with 0xF0F0F. It works only with a k-bit all-ones mask, i.e. 1 less than a power of two. This is implied by the test program I supplied, but I should have been much more explicit about that. (But note that the weird macro wasn't even used by the rest of my code; it was just an example of a "weird one-liner." I'd hoped it might elicit smiles, but I'm afraid every part of the posts earned only frowns. :-( )
You're welcome to try to simplify or understand the weird macro. But I do NOT think its arithmetic is deliberately over-complicated. It's just "magic arithmetic" ! I'd try to explain what I mean by this but by now we have ample evidence that I am unable to explain things.