[comp.std.c] Macro sustitution inside quotes

boyd@necisa.ho.necisa.oz (Boyd Roberts) (04/10/90)

In article <12534@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>
>Twisted?  It is about as straightforward as anything else about C.  I
>find string catenation very handy in cases where the source code is
>highly indented or the string is particularly long.

If I need a long string, I'll use a long string.

String concatenation and the # operator just isn't keeping with the
style of the language.  The # operators are particularily revolting:

    #define string(s)	# s

It is not obvious or intuitive what kind of expansion occurs.  Whereas:

    #define string(s)	"s"

evaluates in the way you would expect.

Apart from that, # operators break things.  Why weren't the Reiser
conventions just formalised?  Oh no, that would be too easy.

There is no basis in the language for string concatenation.  It is
at odds with the lexical and syntactic structure of the language.

With operators:

    a _op_ b

Not:

    a b

for some defined operation.

Function calls:

    f(a, b)

Not:

    f(a b)

Initialisation:

    int	a[2]	= { 1, 2 };

Not:

    int	a[2]	= { 1 2 };

Etc etc.

The preprocessor and language weren't broken.  But they got `fixed' anyway.


Boyd Roberts			boyd@necisa.ho.necisa.oz.au

``When the going gets wierd, the weird turn pro...''

jenkins@jpl-devvax.JPL.NASA.GOV (Steve Jenkins) (04/10/90)

In article <1284@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes:
>Why weren't the Reiser
>conventions just formalised?  Oh no, that would be too easy.

It's even easier to read in K&R1 that at least one Reiser convention
was dead wrong.

>The preprocessor and language weren't broken.  But they got `fixed' anyway.

Guess again.

-- 
Steve Jenkins N6UNI			jenkins@jpl-devvax.jpl.nasa.gov
Caltech/Jet Propulsion Laboratory	(818) 354-0162

guy@auspex.auspex.com (Guy Harris) (04/11/90)

>Whereas:
>
>    #define string(s)	"s"
>
>evaluates in the way you would expect.

In other words, it evaluates to the string

	"s"

i.e., a one-character string containing the letter "s"?  That's what a
reader of K&R would expect; too bad their expectations are dashed on
systems like UNIX that use the Reiser preprocessor.  (Reference: K&R I,
Appendix A "C Reference Manual", p. 207: "Text inside a string or a
character constant is not subject to replacement.")

henry@utzoo.uucp (Henry Spencer) (04/11/90)

In article <1284@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes:
>    #define string(s)	# s
>It is not obvious or intuitive what kind of expansion occurs.  Whereas:
>    #define string(s)	"s"
>evaluates in the way you would expect.

Uh, in the way *who* would expect?  I, for one, certainly don't expect
the preprocessing phase to look for "identifiers" inside strings!
Especially since K&R1 outlawed substitution into strings, albeit with
slightly ambiguous language.

>Apart from that, # operators break things.  Why weren't the Reiser
>conventions just formalised?  Oh no, that would be too easy.

The Reiser conventions are almost impossible to implement in many C
compilers, especially the ones that tokenize at preprocessor time
rather than doing preprocessor operations on raw text.  They were never
documented, and in fact they openly violate K&R1, which many non-Unix
C implementors used as the basis for their compilers.  There is no
shortage of existing code which relies on the Reiser botches *not*
being done.  They were not in any sense a de facto standard -- they
were undocumented quirks of the Unix preprocessor.
-- 
Apollo @ 8yrs: one small step.|     Henry Spencer at U of Toronto Zoology
Space station @ 8yrs:        .| uunet!attcan!utzoo!henry henry@zoo.toronto.edu

gwyn@smoke.BRL.MIL (Doug Gwyn) (04/11/90)

In article <1284@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes:
>    #define string(s)	# s
>It is not obvious or intuitive what kind of expansion occurs.  Whereas:
>    #define string(s)	"s"
>evaluates in the way you would expect.

According to K&R, the macro argument is not substituted inside the
string literal.

>Apart from that, # operators break things.  Why weren't the Reiser
>conventions just formalised?  Oh no, that would be too easy.

Because the Reiser CPP was in violation of the closest thing to an
accepted standard for the C language prior to ANSI C.  Many
independent implementations had obeyed the rules, and there was
code that depended on that.  It would have been really hard to justify
standardizing the erroneous behavior of the Reiser cpp implementation.
(Making Boyd Roberts happy was not a primary goal of X3J11.)

>There is no basis in the language for string concatenation.  It is
>at odds with the lexical and syntactic structure of the language.

It's now part of the language.

>With operators:
>    a _op_ b
>Not:
>    a b
>for some defined operation.

C has always had unary operators.  Stringization is a unary operator.
For technical reasons it fit best in the preprocessing phase.

While an explicit catenation operator COULD have been introduced, it
would then have been a run-time operation.  The intention was for
concatenation of string literals to be a compile-time operation.

>The preprocessor and language weren't broken.  But they got `fixed' anyway.

The Reiser preprocessor was badly broken, and the C language had
no way to perform these highly desirable operations, which is why
we added support for them in the ANSI standard.

diamond@tkou02.enet.dec.com (diamond@tkovoa) (04/11/90)

In article <1284@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes:

>>Why weren't the Reiser
>>conventions just formalised?  Oh no, that would be too easy.

In article <7722@jpl-devvax.JPL.NASA.GOV> jenkins@jpl-devvax.JPL.NASA.GOV (Steve Jenkins) writes:

>It's even easier to read in K&R1 that at least one Reiser convention
>was dead wrong.

True.  But Reiser's inventions were easier to understand, easier to use,
easier to implement, and less surprising than ANSI's inventions.  ANSI
should have done less work.

-- 
Norman Diamond, Nihon DEC     diamond@tkou02.enet.dec.com
This_blank_intentionally_left_underlined________________________________________

seanf@sco.COM (Sean Fagan) (04/11/90)

In article <1284@necisa.ho.necisa.oz> boyd@necisa.ho.necisa.oz (Boyd Roberts) writes:
>String concatenation and the # operator just isn't keeping with the
>style of the language.  The # operators are particularily revolting:
>
>    #define string(s)	# s
>
>It is not obvious or intuitive what kind of expansion occurs.  

I have to agree with you there.  I get confused about # and ## all the time,
which, considering what I do for a living, means it's not going to be fun
for everyone who is relearning C (I suspect people learning it from scratch
will not have this problem).

>Whereas:
>
>    #define string(s)	"s"
>
>evaluates in the way you would expect.

Yes.  On "my" compiler, it certainly does.  It expands as "s", no matter
what is passed into string.

>Apart from that, # operators break things.  

Uhm, what does it break, pray tell?  I know of no valid construct in C which
allows '#' (except preprocessor directives, and I have never seen anyone use
a p.p. directive *inside* a macro).

>Why weren't the Reiser
>conventions just formalised?  Oh no, that would be too easy.

Because some of us think it is really stupid, disgusting, etc.  Perhaps you
also want to check for '*/' inside of quotes?  Or how about non-paramater
macros?  (Checking for parameter expansions *only* was more difficult in my
implementation, albeit not much.)

>There is no basis in the language for string concatenation.  It is
>at odds with the lexical and syntactic structure of the language.

Maybe.  However, I happen to like it.  It is easy to remember, and breaks
nothing.

>Function calls:
>
>    f(a, b)
         ^
>Not:
>
>    f(a b)

Uhm, actually, it did.  Note that the space is optional in C, both K&R, 
Reiser, and ANSI.

>The preprocessor and language weren't broken.  But they got `fixed' anyway.

You pointed it out yourself.  The "Reiser" conventions.  Other people were
*not* doing it that way, and it was not used in K&R.  The preprocessor was
lacking, in terms of stringizing (although I really really want a
characterizer 8-)), and concatenating strings is a truly *marvelous*
thing to do.  There is one program in AT&T's distribution which has a 7k
long string.  All but the first line begins at the first character, and is
really difficult to read.  Using string concatenation, it ends up being
*much* easier, and is very difficult to confuse it with the rest of the
program (consider:

	char *p = "to declare a variable of type int in C, use \
	int a; \
	Simple, no?";

versus

	char *p = "to declare a variable of type in in C, use "
		"int a; "
		"Simple, no?";

I prefer the latter.  If you don't, maybe you should stick with fortran?)

-- 
-----------------+
Sean Eric Fagan  | "It's a pity the universe doesn't use [a] segmented 
seanf@sco.COM    |  architecture with a protected mode."
uunet!sco!seanf  |         -- Rich Cook, _Wizard's Bane_
(408) 458-1422   | Any opinions expressed are my own, not my employers'.

jfh@rpp386.cactus.org (John F. Haugh II) (04/11/90)

In article <1457@tkou02.enet.dec.com> diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
>True.  But Reiser's inventions were easier to understand, easier to use,
>easier to implement, and less surprising than ANSI's inventions.  ANSI
>should have done less work.

Had Reiser never violated the constraints in K&R1 against macro expansion
in strings and character constants, there would be no discussion.  All
ANSI did in this case was reitterate what K&R1 says already.

This is one area [ other than their work in token pasting ] where ANSI
did not "invent" anything.
-- 
John F. Haugh II                             UUCP: ...!cs.utexas.edu!rpp386!jfh
Ma Bell: (512) 832-8832                           Domain: jfh@rpp386.cactus.org

richard@aiai.ed.ac.uk (Richard Tobin) (04/11/90)

In article <3155@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
> (Reference: K&R I, Appendix A "C Reference Manual", p. 207: "Text inside
> a string or a character constant is not subject to replacement.")

I have heard it suggested that the Reiser behaviour arises from the
misinterpretation of this sentence as meaning that macro calls are not
expanded when they appear in strings.  It's fairly clear that this is
a *mis*interpretation since the preceding text refers to macro
expansion as replacement of *identifiers*, which obviously don't
occur in strings.

-- Richard

-- 
Richard Tobin,                       JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,           ARPA:  R.Tobin%uk.ac.ed@nsfnet-relay.ac.uk
Edinburgh University.                UUCP:  ...!ukc!ed.ac.uk!R.Tobin

jenkins@jpl-devvax.JPL.NASA.GOV (Steve Jenkins) (04/11/90)

In article <1457@tkou02.enet.dec.com> diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
>[....]  But Reiser's inventions were easier to understand, easier to use,
>easier to implement, and less surprising than ANSI's inventions.  ANSI
>should have done less work.

If the criterion for language design were always "easier to
understand, easier to use, easier to implement, and less surprising",
we'd all be programming in BASIC.

The point is still that Reiser was wrong and ANSI is right.  Had ANSI
adopted the Reiser behavior, perfectly correct (by K&R1) C programs
would have become broken.  I can't see the justification for that.

I guess we agree to disagree.

-- 
Steve Jenkins N6UNI			jenkins@jpl-devvax.jpl.nasa.gov
Caltech/Jet Propulsion Laboratory	(818) 354-0162

henry@utzoo.uucp (Henry Spencer) (04/11/90)

In article <1457@tkou02.enet.dec.com> diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
>...Reiser's inventions were easier to understand, easier to use,
>easier to implement, and less surprising than ANSI's inventions...

The first and last are very much matters of opinion, and many people
disagree with you.  The "easier to implement" part depends on which
compiler you are implementing it in; I assure you that the Reiserisms
are a lot *harder* to implement in compilers which tokenize immediately.
-- 
With features like this,      |     Henry Spencer at U of Toronto Zoology
who needs bugs?               | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

scjones@sdrc.UUCP (Larry Jones) (04/12/90)

In article <1457@tkou02.enet.dec.com>, diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
> Reiser's inventions were easier to understand, easier to use,
> easier to implement, and less surprising than ANSI's inventions.  ANSI
> should have done less work.

Well, yes, if you're already familiar with them!  I find it very
hard to believe that any who wasn't familiar with these [ bugs |
features ] wouldn't be very surprised to run across them and have
a hard time understanding them.  Nor can I believe that either is
easier to use or implement, although I will grant you that using
# and ## is pretty disgusting.

"What?!?  The preprocessor looks INSIDE STRINGS?  But it doesn't
replace macros inside strings.  Oh, just parameters?  Huh."

"What?!?  The preprocessor makes comments completely disappear?
But I thought that comments were supposed to be the same as
blanks!  You mean that if I stick a comment in without putting
spaces around it the things on each side get pasted together?
Ick!"
----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                      scjones@SDRC.UU.NET
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
"You know how Einstein got bad grades as a kid?  Well MINE are even WORSE!"
-Calvin