Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #84018

Re: nullptr is not 0

From Andrey Tarasevich <andreytarasevich@hotmail.com>
Newsgroups comp.lang.c++
Subject Re: nullptr is not 0
Date 2022-05-09 22:33 -0700
Organization A noiseless patient Spider
Message-ID <t5ctfr$e3k$1@dont-email.me> (permalink)
References <cone.1652017546.512687.21572.1004@monster.email-scan.com> <t5a7h3$od0$1@gioia.aioe.org> <t5buj0$od3$1@dont-email.me> <t5bv6v$ht7$1@dont-email.me> <t5crob$bf4$1@gioia.aioe.org>

Show all headers | View raw


On 5/9/2022 10:04 PM, Juha Nieminen wrote:
> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>> It is very difficult (if at all possible) to implement proper member
>> function pointers without having to embed some extra information into
>> them, thus bloating their size.
> 
> Isn't that true only for pointers to virtual functions (due to how they
> have to work)? Pointers to regular member functions wouldn't need any
> extra info.
> 

Pointers to member functions do need to store extra information to 
properly handle contra-variant conversions and calls in 
multiple-inheritance contexts. The language specification permits you to 
forcefully `static_cast` pointers to members of `Derived` to pointers to 
members of `Base` even if said member does not exist in the base.

Furthermore, you are allowed to dereference such pointers using a 
reference/pointer to `Base` as long as the dynamic-type of the 
referenced object is `Derived`. Otherwise, the behavior is undefined. 
I.e. the validity of the call is determined at run time.

Here's an example

   #include <iostream>

   struct Base1 { int b = 1; };
   struct Base2
   {
     int b = 2;
     void foo() { std::cout << b << std::endl; }
   };

   struct Derived : Base1, Base2
   {
     int d = 42;
     void bar() { std::cout << d << std::endl; }
   };

   void invoke(Base2 *b, void (Base2::*pfb)())
   {
     (b->*pfb)();
   }

   int main()
   {
     void (Base2::*pfb1)() = &Base2::foo;
     void (Derived::*pfd)() = &Derived::bar;

     void (Base2::*pfb2)() = static_cast<void (Base2::*)()>(pfd); // 1

     Derived d;
     Base2 *pb = &d;
     assert((void *) pb != (void *) &d);

     invoke(pb, pfb1); // 2 OK, calls `d.foo()`
     invoke(pb, pfb2); // 3 OK, calls `d.bar()`

     Base2 b2;
     invoke(&b2, pfb1); // 4 OK, calls `b2.foo()`
     invoke(&b2, pfb2); // 5 UB
   }

The `static_cast` at point 1 is allowed by contra-variant 
pointer-to-member conversion rules.

Now, invocations of member functions through pointers at points 2 and 3 
are perfectly legal.

The most interesting invocation is the one at 3: it is legal 
specifically because `pb` actually points to a `Derived` object. 
However, in order to properly invoke `Derived::bar` the compiler will 
have to supply proper `this` pointer value to `Derived::bar`. And this 
is non-trivial, since that value is numerically different from `pb` 
(because of multiple inheritance). The adjustment of `this` pointer 
value has to occur at run time. And that is where the extra information 
stored in the pointer (base-to-derived offset) comes into the picture.

Invocation at 4 is also legal, while invocation at 5 leads to UB since 
`&b2` does not point to a `Derived` object.

The necessity to support run-time adjustment of `this` pointer when 
calling member functions from other levels of hierarchy is the reason 
member function pointers are forced to store the "offset" value in 
addition to the function entry address.

-- 
Best regards,
Andrey

Back to comp.lang.c++ | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

nullptr is not 0 Sam <sam@email-scan.com> - 2022-05-08 09:45 -0400
  Re: nullptr is not 0 "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-05-08 16:21 +0200
  Re: nullptr is not 0 Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-08 10:00 -0700
  Re: nullptr is not 0 Bonita Montero <Bonita.Montero@gmail.com> - 2022-05-09 06:38 +0200
  Re: nullptr is not 0 Juha Nieminen <nospam@thanks.invalid> - 2022-05-09 05:06 +0000
    Re: nullptr is not 0 Vir Campestris <vir.campestris@invalid.invalid> - 2022-05-09 21:46 +0100
      Re: nullptr is not 0 Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-09 13:57 -0700
        Re: nullptr is not 0 Juha Nieminen <nospam@thanks.invalid> - 2022-05-10 05:04 +0000
          Re: nullptr is not 0 Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-09 22:33 -0700
      Re: nullptr is not 0 scott@slp53.sl.home (Scott Lurndal) - 2022-05-09 21:56 +0000
        Function pointer size (was Re: nullptr is not 0) Vir Campestris <vir.campestris@invalid.invalid> - 2022-05-17 21:30 +0100
          Re: Function pointer size (was Re: nullptr is not 0) scott@slp53.sl.home (Scott Lurndal) - 2022-05-17 21:00 +0000
            Re: Function pointer size (was Re: nullptr is not 0) Vir Campestris <vir.campestris@invalid.invalid> - 2022-05-19 21:52 +0100
            Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 14:08 -0700
          Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-17 17:05 -0700
          Re: Function pointer size (was Re: nullptr is not 0) Juha Nieminen <nospam@thanks.invalid> - 2022-05-18 04:46 +0000
            Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-18 02:14 -0700
              Re: Function pointer size (was Re: nullptr is not 0) Juha Nieminen <nospam@thanks.invalid> - 2022-05-19 14:53 +0000
                Re: Function pointer size (was Re: nullptr is not 0) "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-05-19 17:19 +0200
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 10:14 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Richard Damon <Richard@Damon-Family.org> - 2022-05-19 13:45 -0400
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 11:31 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Juha Nieminen <nospam@thanks.invalid> - 2022-05-20 06:58 +0000
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-20 00:11 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Richard Damon <Richard@Damon-Family.org> - 2022-05-19 12:27 -0400
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 09:47 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Richard Damon <Richard@Damon-Family.org> - 2022-05-19 13:36 -0400
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 11:24 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Richard Damon <Richard@Damon-Family.org> - 2022-05-19 21:32 -0400
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 20:28 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Richard Damon <Richard@Damon-Family.org> - 2022-05-20 10:57 -0400
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 09:35 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-19 10:10 -0700
                Re: Function pointer size (was Re: nullptr is not 0) Juha Nieminen <nospam@thanks.invalid> - 2022-05-20 07:15 +0000
          Re: Function pointer size (was Re: nullptr is not 0) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-05-18 11:50 -0700
            Re: Function pointer size (was Re: nullptr is not 0) Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-05-18 15:46 -0700
              Re: Function pointer size (was Re: nullptr is not 0) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-05-19 20:52 -0700

csiph-web