[gnu.gcc.bug] gcc vs. convoluted macros

earle@SUN.COM (Greg Earle) (12/21/88)

Description:

The following file, which is condensed from X V11 R3's lib/X/Xlibint.h and
lib/X/XBackgnd.c (combination, and then removal of extraneous noise), shows
that when compiled with `-ansi -pedantic', gcc-cpp produces macro expansions
that are different (and cause gcc-cc1 to gag) from when `-traditional' is
invoked.  To be more to the point, there are two macros, SIZEOF(x) and
GetReqExtra(name, n, req), that are the cause.  GetReqExtra calls SIZEOF;
both are conditionally compiled for dpANS C or traditional K&R C.  When
using `-ansi -pedantic', the `#if defined(__STDC__)' conditional code is
compiled.  Inside `GetReqExtra', a macro, is a line that uses the
SIZEOF macro call, with an argument of `SIZEOF(*req)'.  This macro is the
one that, when expanded under `-ansi', doesn't match the same macro expansion
using `-traditional'.  As mentioned, this later causes gc-cc1 to complain
vociferously about the resultant code ...

Repeat-By:

	% gcc -v -E -fstrength-reduce -finline-functions -fcombine-regs \
		-ansi -pedantic dummy.c > dummy.ansi.i
	% gcc -v -E -fstrength-reduce -finline-functions -fcombine-regs \
		-traditional dummy.c > dummy.trad.i
	% diff -c dummy.trad.i dummy.ansi.i | more

	[ Note the differences, and incorrect `dummy.ansi.i' output ... ]
	[ I assume the `-fmumble' switches are irrelevant for this stage, ]
	[ but I heisted them from the makefile line ... ]

Can someone tell me if this is a gcc bug (gcc CPP, actually), or are the X
people's assumptions about string concatenation macros under dpANS C incorrect
(i.e., their 2 macro definitions are incorrect, when used with __STDC__ set) ??

Note that in the original X library code (lib/X/Xlibint.h), there are 2 other
macros, GetReq and GetResReq, which are almost identical, but neither of
them uses a pointer indirection (`SIZEOF(*req)') in the call to SIZEOF; I
                                         ^^^^
                                         ||||
got no compiler complaints from either of those macros being used/referenced.
Only the `*' inside the inner expansion seems to have caused havoc ...

Thanks in advance,

	- Greg Earle
	  Sun Los Angeles Consulting
	  earle@Sun.COM
	  poseur!earle@elroy.JPL.NASA.GOV

------------------  >8  Cut here - dummy.c - Cut here  8<  -----------------

/* $XConsortium: XBackgnd.c,v 11.7 88/09/06 16:04:08 jim Exp $ */
/* Copyright    Massachusetts Institute of Technology    1986	*/

#define SyncHandle() \
	if (dpy->synchandler) (*dpy->synchandler)(dpy)

/* a little bit of magic */
#define OneDataCard32(dpy,dstaddr,srcvar) \
  { dpy->bufptr -= 4; Data32 (dpy, (char *) &(srcvar), 4); }

/*
 * Definition of macro used to set constants for size of network structures;
 * machines with preprocessors that can't handle all of the sz_ symbols
 * can define this macro to be sizeof(x) if and only if their compiler doesn't
 * pad out structures (esp. the xTextElt structure which contains only two 
 * one-byte fields).  Network structures should always define sz_symbols.
 *
 * The sz_ prefix is used instead of something more descriptive so that the
 * symbols are no more than 32 characters long (which causes problems for some
 * compilers and preprocessors).
 */

#if defined(__STDC__) && !defined(UNIXCPP)
#define SIZEOF(x) sz_##x
#else
#define SIZEOF(x) sz_/**/x
#endif /* if ANSI C compiler else not */

/* GetReqExtra is the same as GetReq, but allocates "n" additional
   bytes after the request. "n" must be a multiple of 4!  */

#define WORD64ALIGN

#if defined(__STDC__) && !defined(UNIXCPP)
#define GetReqExtra(name, n, req) \
	WORD64ALIGN\
	if ((dpy->bufptr + SIZEOF(*req) + n) > dpy->bufmax)\
		_XFlush(dpy);\
	req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
	req->reqType = X_##name;\
	req->length = (SIZEOF(*req) + n)>>2;\
	dpy->bufptr += SIZEOF(*req) + n;\
	dpy->request++
#else
#define GetReqExtra(name, n, req) \
	WORD64ALIGN\
	if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) > dpy->bufmax)\
		_XFlush(dpy);\
	req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
	req->reqType = X_/**/name;\
	req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\
	dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\
	dpy->request++
#endif

XSetWindowBackground(dpy, w, pixel)
    register Display *dpy;
    Window w;
    unsigned long pixel;
{
    register xChangeWindowAttributesReq *req;

    LockDisplay(dpy);
    GetReqExtra (ChangeWindowAttributes, 4, req);
    req->window = w;
    req->valueMask = CWBackPixel;
    OneDataCard32 (dpy, NEXTPTR(req,xChangeWindowAttributesReq), pixel);
    UnlockDisplay(dpy);
    SyncHandle();
}

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

casey@gauss.llnl.gov (Casey Leedom) (12/22/88)

| From: tsunami!valley!poseur!earle@SUN.COM (Greg Earle)
| 
| Can someone tell me if this is a gcc bug (gcc CPP, actually), or are the X
| people's assumptions about string concatenation macros under dpANS C
| incorrect (i.e., their 2 macro definitions are incorrect, when used with
| __STDC__ set)??

  You should be following comp.windows.x (yes, I know, almost impossible
given its volume).  In any case, I've already posted a fix to X.V11R3 for
this problem.  The ANSI C side of the ``#ifdef __STDC__'' just wasn't
correct.  Just copy the code from the K&R side of the ifdef and replace
occurrences of "/**/" with "##".

Casey