Мы просто обновили наш компилятор до gcc 4.6, и теперь мы получаем некоторые из этих предупреждений. На данный момент наша кодовая база не находится в состоянии, которое должно быть скомпилировано с помощью С++ 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 приведенное выше значение генерирует:
предупреждение: тип punned pointer будет нарушать правила строгого сглаживания
Теперь чистый способ удалить эту ошибку - использовать union
, но, как я уже сказал, мы не можем использовать С++ 0x (и, следовательно, неограниченные объединения), поэтому я использовал ужасный hack ниже - теперь предупреждение ушло, но могу ли я вызвать демонов носа?
static_cast<SomeType*>(reinterpret_cast<void*>(page.vData))->some_member();
Это, похоже, работает нормально (см. простой пример здесь: http://www.ideone.com/9p3MS) и не генерирует никаких предупреждений, это нормально (не в стилистическом смысл) использовать это до С++ 0x?
ПРИМЕЧАНИЕ. Я не хочу использовать -fno-strict-aliasing
в целом...
РЕДАКТИРОВАТЬ. Кажется, я ошибался, это же предупреждение существует в 4.4, я думаю, мы только недавно это сделали с изменением (это всегда было маловероятным для компилятора), вопрос все еще стоит.
EDIT: дальнейшее исследование дало некоторую интересную информацию, кажется, что выполнение роли и вызов функции-члена в одной строке является тем, что вызывает предупреждение, если код разбит на две строки следующим образом
SomeType* ptr = reinterpret_cast<SomeType*>(page.vData);
ptr->some_method();
это действительно не вызывает предупреждения. В результате мой простой пример на идеоне ошибочен и, что более важно, мой взломанный выше не исправляет предупреждение, единственный способ исправить это - разделить вызов функции от актера - тогда актерский состав может оставить как reinterpret_cast
.