On Fri, Jun 26, 2015 at 5:32 PM, Davin McCall <dav...@davmac.org> wrote: > On 26/06/15 15:29, Erik Faye-Lund wrote: > > On Fri, Jun 26, 2015 at 4:16 PM, Davin McCall <dav...@davmac.org> wrote: > > On 26/06/15 14:53, Erik Faye-Lund wrote: > > On Fri, Jun 26, 2015 at 3:05 PM, Davin McCall <dav...@davmac.org> wrote: > > [...] > > It is. In fact, it's not even possible to violate strict-aliasing > without doing at least two operations. You cannot validate operations > in a vacuum, because that's not how strict-aliasing is defined. > > Any pointer dereference can violate strict aliasing - that's one operation. > If you mean that it's first necessary to construct a pointer value in such a > way that de-referencing it will be an aliasing violation, then yes, I agree > with this statement. > > Yes, I mean exactly the latter. You cannot look at one operation in > isolation, you need to look at the whole program. > > As I have pointed out, with your reading, > pretty much any pointer cast constitutes an aliasing violation. > > No, only those violating the strict aliasing rules I posted before. > > ... which would only allow changing const/volatile qualifiers, not the > pointed-to type. > > You can change the pointed to type in terms of signedness, you can > cast it to a compatible type, you can cast a void-pointer or > char-pointer to any type. But you need to make sure you don't violate > the strict-aliasing rules in some other way while doing the latter. > > > A cast by itself simply can't cause an aliasing violation, because it > doesn't "access the stored value of an object". The aliasing violation has > to happen either before or after the cast. > > > Aliasing *is* hard. But let's not go shopping for that reason. > > > Agreed, though maybe this is getting to the point where we should take it > off-list. > > > Your reading also disallows casting an 'int' variable to type 'long', > because that isn't on the list. > > The strict aliasing rules specify what kind of reference you can use to > access an object of a particular type. They say nothing about how that > reference is obtained. > > Which means that it applies regardless of how you obtain it. > > Yes. > > "If a program attempts to access the stored value of an object through > a glvalue of other than one of the following types the behavior is > undefined" > > It says "if a *program* attempts", not "if a *statement* attempts" or > "if an *opreation* attempts". This is a whole-program deal, not > limited to one operation in isolation. > > The key part of the wording is "through a glvalue": > > "If a program attempts to access the stored value of an object *through > a glvalue* of other than one of the following types ..." > > This is exactly what makes this invalid AFAICT, see below. > > Going back to the original example: > > return ((const struct exec_node **)n)[0] > > The glvalue used to access the object in n is n itself. (I do not think that > '(const struct exec_node **)n' is even a glvalue). > > Bur 'n' *is* an lvalue, which also makes it an glvalue (for reference, > a glvalue is a "generalized lvalue", which means that it's either an > lvalue or an xvalue). > > > 'n' is an lvalue, yes. Its type is 'struct exec node *' (disregarding const > for now). So when the object that is in 'n' is accessed, it is accessed via > an appropriate type. The cast does not itself cause an access and the cast > expression as a whole is not an lvalue. > > The fact that n is an lvalue does not mean that it can appear anywhere on > the left-hand-side of an assignment expression; the entire left-hand-side > expression must be an lvalue. So when you then say: > > You can write stuff like: > > "((const struct exec_node **)n)[0] = foo;" > > ...so it can appear on the left-hand side of an assignment, which > makes it an lvalue. > > > ... it is not quite correct. The fact that you could put n itself on the > left-hand side of an assignment (eg "n = NULL") makes it an lvalue, not the > fact that it appears *within* a larger expression that is on the left-hand > side of an assignment. > > In fact, the whole of '((const struct exec_node **)n)[0]' is an lvalue. > However, '(const struct exec_node **)n' is not an lvalue. > > I do believe you have some sort of misconception, and I'm trying hard to > understand the nature of this misconception.
I think Francisco managed to clear it up. Yeah, you're right, I had the misconception that "(const struct exec_node **)n" was an lvalue. But it's not, and that makes my whole line of arguing invalid. So yeah, I no longer think the proposed code violates the strict-aliasing rules. Sorry for the noise. _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev