This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: glibc-19980524: invalid use of GCC's `transparent union'


Hi!

>>>>> Roland McGrath writes:

 RM> That is not correct.  The entire purpose of `transparent_union'
 RM> is for this hack, and the purpose of the hack is exactly that
 RM> such redeclarations will work without an error.

I disagree, and believe that it is a good idea to give an error for
such redeclarations.

 RM> If the boneheads broke this in GCC again, either it has to get
 RM> fixed or we have to just punt this feature entirely and break all
 RM> programs that use `union wait'.

It may very well be that `transparent_union' does not have the same
semantics as when it was originally implemented, but I believe it is
both simpler than the original semantics, and just as functional.

As far as I can tell, you are complaining because it is not possible
to do:

typedef union
  {
    union wait *__uptr;
    int *__iptr;
  } __WAIT_STATUS __attribute__ ((__transparent_union__));

/* Declaration */
extern __pid_t __wait __P ((__WAIT_STATUS __stat_loc));

/* Definition */
__pid_t
__wait (int *__stat_loc)
/* GCC complains about differing types in __wait's signature */
{
  /* some expression involving an int *. */
  return *__stat_loc = 0;
}


Now, I suggest that the above sequence of code is in bad style.  The
definition of __wait should use __WAIT_STATUS as its argument type.
The GCC implementors seem to agree with me.

So, my patch changes libc to do something like the following, in line
with the example in the GCC manual (*Note (gcc)Type Attributes::):

[omitting some hairy #if blocks...]
#  define __WAIT_PTR(stat_loc)	((stat_loc).__iptr)
[...]
/* Definition */
__pid_t
__wait (__WAIT_STATUS __stat_loc)
{
  return *__WAIT_PTR (stat_loc) = 0;
}


How many packages both #include libc's <sys/wait.h> *and* define their
own __wait function.  I would assert that there are no such packages,
except libc itself.  Even if there *are* packages who do this, then it
is certainly no inconvenience for them to use the macros I have
supplied.

But, that's only half the story (otherwise, there would be no reason
to use a transparent union at all).  The macros I define are fine for
smart implementors of wait, but what about naive users of wait?

The transparent_union allows them to do:

{
  union wait wu;
  int wi;
  float wf;
  wait (&wu);
  wait (&wi);
  wait (&wf);
}

causing GCC to warn about typecasts only on the last `wait' call, even
though to the naked eye it appears as if at least one of the other two
`wait' calls needs a typecast.

I believe that this behaviour is exactly the intention of the original
`transparent_union' flag, and that allowing different function
prototypes is both confusing and unnecessary, and therefore
undesirable.

So, please have another look at my patch.  It implements the above
semantics, and makes them obvious to a reader of the libc code.

Thanks,

-- 
Gordon Matzigkeit   \ Proudly running pieces of the GNU operating system.
gord@profitpress.com \ Jacques Cousteau loved programming in assembler.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]