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

            Bug ID: 80849
           Summary: Brace-init causes multiple runs of virtual base ctor
                    if its signature differs from its derived classes'
                    ctors
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: db0451 at gmail dot com
  Target Milestone: ---

This appears to be a lingering offshoot of this:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66617

which I was reminded of via:
http://stackoverflow.com/questions/38466871/invoking-constructors-during-virtual-inheritance-with-c


As the user on SO reported, and verified with GDB, when they are initialised
using braces, the intermediate classes' constructors also invoke the virtual
base class's constructor, redundantly. They were using 5.4.0


With additional testing, on 6.3.0, I determined that - much like that other old
bug - this problem only occurs if the virtual base constructor and the
constructors of the intermediate derived classes have different argument
signatures.


reduced test case:

        #include <iostream>

        // Choose one:
        //#define DB_INITIALISE(...) (__VA_ARGS__)
        #define DB_INITIALISE(...) {__VA_ARGS__}

        struct V {
                V(int i) { std::cout << 'V' << i << std::endl; }
        };

        struct A:  virtual V {
                A(int i, char c): V DB_INITIALISE(i) { std::cout << 'A' << i <<
c << std::endl; }
        };

        struct B:  virtual V {
                B(int i, char c): V DB_INITIALISE(i) { std::cout << 'B' << i <<
c << std::endl; }
        };

        struct C:  A,  B {
                C(int i, char c): V DB_INITIALISE(i), A DB_INITIALISE(i, c), B
DB_INITIALISE(i, c) { std::cout << 'C' << i << c << std::endl; }
        };

        int main()
        {
                C c{42, '?'};
        }

Expected output, obtained when DB_INITIALISE causes initialisation with ():

        V42
        A42?
        B42?
        C42?

Actual output, obtained when DB_INITIALISE causes initialisation with {}:

        V42
        V42
        A42?
        V42
        B42?
        C42?

Like the other bug, if you alter the constructors of V, A, and B to have the
same number/type of arguments, then the problematic extra calls are suppressed.

Reply via email to