C++ Logo

std-proposals

Advanced search

Re: [std-proposals] about incrementing a pointer of a type with pure virtual function

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Mon, 23 Jan 2023 10:03:50 +0000
On 23 January 2023 09:49:05 GMT, Edward Catmur via Std-Proposals <std-proposals_at_[hidden]> wrote:
>On Sun, 22 Jan 2023 at 08:32, Thiago Macieira via Std-Proposals <
>std-proposals_at_[hidden]> wrote:
>
>> On Saturday, 21 January 2023 06:20:25 PST Edward Catmur via Std-Proposals
>> wrote:
>> > Right. The existence of that unary array is somewhat questionable, since
>> it
>> > would not be possible to create such an array within the program. That
>> > aside, you are correct which means that the UB occurs in the next
>> > iteration, when the past the end iterator is indirected.
>>
>> Which points to a valid use-case of sizeof in an abstract class and
>> pointer
>> math with it.
>>
>> template <typename It, typename L> void apply(It begin, It end, L lambda)
>> {
>> for ( ; begin <= end; ++begin)
>> lambda(*begin);
>> }
>>
>> void f(I *ptr)
>> {
>> apply(ptr, ptr+1, [](auto p) { p->something(); });
>> }
>>
>
>That only uses pointer arithmetic, not `sizeof`?

The problem with removing sizeof for abstract classes, is that sizeof is commonly used to detect incompleteness in a static_assert. For example in the body of std::default_delete<T>::operator(), or in 3rd part libraries in similar circumstances.

So because we don't have a more descriptive tool for detecting incompleteness, well-formed sizeof got overloaded with meanings tied to completeness, like "deleting through a pointer to this type will call its destructor".

>I'm not saying this is good code, but it's perfectly valid. I know I've
>> used
>> the "any object is an array of 1" technique.
>>
>> https://gitlab.com/thiagomacieira/qtbase/-/blob/master/src/corelib/tools/
>> qgenericarray.h#L310-313
>> <https://gitlab.com/thiagomacieira/qtbase/-/blob/master/src/corelib/tools/qgenericarray.h#L310-313>
>> (this code is not in production, it was a prototype)
>>
>
> You aren't going to be able to create a QGenericArray of abstract class
>`I`, though?
>
>I feel like we should be moving away from 1-element array views now we have
>iterator-sentinel pairs (e.g. for std::views::single). I guess you might
>want to erase down to a pointer pair, though.
>
>Also, there's the possibility you might want to inspect the memory of an
>abstract base class, e.g. as_bytes(span(static_cast<I*>(&obj), 1)). You
>need either sizeof or pointer arithmetic to do that, so I don't think we
>can talk about making them ill-formed.
>
>Still, a warning flag would be good to experiment with: -Wabstract-sizeof,
>-Wabstract-pointer-arithmetic.

Received on 2023-01-23 10:03:56