Date: Fri, 20 Jan 2023 17:35:30 +0000
On Fri, 20 Jan 2023 at 08:21, Lénárd Szolnoki via Std-Proposals <
std-proposals_at_[hidden]> wrote:
>
>
> On 20 January 2023 07:32:56 GMT, Bo Persson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >On 2023-01-20 at 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?
> >>
> >
> >Incrementing a pointer to a single element creates a one-past-the-end
> pointer for the type. That is ok to *have*, but of course you cannot
> dereference it.
> >
> >
> >
>
> Why do even abstract base classes have a well-formed sizeof?
>
> https://www.eel.is/c++draft/expr.sizeof#1.sentence-1
>
> "The sizeof operator yields the number of bytes occupied by a
> non-potentially-overlapping object of the type of its operand."
>
> An abstract base class can never be non-overlapping, so the value has no
> meaning.
>
> If an abstract base did not have well-formed sizeof, then not having
> well-formed pointer arithmetic would also be consistent with this.
>
Great point; I think it'd be worth exploring.
More directly, it may not be possible to form a type array of abstract
class type - well, clang, MSVC and EDG disallow it, whereas gcc allows it -
I can't work out where if anywhere this is specified?
If it is not possible to form the type array of abstract class type, then
[expr.add]/4.2 is excluded, and pointer arithmetic on an abstract class
type pointer has undefined behavior already (and is readily diagnosable).
I wonder whether there are any compiler modes / static analysis tools that
check for this already (sizeof or pointer arithmetic on abstract types)?
std-proposals_at_[hidden]> wrote:
>
>
> On 20 January 2023 07:32:56 GMT, Bo Persson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >On 2023-01-20 at 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?
> >>
> >
> >Incrementing a pointer to a single element creates a one-past-the-end
> pointer for the type. That is ok to *have*, but of course you cannot
> dereference it.
> >
> >
> >
>
> Why do even abstract base classes have a well-formed sizeof?
>
> https://www.eel.is/c++draft/expr.sizeof#1.sentence-1
>
> "The sizeof operator yields the number of bytes occupied by a
> non-potentially-overlapping object of the type of its operand."
>
> An abstract base class can never be non-overlapping, so the value has no
> meaning.
>
> If an abstract base did not have well-formed sizeof, then not having
> well-formed pointer arithmetic would also be consistent with this.
>
Great point; I think it'd be worth exploring.
More directly, it may not be possible to form a type array of abstract
class type - well, clang, MSVC and EDG disallow it, whereas gcc allows it -
I can't work out where if anywhere this is specified?
If it is not possible to form the type array of abstract class type, then
[expr.add]/4.2 is excluded, and pointer arithmetic on an abstract class
type pointer has undefined behavior already (and is readily diagnosable).
I wonder whether there are any compiler modes / static analysis tools that
check for this already (sizeof or pointer arithmetic on abstract types)?
Received on 2023-01-20 17:35:43