|  | empty macro arguments |  | |
| | | Two-Horned Unicorn |  |
| Posted: Sun Jun 08, 2008 9:41 pm Post subject: empty macro arguments |  |
The following code compiles and works as expected when compiled with gcc.
/* empty-args.c */
#include <stdio.h>
#define foo(x,y) puts("bar: x=\"" #x "\"; y=\"" #y "\"") #define bar(x) puts("foo: x=\"" #x "\"")
int main(void) { foo(,); foo(FOO,); foo(,BAR); foo(FOO,BAR); bar(); bar(FOO); return 0; }
However, when I compiled it with a different compiler, I received the following compiler messages:
| cpp: empty-args.c:14 Disagreement in number of macro arguments | Warning empty-args.c: 14 missing prototype for bar | Warning empty-args.c: 14 Missing prototype for 'bar' | 0 errors, 3 warnings | empty-args.obj .text: undefined reference to '_bar' | linker returned 1
It seems there are no problems with 'foo' if one or both arguments are empty, but the same is not true for 'bar'. Is this an extension in gcc? A new thing in C99?
What does the standard say? (I'm not that good at standardese) |
| |
| | | Hallvard B Furuseth |  |
| Posted: Sun Jun 08, 2008 9:41 pm Post subject: Re: empty macro arguments |  |
Two-Horned Unicorn <two_horned.unicorn@yahoo_NOSPAM_.com> writes:
| Quote: | #define foo(x,y) puts("bar: x=\"" #x "\"; y=\"" #y "\"") #define bar(x) puts("foo: x=\"" #x "\"") (...) foo(,); foo(FOO,); foo(,BAR);
|
ANSI C section 3.8.3: "If (before argument substitution) any argument consists of no preprocessing tokens, the behavior is undefined." So gcc is free to accept it.
The gcc folks say this is a macro invocation with an empty argument: <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11233>. Maybe your other compiler vendor disagrees. In any case, as above it is undefined behavior.
-- Hallvard |
| |
| | | Thad Smith |  |
| Posted: Sun Jun 08, 2008 9:41 pm Post subject: Re: empty macro arguments |  |
| |  | |
Hallvard B Furuseth wrote:
| Quote: | Two-Horned Unicorn <two_horned.unicorn@yahoo_NOSPAM_.com> writes:
#define foo(x,y) puts("bar: x=\"" #x "\"; y=\"" #y "\"") #define bar(x) puts("foo: x=\"" #x "\"") (...) foo(,); foo(FOO,); foo(,BAR);
ANSI C section 3.8.3: "If (before argument substitution) any argument consists of no preprocessing tokens, the behavior is undefined." So gcc is free to accept it.
|
That was true of C89, but is not true of C99: 6.10.3 Macro Replacement, p4:
"If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition."
| Quote: | bar();
The gcc folks say this is a macro invocation with an empty argument: LINK Maybe your other compiler vendor disagrees.
|
This is a rather subtle change in C that was discussed a while ago in comp.std.c. A macro invocation with no arguments matches a function-like macro with either 0 or 1 parameters in C99.
-- Thad |
| |
| | | Ben Bacarisse |  |
| Posted: Sun Jun 08, 2008 10:38 pm Post subject: Re: empty macro arguments |  |
Hallvard B Furuseth <h.b.furuseth@usit.uio.no> writes:
| Quote: | Two-Horned Unicorn <two_horned.unicorn@yahoo_NOSPAM_.com> writes:
#define foo(x,y) puts("bar: x=\"" #x "\"; y=\"" #y "\"") #define bar(x) puts("foo: x=\"" #x "\"") (...) foo(,); foo(FOO,); foo(,BAR);
ANSI C section 3.8.3: "If (before argument substitution) any argument consists of no preprocessing tokens, the behavior is undefined."
|
That text has gone from C99 and there are several examples of empty arguments later on to drive home the point.
lcc-win32 (the original compiler whose messages started the thread) makes no claim to support C99 so it is free to take the older point of view, but oddly the pre-processors tries to implement __VA_ARGS__ suggesting an intent to be C99 conforming.
-- Ben. |
| |
| | | Keith Thompson |  |
| Posted: Mon Jun 09, 2008 2:49 am Post subject: Re: empty macro arguments |  |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: [...]
| Quote: | lcc-win32 (the original compiler whose messages started the thread) makes no claim to support C99 so it is free to take the older point of view, but oddly the pre-processors tries to implement __VA_ARGS__ suggesting an intent to be C99 conforming.
|
I thought lcc-win32's author *did* claim that it supports C99, or at least most of it with a couple of exceptions. But I think variadic macros were one of the exceptions. It's probably a work in progress.
-- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
| |
| | | Ben Bacarisse |  |
| Posted: Mon Jun 09, 2008 9:40 am Post subject: Re: empty macro arguments |  |
Keith Thompson <kst-u@mib.org> writes:
| Quote: | Ben Bacarisse <ben.usenet@bsb.me.uk> writes: [...] lcc-win32 (the original compiler whose messages started the thread) makes no claim to support C99 so it is free to take the older point of view, but oddly the pre-processors tries to implement __VA_ARGS__ suggesting an intent to be C99 conforming.
I thought lcc-win32's author *did* claim that it supports C99, or at least most of it with a couple of exceptions. But I think variadic macros were one of the exceptions. It's probably a work in progress.
|
I don't recall any clear statement on current or planned conformance and I concluded that that was the way Jacob wanted it. Having C99 conformance as an objective for some unspecified time in the future means there are fewer bugs now. If I have that wrong I hope he will clear the matter up.
-- Ben. |
| |
| | | Flash Gordon |  |
| Posted: Mon Jun 09, 2008 6:41 pm Post subject: Re: empty macro arguments |  |
| |  | |
Ben Bacarisse wrote, On 09/06/08 12:40:
| Quote: | Keith Thompson <kst-u@mib.org> writes:
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: [...] lcc-win32 (the original compiler whose messages started the thread) makes no claim to support C99 so it is free to take the older point of view, but oddly the pre-processors tries to implement __VA_ARGS__ suggesting an intent to be C99 conforming. I thought lcc-win32's author *did* claim that it supports C99, or at least most of it with a couple of exceptions. But I think variadic macros were one of the exceptions. It's probably a work in progress.
I don't recall any clear statement on current or planned conformance and I concluded that that was the way Jacob wanted it. Having C99 conformance as an objective for some unspecified time in the future means there are fewer bugs now. If I have that wrong I hope he will clear the matter up.
|
He has made it pretty clear that it is not intended to conform to C90/C95 (this is *not* a complaint, merely a comment) and that he personally wants everyone to go C99 so I think the only standard we can in fairness check it against is C99. This means that it is correct for it to behave with the C99 rules for variadic macros. -- Flash Gordon |
| |
| | | Ben Bacarisse |  |
| Posted: Mon Jun 09, 2008 8:50 pm Post subject: Re: empty macro arguments |  |
| |  | |
Flash Gordon <spam@flash-gordon.me.uk> writes:
| Quote: | Ben Bacarisse wrote, On 09/06/08 12:40: Keith Thompson <kst-u@mib.org> writes:
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: [...] lcc-win32 (the original compiler whose messages started the thread) makes no claim to support C99 so it is free to take the older point of view, but oddly the pre-processors tries to implement __VA_ARGS__ suggesting an intent to be C99 conforming. I thought lcc-win32's author *did* claim that it supports C99, or at least most of it with a couple of exceptions. But I think variadic macros were one of the exceptions. It's probably a work in progress.
I don't recall any clear statement on current or planned conformance and I concluded that that was the way Jacob wanted it. Having C99 conformance as an objective for some unspecified time in the future means there are fewer bugs now. If I have that wrong I hope he will clear the matter up.
He has made it pretty clear that it is not intended to conform to C90/C95 (this is *not* a complaint, merely a comment) and that he personally wants everyone to go C99 so I think the only standard we can in fairness check it against is C99. This means that it is correct for it to behave with the C99 rules for variadic macros.
|
You mean, presumably, that it *would* be correct for it to behave with the C99 rules for variadic macros. The forward in the standard lists only two changes that relate to macros: variable number of arguments and empty arguments. The lcc-win32 I have gets both of these wrong:
#define ONE(x) #x #define MANY(...) [__VA_ARGS__] ONE() MANY(abc, def, ghi)
Produces:
ONE() [abc,def,ghi)
along with a warning about the empty argument. The C99 rules may be the ones aspired to but there is a way to go yet.
-- Ben. |
| |
| | | Ben Bacarisse |  |
| Posted: Mon Jun 09, 2008 10:02 pm Post subject: Re: empty macro arguments |  |
| |  | |
roberson@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
| Quote: | In article <87hcc2dxzt.fsf@bsb.me.uk>, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
The lcc-win32 I have gets both of these wrong:
#define ONE(x) #x #define MANY(...) [__VA_ARGS__] ONE() MANY(abc, def, ghi)
Produces:
ONE() [abc,def,ghi)
along with a warning about the empty argument.
Was that a typo, or does it truly end the list with ) instead of ] ??
|
No typo. It was a file include (and I then cut the file name that appears in a #line directive).
It is different with stringise. I've removed the []s to make it clearer. This input:
--- macros.c --- #define MANY(...) __VA_ARGS__ #define STRING(...) #__VA_ARGS__ MANY(abc, def, ghi) STRING(abc, def, ghi) ----------------
Produces: --- macros.i --- #line 1 "Z:\home\ben\play\lcc\macros.c"
abc,def,ghi) "abc"
----------------
and this:
--- at-end.c --- #define MANY_1(x, ...) __VA_ARGS__, x MANY_1(abc, def, ghi) ----------------
crashes the compiler:
Error (null) 0 Compiler error (trap). Stopping compilation 1 error
-- Ben. |
| |
| | | Walter Roberson |  |
| Posted: Mon Jun 09, 2008 11:08 pm Post subject: Re: empty macro arguments |  |
In article <87hcc2dxzt.fsf@bsb.me.uk>, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
| Quote: | The lcc-win32 I have gets both of these wrong:
#define ONE(x) #x #define MANY(...) [__VA_ARGS__] ONE() MANY(abc, def, ghi)
Produces:
ONE() [abc,def,ghi)
along with a warning about the empty argument.
|
Was that a typo, or does it truly end the list with ) instead of ] ?? -- So you found your solution What will be your last contribution? -- Supertramp (Fool's Overture) |
| |
|
|