By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,273 Members | 1,037 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,273 IT Pros & Developers. It's quick & easy.

No Rest Args in Variadic Macro Ok?

P: n/a
If I define a variadic macro like say:

#define PRINT(fmt, ...) _myprintf(__FILE__ ": " fmt, __VA_ARGS__)

and I call this like:

PRINT("no args");

the preprocessor generates:

_myprintf("file.c" ": " "no args",);

which isn't going to work because of the comma. Is there a workaround?
This seems like a drab oversight in variadic macros.

Mike
Nov 14 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Michael B Allen wrote:
If I define a variadic macro like say:

#define PRINT(fmt, ...) _myprintf(__FILE__ ": " fmt, __VA_ARGS__)

and I call this like:

PRINT("no args");

the preprocessor generates:

_myprintf("file.c" ": " "no args",);

which isn't going to work because of the comma. Is there a
workaround? This seems like a drab oversight in variadic macros.


Have you read the examples from the standard (or N869)?

A quick replacement is...

#define PRINT(...) myprintf(__FILE__ ": " __VA_ARGS__)

A more robust macro might be...

#define PRINT(...) \
do { myprintf("%s: ", __FILE__); \
myprintf( __VA_ARGS__ ); } while (0)

--
Peter

Nov 14 '05 #2

P: n/a
Michael B Allen wrote:
If I define a variadic macro like say:

#define PRINT(fmt, ...) _myprintf(__FILE__ ": " fmt, __VA_ARGS__)

and I call this like:

PRINT("no args");

the preprocessor generates:

_myprintf("file.c" ": " "no args",);

which isn't going to work because of the comma. Is there a workaround?
This seems like a drab oversight in variadic macros.

Mike


Make this
#define PRINT(...) _myprintf(__FILE__ ": " __VA_ARGS__)

If you want to provide an automatic linefeed (i.e. append '\n'
to fmt), then you need a separate call:
#define PRINT(...) do { \
_myprintf(__FILE__ ": " __VA_ARGS__); \
_myputchar('\n'); \
} while (0)
(untested)

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #3

P: n/a
Michael Mair wrote:
Michael B Allen wrote:
If I define a variadic macro like say:

#define PRINT(fmt, ...) _myprintf(__FILE__ ": " fmt, __VA_ARGS__)

and I call this like:

PRINT("no args");

the preprocessor generates:

_myprintf("file.c" ": " "no args",);
On a second thought:
You are aware that you are invading the implementation's namespace
by the use of leading underscores? If you want to have an underscore
sticking out at an end then rather use "myprintf_"

Cheers
Michael
which isn't going to work because of the comma. Is there a workaround?
This seems like a drab oversight in variadic macros.

Mike

Make this
#define PRINT(...) _myprintf(__FILE__ ": " __VA_ARGS__)

If you want to provide an automatic linefeed (i.e. append '\n'
to fmt), then you need a separate call:
#define PRINT(...) do { \
_myprintf(__FILE__ ": " __VA_ARGS__); \
_myputchar('\n'); \
} while (0)
(untested)

Cheers
Michael

--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #4

P: n/a
On Sat, 12 Mar 2005 05:55:05 -0500, Michael Mair wrote:
_myprintf("file.c" ": " "no args",);


On a second thought:
You are aware that you are invading the implementation's namespace by
the use of leading underscores?


No, I wasn't. I thought <underscore><upper> was reserved, not
<underscore><lower>. Are you certain?

Mike
Nov 14 '05 #5

P: n/a
Michael B Allen <mb*****@ioplex.com> writes:
On Sat, 12 Mar 2005 05:55:05 -0500, Michael Mair wrote:
_myprintf("file.c" ": " "no args",);


On a second thought:
You are aware that you are invading the implementation's namespace by
the use of leading underscores?


No, I wasn't. I thought <underscore><upper> was reserved, not
<underscore><lower>. Are you certain?


C99 7.1.3p1:

All identifiers that begin with an underscore and either an
uppercase letter or another underscore are always reserved for any
use.

All identifiers that begin with an underscore are always reserved
for use as identifiers with file scope in both the ordinary and
tag name spaces.

(I tend not to remember these details; I just avoid identifers with
leading underscores.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #6

P: n/a
Michael B Allen wrote:
On Sat, 12 Mar 2005 05:55:05 -0500, Michael Mair wrote:

_myprintf("file.c" ": " "no args",);


On a second thought:
You are aware that you are invading the implementation's namespace by
the use of leading underscores?


No, I wasn't. I thought <underscore><upper> was reserved, not
<underscore><lower>. Are you certain?


You are right but as soon as _myprintf() resides in a different
translation unit the difference gets blurry as we only have six
significant characters _without_ looking at upper or lower
case for identifiers in C89; C99 nonetheless restricts the
scope of such identifiers to file IIRC.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #7

P: n/a
On Sat, 12 Mar 2005 04:56:05 -0500, Peter Nilsson wrote:
A quick replacement is...

#define PRINT(...) myprintf(__FILE__ ": " __VA_ARGS__)
Yeah, but with this you cannot reorder the arguments.

#define PRINT(err, fmt, ...) \
_myprintf(__FILE__ ": %s" fmt, errstr(err), __VA_ARGS__)

used like:

PRINT(EFOO, ": ouch!");

gives:

_myprintf("file.c" ": %s" ": ouch!", errstr(err),)
A more robust macro might be...

#define PRINT(...) \
do { myprintf("%s: ", __FILE__); \
myprintf( __VA_ARGS__ ); } while (0)


I don't think this helps in this case either.

Mike
Nov 14 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.