Date: Sat, 21 Jan 2023 13:01:21 +0000
On Sat, 21 Jan 2023, 12:57 , <language.lawyer_at_[hidden]> wrote:
> On 21/01/2023 17:49, Edward Catmur wrote:
> > 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.
>
> How can T in «pointer to T» expression type be similar to the type of the
> base class subobject, and not similar to the «array element type» at the
> same time, when array element here is the base class subobject?
>
The array element type is B. The base class subobject type is I. These are
different types.
>
> On 21/01/2023 17:49, Edward Catmur wrote:
> > 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.
>
> How can T in «pointer to T» expression type be similar to the type of the
> base class subobject, and not similar to the «array element type» at the
> same time, when array element here is the base class subobject?
>
The array element type is B. The base class subobject type is I. These are
different types.
>
Received on 2023-01-21 13:01:35