Я прочитал следующее правило, и я пытался написать пример, который отражает его. Правило от 3.8/5 N3797:
До начала жизни объекта, но после хранения который объект будет занимать, был выделен или, после жизни объекта и до хранения, который объект занято повторно или освобождено, любой указатель, который ссылается на хранилище местоположение, в котором объект будет находиться или находится, может использоваться, но только ограниченным образом. Для объекта, находящегося в стадии строительства или уничтожения, см. 12,7. В противном случае, такой указатель относится к выделенному хранилищу (3.7.4.2) и с использованием указателя, как если бы указатель имел тип
void*
, был корректно определен. Разрешено использование такого указателя, но полученное значение lvalue может использоваться только ограниченным образом, как описано ниже. Программа имеет undefined поведение, если:[...]
- указатель используется для доступа к нестатическому элементу данных или вызова нестатическая функция-член объекта или
[...]
Пример, который я написал для:
#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
}
Верно ли, что в случае //1
хорошо сформировано и не вызывает никаких UB
, но //2
возникла ошибка сегментации, которая равна UB
?