Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Re: Rationale for base class pure virtual function call fromctor/dtor being undefined behaviour.

Reply
Thread Tools

Re: Rationale for base class pure virtual function call fromctor/dtor being undefined behaviour.

 
 
gwowen
Guest
Posts: n/a
 
      01-17-2012
On Jan 17, 2:11*pm, Leigh Johnston <(E-Mail Removed)> wrote:
> Read:
>
> http://www.open-std.org/jtc1/sc22/wg...ctive.html#230
>
> The above is an open issue that agrees with my position on this issue..


True, but given that there have been two ratified versions since that
issue was first noted, it doesn't seem the committee are minded to
amend the issue.

A single motivating use-case where defined behaviour was
(a) useful and
(b) not trivially obtained by other means
would probably have helped.
 
Reply With Quote
 
 
 
 
gwowen
Guest
Posts: n/a
 
      01-17-2012
On Jan 17, 2:52*pm, Leigh Johnston <(E-Mail Removed)> wrote:
> I agree; this is a rather esoteric corner of C++ we are dealing with. *I
> personally have never had the need in my code to call a pure virtual
> function from a ctor but I nevertheless thought it interesting to post
> about it in this forum.


Don't get me wrong - I'm not criticising you for doing so. I've
learned that you can define pure virtual functions (although you
probably shouldn't ), so I've gained something from your bringing
it up.
 
Reply With Quote
 
 
 
 
gwowen
Guest
Posts: n/a
 
      01-17-2012
On Jan 17, 4:35*pm, "Paul" <pchrist<nospam>(E-Mail Removed)> wrote:

> I think its a handy feature for supplying some default functionality.


But, as far as I can tell, the only benefit over a protected non-
virtual is that you use the same name when calling, so you can write:

class Base
{
public: virtual void f() = 0;
};
void Base::f()
{
//whatever
}
class Derived : public Base
{
public: virtual void f() {
Base::f();
// Derived-specific stuff goes here.
}
}

/// Alternatively, without this language feature
class Base
{
protected: void f_helper() {
//whatever
}
public: virtual void f() = 0;
};
class Derived : public Base
{
public: virtual void f() {
f_helper();
// Derived-specific stuff goes here.
}
}

Is it handy? Well arguably, yes, but its not *very* handy, especially
as I can define f_helper() inline, but can't do so for Base::f().

Is there anything else I can do with it? Well I suppose Base::f()
enables me to do something clever template things with by calling
T::f() in template code.
 
Reply With Quote
 
MikeWhy
Guest
Posts: n/a
 
      01-17-2012
gwowen wrote:
> On Jan 17, 4:35 pm, "Paul" <pchrist<nospam>(E-Mail Removed)> wrote:
> Is [PVF] handy? Well arguably, yes, but ...


The issue isn't that it is or might be useful. It is valid for a class
method to invoke a virtual function. It is also valid for the ctor to call
class methods, which might or might not indirectly invoke a virtual method.
The compiler can't enforce that the ctor cannot indirectly invoke a virtual,
pure or otherwise.

Arguably, then, the PVF with implementation is not really useful, but simply
serves as an escape for defining a benign default action during
construction. The alternative is to always hit the UB behavior on invoking a
PVF. On both g++ and MSVC, the result is abrupt termination.


 
Reply With Quote
 
MikeWhy
Guest
Posts: n/a
 
      01-17-2012
MikeWhy wrote:
> gwowen wrote:
>> On Jan 17, 4:35 pm, "Paul" <pchrist<nospam>(E-Mail Removed)> wrote:
>> Is [PVF] handy? Well arguably, yes, but ...

>
> The issue isn't that it is or might be useful. It is valid for a class
> method to invoke a virtual function. It is also valid for the ctor to
> call class methods, which might or might not indirectly invoke a
> virtual method. The compiler can't enforce that the ctor cannot
> indirectly invoke a virtual, pure or otherwise.
>
> Arguably, then, the PVF with implementation is not really useful, but
> simply serves as an escape for defining a benign default action during
> construction. The alternative is to always hit the UB behavior on
> invoking a PVF. On both g++ and MSVC, the result is abrupt
> termination.


(FWIW, I think the better action is to fix the object model when you
encounter a PVF termination, rather than hide it (forever more) behind the a
default PVF implementation.)


 
Reply With Quote
 
MikeWhy
Guest
Posts: n/a
 
      01-18-2012
"Gareth Owen" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "MikeWhy" <(E-Mail Removed)> writes:
>
>> Arguably, then, the PVF with implementation is not really useful, but
>> simply serves as an escape for defining a benign default action during
>> construction.

>
> With the irony being, as Leigh initially pointed out, this is the one
> thing you're not allowed to do...


I'm a bit vexed this moment. At one point, some earlier version of the
following did manage to print "AbstractBase:ureVirtual()." Toggling the
#if now produces no difference. PVF termination is hit, whether the PVF has
an implementation or not.


#include <iostream>
//================================================== ====
//================================================== ====
class AbstractBase
{
public:
AbstractBase() { foo(); }
virtual ~AbstractBase() {}

void foo() { PureVirtual(); }
private:
virtual void PureVirtual() = 0;
};
//================================================== ====
// not so pure
//##########
#if 1
//##########
void AbstractBase:ureVirtual()
{ std::cout << "AbstractBase:ureVirtual().\n";
}
//##########
#endif
//##########
//================================================== ====
//================================================== ====
class Derived : public AbstractBase
{
public:
Derived() { }
private:
void PureVirtual()
{ std::cout << "Derived:ureVirtual().\n";
}
};

//================================================== ====
//================================================== ====
//================================================== ====

int main(int argc, char **argv)
{
Derived a;
a.foo();

std::cout << "Hello, world!" << std::endl;

return 0;
}


 
Reply With Quote
 
MikeWhy
Guest
Posts: n/a
 
      01-18-2012
"MikeWhy" <(E-Mail Removed)> wrote in message
news:jf75be$8sp$(E-Mail Removed)...
> "Gareth Owen" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
>> "MikeWhy" <(E-Mail Removed)> writes:
>>
>>> Arguably, then, the PVF with implementation is not really useful, but
>>> simply serves as an escape for defining a benign default action during
>>> construction.

>>
>> With the irony being, as Leigh initially pointed out, this is the one
>> thing you're not allowed to do...

>
> I'm a bit vexed this moment. At one point, some earlier version of the
> following did manage to print "AbstractBase:ureVirtual()." Toggling the
> #if now produces no difference. PVF termination is hit, whether the PVF
> has an implementation or not.


Hmmm. The earlier version probably called the PVF directly from the ctor,
rather than indirectly through another method. That would apparently succeed
with a statically scoped, non-virtual call.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Pure virtual functions: declaring a function in a base class Martin C++ 5 08-26-2010 09:52 AM
Non-template class from a template base class with pure virtual methods vilarneto@gmail.com C++ 2 03-25-2007 08:19 PM
Can pure virtual function be called in base class constructor? PengYu.UT@gmail.com C++ 10 10-18-2005 03:45 PM
virtual function and pure virtual function in the implementation of COM IK C++ 2 07-23-2004 02:55 PM
Virtual function 'BasicMidReader::~BasicMidReader()' conflicts with base class 'base 'TMemoryStream' tomek C++ 2 12-01-2003 06:31 AM



Advertisments