No, your assertion is untrue :-)
a = val_plus_two( val )
would expand to
a = do { ((val) + 2); } while (0 );
which is illegal in C. gcc doesn't even have this extension and gives
a parse error at the "do" (at least for 2.6.3 and 2.7.2).
What your construct does do is make it safe to be used in an
"statement" context, but not an expression context.
While you can do very very very simple things that return a value, you
can't have a macro that walks a list and returns something out of the
middle of the list (unless you cunningly cached a pointer to it
somehow).
This, imho, is one of the flaws in the C language where it doesn't
quite hang right together.
Warner