-
Notifications
You must be signed in to change notification settings - Fork 4
How do I properly dereference an iterator? #94
Description
The -Wlifetime project is intriguing, but there are still too many false positives in real-world projects I have tested it on. One thing I quite haven't understood is how to treat iterators in order not to trigger null dereference warnings. Very often in generic iterator code, you don't compare an iterator against a null value before dereferencing it, but against the end of a range. Do I need to annotate iterator code in any way to avoid diagnostics? For instance, consider this silly function that just returns the value of the first integer in a range or zero if the range is empty:
template<typename It>
int check(It begin, It end)
{
return begin < end ? *begin : 0;
}
...
// Called from somewhere
std::array x { 1, 2, 3 };
int y = check(x.begin(), x.end());This results in the following diagnostics:
warning: dereferencing a possibly null pointer [-Wlifetime-null]
return begin < end ? *begin : 0;
^~~~~~
note: in instantiation of function template specialization 'check<int *>' requested here
return check(x.begin(), x.end());
^
note: the parameter is assumed to be potentially null. Consider using gsl::not_null<>, a reference instead of a pointer or an assert() to explicitly remove null
int check(It begin, It end)
^~~~~~~~
Now, not_null<> doesn't feel like a good option here, and depending on the iterator, it can't be checked against null before dereferencing. In the case of std::array, this would work:
template<typename It>
int check(It begin, It end)
{
return begin && begin < end ? *begin : 0;
}It doesn't look like ideomatic iterator code, though. And it wouldn't compile if std::vector iterators were used. Comparing against a default constructed iterator technically works for some more iterator types, but it doesn't remove the -Wlifetime-null diagnostic for std::vector iterators. See an example here: https://godbolt.org/z/aUCm3D
I suppose that I have missed something fundamental here. I would like to be reminded if I dereference an iterator with comparing it to something, but sometimes and end iterator is the "null value".