On Tue, Mar 2, 2010 at 10:38 AM, Peter Kourzanov <peter.kourza...@gmail.com> wrote: > > Hi guys, > > I have the following variation on Duff's device that seems to > mis-compile on all GCC versions I can access within a minute (that > is gcc-3.{3,4}, gcc-4.{1,2,3,4} on x86 and gcc-4.3.2 on x86_64). The > symptoms are as follows: > > $ gcc-4.4 -o duffbug duffbug.c ; ./duffbug > { he��3) > { hello world ! } > > As you can observe in the difference between duff4_works() and > duff4_fails(), apparently due to for-loop initializer being externalized > vs. specified as the first for-loop expression. It doesn't matter if the > 'case 0' is labeling the for-loop, or the first statement in the > for-loop in case of duff4_works() of course. However, older gcc-3.x do > give a warning though if the 'case 0' labels the first statement for > duff4_fails(), since the first expression in the for-loop is then > inaccessible. All gcc-4.x versions don't warn, even when supplied with > the -Wall flag (which is wrong, hence this *first* bug): > > $ gcc-4.4 -Wall -o duffbug duffbug.c ; ./duffbug > $ gcc-3.4 -Wall -o duffbug duffbug.c ; ./duffbug > duffbug.c: In function `duff4_fails': > duffbug.c:28: warning: unreachable code at beginning of switch statement > > I think the compiler is generating wrong code for duff4_fails() when > 'case 0' labels the for-loop. It somehow skips the first for-loop > expression, just as if 'case 0' pointed to the first statement in the > for-loop (hence this *second* bug). Haven't checked the assembly > though...
The routines are not equivalent. in _works you unconditionally do dst += n while in _fails you only do it for rem == 0. Richard. > Kind regards, > > Pjotr Kourzanov >