I'll also attach the preprocessor output from --save-temps. This is the output of g++ -v when compiling the code... g++ -v --save-temps -pipe -I./include -g -MD -c StrMod/ChunkIterator.cxx -o generated/obj/StrMod_ChunkIterator.o g++: Warning: -pipe ignored since -save-temps specified Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.0) /usr/lib/gcc-lib/i386-redhat-linux/2.96/cpp0 -lang-c++ -D__GNUG__=2 -v -I./include -MD ChunkIterator.d -D__GNUC__=2 -D__GNUC_MINOR__=96 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -g -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -D__tune_i386__ StrMod/ChunkIterator.cxx ChunkIterator.ii GNU CPP version 2.96 20000731 (Red Hat Linux 7.0) (cpplib) (i386 Linux/ELF) ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/usr/i386-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: include /usr/include/g++-3 /usr/lib/gcc-lib/i386-redhat-linux/2.96/include /usr/include End of search list. /usr/lib/gcc-lib/i386-redhat-linux/2.96/cc1plus ChunkIterator.ii -quiet -dumpbase ChunkIterator.cxx -g -version -o ChunkIterator.s GNU C++ version 2.96 20000731 (Red Hat Linux 7.0) (i386-redhat-linux) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.0). StrMod/ChunkIterator.cxx: In method `StrChunk::__iterator StrChunk::end ()': StrMod/ChunkIterator.cxx:356: Internal error #40. StrMod/ChunkIterator.cxx:356: Internal compiler error in cplus_expand_expr, at ../gcc/cp/expr.c:159 Please submit a full bug report. See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.
Created attachment 3965 [details] This is the preprocessor output that causes the compiler to crash
This happens with or without the -march=i686 flag, and with or without the -O2 flag. It stops happening when I remove the named return value thing, but then the code generated is sub-optimal, even with -O2. I don't understand why you can't just perform the named return value optimization without any funny hints. Is there something in the standard explicitly stating how many constructor and destructor calls must be seen in a function call pass-by-value situation?
You actually put the end() without named return value, but I figured out. This does no longer crash in mainline CVS, so I'll just scan all named return value related patches and see which one fixes it (BTW: named return value extension is deprecated and will be removed probably soon after gcc3 is out, mainline CVS issues warnings whenever it is used).
Oops. *grin* Thanks for figuring it out. I thought I had tested the preprocessed output. Apparently I hadn't. Will gcc3 make the named return value thing obsolete by automatically doing an equivalent optimization, or will the feature be removed with no ability to optimize in this fashion? The named return value optimization can improve things enormously in certain situations. In this particular one, the improvement is probably not that fantastic, but in others...
Even gcc 2.95.2 supports the return value optimization. See any good textbook on C++ for how to have it ``do the right thing''. Generally, a construction like: return MyObject(arg1, arg2) and a call like: MyObject value(myfunction(param1, param2, param3)); ... will do the trick.
I know what's in a good C++ book on the subject. :-) If you can name one I haven't read, I'd be very obliged. :-) It's just that this idea has been in C++ books for a couple years (or more), and hasn't yet made it into the compiler. But, take my end() function. That strict construction won't work. There are many cases where the return value optimization is feasible, but they don't strictly fit within the mold you just outlined. In fact, the return value optimization can be applied whenever you return an object that was constructed on the stack inside the function. You 'just' (yeah, I make it sound easy, don't I?) have to trace back from the return statement to where the object is constructed and construct the object into a space provided by the function caller. I would actually suggest this as standard practice in handling complex return types since the caller usually has better information about what will be done with the return value than the called function. A bug tracking system is probably not the place for this discussion though. :-)
gcc-2.96-61 should fix this ICE and just print warning like StrMod/ChunkIterator.cxx: In method `StrChunk::__iterator StrChunk::end ()': StrMod/ChunkIterator.cxx:354: warning: the named return value extension is deprecated. StrMod/ChunkIterator.cxx:354: warning: Please see the documentation for details.