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


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

Re: Function pointer size (was Re: nullptr is not 0)

Subject Re: Function pointer size (was Re: nullptr is not 0)
Newsgroups comp.lang.c++
References (5 earlier) <t61tn1$1gd6$1@gioia.aioe.org> <t62ddu$41b$1@dont-email.me> <t65lls$1nug$1@gioia.aioe.org> <IduhK.86$vAW9.18@fx10.iad> <t65sau$jta$1@dont-email.me>
From Richard Damon <Richard@Damon-Family.org>
Message-ID <IevhK.7$x7oc.1@fx01.iad> (permalink)
Organization Forte - www.forteinc.com
Date 2022-05-19 13:36 -0400

Show all headers | View raw


On 5/19/22 12:47 PM, Andrey Tarasevich wrote:
> On 5/19/2022 9:27 AM, Richard Damon wrote:
>>>
>>> Thus, the compiler needs to create code that somehow figures out if
>>> that member function is virtual, and which function it is, and then
>>> use the vtable as normal to jump to the actual most-derived 
>>> implementation.
>>> I don't think it can do this without the extra data in the pointer.
>>> (Well, I suppose it theoretically could, but that might require some
>>> searching).
>>>
>>> Please correct me if I'm wrong. (Honestly. This isn't sarcasm.)
>>
>> Yes that sort of describes the problem. The pointer to member needs to 
>> be able to refer to a virtual function, or even a function that is a 
>> member of a virtual base class, and handling that sort of stuff is 
>> what forces the extra memory in the pointer-to-member.
> 
> That's incorrect in general. Again, using x86 as a counterexample:
> 
> Implementations that use different representations for virtual vs. 
> non-virtual member pointers (GCC, Clang) manage to stuff that extra 
> information into the "original" memory - they use the lowest bit of the 
> pointer as a flag.
> 
> Implementations that use identical representations for virtual vs. 
> non-virtual member pointers (MSVC) naturally don't have this issue at all.
> 
> So, no, the need to handle virtual functions does not require extra 
> memory in pointer-to-member function.

But not all processors have a LSB to use for that sort of flag.

Some have instructions that can be at any address, because the 
instruction set has single byte opcodes (They could just force all 
functions to be at addresses with lower order zeros, but that is wasteful)

Others, like the ARM, use the low order bit to indicate which 
instruction set the function is written in, so it isn't available for 
such a use.

Thus, there sometimes IS a need for an additional flag bit to indicate 
if the pointer is an index into the v-table or the actual address of the 
function.

> 
>> I remember seeing documentation in one compiler that gave options for 
>> "optimizations" where you could limit what sort of member functions 
>> you could take the address of to make the pointers smaller. Omitting 
>> the handling of Virtual Base classes, or those and virtual functions 
>> (I forget if there was some other level).
> 
> Well, you forget.
> 
> These optimizations have absolutely nothing to do with virtual 
> functions. They have everything to do with the hierarchy structure. They 
> depend on the answer to one question: is it necessary to correct the 
> `this` pointer value when making a call?

Not to my knowledge. That adjustment tends to be done by a "Thunk" to 
correct the base address of "this" for non-first base classes. This 
needs to happen even without pointer-to-member functions, as if you call 
a virtual function from a pointer to a non-first base that is 
over-ridden after the multiple-inheritance. The virtual-function table 
for that non-first base will point to the thunk doing the adjustment, 
will the same class will have another virtual-function table for uses 
that refer to the class or its first base class.

Deciding if the "pointer" is an actual address of the function or an 
offest into the virtual function table is orthogonal to that, and is an 
issue even with multiple inheretance that needs that fixup.

> 
> Correction to `this` might be necessary in case of multiple inheritance, 
> in case of virtual inheritance and in some other niche cases. This 
> correction is what the extra memory in pointer-to-member function 
> stores. This is why pointer-to-member-function is larger than an 
> ordinary pointer.
> 
> But it has nothing to do with calls to virtual functions.
> 

Nope, because the pointer-to-member function pointer has no idea of the 
type of the object that it will be used on, so CAN'T store the full 
offset. (That is the job of the Thunk).

But it may be needed for a pointer-to-member function pointer which 
doesn't always hold the address of the member function to call but 
sometimes an offset/index into the vtable.

As an example:

class B {
public:
             void f1();
     virtual void f2();
}

class D : public B {
public:
     virtual void f2();
}

we take the member-function-pointers

void (B::*ptr1)() = &B::f1;
void (B::*ptr2)() = &B::f2;


B b;
D d;

b*->ptr1() vs b *->ptr2() vs d*->ptr1() vs d*->ptr2()

There is a need to know that the "value" stored in ptr1 is the actual 
address of B:f1(), while ptr2 is storing an offset into the vtable of B 
for the member function.

ptr2 can NOT just have the address of B::f2() as if derived class D 
overrides f2(), then the call via ptr2 needs to go to D::f2().

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