Article View: comp.lang.c.moderated
Article #2369Re: Macros and Braces
From: Stig Hemmer
Date: Sun, 24 Mar 1996 17:41
Date: Sun, 24 Mar 1996 17:41
75 lines
2958 bytes
2958 bytes
In article <4j06iu$7qm@solutions.solon.com> 100576.1776@compuserve.com (Antony Pace (UK/CH)) writes:
[How can I write a macro that works like a function in all contexts?]
There are many ways, here are some variants of your methods:
> #define CLEAR_ERROR(e) \
> clear_error(e)
>
> void clear_error(t_error error) {
> (error).a = 0;
> (error).b = 0;
> (error).c = 0;
> TRACE("clear error");
> }
Try:
#define CLEAR_ERROR(e) \
clear_error(e,__FILE__,__LINE__)
You'll need another macro TRACE2 which accepts file and line arguments
but this is just a minor rewrite of TRACE. And you can do
#define TRACE(s) TRACE2(s,__FILE__,__LINE__)
If this is something you do often, you probably don't want the
function call overhead though...
>#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.
Rewrite TRACE as an expression too and it will work:
#define TRACE (trace_on && fprintf(...))
> #define CLEAR_ERROR(e) \
> if (!((e).a = (e).b = (e).c = 0)) TRACE("clear error")
> It uses an unnecessary comparison which I don't like but at least it
> works!
Never mind the comparison, the compiler will probably optimize it away
anyway. Another similar way of doing this:
#define CLEAR_ERROR(e)\
do {\
...\
} while(0)
Again a good compiler should kill the comparison. In this version
"..." can be anything, not just expressions.
>As I said at the top, I am sure that I am not the first with this
>problem and would love to hear of THE clean solution. Thanks very much.
As you can see, there are many ways of solving this problem. The last
one is IMHO closest to being THE solution since it can be used
regardless what you want to do in the macro. In fact, I have a feeling
that this is the 'traditional' way of solving this problem, though I
can't really remember where I learnt it first.
Happy hacking!
Stig Hemmer aka stig@pvv.unit.no
pvv - ProgramVareVerkstedet ("The Software Workshop", a student society)
.unit - UNiversitetet I Trondheim
.no - NOrway, a minor kingdom in northern Europe. Yes in 2016!
Technical Details
Message-ID:
<4j41fn$nha@solutions.solon.com>Path:
arc1-ca.pugleaf.net!solon.com!not-for-mailReferences:
<4j06iu$7qm@solutions.solon.com>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail From: stig@pvv.unit.no (Stig Hemmer) Newsgroups: comp.lang.c.moderated Subject: Re: Macros and Braces Date: 24 Mar 1996 11:41:11 -0600 Organization: Norwegian University of Science and Technology Sender: clc@solutions.solon.com Approved: clc@solutions.solon.com Message-ID: <4j41fn$nha@solutions.solon.com> References: <4j06iu$7qm@solutions.solon.com> NNTP-Posting-Host: solutions.solon.com X-Newsreader: Gnus v5.1