https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80575

            Bug ID: 80575
           Summary: unnecessary virtual function table support in member
                    function call
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: drepper.fsp+rhbz at gmail dot com
  Target Milestone: ---

Created attachment 41288
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41288&action=edit
example for ineffectiveness of final with member function pointers

The support for virtual function requires more complex code at the call site
through a member function pointer.  gcc has some support to elide the handling
of virtual functions.  Take the following code:

struct foo {
  int a = 0, b =0;
  int get1() const { return a; }
  int get2() const { return a + b; }
};

foo f;
int (foo::*mfp)() const = &foo::get1;

int get()
{
  return (f->*mfp)();
}

The generated code (on x86-64) for get is:

        movq    mfp+8(%rip), %rax
        leaq    f(%rax), %rdi
        jmp     *mfp(%rip)

Perfectly fine.  If now the variable 'f' is changed to a pointer the code looks
like this:

        movq    mfp(%rip), %rax
        movq    mfp+8(%rip), %rdi
        addq    f(%rip), %rdi
        testb   $1, %al
        je      .L4
        movq    (%rdi), %rdx
        movq    -1(%rdx,%rax), %rax
.L4:
        jmp     *%rax

This is due to the fact that other classes derived can be derived from 'foo'
and those could have virtual functions.

To prevent this it should be possible to mark 'foo' as final.  If you do this
nothing changes, though.

--- u.cc-old    2017-04-30 16:30:50.704469153 +0200
+++ u.cc        2017-04-30 16:24:56.619672469 +0200
@@ -1,4 +1,4 @@
-struct foo {
+struct foo final {
   int a = 0, b =0;
   int get1() const { return a; }
   int get2() const { return a + b; }

Reply via email to