Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #80079 > unrolled thread

A way around _HAS_ITERATOR_DEBUGGING

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2021-06-02 14:49 +0200
Last post2021-06-03 17:52 +0000
Articles 15 on this page of 35 — 13 participants

Back to article view | Back to comp.lang.c++


Contents

  A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-02 14:49 +0200
    Re: A way around _HAS_ITERATOR_DEBUGGING "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2021-06-02 15:07 +0200
      Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-02 15:12 +0200
        Re: A way around _HAS_ITERATOR_DEBUGGING "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2021-06-02 20:27 +0200
          Re: A way around _HAS_ITERATOR_DEBUGGING red floyd <myob@its.invalid> - 2021-06-02 14:24 -0700
          Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-03 00:54 +0200
          Re: A way around _HAS_ITERATOR_DEBUGGING Öö Tiib <ootiib@hot.ee> - 2021-06-02 17:30 -0700
    Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-02 16:46 +0300
      Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-02 16:23 +0200
        Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-02 19:43 +0300
          Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-02 18:57 +0200
            Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-02 21:13 +0300
              Re: A way around _HAS_ITERATOR_DEBUGGING James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-02 17:23 -0400
                Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-03 00:53 +0200
              Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-03 00:52 +0200
          Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-02 18:59 +0200
        Re: A way around _HAS_ITERATOR_DEBUGGING Juha Nieminen <nospam@thanks.invalid> - 2021-06-03 09:21 +0000
          Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-03 11:33 +0200
            Re: A way around _HAS_ITERATOR_DEBUGGING Bo Persson <bo@bo-persson.se> - 2021-06-03 12:17 +0200
              Re: A way around _HAS_ITERATOR_DEBUGGING Bonita Montero <Bonita.Montero@gmail.com> - 2021-06-03 12:25 +0200
            Re: A way around _HAS_ITERATOR_DEBUGGING Juha Nieminen <nospam@thanks.invalid> - 2021-06-03 17:49 +0000
              Re: A way around _HAS_ITERATOR_DEBUGGING MrSpook_ujp@3p26kggzpvpn2h.gov.uk - 2021-06-04 07:43 +0000
          Re: A way around _HAS_ITERATOR_DEBUGGING James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-03 11:06 -0400
            Re: A way around _HAS_ITERATOR_DEBUGGING David Brown <david.brown@hesbynett.no> - 2021-06-03 19:07 +0200
            Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-03 20:18 +0300
              Re: A way around _HAS_ITERATOR_DEBUGGING Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-06-04 10:22 +0100
                Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-04 14:19 +0300
                  Re: A way around _HAS_ITERATOR_DEBUGGING Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2021-06-04 13:07 +0100
              Re: A way around _HAS_ITERATOR_DEBUGGING James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-04 10:40 -0400
                Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-04 19:28 +0300
                  Re: A way around _HAS_ITERATOR_DEBUGGING James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-04 13:04 -0400
                    Re: A way around _HAS_ITERATOR_DEBUGGING "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-06-04 13:30 -0700
                      Re: A way around _HAS_ITERATOR_DEBUGGING MrSpook_6qpp@dggw8.org - 2021-06-05 09:28 +0000
                    Re: A way around _HAS_ITERATOR_DEBUGGING Paavo Helde <myfirstname@osa.pri.ee> - 2021-06-04 23:45 +0300
            Re: A way around _HAS_ITERATOR_DEBUGGING Juha Nieminen <nospam@thanks.invalid> - 2021-06-03 17:52 +0000

Page 2 of 2 — ← Prev page 1 [2]


#80139

FromJuha Nieminen <nospam@thanks.invalid>
Date2021-06-03 17:49 +0000
Message-ID<s9b4ni$lee$1@gioia.aioe.org>
In reply to#80129
Bonita Montero <Bonita.Montero@gmail.com> wrote:
>> The problem with relying on undefined behavior is that you have no
>> guarantees about what the compiler will do to your code.
> 
> In theory - but in this case actually practically not.
> 
> Rest of your nonsense unread.

I honestly cannot understand why you feel the need to behave like such
an asshole. I merely made a remark about the language standard and what
it could allow the compiler to behave like (and gave a practical example
of when this caused a huge issue in the Linux kernel).

So why are you treating it like shit? I don't understand. What exactly
did I do or say that elicits such irrational behavior?

It's not even the first time. You keep doing this again and again,
most often completely unpromted out of the blue, in response to completely
innocuous posts, for completely unknown reasons. Why?

[toc] | [prev] | [next] | [standalone]


#80145

FromMrSpook_ujp@3p26kggzpvpn2h.gov.uk
Date2021-06-04 07:43 +0000
Message-ID<s9clij$kv9$1@gioia.aioe.org>
In reply to#80139
On Thu, 3 Jun 2021 17:49:40 +0000 (UTC)
Juha Nieminen <nospam@thanks.invalid> wrote:
>Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>> The problem with relying on undefined behavior is that you have no
>>> guarantees about what the compiler will do to your code.
>> 
>> In theory - but in this case actually practically not.
>> 
>> Rest of your nonsense unread.
>
>I honestly cannot understand why you feel the need to behave like such
>an asshole. I merely made a remark about the language standard and what
>it could allow the compiler to behave like (and gave a practical example
>of when this caused a huge issue in the Linux kernel).
>
>So why are you treating it like shit? I don't understand. What exactly
>did I do or say that elicits such irrational behavior?
>
>It's not even the first time. You keep doing this again and again,
>most often completely unpromted out of the blue, in response to completely
>innocuous posts, for completely unknown reasons. Why?

You're a fine one to talk.

[toc] | [prev] | [next] | [standalone]


#80134

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2021-06-03 11:06 -0400
Message-ID<s9ar5t$hik$1@dont-email.me>
In reply to#80126
On 6/3/21 5:21 AM, Juha Nieminen wrote:
> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>> Because i needed something like ptr = &*vec.end() and MSVC has iterator
>>>> -debugging by default
>>
>>> Dereferencing vec.end() is UB, ...
>>
>> In theory, but there's for sure no actual vector-implementation
>> where this doesn't work as long as you don't read from or write
>> to the reference.
> 
> The problem with relying on undefined behavior is that you have no
> guarantees about what the compiler will do to your code.

The C standard, while describing the unary & operator,says "If the
operand is the result of a unary * operator, neither that operator nor
the & operator is evaluated and the result is as if both were omitted,
except that the constraints on the operators still apply and the result
is not an lvalue." (C 6.5.3.2p3).

I could find no corresponding statement in the C++ standard, but
shouldn't there be one? The C++ version would have to be more
complicated, to deal with issues that can't come up in C, such as
operator overloads. However, is there any good reason why there
shouldn't be a similar clause in the C++ standard? That would make
Bonita's code perfectly safe.

[toc] | [prev] | [next] | [standalone]


#80137

FromDavid Brown <david.brown@hesbynett.no>
Date2021-06-03 19:07 +0200
Message-ID<s9b291$ese$1@dont-email.me>
In reply to#80134
On 03/06/2021 17:06, James Kuyper wrote:
> On 6/3/21 5:21 AM, Juha Nieminen wrote:
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>>> Because i needed something like ptr = &*vec.end() and MSVC has iterator
>>>>> -debugging by default
>>>
>>>> Dereferencing vec.end() is UB, ...
>>>
>>> In theory, but there's for sure no actual vector-implementation
>>> where this doesn't work as long as you don't read from or write
>>> to the reference.
>>
>> The problem with relying on undefined behavior is that you have no
>> guarantees about what the compiler will do to your code.
> 
> The C standard, while describing the unary & operator,says "If the
> operand is the result of a unary * operator, neither that operator nor
> the & operator is evaluated and the result is as if both were omitted,
> except that the constraints on the operators still apply and the result
> is not an lvalue." (C 6.5.3.2p3).
> 
> I could find no corresponding statement in the C++ standard, but
> shouldn't there be one? The C++ version would have to be more
> complicated, to deal with issues that can't come up in C, such as
> operator overloads. However, is there any good reason why there
> shouldn't be a similar clause in the C++ standard? That would make
> Bonita's code perfectly safe.
> 

I looked up exactly the same thing myself.  In C++, this kind of thing
is complicated by overloaded operators.  It is perfectly allowable for
the "*" operator on a class to have side-effects, or do something that
is not normal dereferencing.  The same applies to the "&" operator.  So
it would not be good to say that "&*" is eliminated in the way it is in
C - you would have to say it only applied to standard types, and then
things get inconsistent.

[toc] | [prev] | [next] | [standalone]


#80138

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2021-06-03 20:18 +0300
Message-ID<s9b2se$jrs$1@dont-email.me>
In reply to#80134
03.06.2021 18:06 James Kuyper kirjutas:
> On 6/3/21 5:21 AM, Juha Nieminen wrote:
>> Bonita Montero <Bonita.Montero@gmail.com> wrote:
>>>>> Because i needed something like ptr = &*vec.end() and MSVC has iterator
>>>>> -debugging by default
>>>
>>>> Dereferencing vec.end() is UB, ...
>>>
>>> In theory, but there's for sure no actual vector-implementation
>>> where this doesn't work as long as you don't read from or write
>>> to the reference.
>>
>> The problem with relying on undefined behavior is that you have no
>> guarantees about what the compiler will do to your code.
> 
> The C standard, while describing the unary & operator,says "If the
> operand is the result of a unary * operator, neither that operator nor
> the & operator is evaluated and the result is as if both were omitted,
> except that the constraints on the operators still apply and the result
> is not an lvalue." (C 6.5.3.2p3).
> 
> I could find no corresponding statement in the C++ standard, but
> shouldn't there be one? The C++ version would have to be more
> complicated, to deal with issues that can't come up in C, such as
> operator overloads. However, is there any good reason why there
> shouldn't be a similar clause in the C++ standard? That would make
> Bonita's code perfectly safe.

C does not have user-defined operators. In C++ every iterator has its 
own implementation of operator*() and there is no guarantee that the 
operator & would exactly undo that operation. Indeed, typically it 
cannot and does not. Typically the result of &*iter is a pointer, not an 
iterator, and that's exactly why one might use such a construction in 
the first place.

So in C++ one just cannot "cancel" &* as the result would be of a wrong 
type. It might be possible to make it happen (maybe by adding a special 
operator()&* to the standard which iterator classes would use for 
converting an iterator into a pointer), but the needed legalese seems 
daunting, and the benefits seem pretty meager (satisfying one angry 
Bonita Montero somewhere on the internet; everybody else is happy with 
vec.data()+vec.size()).

[toc] | [prev] | [next] | [standalone]


#80146

FromChris Vine <chris@cvine--nospam--.freeserve.co.uk>
Date2021-06-04 10:22 +0100
Message-ID<20210604102219.27b4d963cb1c5965e78993c3@cvine--nospam--.freeserve.co.uk>
In reply to#80138
On Thu, 3 Jun 2021 20:18:05 +0300
Paavo Helde <myfirstname@osa.pri.ee> wrote:
> 03.06.2021 18:06 James Kuyper kirjutas:
[snip]
> > The C standard, while describing the unary & operator,says "If the
> > operand is the result of a unary * operator, neither that operator nor
> > the & operator is evaluated and the result is as if both were omitted,
> > except that the constraints on the operators still apply and the result
> > is not an lvalue." (C 6.5.3.2p3).
> > 
> > I could find no corresponding statement in the C++ standard, but
> > shouldn't there be one? The C++ version would have to be more
> > complicated, to deal with issues that can't come up in C, such as
> > operator overloads. However, is there any good reason why there
> > shouldn't be a similar clause in the C++ standard? That would make
> > Bonita's code perfectly safe.
> 
> C does not have user-defined operators. In C++ every iterator has its 
> own implementation of operator*() and there is no guarantee that the 
> operator & would exactly undo that operation. Indeed, typically it 
> cannot and does not. Typically the result of &*iter is a pointer, not an 
> iterator, and that's exactly why one might use such a construction in 
> the first place.
> 
> So in C++ one just cannot "cancel" &* as the result would be of a wrong 
> type. It might be possible to make it happen (maybe by adding a special 
> operator()&* to the standard which iterator classes would use for 
> converting an iterator into a pointer), but the needed legalese seems 
> daunting, and the benefits seem pretty meager (satisfying one angry 
> Bonita Montero somewhere on the internet; everybody else is happy with 
> vec.data()+vec.size()).

They shouldn't have been happy with that.  It says something about the
state of the C++ language standard that until C++20, although
std::vector::data() was said to return "A pointer such that [data(),
data() + size()) is a valid range", actually applying pointer
arithmetic to the result of std::vector::data() as in 'vec.data() +
vec.size()' gave undefined behaviour - undefined bahaviour arising from
the use of pointer arithmetic on a pointer not pointing within (or one
past the end of) an array object.

No one seems to have noticed until P0593 arrived on the scene, which
also pointed out that use of the standard's std::uninitialized_*()
functions also generated undefined behaviour, for the same reason.

[toc] | [prev] | [next] | [standalone]


#80147

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2021-06-04 14:19 +0300
Message-ID<s9d28h$c9o$1@dont-email.me>
In reply to#80146
04.06.2021 12:22 Chris Vine kirjutas:
> On Thu, 3 Jun 2021 20:18:05 +0300
> Paavo Helde <myfirstname@osa.pri.ee> wrote:
>> Bonita Montero somewhere on the internet; everybody else is happy with
>> vec.data()+vec.size()).
> 
> They shouldn't have been happy with that.  It says something about the
> state of the C++ language standard that until C++20, although
> std::vector::data() was said to return "A pointer such that [data(),
> data() + size()) is a valid range", actually applying pointer
> arithmetic to the result of std::vector::data() as in 'vec.data() +
> vec.size()' gave undefined behaviour - undefined bahaviour arising from
> the use of pointer arithmetic on a pointer not pointing within (or one
> past the end of) an array object.
> 
> No one seems to have noticed until P0593 arrived on the scene, which
> also pointed out that use of the standard's std::uninitialized_*()
> functions also generated undefined behaviour, for the same reason.

You mean, an array encapsulated by a std::vector might not be an array?

At least https://en.cppreference.com/w/cpp/container/vector/data says:
"Returns pointer to the underlying array serving as element storage."
This wording would make vec.data()+vec.size() legal. Alas, the standard 
indeed uses a different wording.

P0593 seems to be more worried about how it is even possible to 
implement std::vector, this is a bit different topic.

[toc] | [prev] | [next] | [standalone]


#80148

FromChris Vine <chris@cvine--nospam--.freeserve.co.uk>
Date2021-06-04 13:07 +0100
Message-ID<20210604130726.b8021065d2a509588a8fb701@cvine--nospam--.freeserve.co.uk>
In reply to#80147
On Fri, 4 Jun 2021 14:19:44 +0300
Paavo Helde <myfirstname@osa.pri.ee> wrote:
> 04.06.2021 12:22 Chris Vine kirjutas:
> > On Thu, 3 Jun 2021 20:18:05 +0300
> > Paavo Helde <myfirstname@osa.pri.ee> wrote:
> >> Bonita Montero somewhere on the internet; everybody else is happy with
> >> vec.data()+vec.size()).
> > 
> > They shouldn't have been happy with that.  It says something about the
> > state of the C++ language standard that until C++20, although
> > std::vector::data() was said to return "A pointer such that [data(),
> > data() + size()) is a valid range", actually applying pointer
> > arithmetic to the result of std::vector::data() as in 'vec.data() +
> > vec.size()' gave undefined behaviour - undefined bahaviour arising from
> > the use of pointer arithmetic on a pointer not pointing within (or one
> > past the end of) an array object.
> > 
> > No one seems to have noticed until P0593 arrived on the scene, which
> > also pointed out that use of the standard's std::uninitialized_*()
> > functions also generated undefined behaviour, for the same reason.
> 
> You mean, an array encapsulated by a std::vector might not be an array?
> 
> At least https://en.cppreference.com/w/cpp/container/vector/data says:
> "Returns pointer to the underlying array serving as element storage."
> This wording would make vec.data()+vec.size() legal. Alas, the standard 
> indeed uses a different wording.
> 
> P0593 seems to be more worried about how it is even possible to 
> implement std::vector, this is a bit different topic.

std::vector does not encapsulate an array.  std::vector constructs
objects in memory dynamically allocated by malloc, operator new or some
custom allocator.

[expr.add]/4 on pointer arithmetic is clear:

  "When an expression J that has integral type is added to or subtracted
  from an expression P of pointer type, the result has the type of P.

  — If P evaluates to a null pointer value and J evaluates to 0, the
    result is a null pointer value.

  — Otherwise, if P points to an array element i of an array object x
    with n elements, the expressions P + J and J + P (where J has the
    value j) point to the (possibly-hypothetical) array element i + j of
    x if 0 ≤ i + j ≤ n and the expression P - J points to the
    (possibly-hypothetical) array element i − j of x if 0 ≤ i − j ≤ n.

  — Otherwise, the behavior is undefined."

"Array" here means a C-style array, although std::array would do as
that allocates its storage in a C-style array.  std::vector does not.

If you compile 'vec.data()+vec.size()' with the -std=c++20 flag, the
expression is valid (but not otherwise), and that is presumably what
cppreference.com is thinking of.  In C++20 an array is an implicit
lifetime type which is separate from the sub-objects (the elements) it
contains - the latter may or may not be implicit lifetime types.  In
C++20 an array always is, and it will spring into life automatically if
necessary to give the code defined behaviour.  'vec.data()+vec.size()'
creates an array implicitly.  Prior to that the allocated storage
concerned is in super-position, being of both array and non-array type
at the same time (Shroedinger's Array).

As you say, in C++17 it is impossible to implement your own equivalent
of std::vector with defined behaviour, and much else besides.  In C++20
it is at least now possible to build your own vector type and
associated allocators with something approaching defined behaviour.
You can also used std::uninitialized_copy() with defined behaviour.
To be honest, I regard this as a pretty major fail for C++: it turned
out that the C++ standard committee did not understand its own standard
on fairly fundamental points.

[toc] | [prev] | [next] | [standalone]


#80149

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2021-06-04 10:40 -0400
Message-ID<s9de0b$1oe$1@dont-email.me>
In reply to#80138
On 6/3/21 1:18 PM, Paavo Helde wrote:
...
> So in C++ one just cannot "cancel" &* as the result would be of a wrong 
> type.

It could be the right type if the return type of the relevant
operator&() overload is the same as the iterator type.

[toc] | [prev] | [next] | [standalone]


#80150

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2021-06-04 19:28 +0300
Message-ID<s9dkat$j40$1@dont-email.me>
In reply to#80149
04.06.2021 17:40 James Kuyper kirjutas:
> On 6/3/21 1:18 PM, Paavo Helde wrote:
> ...
>> So in C++ one just cannot "cancel" &* as the result would be of a wrong
>> type.
> 
> It could be the right type if the return type of the relevant
> operator&() overload is the same as the iterator type.

In general, it cannot be. Imagine:

class A {
   std::vector<A>::iterator operator&() {
      // magic here???
   }
};

An object in C++ does not know if and in which vector it might reside 
(unless specifically told so, resulting in some pretty convoluted 
design), and so it cannot construct a correct iterator to itself.

Even if it were the "right type" this would not solve the OP's problem 
as she specifically wanted to get a pointer, not an iterator.

[toc] | [prev] | [next] | [standalone]


#80151

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2021-06-04 13:04 -0400
Message-ID<s9dmf9$39b$1@dont-email.me>
In reply to#80150
On 6/4/21 12:28 PM, Paavo Helde wrote:
> 04.06.2021 17:40 James Kuyper kirjutas:
>> On 6/3/21 1:18 PM, Paavo Helde wrote:
>> ...
>>> So in C++ one just cannot "cancel" &* as the result would be of a wrong
>>> type.
>>
>> It could be the right type if the return type of the relevant
>> operator&() overload is the same as the iterator type.
> 
> In general, it cannot be. Imagine:
> 
> class A {
>    std::vector<A>::iterator operator&() {
>       // magic here???
>    }
> };
> 
> An object in C++ does not know if and in which vector it might reside 
> (unless specifically told so, resulting in some pretty convoluted 
> design), and so it cannot construct a correct iterator to itself.
> 
> Even if it were the "right type" this would not solve the OP's problem 
> as she specifically wanted to get a pointer, not an iterator.

I've never attempted implementing any of the standard containers (not
because I couldn't, but just to avoid reinventing the wheel), so I might
be missing some important detail (possibly one introduced by recent
updates - I'm sill more somewhat shaky in my understanding of some of
the features introduced after C++ 2003). However, it seems to me that it
should be possible to implement std::vector<T> with the iterator type
being T*, in which case that wouldn't be a problem. If that's not
feasible, could you explain what's problematic about it?

[toc] | [prev] | [next] | [standalone]


#80153

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2021-06-04 13:30 -0700
Message-ID<s9e2gp$5bb$1@gioia.aioe.org>
In reply to#80151
On 6/4/2021 10:04 AM, James Kuyper wrote:
> On 6/4/21 12:28 PM, Paavo Helde wrote:
>> 04.06.2021 17:40 James Kuyper kirjutas:
>>> On 6/3/21 1:18 PM, Paavo Helde wrote:
>>> ...
>>>> So in C++ one just cannot "cancel" &* as the result would be of a wrong
>>>> type.
>>>
>>> It could be the right type if the return type of the relevant
>>> operator&() overload is the same as the iterator type.
>>
>> In general, it cannot be. Imagine:
>>
>> class A {
>>     std::vector<A>::iterator operator&() {
>>        // magic here???
>>     }
>> };
>>
>> An object in C++ does not know if and in which vector it might reside
>> (unless specifically told so, resulting in some pretty convoluted
>> design), and so it cannot construct a correct iterator to itself.
>>
>> Even if it were the "right type" this would not solve the OP's problem
>> as she specifically wanted to get a pointer, not an iterator.
> 
> I've never attempted implementing any of the standard containers (not
> because I couldn't, but just to avoid reinventing the wheel), so I might
> be missing some important detail (possibly one introduced by recent
> updates - I'm sill more somewhat shaky in my understanding of some of
> the features introduced after C++ 2003). 

I always thought that implementing standard containers in a C++ course 
would be fun. The teacher says something like: We are going to implement 
several std containers under the namespace std_course. Imvvho, it would 
be an interesting and worth while exercise.

> However, it seems to me that it
> should be possible to implement std::vector<T> with the iterator type
> being T*, in which case that wouldn't be a problem. If that's not
> feasible, could you explain what's problematic about it?
> 

[toc] | [prev] | [next] | [standalone]


#80155

FromMrSpook_6qpp@dggw8.org
Date2021-06-05 09:28 +0000
Message-ID<s9fg35$17j4$1@gioia.aioe.org>
In reply to#80153
On Fri, 4 Jun 2021 13:30:16 -0700
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> wrote:
>On 6/4/2021 10:04 AM, James Kuyper wrote:
>> I've never attempted implementing any of the standard containers (not
>> because I couldn't, but just to avoid reinventing the wheel), so I might
>> be missing some important detail (possibly one introduced by recent
>> updates - I'm sill more somewhat shaky in my understanding of some of
>> the features introduced after C++ 2003). 
>
>I always thought that implementing standard containers in a C++ course 
>would be fun. The teacher says something like: We are going to implement 
>several std containers under the namespace std_course. Imvvho, it would 
>be an interesting and worth while exercise.

Writing a basic implementation of a doubly linked list used to be a fairly
standard interview test for C programmers back in the day before C++ became
popular. You'd be amazed (or maybe not) how many of them didn't have a clue
what such a construct even was never mind how to implement it.

[toc] | [prev] | [next] | [standalone]


#80154

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2021-06-04 23:45 +0300
Message-ID<s9e3do$n0q$1@dont-email.me>
In reply to#80151
04.06.2021 20:04 James Kuyper kirjutas:
> On 6/4/21 12:28 PM, Paavo Helde wrote:
>> 04.06.2021 17:40 James Kuyper kirjutas:
>>> On 6/3/21 1:18 PM, Paavo Helde wrote:
>>> ...
>>>> So in C++ one just cannot "cancel" &* as the result would be of a wrong
>>>> type.
>>>
>>> It could be the right type if the return type of the relevant
>>> operator&() overload is the same as the iterator type.
>>
>> In general, it cannot be. Imagine:
>>
>> class A {
>>     std::vector<A>::iterator operator&() {
>>        // magic here???
>>     }
>> };
>>
>> An object in C++ does not know if and in which vector it might reside
>> (unless specifically told so, resulting in some pretty convoluted
>> design), and so it cannot construct a correct iterator to itself.
>>
>> Even if it were the "right type" this would not solve the OP's problem
>> as she specifically wanted to get a pointer, not an iterator.
> 
> I've never attempted implementing any of the standard containers (not
> because I couldn't, but just to avoid reinventing the wheel), so I might
> be missing some important detail (possibly one introduced by recent
> updates - I'm sill more somewhat shaky in my understanding of some of
> the features introduced after C++ 2003). However, it seems to me that it
> should be possible to implement std::vector<T> with the iterator type
> being T*, 

Indeed, there have been implentations where iterator type was T*. 
However, for now the major C++ implementations have abandoned this idea, 
both for more type safety (to avoid accidental conversion from pointers 
to iterators) and for supporting different levels of iterator debugging 
(catching out-of-range iterators, stale iterators, dereferencing 
non-dereferencable iterators like vec.end(), etc).

> in which case that wouldn't be a problem.

There is no problem. There is no need to dereference non-dereferencable 
iterators.

> If that's not
> feasible, could you explain what's problematic about it?

Apparently there is a perceived problem of misusing iterators and a 
desire to provide iterator safety checks and debugging aids. This would 
not be possible if iterators were just plain pointers.

A demo: this program reports a run-time error "Error: attempt to advance 
a [...] iterator 10 steps, which falls outside its valid range." when 
compiled with right options.

 > cat test1.cpp
#include <vector>
#include <algorithm>

int main() {
         std::vector<int> v = {3,2,1,5,2,5,3};
         std::sort(v.begin(), v.begin()+10);
}

 > g++ test1.cpp -D_GLIBCXX_DEBUG
 > ./a.exe
/usr/lib/gcc/x86_64-pc-cygwin/10/include/c++/debug/safe_iterator.h:906:
In function:
     __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*,
     std::__cxx1998::vector<int, std::allocator<int> > >,
     std::__debug::vector<int>, std::random_access_iterator_tag>::_Self
     __gnu_debug::operator+(const _Self&,
     __gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*,
     std::__cxx1998::vector<int, std::allocator<int> > >,
     std::__debug::vector<int>,
     std::random_access_iterator_tag>::difference_type)

Error: attempt to advance a dereferenceable (start-of-sequence) iterator 10
steps, which falls outside its valid range.

Objects involved in the operation:
     iterator @ 0x0xffffcbc0 {
       type = __gnu_cxx::__normal_iterator<int*, 
std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
       state = dereferenceable (start-of-sequence);
       references sequence with type 'std::__debug::vector<int, 
std::allocator<int> >' @ 0x0xffffcb30
     }
Aborted (core dumped)

[toc] | [prev] | [next] | [standalone]


#80140

FromJuha Nieminen <nospam@thanks.invalid>
Date2021-06-03 17:52 +0000
Message-ID<s9b4tg$lee$2@gioia.aioe.org>
In reply to#80134
James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
> The C standard, while describing the unary & operator,says "If the
> operand is the result of a unary * operator, neither that operator nor
> the & operator is evaluated and the result is as if both were omitted,
> except that the constraints on the operators still apply and the result
> is not an lvalue." (C 6.5.3.2p3).
> 
> I could find no corresponding statement in the C++ standard, but
> shouldn't there be one? The C++ version would have to be more
> complicated, to deal with issues that can't come up in C, such as
> operator overloads. However, is there any good reason why there
> shouldn't be a similar clause in the C++ standard? That would make
> Bonita's code perfectly safe.

It's different when dealing with iterators. I thing some std::vector
implementations in fact use raw pointers as iterators, but that's
not guaranteed.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.c++


csiph-web