Date: Sat, 21 Jan 2023 17:40:34 +0500
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.
> 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.
Received on 2023-01-21 12:40:39