[comp.lang.c] cpp of Sun's Unix version 3.2.

yoshiki@gama.UUCP (04/22/87)

I have a trouble on cpp of Sun's Unix version 3.2.  I tryed to expand a text
like the following.


# define Macro(f) f

Macro(Func(a,
# ifdef B
     b,
# endif
     c))


I want to get Func(a, c) if B is not defined.  It is, however, expanded by
the cpp to


# 1 "" 


 Func(a, # ifdef B      b, # endif      c)
# 8 "" 


I can get what I want by other cpps (4.2BSD on VAX and Sequent).  Is this a
bug of the cpp, or dependent on implementation?

Sorry if this has been discussed before.

-----------------------------------------------------------------------------

Yoshiki WATANABE
University of Tsukuba

JUNET Address:
	yoshiki@is.tsukuba.junet
UUCP:
	..!nttlab!gama!yoshiki
	..!mcvax!kddlab!nttlab!gama!yoshiki
Telephone:
	0298-53-5051

guy%gorodish@Sun.COM (Guy Harris) (05/01/87)

> I can get what I want by other cpps (4.2BSD on VAX and Sequent).  Is this a
> bug of the cpp, or dependent on implementation?

Well, if I read my ANSI C draft right, it's dependent on the implementation:

	3.8.3 Macro replacement

	   ...If there are sequences of preprocessing tokens in the list of
	arguments that would otherwise act as preprocessing
	directives, the behavior is undefined.

K&R is less clear on this, but I read it as indicating that
the text between the opening "(" and closing ")" of a macro call is
to be treated as a comma-separated list of tokens (and white space
between the tokens):

	12.1 Token replacement

	   ...Subsequent instances of the first identifier followed
	by a "(", a sequence of tokens delimited by commas, and a ")"
	are replaced by the token string in the definition.  Each
	occurrence of an identifier mentioned in the formal parameter
	list of the definition is replaced by the corresponding token
	string from the call.  The actual arguments in the call are
	token strings separated by commas; however commas in quoted
	strings or protected by parentheses do not separate
	arguments.

And the white space between the tokens is not included in the
replacement:

	2. Lexical conventions

	   ...Blanks, tabs, newlines, and comments (collective,
	``white space'') as described below are ignore except as they
	serve to separate tokens.

(Of course, two sentences beyond the ones quoted from "12.1 Token
replacement" it says "Text inside a string or a character constant is
not subject to replacement", and we all know how seriously Reiser
took that exhortation....)

You certainly can't get what you want with *all* other "cpp"s.  The
SunOS 3.2 "cpp" is derived from the System V Release 2 "cpp", which
works the same way.

david@sun.uucp (David DiGiacomo) (05/01/87)

In article <641@gama.is.tsukuba.junet> yoshiki@gama.is.tsukuba.junet 
(Yoshiki Watanabe) writes:

>I have a trouble on cpp of Sun's Unix version 3.2.  I tryed to expand a text
>like the following.
>
># define Macro(f) f
>
>Macro(Func(a,
># ifdef B
>     b,
># endif
>     c))
>
>I want to get Func(a, c) if B is not defined...
>
>I can get what I want by other cpps (4.2BSD on VAX and Sequent).  Is this a
>bug of the cpp, or dependent on implementation?

As Guy has pointed out, it is implementation dependent.  However, there
is an easy way to get the result you want out of the Sun/SystemV cpp if
you don't mind defining an extra macro:

#define Macro(f) f

#ifdef B
#define IFB(x) x,
#else
#define	IFB(x)
#endif

Macro(Func(a, IFB(b) c)

-- 
David DiGiacomo, Sun Microsystems, Mt. View, CA  sun!david david@sun.com