strict-aliasing warning workaround
The following piece of code, which I believe is correct w.r.t strict-
aliasing restrictions, generates a warning in gcc -O3 -Wall (tested
4.4.1 and trunk). This pattern is common, so it has to have come up
for other people, so my question is: are there any good ways to
achieve the same effect without getting the gcc warning?
The problematic pattern occurs in classes that want to do conditional
in-place construction, like Conditionally below:
void *operator new (unsigned, void *p) { return p; }
template <class T>
struct Conditionally {
union {
char bytes[sizeof(T)];
int align;
};
bool b;
public:
Conditionally(bool b) : b(b) { if (b) new(bytes) T(); }
T &asT() { return *reinterpret_cast<T *>(bytes); }
~Conditionally() { if (b) asT().~T(); }
};
struct A { int x; A() {} ~A() {} };
int main() {
Conditionally<A> c(true);
}
g++ -O3 -Wall test.cpp
test.cpp: In member function ?T& Conditionally<T>::asT() [with T =
A]?:
test.cpp:13:31: instantiated from
?Conditionally<T>::~Conditionally() [with T = A]?
test.cpp:19:28: instantiated from here
test.cpp:12:51: warning: dereferencing type-punned pointer will break
strict-aliasing rules
The analysis seems to miss the fact that the memory represented by
bytes is only ever being accessed as its effective type: T.
Although I'd prefer not to use a #pragma, I have had problems even
using #pragma: I've found that "#pragma GCC diagnostic ignored "-
Wstrict-aliasing" only works if set for the entire translation unit.
Specifically, to ignore the warning, the -Wstrict-aliasing has to be
set to 'ignored' by the last line of the translation unit, at which
point it applies globally to the entire tu. Or, that is what I have
been able to determine through experiment; perhaps someone understands
this better? In general, I like the warning; it finds real bugs, so
I'd like to keep it active and watching as much of the codebase as
possible.
Thanks for any help!
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]