Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #84018
| 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> |
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 | Next — Previous in thread | Next in thread | Find similar | Unroll 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