I don't know if this is a common problem, but I've sometimes encountered unexpected runtime issues caused by unsigned values being decremented below zero.
Example 1: "unsigned_value += negative_integer_value;"
Example 2: "for( size_t i = size - 1; i >= 0; --i )"
My compiler doesn't provide any compile-time or run-time warnings.
As far as I know, it's not possible to overload operators of primitive data types to check if the unsigned value is decremented below zero.
Do you know of any clever strategy to trace such cases at debug runtime, without having to add asserts all over the code? It's important that it does not affect performance in release mode.
Decrementing an unsigned integer that is zero is well defined and not necessarily a mistake. The solution, methinks, is to write tests to check that your code is doing what you intend.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
Yes, it's legal, but I can't recall that I have ever done it on purpose. Maybe that behaviour is defined just because it's better than the alternative of undefined behaviour?
Writing unit tests is a good recommendation though :-)
I don't know if this is a common problem, but I've sometimes encountered unexpected runtime issues caused by unsigned values being decremented below zero.
Example 1: "unsigned_value += negative_integer_value;"
Example 2: "for( size_t i = size - 1; i >= 0; --i )"
My compiler doesn't provide any compile-time or run-time warnings.
Of course not, it also doesn't flag integer division or using ++i when you actually meant --i. The compiler has a lot of tricks up its sleeve, but it cannot peak inside your head; it does not know what you want your code to do. If the result of an operation can be a negative number, then don't use unsigned integers for it; or rewrite the code such that the result cannot be negative.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
VisualStudio 2010 issues a "warning C4296: '>=' : expression is always true" when the warning level is set to /Wall. However, this level is quite a pain as a lot of headers that come with the compiler are candidates for warnings as well.
I could not get my g++ (4.6.1) to issue any warning.
Cppcheck (http://cppcheck.sourceforge.net/), a tool for static analysis, issues a warning. This tool is very useful, I use it regularly in my projects.
if you have code where such examples are very common and unavoidable an alternative to asserts could be to replace the unsigned type with a runtime checked size_t-like type in debug builds only. You can use boost operator library to ease the writing of such a custom numeric type, adding internal asserts where needed protecting you against underflow.
That said, this solution would bring its own set of issues, like properly controlling implicit conversions to mantain consistency with the relase build behavior.
However, it may be the way to go if asserts become excessive; indeed, note that asserts ( and tests ) may contain errors themselves, so you should avoid code duplication and favour incapsulation in the same way you do with the rest of the code ...
Do you know of any clever strategy to trace such cases at debug runtime, without having to add asserts all over the code? It's important that it does not affect performance in release mode.
You could systematically seek higher level language constructs. For example instead of integer counters in for-loops you can use iterators, or the new for-each loop in C++ 11, or BOOST_FOREACH/BOOST_REVERSE_FOREACH. The Boost way is my favourite. You can easily, safely and quickly loop over every standard data structure.
Start programming at a higher abstraction level and avoid low level fiddling. It's not as efficient as one might think and it's error-prone. Seek the highest abstraction level that's reasonable and optimize only when necessary at proven bottlenecks.
Last edited by nuzzle; October 12th, 2012 at 03:23 PM.
Bookmarks