all right, after long and lively discussions on the subject, here's what we've gathered so far. Sorry for the long message, but I thought you might be interested into getting into the nitty gritty.
The problem stems from the fact that if s_int32 a = 0x80000000
and s_int32 b = 0x00000001
, then the expression a-b
causes an integer overflow. The ANSI C/90 standard says that in such a situation behaviour is unspecified. I'm throwing a few quotes straight out of the standard:
ISO/IEC 9899:1990 (E) wrote:3.17 unspecified behavior: Behavior, for a correct program construct and correct data, for which this International Standard explicitly imposes no requirements.
2. An example of undefined behavior is the behavior of integer overflow.
3. An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.
ISO/IEC 9899:1990 (E) wrote:18.104.22.168 Types
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.
ISO/IEC 9899:1990 (E) wrote:6.3 Expressions
If an exception occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behevior is undefined.
On these grounds, I'd say that our compiler is complying to the standard in this regard.
Having said that, and having thrown the (standard) book at you, I very much understand that this is a real problem in porting real programs
So, what we have discussed is adding a command line option to the C compiler that would reset the guard bits each time before performing one of the potentially dangerous operations: shifting to the right, and comparisons. Signed 32-bit division is also a potential problem, but Pasi changed the standard libc function in such a way that it protects against the guard bits (the function didn't even get any longer).
As Panu said, adding these checks woukd make the compiler generate larger and slower code, so we have decided to make this optional, activated by a command line option. Lasse is working on it, and we'll let you know when we are ready.
As an aside: unsigned operations on 32-bit integers should work as expected because we've added guard bit clean-up to them already many years ago.
Good signatures never die. They just fade away.