Это хакерство для удаления предупреждения UB о псевдонимах?

Мы только что обновили наш компилятор до gcc 4.6, и теперь мы получить некоторые из этих предупреждений. На данный момент наша кодовая база не находится в состоянии для компиляции с c ++ 0x, и в любом случае мы не хотим запускать это в продукте (по крайней мере, пока) - поэтому мне нужно было исправить удалите это предупреждение.

Как правило, предупреждения возникают из-за чего-то вроде этого:

struct SomeDataPage
{
  // members
  char vData[SOME_SIZE];
};

позже это используется следующим образом

SomeDataPage page;
new(page.vData) SomeType(); // non-trivial constructor

Для чтения, обновления и возврата, например, выполнялось следующее приведение типов

reinterpret_cast(page.vData)->some_member();

Это было нормально с 4.4; в 4.6 выше генерируется:

предупреждение: указатель типа punned будет нарушать правила строгого алиасинга

Теперь чистый способ удалить эту ошибку - использовать объединение , однако как я уже сказал, мы не можем использовать c ++ 0x (и, следовательно, неограниченные союзы), поэтому я применил ужасный хак ниже - теперь предупреждение исчезло, но могу ли я вызвать назальный демоны?

static_cast(reinterpret_cast(page.vData))->some_member();

Это кажется s работает нормально (см. простой пример здесь: http://www.ideone.com/9p3MS ) и не генерирует никаких предупреждений, это нормально (не в стилистическом смысле), чтобы использовать это до c ++ 0x?

ПРИМЕЧАНИЕ. Я не хочу использовать -fno-strict-aliasing в целом ...

РЕДАКТИРОВАТЬ : Кажется, я ошибся, такое же предупреждение есть на 4.4, я думаю, мы только недавно столкнулись с этим с изменением (всегда было маловероятно, что это проблема компилятора), но вопрос все еще остается.

РЕДАКТИРОВАТЬ : дальнейшее расследование дало некоторую интересную информацию, похоже, что приведение типов и вызов функции-члена в одной строке является причиной предупреждения, если код разделен на две строки следующим образом

SomeType* ptr = reinterpret_cast(page.vData);
ptr->some_method();

this фактически не выдает предупреждения. В результате мой простой пример на ideone ошибочен и, что более важно мой хак выше не исправляет предупреждение , единственный способ исправить это - отделить вызов функции от приведения - тогда приведение может быть оставлен как reinterpret_cast .

10
задан curiousguy 13 December 2011 в 15:14
поделиться