[Python-Dev] if/else and macros (was: CVS: python/dist/src/Objects unicodeobject.c,2.48,2.49)

M.-A. Lemburg mal@lemburg.com
Mon, 17 Jul 2000 09:55:02 +0200


Greg Stein wrote:
> 
> On Mon, Jul 17, 2000 at 12:01:48AM +0200, M.-A. Lemburg wrote:
> > Greg Stein wrote:
> >...
> > > ! #define UTF8_ERROR(details) \
> > > !   if (1) {                                                  \
> > > !       if (utf8_decoding_error(&s, &p, errors, (details)))   \
> > > !           goto onError;                                     \
> > > !       continue;                                             \
> > > !   } else
> >
> > Greg, this doesn't work... UTF8_ERROR is used in if-clauses
> > and the above may alter the else-branches in subtle ways which
> > are just as hard to detect as the original bug. The goto may
> > not be the greatest in style, but it doesn't have the above
> > caveats.
> 
> Nope. It *does* work. Note the "else" on the end there. That creates the
> proper binding.

Greg, I did see the "else", but that does two things: it breaks
the code if there's no semicolon after the UT8F_ERROR() macro
and it produces warnings which relate to the fact that the "else"
part is ambiguous:

if (condition) UTF8_ERROR();
else {...}

expands to:

if (condition)
if (1) {...}
else ;
else {...}
 
And gcc doesn't like it:

unicodeobject.c: In function `PyUnicode_FromEncodedObject':
unicodeobject.c:424: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c:429: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c: In function `PyUnicode_DecodeUTF8':
unicodeobject.c:673: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c:687: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c:698: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c:710: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c:716: warning: suggest explicit braces to avoid ambiguous `else'
unicodeobject.c: In function `PyUnicode_EncodeUTF8':
unicodeobject.c:829: warning: suggest parentheses around arithmetic in operand of |
unicodeobject.c: At top level:
unicodeobject.c:755: warning: `utf8_encoding_error' defined but not used

> All uses of the UTF8_ERROR() macro have a semicolon after them (like any
> normal statement does(!)). This expands the macro to:
> 
>     if (1) {
>        ...
>     } else
>        ;       /* this is the semicolon I referred to */
> 
> Therefore, it creates a complete if/else statement, and any surrounding
> if/else statements will bind as expected.

The goto solution is much cleaner and also easier to understand.
Please revert the change you made (or I will ;-).

-- 
Marc-Andre Lemburg
______________________________________________________________________
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/