I just found a pretty fun code. GCC optimizations change its behavior weirdly.
- -O0 works
- -O1 segfault
- -O2 infinite loop (from 7 to 1996 inclusive)
- -O3 works
- -Og segfault
- -Ofast works
Here's the code :
int main(int argc, char *argv[])
{
int i, c;
c = 0;
for (i = 10; i < 10000; ++i)
{
if (is_lychrel(i))
++c;
printf("%d\n", i);
}
printf("%d\n", c);
return EXIT_SUCCESS;
}
The function is_lychrel(int)
makes use of the parameter.
As far as I know, this is probably due to an undefined behavior somewhere but I can't spot it. I tried to disable some optimization flags, but I had no luck so far.
If you need more code, feel free to ask.
EDIT: As suggested in the comments, I tried to comment some functions and finally debugged the old school way (because gdb won't work). And I found the culprit (of the segfault at least) :
void add_reverse(int d[], int *len)
{
int i;
int plus[28] = {0};
for (i = 0; i < *len; ++i)
{
//printf("d %d\n", i);
plus[i] = d[*len - i - 1];
}
add(d, plus, len);
}
This function is assumed to add a number (as an array of digits) to his reverse and return the new length. Exemple: ({1, 2}, 2)
should give ({3, 3}, 2)
. It doesn't segfault with the printf
but won't give the good result. I'm trying to analyze d[] step by step. d[] is 0034647260072070369072646341
just before segfault (seems valid).
EDIT 2:
Adding a simple displaying loop (diplay one won't be enough) after computation of plus
correct the output of -O1.
for (i = 0; i < *len; ++i)
printf("%d", plus[i]);
Here's add()
code if ever that could help:
void add(int d[], int plus[], int *maxlen)
{
int i, of;
of = 0;
for (i = 0; i <= *maxlen; ++i)
{
d[i] += plus[i];
if (of)
{
d[i] += of;
of = 0;
}
if (d[i] >= 10)
{
of = 1;
d[i] %= 10;
}
}
if (d[i - 1])
++*maxlen;
}