Мы только что обновили наш компилятор до gcc 4.6, и теперь мы получаем некоторые из этих предупреждений. На данный момент наша кодовая база не находится в состоянии для компиляции с c ++ 0x, и в любом случае мы не хотим запускать это в prod (по крайней мере, пока) - поэтому мне нужно было исправить это предупреждение.
Предупреждения обычно появляются из-за чего-то подобного:
struct SomeDataPage
{
// members
char vData[SOME_SIZE];
};
позже, это используется следующим образом
SomeDataPage page;
new(page.vData) SomeType(); // non-trivial constructor
Для чтения, обновления и возврата, например, использовалось следующее приведение
reinterpret_cast<SomeType*>(page.vData)->some_member();
Это было хорошо с 4.4; в 4.6 выше выдает:
предупреждение: тип перенаправленного указателя нарушит правила строгого алиасинга
Теперь чистый способ устранить эту ошибку - использовать union
, однако, как я уже сказал, мы не можем использовать c ++ 0x (и, следовательно, неограниченные объединения), поэтому я использовал ужасный хак ниже - теперь предупреждение исчезло, но могу ли я вызвать носовые демоны?
static_cast<SomeType*>(reinterpret_cast<void*>(page.vData))->some_member();
Кажется, это работает нормально (см. Простой пример здесь: http://www.ideone.com/9p3MS) и не генерирует предупреждений, это нормально (не в стилистическом смысле), чтобы использовать это до c ++ 0x?
ПРИМЕЧАНИЕ: я не хочу использовать -fno-strict-aliasing
обычно ...
РЕДАКТИРОВАТЬ : Кажется, я ошибся, то же самое предупреждение есть на 4.4, я думаю, что мы только что подняли это с изменением (это всегда было маловероятно, чтобы быть проблемой компилятора), вопрос все еще стоит, хотя.
РЕДАКТИРОВАТЬ : дальнейшее исследование дало некоторую интересную информацию, кажется, что приведение и вызов функции-члена в одной строке вызывает то, что вызывает предупреждение, если код разбит на две строки следующим образом
SomeType* ptr = reinterpret_cast<SomeType*>(page.vData);
ptr->some_method();
это на самом деле не генерирует предупреждение. В результате мой простой пример с ideone некорректен и, что более важно, мой хак выше не исправляет предупреждение , единственный способ исправить это - отделить вызов функции от приведения - тогда приведение может быть оставил как reinterpret_cast
.