Date: Sat, 21 Jan 2023 12:31:26 +0000
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.
>
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.
>
Received on 2023-01-21 12:31:41