Paolo Bonzini <[EMAIL PROTECTED]> writes: >> Or you can do, since elsewhere in the code you compute time_t_max: >> for (j = 1; j <= time_t_max / 2 + 1; j *= 2) > > No, this does not work. It would work to have: > > for (j = 1;;) > { > if (j > time_t_max / 2) > break; > j *= 2; > } > > Oops.
"Oops" is my thought as well. Even the second version of your code is incorrect in general, since it assumes that 'int' and 'time_t' are the same width. It's surprisingly tricky to get right. This underscores why -O2's changes in this area are so worrisome. What I eventually ended up doing -- and this was before reading the above-quoted email -- was this: for (j = 1; ; j <<= 1) if (! bigtime_test (j)) return 1; else if (INT_MAX / 2 < j) break; This is portable and should work on all real platforms. But that was the easy code! Here's the harder stuff, the code that computes time_t_max: static time_t time_t_max; static time_t time_t_min; for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2) continue; time_t_max--; if ((time_t) -1 < 0) for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2) continue; Obviously this code is buggy, at least in theory, due to the signed integer overflows. But rewriting it is not so easy, since we have no INT_MAX to rescue us as we did in the bigtime_test loop. Here's what I eventually came up with: for (;;) { time_t t = (time_t_max << 1) + 1; if (t <= time_t_max) break; time_t_max = t; } time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max; This isn't guaranteed to be portable by C99 either, of course; among other things, left-shift has undefined behavior on signed integer overflow. I am relying on your heuristic advice to use left shift rather than multiplication by 2, so that GCC won't mess up here. But it's a weak heuristic and I'm afraid it doesn't inspire a whole lot of confidence.