[comp.lang.c] ANSIfication of #define ctl

doug@feedme.UUCP (Doug Salot) (06/11/88)

No doubt this has been hashed out before (if so, email from the
solution poster would be appreciated), but what is the accepted
method of porting macro substitution within character constants
to dpANS-conforming compilers?

A method which immediately suggests itself (to a warped mind) for
the control character macro in the subject heading is

	#define ctl(X) (#X [0] & 0x1f)

which does the trick, but has (at least) two problems.  First,
and less worrisome for q&d ports, is that a couple of bytes are
added to the string table for each invocation.  Worse is the
sad fact that most compilers treat "xyz"[0] as a non-constant
runtime expression and disallow the macro expansion in case
statements (where I happen to need it).

Question to satisfy curiosity: is it obvious that a constant string
indexed by a constant isn't a constant?  Clearly, this is an exceptional
case of string indexing, but it should be safe to evaluate the expression
to a constant character at compile-time, shouldn't it?

More importantly, is there a way to do what I want to do without
changing the macro invocations?
-- 
Doug Salot || doug@feedme.UUCP || {trwrb,hplabs}!felix!dhw68k!feedme!doug
Feedme Microsystems:Inventors of the Snarf->Grok->Munge Development Cycle

gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/13/88)

In article <37@feedme.UUCP> doug@feedme.UUCP (Doug Salot) writes:
>More importantly, is there a way to do what I want to do without
>changing the macro invocations?

There isn't one.  Change the macro invocations.

ado@elsie.UUCP (Arthur David Olson) (06/13/88)

> > More importantly, is there a way to do what I want to do without
> > changing the macro invocations?

> There isn't one.  Change the macro invocations.

For all practical purposes, change the header file to read

	#define LETR_A	'A'
	#define LETR_B	'B'
	/* ... */
	#define LETR_z	'z'

	#define CTRL(c)	((LETR_ ## c) & 037)

which will handle "calls" of CTRL with alphabetic arguments--the bulk of such
calls--correctly.  You then need only change the header file and any
non-alphabetic invocations (which the compiler politely lets you know about).
-- 
	ado@ncifcrf.gov			ADO is a trademark of Ampex.

karl@haddock.ISC.COM (Karl Heuer) (06/13/88)

In article <8079@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn) writes:
>In article <37@feedme.UUCP> doug@feedme.UUCP (Doug Salot) writes:
>>More importantly, is there a way to do what I want to do without
>>changing the macro invocations?
>
>There isn't one.  Change the macro invocations.

And don't wait until you get an ANSI compiler.  Change them *now*.

(It's been said before, but it bears repeating.)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

flaps@dgp.toronto.edu (Alan J Rosenthal) (06/15/88)

In article <37@feedme.UUCP> doug@feedme.UUCP (Doug Salot) writes:
>	#define ctl(X) (#X [0] & 0x1f)
>does the trick, but has (at least) two problems.  First, and less
>worrisome for q&d ports, is that a couple of bytes are added to the
>string table for each invocation.

No need for the compiler to do this.  That's not to say that I would
be surprised if one (or most) did.

>Worse is the sad fact that most compilers treat "xyz"[0] as a
>non-constant runtime expression and disallow the macro expansion in
>case statements...
>is it obvious that a constant string indexed by a constant isn't a
>constant?

I believe you are confusing constants in the sense that their value is
obvious to the reader or to a smart compiler, and constants in the
sense of a constant-expression in the C language definition.  "xyz"[0]
is the first and not the second.  Or, in other words, "xyz"[0] is a
runtime expression but not a constant-expression.

I would expect the strings
	f("xyz"[0]);
and
	f('x');
to compile identically; that is, to f(120);.  However, the second one
uses a constant-expression and the first does not.

ajr

--
- Any questions?
- Well, I thought I had some questions, but they turned out to be a trigraph.