Re: How do I remove GLIBCXX_ASSERTIONS?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Andrew Lutomirski writes:

On a cursory search of the standard, I couldn't find where it says
what operator* on this type of iterator does at all, let alone whether
it's valid for one-past-the-end iterators, but I'm pretty sure that
your code is, indeed, wrong.

This finally piqued my curiosity enough to take some time to look into this. That expression applied the "*" operator to a random access iterator. So, going down the path:

# [random.access.iterators]
#
# A class or pointer type X satisfies the requirements of a random access # iterator if, in addition to satisfying the requirements for bidirectional # iterators, ...

In a similar fashion, a bidirectional iterator delegates some requirements to a forward iterator.

The forward iterator delegates some of its requirements to an input iterator.

At the end of the road, in [input.iterators]:

#  *a      reference,   convertible to T     Requires: a is dereferenceable.

Then, finally, in [iterator.requirements.general]:

# Values of an iterator i for which the expression *i is defined are called # dereferenceable.

This reads to me like a definition that circularly defines itself. [input.iterators] says "*a requires that a is dereferencable". And [iterator.requirements.general] says that something is dereferencable if "*" for it is defined. That certainly clears that up…

Full disclosure: it's true that the next sentence is:

# The library never assumes that past-the-end values are dereferenceable.

But this only states that the library assumes that, it doesn't authoritatively state that.

But going back to the previous point, if we also want to see what going down "*i refers the unary * operator" route, as a means of avoiding the self- definition, we see that:

# [expr.unary.op]
#
# The unary * operator performs indirection: … the result is an lvalue

Nothing here requires the pointer to be valid, just that "*" gives you an lvaule. Nothing more, nothing else. That's it. Whether the pointer is valid, this gets punted only when the lvalue-to-rvalue conversion take place:

# [conv.lval]
#
# ... if the object to which the glvalue refers contains an invalid pointer
# value the behavior is implementation-defined.

But if you immediately apply the & operator, this conversion never takes place.

The C standard is even more explicit, and even blesses this construct, verbatim:

# The unary & operator yields the address of its operand.
# [ … ]
#
# if the operand is the result of a [] operator, neither the & operator # nor the unary * that is implied by the [] is evaluated and the result is as # if the & operator were removed and the [] operator were changed to a + # operator

I could not find some similar verbiage in the C++ standard, but based on all of the above I have to conclude that this is …too late today, and I should really get some sleep…

But not after rereading the specification for a vector itself, where I found something I glossed over the first time:

# [vector]
#
# A vector satisfies all of the requirements of a container and … of a # contiguous container.

The reference from "contiguous container" goes to:

# [container.requirements.general]
#
# A contiguous container is a container that supports random access iterators
# and whose member types iterator and const_iterator are contiguous iterators.

The reference from "contiguous iterators" goes to:

# [iterator.requirements.general]
#
# Iterators that further satisfy the requirement that, for integral values
# n and dereferenceable iterator values a and (a + n), *(a + n) is
# equivalent to *(addressof(*a) + n), are called contiguous iterators.

There might be more to the "contiguous" semantics that reflects on whether or not "&foo[foo.size()]" is defined behavior, or not, but here addressof(*a) already puts us squarely in pointer equivalence territory, and seems to again go into the unary "*" operator direction here, despite the conflicting wording.

…now it's definitely too late in the day.
_______________________________________________
devel mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxx
Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: https://lists.fedoraproject.org/archives/list/devel@xxxxxxxxxxxxxxxxxxxxxxx




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Fedora Announce]     [Fedora Users]     [Fedora Kernel]     [Fedora Testing]     [Fedora Formulas]     [Fedora PHP Devel]     [Kernel Development]     [Fedora Legacy]     [Fedora Maintainers]     [Fedora Desktop]     [PAM]     [Red Hat Development]     [Gimp]     [Yosemite News]

  Powered by Linux