C++ Logo

std-proposals

Advanced search

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

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Sat, 21 Jan 2023 12:49:41 +0000
On Sat, 21 Jan 2023, 12:40 , <language.lawyer_at_[hidden]> wrote:

> On 21/01/2023 17:37, Edward Catmur wrote:
> > On Sat, 21 Jan 2023, 12:34 , <language.lawyer_at_[hidden]> wrote:
> >
> >> On 21/01/2023 17:31, Edward Catmur wrote:
> >>> On Sat, 21 Jan 2023, 12:25 language.lawyer--- via Std-Proposals, <
> >>> std-proposals_at_[hidden]> wrote:
> >>>
> >>>> On 20/01/2023 12:42, Jens Maurer via Std-Proposals wrote:
> >>>>> On 20/01/2023 07.55, Julien Allali via Std-Proposals wrote:
> >>>>>> Hi everyone,
> >>>>>>
> >>>>>> I checked the following code from one of my student:
> >>>>>>
> >>>>>> class I{
> >>>>>> public:
> >>>>>> virtual ~I(){}
> >>>>>> virtual void print(){
> >>>>>> printf("hello %p\n",this);
> >>>>>> }
> >>>>>> virtual void f()=0;
> >>>>>> };
> >>>>>>
> >>>>>> class B : public virtual I{
> >>>>>> int i,j;
> >>>>>> public:
> >>>>>> ~B(){}
> >>>>>> virtual void f(){
> >>>>>> printf("B %p\n",this);
> >>>>>> }
> >>>>>> };
> >>>>>>
> >>>>>>
> >>>>>> void f(I *i){
> >>>>>> for(int j=0;j<5;++j)
> >>>>>> {
> >>>>>> i->print();
> >>>>>> i->f();
> >>>>>> printf("i=%p ",i);
> >>>>>> i++; // PROBLEM IS HERE
> >>>>>> printf(" => %p \n",i);
> >>>>>> }
> >>>>>> }
> >>>>>>
> >>>>>> int main(){
> >>>>>> B b[]={B(),B()};
> >>>>>> printf("B: %p %p\n",b,b+1);
> >>>>>> f(b);
> >>>>>> }
> >>>>>>
> >>>>>> As you can see, I is a non instantiable type as it has one pure
> >> virtual
> >>>>>> method. My concern is about the line "i++": I believed it will lead
> to
> >>>>>> an error or at least a warning (g++ 11.3.0)... Indeed, I can not
> >> imagine
> >>>>>> a valid case where doing arithmetic on a pointer of a type with pure
> >>>>>> virtual function can be valid.... Shouldn't the standard forbid such
> >>>>>> arithmetic?
> >>>>>
> >>>>> Why is the code iterating over 5 elements of a two-element array to
> >>>>> start with?
> >>>>>
> >>>>> Anyway, the "i++" is undefined behavior per [expr.add] p6:
> >>>>>
> >>>>>> For addition or subtraction, if the expressions P or Q have type
> >>>> “pointer to cv T”,
> >>>>>> where T and the array element type are not similar (7.3.6), the
> >>>> behavior is undefined.
> >>>>
> >>>> In f(b), first we get array-to-pointer conversion to get a pointer to
> >> the
> >>>> first array element, and then conversion to pointer to its I base
> class
> >>>> subobject, so the pointer type and the object it points to are
> aligned.
> >>>> Which means there is no UB per [expr.add]/6.
> >>>>
> >>>
> >>> "similar" isn't specified in terms of alignment.
> >>
> >> "aligned" == "coherent/matching/in agreement"
> >>
> >
> > I have no idea what you mean by that. Are you saying that the array
> element
> > type and the base class type are similar?
>
> I mean that doing pointer arithmetic on a «pointer to I» which points at
> object of type I is OK from [expr.add]/6 POV.
>

The base class subobject and pointer type are similar, but the array
element type is not.

>

Received on 2023-01-21 12:49:56