No, the parameters of m3 are expanded only after they are recognized: so
m3(1, m(3)) sees only two parameters for m3: 1 and m(3). This leads to an
error.
Cheers
Tanmoy
--
tan...@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tan...@lanl.gov"(1.218=1242)
Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87545 H:#9,3000,Trinity Drive,NM87544
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]
#define m(x) 2,x
#define m3(a,b,c) a+b+c
main()
{
int n;
n = m3(1, m(3));
}
It doesn't work with cc or gcc on unix.
I'm sure you think that this should result in something like:
main()
{
int n;
n = 1+2+3;
}
bcc/tcc does this (including the lack of white space).
Most other compilers I am familiar with, including gcc, yield:
main()
{
int n;
n = 1 + 2, 3 + ;
}
The difference arises from the interpretation of ISO/ANSI 6.8.3.1
(Argument substitution). The key is "after the arguments have been
identified ... all macros contained therein have been expanded." This
implies the identification of arguments in m3(1,m(3)) -- there are two
-- before the expansion of m(3). This indicates to me that gcc is right
and bcc/tcc is wrong. We know bcc/tcc is wrong about white space in the
expansion.
--
* Martin Ambuhl net: mam...@ripco.com
* Chicago, IL (USA)
>Could someone tell me if this is supposed to work
>with ANSI-C:
>#define m(x) 2,x
>#define m3(a,b,c) a+b+c
>main()
>{
> int n;
> n = m3(1, m(3));
>}
No - it should give an error since you're calling m3 with only two
arguments when it expects three. If you reverse things:
#define m(x) 2,x
#define m3(a,b) a+m(b)
then it should work. Basically, it first passes the arguments, then
expands the macro, then rescans the result to see if there are any macro
names in the expanded text. If so it expands them _unless_ the name is
of a macro that has already been expanded as part of this macro. Since
macros provide no conditions on expansion, expanding a macro that had
already been expanded would always lead to infinite recursion.
Later,
Jerry.
/* I can barely express my own opinions; I certainly can't
* express anybody else's.
*
* The universe is a figment of its own imagination.
*/
>If a compiler really yields the above, I consider its preprocessor broken.
>See ISO/IEC 9899:1990(E), 6.8.3., 4th paragraph:
> "The number of arguments in an invocation of a function-like macro
> shall agree with the number of parameters in the macro definition,
> ..."
>gcc's allowing empty arguments is a non-standard extension.
gcc properly reports (as the original poster complained) the
macro `m3' used with only 2 args
error (not warning) message.
That the preprocessor might make an attempt to evaluate the macro is
not relevant. That the translator issues an error message (and does not
produce an object/executable) is surely sufficient here.
Since, for the code in question, Borland -- without even a warning --
violates the standard in several ways (incorrect argument
identification, incorrect white space) and _does_ produces an
executable, it _is_ broken.
Faced with a broken implementation (Borland) and a correct one (gcc),
you have chosen the wrong horse to flog.
>This post is _very_ technical: if any novice needs the following (s)he is
>probably going about something in a _very_ wrong way!
Thanks for the warning.
>In article <48dk90$5...@natasha.rmii.com>, jco...@rmii.com (Jerry Coffin)
>writes:
><snip>
>|> then it should work. Basically, it first passes the arguments, then
>|> expands the macro, then rescans the result to see if there are any macro
>|> names in the expanded text. If so it expands them _unless_ the name is
>Almost. It first _recognizes_ the arguments, then expands the _parameters_
>(if they are expandable) unless in the replacement text they are being
>stringized (# operator) or concatenated (## operator), then expands the
>macro, then rescans.
I don't suppose I can claim that the "Basically" was supposed to cover
this? Darn! I was afraid not. <half grin>
>The difference is noticeable in the following
>#define A(x) (
>#define B(x) )
>#define CHECK(x) x
>#define TEST(y,z) CHECK y(x) x z(x)
>#define TRY(y,z) CHECK y x z
>TEST(A,B)
>TRY(A(x),B(x))
I have to agree with your initial statement - if a beginner is writing
macros like this, he's either a genius or crazy...or most likely both.
OTOH, as I sit back and thing about it, this is actually pretty similar
to something Thad Smith ran into 2 or 3 years ago. As I recall, at the
time the only preprocessor we could find that actually handled his test
case correctly was JRCPP. And it was code that came up in real use, not
written to prove a point. Then again, Thad is a LONG ways from a
beginner.
[ ... ]
>That the preprocessor might make an attempt to evaluate the macro is
>not relevant. That the translator issues an error message (and does not
>produce an object/executable) is surely sufficient here.
>Since, for the code in question, Borland -- without even a warning --
>violates the standard in several ways (incorrect argument
>identification, incorrect white space) and _does_ produces an
>executable, it _is_ broken.
>Faced with a broken implementation (Borland) and a correct one (gcc),
>you have chosen the wrong horse to flog.
Though I'm no great fan of Borland's compilers, I do think it's worth
noting that this is a bug Borland fixed quite some time ago - I believe
the last compiler in which it was present was BC 3.1, which has been
obsolete for a couple of years now. I haven't checked on the whitespace
situation, but definitely BC 4.5 gives an error for the original code.