No Rest Args in Variadic Macro Ok?

M

Michael B Allen

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
 
P

Peter Nilsson

Michael said:
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)
 
M

Michael Mair

Michael said:
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
 
M

Michael Mair

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
 
M

Michael B Allen

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
 
K

Keith Thompson

Michael B Allen said:
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.)
 
M

Michael Mair

Michael said:
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
 
M

Michael B Allen

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top