12
votes

In the c++ standard, in [basic.lval]/11.6 says:

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:[...]

  • an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),[...]

This sentence is part of the strict-aliasing rule.

Does it allow us to alias through class member access?

class A{ //"casted to" aggregate
  int i;
  float g;
  };

int j=10;
int l = reinterpret_cast<A*>(&j)->i;

According to the standard, an object value is only accessed if the object is subject to lvalue-to-rvalue-conversion [conv.lval]/2.

[expr.ref] does not stipulate that the object-expression must refer to an object of that type, only that the glvalue must have class type (the object-expression is the expression at the left of the dot "."). Nevertheless there is a word that recurrently appears in sentence related to member access which may imply constraint on the program that I overlooked. For example [expr.ref]/4.1:

If E2 is a static data member and the type of E2 is T, then E1.E2 is an lvalue; the expression designates the named member of the class.

Could "designates" means that this member is within its lifetime and that I cannot use class member access to perfom aliasing? Or is it allowed by [basic.lval]/11.6?

1
I think that you need to analyze pointer-interconvertibility as well (&j is pointer-interconvertible to A*).geza
There is no "union or a class", since unions are classes. :)Lightness Races in Orbit
@geza: Quite the contrary - since the question is tagged language-lawyer, a careful reading is mandated, and a careful reader will note that "class" includes unions unless otherwise qualified.Lightness Races in Orbit
I have to think about it some more but I believe the case it was meant to support was the example I give in my strict aliasing answer here for that paragraph. Also see the paper I reference hereShafik Yaghmour
[basic.lval]/11.6 is a negative rule. "If you do X, the behavior is undefined" doesn't mean "if you don't do X, the behavior is defined". That's denying the antecedent.T.C.

1 Answers

1
votes

For non-static data member, the word is:

If E2 is a non-static data member and the type of E1 is “cq1 vq1 X”, and the type of E2 is “cq2 vq2 T”, the expression designates the named member of the object designated by the first expression.

Clearly the object designated by *reinterpret_cast<A*>(&j), i.e. j, has no member, so the behavior is undefined by omission.