Yes, absolutely, it is worth catching this at compile-time. But what you describe above wouldn't catch that at compile-time, because the compiler would use this operator to get an implicit conversion to size_t followed by implicit conversion from size_t to uint32_t.
You could use MFBT's new MOZ_EXPLICIT_CONVERSION to annotate this conversion operator with 'explicit' on supporting C++11 compilers. But instead, I would not bother trying to make this a conversion operator, I would just make this a plain old getter method. I would also not call that Size, but IndexOfResult. The problem is that what IndexOf() returns is not necessarily a "size" or "index", it may also be this special thing called "NoIndex". So I don't think that its return type should "feel like" it _is_ just an index. Instead, its return type should be something that is _either_ an index or NoIndex. Something like this: class IndexOfResult { const index_type mIndex; static const index_type NoIndex = index_type(-1); public: IndexOfResult(index_type index) : mIndex(index) {} IndexOfResult(const IndexOfResult& other) : mIndex(other.mIndex) {} bool Found() const { return mIndex != NoIndex; } index_type Value() const { MOZ_ASSERT(Found()); return mIndex; } }; Benoit 2014-05-11 10:25 GMT-04:00 Ehsan Akhgari <ehsan.akhg...@gmail.com>: > On 2014-05-11, 10:15 AM, Benoit Jacob wrote: > >> Hi, >> >> Since Bug 1004098 landed, the type of nsTArray lengths and indices is now >> size_t. >> >> Code using nsTArrays is encouraged to use size_t for indexing them; in >> most >> cases, this does not really matter; however there is one case where this >> does matter, which is when user code stores the result of >> nsTArray::IndexOf(). >> >> Indeed, nsTArray::NoIndex used to be uint32_t(-1), which has the value >> 2^32 >> - 1. Now, nsTArray::NoIndex is size_t(-1) which, on x86-64, has the value >> 2^64 - 1. >> >> This means that code like this is no longer correct: >> >> uint32_t index = array.IndexOf(thing); >> >> Such code should be changed do: >> >> size_t index = array.IndexOf(thing); >> >> Or, better still (slightly pedantic but would have been correct all >> along): >> >> ArrayType::index_type index = array.IndexOf(thing); >> > > > >> Where ArrayType is the type of that 'array' variable (one could use >> decltype(array) too). >> > > Do you think it's worth trying to make the bad code above not compile, by > returning an object from IndexOf which only provides an implicit conversion > to size_t and not uint32_t? Like: > > template <class T> > class nsTArray { > // ... > struct Size { > Size(size_t); > operator size_t() const; > }; > Size IndexOf(...); > }; > _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform