The outer parentheses surrounding the entire macro definition are
necessary (and the original version of the macro had them). I was
referring to parentheses around each parameter reference within the
macro definition:
#define POSITION(mw,row) (+(mw).positions[(row)])
I'm fairly sure that the parentheses around row are unnecessary, since
it's already immediately surrounded by square brackets. I'm less
certain about the parentheses surrounding mw; I can't think of any
possible problems, but I could be missing something.
There is one case where they are required.
For any such macro to work, the macro parameter "mw" must name a
structure object that has a "positions" field. This field is either
an array of size N, or a pointer that points to the first of N
sequential elements.
Suppose we redefine the macro as just:
#define POSITION(mw, row) (+mw.positions[row])
Typically this might be used as:
struct S var;
... POSITION(var, k) ...
which works as desired. The macro expands to:
(+var.positions[k])
which parses as "access the k'th element of the array or pointer
named via the positions member of the variable `var', then apply
the unary + operator". But suppose instead we have a pointer,
e.g.:
struct S *ptr = ...;
... POSITION(*ptr, k) ...
In this case, the version without parentheses expands to:
(+*ptr.positions[k])
which parses the same as:
(+(*(ptr.positions[k])))
This attempts to apply the unary "*" and binary "." operators
to the wrong operands.
Parenthesizing "mw" in the expansion gives, instead:
(+(*ptr).positions[k])
which now applies unary "*" to "ptr" as desired, and binary "."
to the structure found via *ptr.
The parentheses around "row" are in fact unnecessary. (A good
proof requires exhaustive enumeration, but a hand-wavey version
simply notes that the square brackets function identically to
parentheses, provided the expression in "row" is syntactically
legal to begin with. Writing POSITION(*ptr,]) causes problems,
but these problems are not fixable via parentheses.)