Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #80079 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2021-06-02 14:49 +0200 |
| Last post | 2021-06-03 17:52 +0000 |
| Articles | 15 on this page of 35 — 13 participants |
Back to article view | Back to comp.lang.c++
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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2021-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]
| From | MrSpook_ujp@3p26kggzpvpn2h.gov.uk |
|---|---|
| Date | 2021-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2021-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2021-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]
| From | Chris Vine <chris@cvine--nospam--.freeserve.co.uk> |
|---|---|
| Date | 2021-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2021-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]
| From | Chris Vine <chris@cvine--nospam--.freeserve.co.uk> |
|---|---|
| Date | 2021-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2021-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2021-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2021-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]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-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]
| From | MrSpook_6qpp@dggw8.org |
|---|---|
| Date | 2021-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2021-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2021-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