Предположим, что в моем коде я должен сохранить 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 * &)
, иначе я не могу использовать оператор ++
; но также выдает предупреждение поскольку, разыменование указателя с перфорированными типами нарушает правила строгого алиасинга . Есть ли какой-нибудь достойный способ обойти предупреждение?