Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: How to disambiguate macro? Date: Tue, 20 Jul 2021 20:27:08 -0700 Organization: None to speak of Lines: 39 Message-ID: <87eebs1h4j.fsf@nosuchdomain.example.com> References: <878s21gney.fsf@bsb.me.uk> <87fsw9m4qd.fsf@bsb.me.uk> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="3dbb069d6fac32b4b637197387ebf1ae"; logging-data="6189"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX182AUrEgrd6HSUhXBPaNStO" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) Cancel-Lock: sha1:/56bcb6K41mhW+4lQU/h9hODeVY= sha1:cHcFYlQpM+6ff7u5UY8oIiqg7VI= Xref: csiph.com comp.lang.c:162007 John Forkosh writes: > Ben Bacarisse wrote: [...] >> When the contingent action is actually just an expression, you can avoid >> the if (...) altogether like this: >> >> #define setlink(ptr,nsew,link) \ >> ( checknode(ptr) && (((node *)(ptr))->nsew = (node *)(link)) ) >> >> so that there are no 'else' issues at all. > > Thanks, again, for the alternative solution. I actually like it > a little better since it avoids the klutzy do-while construction > that has no useful purpose and might only confuse the casual reader, > i.e., "What the heck is he doing that for?" But then again, I never > much liked relying that (a&&b) always evaluates a first, immediately > becoming 0 without evaluating b at all if a is itself 0. You never know > exactly what the next C standard might mess around with. > But your suggestion itself suggested the more explicit version > #define setlink(ptr,nsew,link) \ > ( checknode(ptr)? (((node *)(ptr))->nsew = (node *)(link)) : 0 ) > which I think accomplishes the same thing with explicitly visible logic. The "do .. while (0)" idiom is very widely know. All C programmers *should* know about it. If the macro body is intended to be used in at statement context, that idiom is, as far as I know, the only method that actually works in all cases. Saying that it "has no useful purpose" is incorrect. It's question 10.4 in the comp.lang.c FAQ, http://www.c-faq.com/ If you can make the macro expansion an expression instead, that's good, but you can't do so in all cases. An if/then can often be rewritten using the &&, ||, or ?: operator. A loop cannot. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips void Void(void) { Void(); } /* The recursive call of the void */