Hello,

if I compile the following little code snippet:

  #include <stdio.h>
  class A {
  public:
    virtual ~A(void) {}
    static void function1(void) throw() {puts("Hello world\n");}
    void function2(void) throw() {puts("Hello world!\n");}
  };

  int main()
  {
    A a;
    void (*function1)(void) throw()=&A::function1;
    (*function1)();

    void (A::*function2)(void) throw()=&A::function2;
    (a.*function2)();
  }

then gcc will generate a direct call to the referenced function for the
call through the pointer function1 (by "direct" I mean using the address,
instead of using the value in a register)

however for the call through pointer function2 gcc will always generate an
indirect call, i386 assembly for example looks like:

    movl        $_ZN1A9function2Ev, %edx
    movl        %edx, %eax
    testb       $1, %al
    je  .L8
    movl        -12(%ebp), %eax
    movl        _ZN1A9function2Ev-1(%eax), %edx
  .L8:
    leal        -12(%ebp), %esi
    movl        %esi, (%esp)
    call        *%edx

On other architectures it looks similiar (or worse, on PPC for example the
branch is additionally hinted as "predict not taken"...) IMHO the compiler
should be able to conclude that bit 0 of the adress is always cleared
(it is a compile-time constant, no?)

Can someone explain why it is not possible for the compiler to turn this
into a direct call? Is this an ABI thing?

Best regards,
Helge

Reply via email to