[comp.lang.c] #define CTRL

sbs@valid.UUCP (Steven Brian McKechnie Sargent) (11/12/86)

> Thanks to everyone who replied to my question on whether an emulation of
> Reiser cpp's handling of
> 
> 	#define CTRL(x) ('x' & 037)
> 
> could be done in tentative proposed draft ANSI C.
...

*** REPLACE THIS LINE WITH YOUR MESSAGE ***

Guess I came into the discussion late.  What's wrong with the Reiser
treatment (it's always worked for me)?  Sounds like if it doesn't work
in ANSI, then ANSI is breaking its own "don't break working code" rule.

The cheapest way to an emulation of Reiser treatment might be by using
your old buddy, sed(1).  But if ANSI is standardizing that, too, forget
I said anything...


Love,

S.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (11/15/86)

In article <779@valid.UUCP> sbs@valid.UUCP (Steven Brian McKechnie Sargent) writes:
>Guess I came into the discussion late.  What's wrong with the Reiser
>treatment (it's always worked for me)?  Sounds like if it doesn't work
>in ANSI, then ANSI is breaking its own "don't break working code" rule.

Unfortunately the Reiser CPP didn't follow the rules in K&R,
whereas many other C compilers did.  No matter what was chosen
for this issue, some "working code" was going to break.

mouse@mcgill-vision.UUCP (11/23/86)

In article <5396@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <779@valid.UUCP> sbs@valid.UUCP (Steven Brian McKechnie Sargent) writes:
>> Guess I came into the discussion late.  What's wrong with the Reiser
>> treatment (it's always worked for me)?
> Unfortunately the Reiser CPP didn't follow the rules in K&R, whereas
> many other C compilers did.  No matter what was chosen for this
> issue, some "working code" was going to break.

I thought we'd been over this already.  K&R is not totally clear on
this point.  The index refers to two places for "preprocessor".  One of
them (page 86) states that
	Substitutions do not take place within quoted strings, so, for
	example, if YES is a defined name, there would be no
	substitution in printf("YES").
while the other (page 207) states that
	Text inside a string or character constant is not subject to
	replacement.

Neither one clearly forbids the Reiser cpp's interpretation, which
appears to be that formal parameters are expanded to their actuals
inside strings (and character constants) in the macro definition, but
that macros expansion itself *is* suppressed by such quotes.

The first quote does not address the issue; the second is open to
interpretation of "replacement" - is it just macro expansion (Reiser)
or also formal parameter substitution (the others)?

This is completely separate from the token concatenation issue, which
is another Reiser stumbling block.

Personally, I like the Reiser way of doing things in the first case; in
the second, I don't care (the ANSI way (## isn't it?) is just as good
as /**/ for gluing two tokens together).

Does ANSI C permit the analogue of the following?
	#define foobar baz
	#define x(y) foo/**/y
	x(bar) /* expands to baz */

					der Mouse

USA: {ihnp4,decvax,akgua,utzoo,etc}!utcsri!mcgill-vision!mouse
     think!mosart!mcgill-vision!mouse
Europe: mcvax!decvax!utcsri!mcgill-vision!mouse
ARPAnet: think!mosart!mcgill-vision!mouse@harvard.harvard.edu

[USA NSA food: terrorist, cryptography, DES, drugs, CIA, secret, decode]

minow@decvax.UUCP (Martin Minow) (11/25/86)

According to what I have heard, the *latest* version of the C spec.
(i.e., the one "available for public comment") will permit CTRL(X)
as follows:

You must provide a header file such as

	#define __A	001
	#define __B	002
	 (etc.)
	#define CTRL(X) __##X

Now, writing CTRL(A) expands to __A which is rescanned, recognized as
a macro, and expanded as 001.  There are a few control characters
that can't be expanded this way, such as <CTRL/@> (NUL).

It should be pointed out that a better approach to this specific problem
would be
	#define NUL	'\000'
	#define SOH	'\001'
	 (etc.)
	#define DEL	'\177'

Then, the control characters will be functionally described.

As I understand the spec, Reiser constructions map into ANSI C as follows:

		Reiser				ANSI
token pasting:	#define foo(a,b) a/**/b		a##b
string repl.:	#define foo(a) "xxx a yyy"	"xxx #a yyy"
char repl.:	#define foo(a) 'a'		Not provided to my knowledge.

It should be pointed out that the Reiser constructions are not provided
in many non-Unix compilers, nor have they been well-documented and
formally specified.

Disclaimer: I am speaking for myself; and am neither a spokesman for
the ANSI committee nor for Dec.

Martin Minow
decvax!minow

tim@ism780c.UUCP (Tim Smith) (12/02/86)

K&R clearly allow the Reiser cpp behaviour.  When they say macro
substitution does not occur in quoted strings, they must mean C
quoted strings ( since those are the only quoted strings that
have been defined ).

K&R state that cpp has a syntax independent from the rest of C.
Thus, there is no problem with something like

	#define foo(X) "this is X"

because "this is X" is not a quoted string.  It is a token string,
where token is defined by cpp.

Note that this is not portable, because cpp does not have to work
this way.  It is just not illegal for it to work this way.
-- 
emordnilapregnolanalpanama

Tim Smith       USENET: sdcrdcf!ism780c!tim   Compuserve: 72257,3706
                Delphi or GEnie: mnementh

gnu@hoptoad.uucp (John Gilmore) (12/02/86)

In article <103@decvax.UUCP>, minow@decvax.UUCP (Martin Minow) writes:
> As I understand the spec, Reiser constructions map into ANSI C as follows:
> 
> 		Reiser				ANSI
> token pasting:	#define foo(a,b) a/**/b		a##b
> string repl.:	#define foo(a) "xxx a yyy"	"xxx #a yyy"
> char repl.:	#define foo(a) 'a'		Not provided to my knowledge.
 
I believe this is wrong.  Try:

  string repl.:	#define foo(a) "xxx a yyy"	"xxx " #a " yyy"

There is still no way to do character replacement as in the Reiser CPP.
Some people have suggested
  char repl.:	#define foo(a) 'a'		(#a)[0]
but this is not a constant expression (as defined in section 3.4 of the
dpANS) so it cannot be used e.g. in a case label.  There was a kludge posted
that defined 52 new #define's (__a, __A, __b, __B, etc) but this is horrid
and does not support things like CTRL([).

It seems to me that the standards committee should support subscripting of
constant expressions (e.g. "["[0]) in constant expressions; that would
lay this issue to rest, finally.
-- 
John Gilmore  {sun,ptsfa,lll-crg,ihnp4}!hoptoad!gnu   jgilmore@lll-crg.arpa
    "I can't think of a better way for the War Dept to spend money than to
  subsidize the education of teenage system hackers by creating the Arpanet."

greg@utcsri.UUCP (Gregory Smith) (12/04/86)

In article <1375@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>Some people have suggested
>  char repl.:	#define foo(a) 'a'		(#a)[0]
>but this is not a constant expression (as defined in section 3.4 of the
>dpANS) so it cannot be used e.g. in a case label.

 ... and generates superfluous code wherever it *is* used.

>It seems to me that the standards committee should support subscripting of
>constant expressions (e.g. "["[0]) in constant expressions; that would
>lay this issue to rest, finally.

Is it that hard to write CTRL('X') rather than CTRL(X), that you want
to add a somewhat bizarre, difficult-to-support feature to a language
that already has more than its fair share of weird? "string"[2] is
supposed to mean *("string"+2), and the * operator obviously cannot be
allowed in constant expressions in general. So do you want to (a) allow
* to be applied to expressions which are addresses of bytes known
to be within constant strings (which do not necessarily exist at run-time!)
or (b) allow "string"[constant] (with the obvious restriction on constant)
and make a[b] differ from *(a+b) in this Yet Another Special Case?

Obviously (a) is silly, and (b) *could* be done, but you get my point.
If you have lots of code with CTRL([) etc, in it, why not write a lex
script to change it to the way it should have been written in the first
place?

-- 
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg
Have vAX, will hack...

levy@ttrdc.UUCP (Daniel R. Levy) (12/07/86)

In article <3721@utcsri.UUCP>, greg@utcsri.UUCP writes:
>>Some people have suggested
>>  char repl.:	#define foo(a) 'a'		(#a)[0]
>
>Is it that hard to write CTRL('X') rather than CTRL(X), that you want
>to add a somewhat bizarre, difficult-to-support feature to a language
>that already has more than its fair share of weird? ...
>If you have lots of code with CTRL([) etc, in it, why not write a lex
>script to change it to the way it should have been written in the first
>place?

Hey, not all of us are lex wizards.  Some people even have trouble with
ed(1) !  (Using ed or [more efficiently] sed, or even awk, is the reasonable
way to go for the average Joe Hacker; why use a cannon to kill a gopher?)