From: John K. <jko...@on...> - 2006-02-14 16:04:51
|
William S Fulton wrote: > John Koleszar wrote: >> On newer GCC's (4.0.2 in my case) with -O2 or higher, the return value >> of the cpointer typemaps is being optimized incorrectly due to aliasing >> issues. Adding -fno-strict-aliasing works as a workaround, but it'd >> probably be worth correcting this code to safely convert the pointer >> into a jlong. >> > From what I recall, this casting is meant to be the safest guaranteed > way to cast from one type to another. I think there is a name for it, > but don't recall. This has never been reported as failing before. Do > you have a complete standalone example that fails and can you tell me > please which platform it is failing on, is it a 64 bit architecture? > > Thanks > William Modifying the Example/Makefile's CFLAGS and running the test suite causes the error to show up in several cases. Adding -fno-strict-aliasing causes the error to go away. This seems to be related to new versions of GCC and its more aggressive optimizer, as I had no problem with version 3.3.6. It looks to me like you're doing an intermediate cast to void* to hint the compiler about the aliasing (not just in the function I mentioned, based on the test suite results it looks like it happens in several places). I guess the question is whether this is a gcc bug in that it's not recognizing the aliasing hint anymore, or whether the hint isn't really guaranteed to always work, in which case gcc is right and a different method of conversion is needed. The text I have says that many existing programs rely on this behavior (void * as an aliasing hint) but that doesn't mean that the gcc folks wouldn't break that (if it is in fact illegal) in favor of better optimizations, given that projects that don't want strict aliasing can easily add a flag and disable it. The fundamental problem is that pointers and longs are incompatible types as far as C goes, so most solutions for converting them directly are hacks. The only 100% legal way I know of doing the conversion is copying it bytewise, but you can't legally do any operations on the result (though i don't think that matters in this case). Not trying to lecture here, just throwing out ideas. Various test suite runs attached (Swig1.3.28 release). My gcc (from debian testing): $ gcc -v Using built-in specs. Target: i486-linux-gnu Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt=gtk-default --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --with-tune=i686 --enable-checking=release i486-linux-gnu Thread model: posix gcc version 4.0.3 20060128 (prerelease) (Debian 4.0.2-8) Cheers, John |