This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Should _GLIBCXX_DEBUG affect tr1/array?


On 13 Jan 2012, at 17:41, Jonathan Wakely wrote:

> On 13 January 2012 16:03, Christopher Jefferson wrote:
>> 
>> On 13 Jan 2012, at 12:40, Edward Rosten wrote:
>> 
>>> Should the _GLIBCXX_DEBUG macro affect the operation of
>>> std::tr1::array? At the moment it has no effect (I assumed it had and
>>> chased my tail for a while).
>>> 
>>> The following code:
>>> 
>>> #define _GLIBCXX_DEBUG
>>> #include <vector>
>>> #include <tr1/array>
>>> #include <iostream>
>>> using namespace std;
>>> 
>>> int main()
>>> {
>>>       tr1::array<int, 10> a;
>>>       a[11] = 0;
>>> 
>>>       cerr << "Array OK\n";
>>> 
>>>       vector<int> b(10);
>>>       b[11] = 0;
>>>       cerr << "Vector OK\n";
>>> }
>>> 
>>> Produces the output:
>>> 
>>> Array OK
>>> /usr/include/c++/4.6/debug/vector:313:error: attempt to subscript container
>>>    with out-of-bounds index 11, but container only holds 10 elements.
>>> 
>>> Objects involved in the operation:
>>> sequence "this" @ 0x0x7fff001872e0 {
>>>  type = NSt7__debug6vectorIiSaIiEEE;
>>> }
>>> Aborted
>>> 
>>> Is this a bug?
>>> 
>>> I'm using Ubuntu 11.10's default install of gcc 4.6.1
>> 
>> I literally had the same problem just today. adding a check to operator[] would seem like an easy addition, and would catch many issues.
> 
> I've opened http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51850
> 
> Patches welcome :)

The patch actually got slightly more interesting, as the operator[] const is both constexpr and noexcept. The standard doesn't require it, but they are nice additions.  In particular constexpr prevents the use of the normal debug-mode stuff.

After poking a few attempts, my current best implementation is actually to just use the same implementation as 'at()', throwing if an error occurs, and then let the noexcept's terminate kill the program, so something like:

return __n < _Nm ? 
	       _M_instance[__n] : throw out_of_range(__N("Array operator[] out of bounds"));

Wrapped approriately in #ifdef _GLIBCXX_DEBUG, and #ifdef EXCEPTIONS. This would make it an oddity with respect to the other tests, not producing such a nice message (the message could obviously be made to look a bit more standard).

Comments?

Chris

> 
>> In principle, full iterator checking could also be added, as the C++ standard does say the type of array::iterator is implementation defined.  However, array has to be an aggregate type, and I'm not sure if adding more members (to handle iterator checks) could lead to breaking code which uses array.
> 
> Hmm, as the length is a compile-time constant an iterator could store
> its index into the array and the total length.  An array<T>::iterator
> can only be invalidated by destroying the array, so although that
> wouldn't be checked, at least incrementing or dereferencing past the
> end could be checked.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]