🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.c.moderated
Article #2382

Re: Macros and Braces

#2382
From: Thad Smith
Date: Sun, 24 Mar 1996 17:51
61 lines
2383 bytes
In article <4j06iu$7qm@solutions.solon.com>,
100576.1776@compuserve.com (Antony Pace (UK/CH)) wrote:
 >I am having problems writing a macro (Ansi C) for which I feel there
 >must be standard technique.  Can anyone help?
...
 >#define CLEAR_ERROR(e) { \
 >  (e).a = 0;             \
 >  (e).b = 0;             \
 >  (e).c = 0;             \
 >  TRACE("clear error");  \
 >}
...
 >#define TRACE(s)                                    \
 >  if (trace_on)                                     \
 >    fprintf(trace_file, __FILE__ __LINE__ "%s", s);
...
 >In this code segment, my macro does not work:
 >
 >  ...
 >  if (a==3)
 >    CLEAR_ERROR(error);
 >  else
 >    b=5;
 >  ...

The clever trick for this is to enclose the multiple statements within 
    do { /* statements here */ }while(0)
bracketing.  This avoids the problem you found with braces.

 >Now normally in this situation I would either combine the macro
 >statements to make a single statement by using the comma expression, or
 >I would call a function from the macro.
 >
 >
 >The comma expression
 >--------------------
 >
 >#define CLEAR_ERROR(e)  \
 >  (e).a = 0, (e).b = 0 ,  (e).c = 0 , TRACE("clear error")
 >
 >which expands to 
 >
 >  (e).a = 0, (e).b = 0 ,  (e).c = 0 ,  if (trace_on)
 >    fprintf(trace_file, __FILE__ __LINE__ "%s", "clear error")
 >  ;
 >
 >The semicolon is now a statement separator and not a null statement, but
 >the TRACE expands to an if statement which does not work with the comma
 >expression.

The situation applies to TRACE() as well as CLEAR_ERROR().  If TRACE()
were defined as

  #define TRACE(msg) (void)(trace_on? fprintf(...):0)

you could use it in a comma expression for CLEAR_ERROR.  The semicolon
in the current definition is a potential problem of the type you found
with CLEAR_ERROR().  I often add the void cast to a function-like
macro that does not return any meaningful value.

Thad
Technical Details
Message-ID: <4j422q$o0d@solutions.solon.com>
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
References: <4j06iu$7qm@solutions.solon.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
From: thads@csn.net (Thad Smith)
Newsgroups: comp.lang.c.moderated
Subject: Re: Macros and Braces
Date: 24 Mar 1996 11:51:22 -0600
Organization: T3 Systems
Sender: clc@solutions.solon.com
Approved: clc@solutions.solon.com
Message-ID: <4j422q$o0d@solutions.solon.com>
References: <4j06iu$7qm@solutions.solon.com>
Reply-To: ThadSmith@acm.org
NNTP-Posting-Host: solutions.solon.com