Linux and aliasing?

Linus Torvalds torvalds@transmeta.com
Wed Jun 30 15:43:00 GMT 1999


On Sun, 6 Jun 1999, Martin v. Loewis wrote:
> 
> Well, no. The 'normal' kind of cast is very common, and frequently
> used in the Linux kernel. For example, if a tty driver routine is
> called (e.g. drivers/char/rocket.c :-), it fetches driver_data and
> casts it to the device-specific type (i.e. (struct r_port *)).

No, but that "normal" kind of cast does not imply a immediate _derefernce_
(which is the only case where my new rule would kick in.

I agree that it is perfectly normal (and unavoidable) to do pointer
casting like

	struct specific_struct * mystruct;

	mystruct = (struct specific_struct *) data_struct->private_member;

and then use "mystruct". No argument. Linux (and tons of other programs) 
do this all over the place, exactly because you have "anonymous"  generic
pointers whose usage depends on who is the "owner" of that pointer. 

The other obvious case is things like

	mystruct = (struct specific_struct *) malloc();

which kind of falls under the same header.

But my proposal would only change cases where you actually dereference
such a cast without ever using the cast for anything else, which I
consider to be "dodgy" code unless the cast is there explicitly as a type
forcing conversion (that would imply no alias information). 

"Normal" use like the two examples above would (and should) NOT be
impacted by any proposal of mine.

> In these cases, people typically save the cast result in a variable
> instead of derefencing it, so they would not suffer from your
> anti-aliasing mechanism. These uses of casts are conforming C code:
> The driver put an r_port pointer into driver_data earlier on.

Indeed. 

Maybe people worried that those kinds of uses would be changed by the
change I proposed. They wouldn't. I would be upset if they were, and I
would understand that others would be upset if they were. That would imply
a real lack of alias information. 


> > 	grep '\*(.*\* *)' */*.c
> 
> It is actually the other casts that the Linux contributors need to
> worry about. Alias problems are very hard to find (as you pointed
> out), and somebody will have to go over the complete kernel source and
> investigate every single cast - if you ever plan to turn-on
> -fstrict-aliasing.

I agree. We need to be careful. But my proposal has two advantages: 

 - it takes care of the obvious cases (not just for the kernel, but for a
   ton of other programs), and has a nice "do what I mean" kind of
   semantic for all the cases I found.

   In fact, try the above "grep" on the gcc sources themselves. You'll see
   code like

	*((EMUSHORT *) r) = w[3];
	*((EMUSHORT *) r + 1) = w[2];
	*((EMUSHORT *) r + 2) = w[1];
	*((EMUSHORT *) r + 3) = w[0];

   as part of the "PUT_REAL()" macro, and then you'll see usage like

	PUT_REAL (g, &r);
	return (r);

   which is ILLEGAL because strict-aliasing might decide that "r" could be
   loaded before PUT_REAL hass changed it, because "EMUSHORT" cannot alias
   with "double". But it's _exactly_ the kind of code that my proposal
   would just automatically do the right thing for. 

   It's "Do what I mean!"

   Do you see? Gcc _itself_ wouldn't mind having the feature I propose.
   Does that make people more likely to realize why I'm proposing it? 
   Maybe people still thought that this was something kernel-specific? 

 - The other advantage is that when going through the other cases more
   carefully, my proposal would make it trivial to fix them up by just
   adding a cast. I consider this part of the proposal to be a smaller
   advantage, though.

Oh, well. I don't seem to be convincing people who have all dug themselves
into their own view.

		Linus



More information about the Gcc mailing list