On Sat, Mar 13, 2010 at 12:17:14PM +0100, sean finney wrote: > On Sat, Mar 13, 2010 at 11:07:13AM +0100, Iustin Pop wrote: > > So again, sorry if I'm talking stupid things. But here the compiler does > > exactly what you required it to do. 0x80000000 as a positive constant > > doesn't > > work already, if you for example try to print it it's stored as a negative > > 0x80000000 is perfectly valid to put into an int32_t (it is 4 bytes, after > all, > isn't it?), i'm not sure what you're saying here. interpreted/stored as > signed value it has negative value equal to INT_MIN, but interpreted/stored as > unsigned it has a positive value.
Agreed. What I meant is you can't represent 0x80000000 as a signed int. Of course, as raw bits they are valid, but they don't represent that number value. > > value (it actually becomes equal to a, -0x80000000), which of course cannot > > be > > negated again because it would overflow. > > this "equivalence" is a bit sketchy. to get my point, see what happens > when you do > > int32_t a = (int32_t)0x80000000 /* okay */ > > vs > > int32_t a = -(int32_t)0x80000000 /* not okay */ Agreed. > > Check this version: > > #include <stdint.h> > > #include <stdio.h> > > > > int main(int argc, char *argv[]){ > > int32_t a = -0x80000000; /* okay, apparently */ > > int32_t b = 0x80000000; > > printf("%i\n", b); > > printf("%i\n", a==b); > > if (argc > 1) b = -b; /* not okay */ > > return 0; > > } > > > > The problem occurs at the original assignment to b, not at the negation > > of it. > > you can run it step by step through a debugger (x86/amd64), > the OF (overflow) flag will not be set until b is negated. > > Breakpoint 1, main (argc=2, argv=0x7fffffffe698) at foo.c:4 > 4 int32_t a = -0x80000000; /* okay, apparently */ > (gdb) display $eflags > 1: $eflags = [ PF IF ] > (gdb) next > 5 int32_t b = 0x80000000; > 1: $eflags = [ PF IF ] > (gdb) > 6 printf("%i\n", b); > 1: $eflags = [ PF IF ] > (gdb) > -2147483648 > 7 printf("%i\n", a==b); > 1: $eflags = [ PF IF ] > (gdb) > 1 > 8 if (argc > 1) b = -b; /* not okay */ > 1: $eflags = [ PF IF ] > (gdb) > 9 return 0; > 1: $eflags = [ CF PF SF IF OF ] I'll have to study more to understand this, but thanks :) > > > > #include <stdio.h> > > > > #include <limits.h> > > > > > > > > int main() { > > > > long long int j = LLONG_MAX; > > > > int check = 0; > > > > > > > > j -= 10; > > > > j += 5; > > > > j += 3; > > > > j += 2; > > > > check = (-j -1 ) == LLONG_MIN; > > > > > > > > printf("%d\n", check); > > > > return 0; > > > > } > > > > > > > > This small test program gives 1 with any combination of the flags below. > > > > > > why shouldn't it? > > > > Because I'm wrapping arround while doing arithmetic, and even after that, > > the > > wraparound behaviour results in the original value. No uncertainties. No > > aborts > > with -ftrapv. > > i don't see any wraparound there, i see you subtract 10 from the max > value, add it back, and then subtract one from the negated value, > all of this is within the bounds of LLONG_MIN...LLONG_MAX. then again > i haven't had my coffee this morning so maybe i'm missing something :) > > > > i'm not saying it *isn't* a compiler error, but inserting a few printfs > > > and > > > the problem disappearing is also pretty common in other situations of > > > "undefined behavior"... > > > > I disagree here. Undefined behaviour related to integer arithmetic > > should only corrupt the values in question, and a printf can't magically > > make them correct again. So yes, it might be a compiler bug, but I still > > don't think it's related to 64-bit arithmetic, but rather something else > > (storage of 64-bits values in registers/memory? optimization of such > > values? etc.). > > undefined behavior means "undefined behavior". a program can crash or > print out haikus to the console, no assumptions :) Agreed. But my problem as a maintainer is different: - is the upstream code correct, so therefore I should report a bug against gcc on armel? - or is the actual upstream code wrong, and this is an upstream bug? Honestly, since it tends to look like gcc bug, the thing I care most is to workaround this issue *somehow*. If the simplest way is to require gcc 4.3, or a different version of gcc, then… > > I'll run a compile with trapv, but a few small tests with the > > ZigZagEncode64/ZigZagDecode64 a -ftrapv shows there is no overflow. Expect > > results in a few hours… > > i ran a compile last night with ftrapv along with all those warning flags, > and it produced, around 4000(!) lines of warnings and resulted in an abort > different from what we see in the buildd log: > > /bin/bash: line 1: 25502 Aborted $oldpwd/protoc -I. > --cpp_out=$oldpwd google/protobuf/unittest.proto > google/protobuf/unittest_empty.proto google/protobuf/unittest_import.proto > google/protobuf/unittest_mset.proto > google/protobuf/unittest_optimize_for.proto > google/protobuf/unittest_embed_optimize_for.proto > google/protobuf/unittest_custom_options.proto > google/protobuf/unittest_lite.proto > google/protobuf/unittest_import_lite.proto > google/protobuf/unittest_lite_imports_nonlite.proto > google/protobuf/unittest_no_generic_services.proto > google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto > > you get that too? yep, I get this at the exact same step. > it seems that many of the warnings are valid (using signed ints to represent > size, etc), but ultimately i'm guessing they're not related to the > problem at hand. Hmm. Hmm… Are there really no valid uses here, if you know what you're doing? Or put another way: is upstream lucky on other arches, or they know exactly how integers wraparound and rely on the wraparound? > if you want i can send you the stderr output from the > build, might be useful to look for correlations from the aborting codepath. Yes, please send, saves me from doing a compile run :) thanks, iustin -- To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org