[comp.lang.c] Macros in ANSI C

mojy@iSC.intel.com (Mojy Mirashrafi) (03/02/91)

Here is my question:

In the old C if you wanted to define a macro to convert its parameter to a 
char you would write a macro like this:

#define conv(s) 's'

and if you used "conv(X)" in your code you would get 'X'.

In ANSI C the "'" prevents evaluation of the enclosed characters.
The above macro will expand to: 's'. Is there a way to escape the "'"s, in ANSI
C?

Thanx.

gwyn@smoke.brl.mil (Doug Gwyn) (03/03/91)

In article <1172@intelisc.isc.intel.com> mojy@iSC.intel.com (Mojy Mirashrafi) writes:
>In the old C if you wanted to define a macro to convert its parameter to a 
>char you would write a macro like this:
>#define conv(s) 's'
>and if you used "conv(X)" in your code you would get 'X'.

No, what you mean is that certain C preprocessors (notably Reiser's)
incorrectly implemented the C language specification of K&R (1st Ed.)
and some programmers decided to exploit that bug to perform the sort
of "charizing" (more usually, "stringizing") that you show in the
example.

>In ANSI C the "'" prevents evaluation of the enclosed characters.

Also in "K&R C".

>The above macro will expand to: 's'. Is there a way to escape the "'"s,
>in ANSI C?

Not that I know of, because character constants must be treated as
single preprocessing tokens; an attempt to make the preprocessor
handle isolated ' characters produces undefined behavior (standard
section 3.1 Semantics).

X3J11 perceived a genuine need to support "stringizing", and thus
added the # operator for that.  I have never seen a genuine need
for "charizing"; the usual example given is BSD's
	#define CTRL(x) ('x' & 0x1F)
which should all along have been written
	#define CTRL(x) (x & 0x1F)
and invoked with a character-constant argument rather than a source
text character.

ckp@grebyn.com (Checkpoint Technologies) (03/03/91)

In article <1172@intelisc.isc.intel.com> mojy@iSC.intel.com (Mojy Mirashrafi) writes:
>In the old C if you wanted to define a macro to convert its parameter to a 
>char you would write a macro like this:
>#define conv(s) 's'
>and if you used "conv(X)" in your code you would get 'X'.
>In ANSI C the "'" prevents evaluation of the enclosed characters.

If you don't need it to result in a constant, you can use:

#define conv(s) #s[0]

The real answer is, no, you can't use that old trick anymore, and
no new trick replaces it.  Sorry.
-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/

gary@hpavla.avo.hp.com (Gary Jackoway) (03/05/91)

Mojy Mirashrafi writes:

> Here is my question:

> In the old C if you wanted to define a macro to convert its parameter to a 
> char you would write a macro like this:

> #define conv(s) 's'

> and if you used "conv(X)" in your code you would get 'X'.

> In ANSI C the "'" prevents evaluation of the enclosed characters.
> The above macro will expand to: 's'. Is there a way to escape the "'"s, 
> in ANSI C?

I don't want to get into an argument about whether it should have worked like
you say it did in the past, so I'll just give you a (mildly ugly) solution.

Since we now have the "stringize" # operator, all you have to do is this:

#define CHARIZE(c) (#c)[0]

That'll do it.

> Thanx.

Your welcome, but don't tell anyone I came up with this solution.
				    -

Gary Jackoway

ado@elsie.nci.nih.gov (Arthur David Olson) (03/05/91)

> In the old C if you wanted to define a macro to convert its parameter to a 
> char you would. . .
> #define conv(s) 's'
> . . .In ANSI C the "'" prevents evaluation of the enclosed characters.
> . . .Is there a way to escape the "'"s, in ANSI C?

For many practical purposes, what works is to

	#define LETR_A	'A'
	#define LETR_B	'B'
	/* ... */
	#define LETR_Z	'Z'

	#define LETR_a	'a'
	#define LETR_b	'b'
	/* ... */
	#define LETR_z	'z'

	#define conv(s)	((LETR_ ## s) & 037)
-- 
	The Multiprocessor Turing Instruction Set Computer:  TISC-TISC
		Arthur David Olson	ado@elsie.nci.nih.gov
		ADO and Elsie are Ampex and Borden trademarks

henry@zoo.toronto.edu (Henry Spencer) (03/05/91)

In article <1172@intelisc.isc.intel.com> mojy@iSC.intel.com (Mojy Mirashrafi) writes:
>#define conv(s) 's'
>
>In ANSI C the "'" prevents evaluation of the enclosed characters.
>The above macro will expand to: 's'. Is there a way to escape the "'"s, in ANSI
>C?

No.
-- 
"But this *is* the simplified version   | Henry Spencer @ U of Toronto Zoology
for the general public."     -S. Harris |  henry@zoo.toronto.edu  utzoo!henry