[net.lang.c++] System V preprocessor problem with <generic.h>

jon@cit-vax.Caltech.Edu (Jonathan P. Leech) (04/25/86)

Expires:
Sender:
Followup-To:

Organization : California Institute of Technology
Keywords:

    The <generic.h> header file defines constructs of the form

	#define name2(a,b) a\
	b
	#define name3(a,b,c) a\
	b\
	c

    with the intent of producing

	name2(a,b) => ab    etc.

    unfortunately the  System  V  cpp  (at  least  the	HP  and  ELXSI
versions) instead produces

	name2(a,b) => a b

    this is a serious problem in  every  case  I  can  find  of  these
constructs  being  used  -  specifically  <vector.h>.  I  don't  think
there's any way to produce this behavior with the System V cpp.

    Combined with the problem of '//' comments	not  being  elided  by
cpp, I think C++ should come with its own  preprocessor  (or  have  it
integrated into cfront).

    Additional	amusement:  try  running  cpp  with  input  from  your
keyboard and #include <generic.h>. Note that it now takes > 1  EOF  to
get out of cpp!
-- 
    Jon Leech (jon@csvax.caltech.edu || ...seismo!cit-vax!jon)
    Caltech Computer Science Graphics Group
    __@/

guy@sun.UUCP (04/29/86)

> Try this fix for system V cpp:
> 
> 	#define name2(a,b)	a/**/b
> 	#define name3(a,b,c)	a/**/b/**/c
> 
> This works because the system V cpp strips the comments from the input.

So do earlier versions of Reiser's "cpp"; this is the "canonical" way of
concatenating two arguments to a macro, and is heavily used in 4BSD.  It
has, however, two problems:

	1) If you run your code through "lint", it won't work - "cpp"
	   is run by "lint" with the "-C" flag, which tells it not to
	   strip comments (for obvious reasons).

	2) It is not a guaranteed property of the C language, but a
	   quirk of the implementation, so it will not work in
	   general.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.arpa

kwh@bentley.UUCP (KW Heuer) (04/30/86)

In article <3597@sun.uucp> sun!guy (Guy Harris) writes:
>> 	#define name2(a,b)	a/**/b
>It has, however, two problems:
>
>	1) If you run your code through "lint", it won't work

I tried this example with "cpp -C" and it worked fine.  I'd guess that
cpp strips all comments in preprocessor directives reg Cdless of "-C".

>	2) It is not a guaranteed property of the C language, but a
>	   quirk of the implementation, so it will not work in
>	   general.

Agreed.  Any application that depends on being able to do this is treading
on thin ice.

Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint

rbm@sfsup.UUCP (R.B.Murray) (05/02/86)

> In article <3597@sun.uucp> sun!guy (Guy Harris) writes:
> >> 	#define name2(a,b)	a/**/b
> >It has, however, two problems:
> >
> >	1) If you run your code through "lint", it won't work
> 
> I tried this example with "cpp -C" and it worked fine.  I'd guess that
> cpp strips all comments in preprocessor directives regardless of "-C".
> 
> >	2) It is not a guaranteed property of the C language, but a
> >	   quirk of the implementation, so it will not work in
> >	   general.
> 
> Agreed.  Any application that depends on being able to do this is treading
> on thin ice.
> 
> Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint

Agreed also.  I also don't believe there 
is a standard and portable way to do this at the present time.
However, the current draft of the ANSI C standard has an
"offical" way to do this:

#define  name2(a,b)	a##b

The "##" is a (new) concatenation operator.
Of course, this is only useful once a standard exists and everybody
conforms to it.  Also, ANSI may change their minds on the syntax of
this feature.

Rob Murray AT&T
Summit, NJ