
On 30.12.2010 00:10, Alessandro Rubini wrote:
Dirk Behme:
Just for the record:
The trick is to ensure that the __arch_putx() containing the volatile is not the last statement in the GCC statement-expression. So, using something like
#define writeb(v,c) ({ __iowmb(); __arch_putb(v,c); v;})
(note the additional 'v;') should result in correct code, too.
Yes, that's good. Also "0" may work, and may be more readable, (or not, according to who reads it).
Yes, indeed,
#define writeb(v,c) ({ __iowmb(); __arch_putb(v,c); 0;})
seems to work, too :)
Thanks
Dirk
The patches sent by Wolfgang and Alexander using
#define writeb(v,c) do { __iowmb(); __arch_putb(v,c); } while (0)
do the same with a slightly different syntax, so these patches are fine, too.
It's not just different syntax, it's different semantics.
The ({...}) trick turns statements into expressions, while the "do {...} while(0)" does not. I'd better not forbid statements like
while (reg = readb(addr), reg != VALUE) { .... }
or
if (readb(addr) == VALUE) { ... }
or swtich (readb(addr)) { ... }
While I agree they may in general not be clean, I can forsee meaningful uses. Moreover, I'd better allow expression-looking macros to really behave like expressions -- otherwise error messages are quite hard to understand for the unaquainted.
IMHO, the only reason to use "do {} while(0)" over statemente expressions is being portable but in u-boot we are gcc-specific anyways.
/alessandro