[comp.lang.c] Embedding macro values in strings

frank@grep.co.uk (Frank Wales) (01/11/91)

Is it possible to write a macro such that the value of one of its
parameters, which is derived from another macro, is embedded in a string
after pre-processing (and if so, how)?

For example, suppose I have  foo(__LINE__); in my source, and I want that
to expand to  bar("Line n"); where n is substituted with the actual value
of __LINE__ at that point.  Trying

  #define foo(n)	bar("Line "#n)

and invoking as  foo(10); yields  bar("Line 10"); , whereas  foo(__LINE__);
yields  bar("Line __LINE__"); .

The zero-parameter alternative version

  #define foo()         bar("Line "#__LINE__)

is illegal.

Some time playing and reading section A12 of K&RII has been unfruitful.
I get the impression I'm being defeated by the sequencing of pre-processor
phases, but I'd like to be sure that what I'm attempting is impossible
before resorting to other means to achieve what I want.

[All this is under MSC 5 under SCO Unix, a supposed ANSI compiler. I'd much
 prefer an ANSI C solution to a Classic C one.  Also, for this problem,
 gcc's pre-processor would be an awkward choice.  Thanks in advance, etc..]
--
Frank Wales, Grep Limited,             [frank@grep.co.uk<->uunet!grep!frank]
Kirkfields Business Centre, Kirk Lane, LEEDS, UK, LS19 7LX. (+44) 532 500303

pfalstad@phoenix.Princeton.EDU (Paul John Falstad) (01/11/91)

In article <1991Jan10.200806.12745@grep.co.uk> frank@grep.co.uk (Frank Wales) writes:
>For example, suppose I have  foo(__LINE__); in my source, and I want that
>to expand to  bar("Line n"); where n is substituted with the actual value
>of __LINE__ at that point.  Trying
>
>  #define foo(n)	bar("Line "#n)
>
>and invoking as  foo(10); yields  bar("Line 10"); , whereas  foo(__LINE__);
>yields  bar("Line __LINE__"); .

You realize, of course, that foo(10) would not actually produce:

   bar("line 10"),

but will produce:

	bar("line " "10")

wish is concatenated into a single string in a later phase of
compilation.  Just clarifying that.

Anyway, adding another level of macro expansion does the trick:

#define foo(n) bar("Line "fee(n))
#define fee(X) #X
foo(10)
foo(__LINE__)

This produces the intended result (using gcc):

bar("Line ""10" ) 
bar("Line ""4" ) 

--
Paul Falstad, pfalstad@phoenix.princeton.edu PLink:HYPNOS GEnie:P.FALSTAD
"We could nuke Baghdad into glass, wipe it with Windex, tie fatback on
our feet and go skating." - Air Force Times columnist Fred Reed

wollman@emily.uvm.edu (Garrett Wollman) (01/13/91)

Doug Gwyn will probably yell at me...


#define foo_bar(baz) "Line " #baz
#define foo() foo_bar(__LINE__)

I *think* that this will work; I can't remember the exact order of
application here, which was posted by one of the net.c.gurus a while
back.  It will work if the preprocessor expands __LINE__ before it
expands foo_bar().  [I.e., is the C preprocessor a lazy or non-lazy
evaluator?]  Someone might have quotations from the relevant sections
of the Standard?

-GAWollman

Garrett A. Wollman - wollman@emily.uvm.edu

Disclaimer:  I'm not even sure this represents *my* opinion, never
mind UVM's, EMBA's, EMBA-CF's, or indeed anyone else's.