RFC: SAFE_MACRO_STMT

Tom de Vries Tom_deVries@mentor.com
Mon Nov 20 16:36:00 GMT 2017


Hi,

when writing macros that are intended to be used as if they were single 
statements, there are a couple of common problems:

1. Ending in semicolon
...
#define foo stmt;
...

This works fine if we use it like:
...
void
bar (void)
{
   foo;
}
...

but we get an "else without a previous if" error when we use it like:
...
void
bar (void)
{
   if (1)
     foo;
   else
     {}
}
...

2. Using if-then-else without wrapping in "do {} while (0)"
...
#define foo if (1) stmt; else {}
...

Again this works fine if we use it like:
...
void
bar (void)
{
   foo;
}
...

but we get an "suggest explicit braces to avoid ambiguous else 
[-Wparentheses]" warning when we use it like:
...
void
bar (void)
{
   if (1)
     foo;
}
...

3. Multi statement without wrapping it in "do {} while (0)"
...
#define foo stmt; stmt
...

Again this works fine if we use it like:
...
void
bar (void)
{
   foo;
}
...

but we get a "macro expands to multiple statements 
[-Wmultistatement-macros]" warning when we use it like:
...
void
bar (void)
{
   if (1)
     foo;
}
...


I've written a macro SAFE_MACRO_STMT that triggers these three 
situations for a macro, but does not change the semantics:
...
#define SAFE_MACRO_STMT(stmt)                   \
   do {                                          \
     stmt;                                       \
     if (0)                                      \
       stmt;                                     \
     else                                        \
       {}                                        \
     if (0)                                      \
       stmt;                                     \
   } while (0)
...

In other words, by wrapping the macro usage in SAFE_MACRO_STMT, we 
trigger an error or warning if the macro body contains any of the problems:
...
void
bar (void)
{
   SAFE_MACRO_STMT (foo);
}
...

The first demonstrator patch applies this strategy to 
ASM_OUTPUT_ADDR_VEC_ELT. This smokes out a type 1 error in the ft32 
definition of ASM_OUTPUT_ADDR_VEC_ELT, which is fixed by the second patch.

Any comments on this approach?

Thanks,
- Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Use-SAFE_MACRO_STMT-for-ASM_OUTPUT_ADDR_VEC_ELT.patch
Type: text/x-patch
Size: 1372 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20171120/52daa53b/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-ft32-Remove-semicolon-after-ASM_OUTPUT_ADDR_VEC_ELT.patch
Type: text/x-patch
Size: 594 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20171120/52daa53b/attachment-0001.bin>


More information about the Gcc-patches mailing list