Richard Guenther <richard.guenther <at> gmail.com> writes: > On Sun, Jan 3, 2010 at 10:55 PM, Joshua Haberman <jhaberman <at> gmail.com> wrote: > > This is why perfect warnings about this issue are not possible; if we > > see a downcast in isolation, we do not know if it is undoing a previous > > upcast or not. Only a tool like valgrind could check this perfectly, by > > observing reads and writes at runtime and checking the types of pointers > > that were used to perform the read/write. > > Correct (though valgrind operates at a too low level to know access types).
Do the DWARF debugging symbols have enough information to determine the pointer type that was used for each load/store? > > char charray[sizeof(long)] = {...}; > > long l = *(long*)charray; // ok > > not correct ;) (the lvalue has to be of character type, yours is of > type 'long' - the type of the actual object does not matter) I see -- good catch. To make it valid, I suppose "memcpy" could be used instead. > Correct. C++ has the notion of dynamic types, so with C++ > > int i; > *(foat *)&i = 0.0; > float f = *(float *)&i; >- > is ok (well - it's ok with a placement new, but a pointer cast is all > GCC sees here). The store changes the dynamic type of the > memory stored to and thus further reads are only valid using > the same type. GCC implements this also for C, but only starting > with GCC 4.5. C++'s notion of a "dynamic type" seems to be the same as what C99 calls the "effective type." See C99, Section 6.5, paragraph 6. Also see Defect Report #236 where the issue is raised, though the committee's reasoning does not make sense to me: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm (Thanks to Daniel Berlin for pointing me to the DR). Josh