On Thu, Apr 24, 2008 at 08:37:43PM -0400, Robert C. Seacord wrote: > The original impetus for this came from a check in a sprint() function > from Plan 9. Because of the API, there was no way to test if the len > was out of bounds, but the developers wanted to make sure they weren't > wrapping the stack on some architectures that have their stacks in high > memory.
It sounds like there are two issues here: a problem with the API (ideally it would be possible to do a proper length check, though sometimes these are legacy issues that one is stuck with), and a problem with the way the test is coded. A portable-in-practice way to do checks on pointer addresses of this kind is to cast the pointers to unsigned integers of the appropriate length before doing the arithmetic. In C, unsigned types are guaranteed to obey the rules of modulo 2**N arithmetic, where N is the number of bits. (I say "portable in practice" because things like segmented architectures raise other issues, but for a flat address space on a conventional processor that has an integral type the same size as a pointer type, you should be OK). > It seems like a reasonable test to make, the code used to work, and they > got burned on the silent change in behavior. Unfortunately, C is not designed that way, which makes it rather surprising that Plan 9 was burned by this (it has architects who should know better, given their role in the definition of C). These are not new issues; they were fought over back in the late 1980s, and we have the rules we do because otherwise, anyone wanting to write fast code would need to use Fortran, as the "consistency" you are asking for would mean that everything aliases everything so it's unsafe to use registers.