Re:Pitfalls in C and C++: Unsigned Types (2011)
by Someone on Wednesday September 25, 2013 @06:56PM
(#6447865)
I don't see why arr[(unsigned)-1] is guaranteed to segfault. Care to explain?
Isn't it equivalent to
* (arr + (unsigned) -1)
, which should be equivalent to * (arr + UINT_MAX)
On typical PC hardware with sizeof(int) == sizeof(char *) that looks like a undefined behavior case to me (maybe barring border conditions; I don't feel like thinking of all edge cases). Most C compilers choose the fastest possible path for undefined behavior cases, so I would expect this to (typically. Again, there will be border cases) be equivalent to arr[-1].(See also http://stackoverflow.com/questions/2578455/pointer-arithmeti...)
Re:Pitfalls in C and C++: Unsigned Types (2011)
by dllthomas on Thursday September 26, 2013 @03:09AM
(#6449321)
"Typical PC hardware", at least in my recent experience, has sizeof(int) == 4, sizeof(char*) == 8 and so the reason they're different should be apparent. I believe you are correct that there is no difference when they are equal.
Re:Pitfalls in C and C++: Unsigned Types (2011)
by duaneb on Wednesday September 25, 2013 @03:17PM
(#6446673)
This is ok in general, but IMHO silently failing code (like a break condition that never happens because of overflow) is far worse than getting your arithmetic right. Getting it wrong implies a clear bug, whereas a seemingly bugless loop might be harder to identify as the source of the error.
First, arr[(unsigned)-1] will segfault while arr[-1] will likely cause harder to debug non-local problems.
Second, mod in C and C++ is broken(ish) on signed values: negative % positive returns a negative number. This means in order to use it as an index you need to check the value and add the table size post-mod if you want to wrap an index into an array (as you might for a hash table or ring buffer).