I had read the following rule and I've been trying to write an example, which reflects one. The rule is from 3.8/5 N3797:
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a pointer refers to allocated storage (3.7.4.2), and using the pointer as if the pointer were of type
void*
is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below. The program has undefined behavior if:[...]
— the pointer is used to access a non-static data member or call a non-static member function of the object, or
[...]
The example I've written for:
#include <iostream>
#include <typeinfo>
using std::cout;
using std::endl;
struct A
{
int b = 5;
static const int a = 5;
};
int main()
{
A *p = (A*)0xa31a3442;
cout << p -> a; //1, Well-fromed, there is no compile-time error
cout << p -> b; //2, Segmentation fault is producing
}
Is it true that in the case //1
is well-formed and doesn't cause any UB
, but //2
produced segmentation fault, which is UB
?