Почему странное поведение с приведением указателя обратно к исходному классу?

Предположим, что в моем коде я должен сохранить void * в качестве элемента данных и привести его обратно к типу исходный указатель class при необходимости. Чтобы проверить его надежность, я написал тестовую программу (linux ubuntu 4.4.1 g ++ -04 -Wall) , и я был шокирован, увидев ее поведение.

struct A
{
  int i;
  static int c;
  A () : i(c++) { cout<<"A() : i("<i = "<<((A*)p)->i<i = "<<((A*)p)->i<i = "<<((A*)p)->i<

Это всего лишь тестовая программа; на самом деле для моего случая обязательно сохранить любой указатель как void * , а затем преобразовать его обратно в фактический указатель (с помощью шаблона ]). Так что не будем беспокоиться об этой части. Вывод приведенного выше кода :

p->i = 0
p->i = 0 // ?? why not 1
p->i = 1

Однако, если вы измените void * p; на A * p ; он дает ожидаемое поведение . ПОЧЕМУ?

Другой вопрос, мне не сойдет с рук (A * &) , иначе я не могу использовать оператор ++ ; но также выдает предупреждение поскольку, разыменование указателя с перфорированными типами нарушает правила строгого алиасинга . Есть ли какой-нибудь достойный способ обойти предупреждение?

6
задан Community 23 May 2017 в 12:12
поделиться