Hello! A code that I wrote was warning-free in GCC 4.9, GCC 5 and GCC 6. It was also warning-free with some older GCC 7 experimental snapshots (for example 7-20170409). But in the most recent snapshot (including the first RC), it started to produce a warning about aliasing. The code basically boils down to this:
-- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- #include <type_traits> std::aligned_storage<sizeof(int), alignof(int)>::type storage; int main() { *reinterpret_cast<int*>(&storage) = 42; } -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- Compilation with latest GCC 7 RC: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- $ g++ -Wall -O2 -c main.cpp main.cpp: In function 'int main()': main.cpp:7:34: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] *reinterpret_cast<int*>(&storage) = 42; -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- (interesting observation is that the warning is not produced when optimizations are disabled) Compilation with GCC 6 gives no warnings at all. Now I'm wondering, the code above definitely HAS type-punning, no question about that, but isn't std::aligned_storage meant to be used that way? For instance the example code given here on cppreference generally produces no warning with GCC 7 but only because: - std::string somehow is not affected, - std::aligned_storage is accessed with an offset. http://en.cppreference.com/w/cpp/types/aligned_storage By changing std::string into int, removing offset access to std::aligned_storage and removing irrelevant parts you get this: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- #include <iostream> #include <type_traits> #include <string> template<class T, std::size_t N> class static_vector { // properly aligned uninitialized storage for N T's typename std::aligned_storage<sizeof(T), alignof(T)>::type data[N]; std::size_t m_size = 0; public: // Access an object in aligned storage const T& operator[](std::size_t pos) const { return *reinterpret_cast<const T*>(data/*+pos*/); // <- note here, offset access disabled } }; int main() { static_vector<int, 10> v1; std::cout << v1[0] << '\n' << v1[1] << '\n'; } -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- And this produces exactly the same warning: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- main.cpp: In instantiation of 'const T& static_vector<T, N>::operator[](std::size_t) const [with T = int; unsigned int N = 10; std::size_t = unsigned int]': main.cpp:24:22: required from here main.cpp:17:16: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] return *reinterpret_cast<const T*>(data/*+pos*/); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- So my question is - is this a bug or a feature? Thanks in advance! Regards, FCh BTW - I've also posted this question on stackoverflow http://stackoverflow.com/questions/43711567/gcc-7-aligned-storage-and-dereferencing-type-punned-pointer-will-break-strict