struct virt { virt() : i(2) {} virt(int i) : i(i){} int i; }; struct der1 : public virtual virt { der1(int i) : virt(i) {} }; struct der2 : public virtual virt { der2(int i) : virt(i) {} }; struct top : public der1, public der2 { top () : der1(0), der2(1) {} }; int main() { top t; } Compiles without comment. However, the null constructor for "virt" is called rather than the explicit constructor that is indicated by the constructor chain from top. In fact, the der* constructors say " : virt(i)" but that sub-constructor will never be called because virt is a virtual base class. I don't know if it is actually an error to try to explicitly construct a virtual base, but is sure is misleading and I think deserves at least a warning.
p.s. I suppose that if there is only a single path to the virtual base then explicit construction is meaningful and the explicit construction in the der* classes is not wrong. But in the constructor for "top" the compiler knows that there are multiple derivations from virt (it has to or it couldn't know to call the null constructor), so the warning could be issued in "top". Something like "base constructor virt(int) in der1(int) bypassed, virt() used instead"? Ivan
This is how C++ is done, maybe a warning can be emitted but it seems like it will emitt too much for valid C++ code.
(In reply to comment #2) > This is how C++ is done, maybe a warning can be emitted but it seems like it > will emitt too much for > valid C++ code. > I don't know; the code shown is very contrived to my taste.
Have you tried compiling with -pedantic -Wall -Wextra ?
No message on 4.1.1 despite -pedantic -Wall -Wextra
Not sure if the summary is 100% correct but it is far better than the previous one.
I've run across this, too. I agree with Ivan's 2005-06-04 suggestion. It would be nice if the compiler would emit a warning that the derived class's constructor's call to the virtual base class's non-default constructor is being ignored and overridden by an implicit call to the virtual base class's default constructor. Similarly, if the virtual base class fails to specify a default constructor (and specifies only a non-default one), the derived class's constructor's call to the virtual base class's non-default constructor produces only this error message: In constructor 'top::top()': error: no matching function for call to 'virt::virt()' which leaves the developer scratching his/her head if he doesn't know that the C++ spec. requires virtual base classes to have default constructors. (True, s/he should know, but the compile error message could be more helpful.) Something to the effect of: "virtual base class lacks default constructor" would be much more helpful. If this issue is different enough to warrant a separate "bug" report, let me know and I'll be happy to file it separately. Thanks.
I've relied on exactly this behaviour and wouldn't want a warning. struct Base : virtual std::ios { Base() : std::ios(0) { } std::streambuf buf; }; struct MyStream : Base, std::iostream { MyStream() : std::iostream(0) { } }; If a concrete Base is constructed I want to call ios::ios(0) but if a MyStream is constructed then I want to call the ios::ios() default ctor and then have iostream::iostream(0) call ios::init(0) If this warning is added (which I'm not convinced it should be) then it should not be given if the most-derived class *explicitly* uses a different ctor for the virtual base i.e. I could suppress the warning by changing the code above like so: MyStream() : std::ios(), std::iostream(0) { } ^^^^^^^^^^^ I also don't think the warning should be given if the unused mem-initializer in der1 and der2 calls the same constructor as is implicitly called by the most-derived class, i.e. if der1 and der2 called virt() then that has the same effect as the implicit initialization done by top. I don't think this should be P2, and I think a better summary would be "Missing warning when virtual base is initialized with different constructor than requested by an ignored mem-initializer"