Topic: virtual destructors and explicit calls


Author: E.Frejaville@frcl.bull.fr (Etienne Frejaville)
Date: 27 Jan 94 16:22:28 GMT
Raw View
ANSI DRAFT C++ (October 92) says that :

 1. A destructor may be virtual (12.4).
 2. Destructors may be invoked implicitly [... text skipped ]
    and explicitly using the destructor's fully qualified name (12.4)
 3. Explicit qualification with the scope operator suppresses the virtual
    call mechanism (10.2)

 These three rules placed one next to the other bring the following
 question :

 Does explicit qualification with the scope operator on an explicit
 call to a virtual destructor break virtuality ?

 I think that the standard is very imprecise on this point.

 Indeed as the particular case of virtual destructors is not mentioned
 at paragraph 10.2, one could understand that virtuality is also
 broken in that case.

 On the other hand if it was the case, this behaviour would appear as a
 loss of functionality (virtuality would be preserved only through
 implicit calls) due to the rule of paragraph 12.4 that is probably
 used to disambiguate calls like ~A() who could be either an explicit
 call to a destructor in the body of a member function (assuming this->~A())
 or the bitwise complement of the value returned by a call to a function A.

 In my opinion, rule of paragraph 12.4 doesn't infer that such a
 qualification breaks the virtual mechanism for destructors.

 Could someone confirm/invalidate that paragraph 10.2 doesn't apply to virtual
 destructors ?

 Is the last version of the draft more precise on this point ?

 If it's not the case, shouldn't it be made in the next version ?

 Just for fun, here are the results I got with different compilers for
 this question :

 struct A {
  virtual ~A() { cout << "in virtual ~A()\n";}
 };
 struct B : A {
  ~B() { cout << "in ~B()\n";}
 };
 main () {
  A *p=new B;
  p->A::~A();
 }

 result with :

                 | p->A::~A()  |    p->~A()           |
 ------------------------------|----------------------|
 g++ 2.5.7            |  broken     | compiles. not broken |
 cfront 2.0           |  not broken | doesn't compile      |
 IBM's xlC 1.1.2 |  broken     | compiles. not broken |

 In my opinion cfront is doing right but ....

 PS : I dont' know if cfront 3.0' s behaviour is different from 2.0.

  Etienne.


--
--------Etienne FREJAVILLE---Bull S.A   -------------------------------------
 BSP/OSO/MDW/LPS/TOPAS                  e-mail: E.Frejaville@frcl.bull.fr
 Rue Jean-Jaures, F6/1D/17, BP 53       tel: (33-1) 30806548
 78340 Les Clayes-sous-Bois, France     Fax: (33-1) 30807950




Author: fst@nimo.claircom.com (Fariborz Skip Tavakkolian)
Date: Sat, 29 Jan 1994 23:57:40 GMT
Raw View
In article <1352@clbull.frcl.bull.fr> E.Frejaville@frcl.bull.fr (Etienne Frejaville) writes:
>  ANSI DRAFT C++ (October 92) says that :
>
>   1. A destructor may be virtual (12.4).
>   2. Destructors may be invoked implicitly [... text skipped ]
>      and explicitly using the destructor's fully qualified name (12.4)
>   3. Explicit qualification with the scope operator suppresses the virtual
>      call mechanism (10.2)
>
>   These three rules placed one next to the other bring the following
>   question :
>
>   Does explicit qualification with the scope operator on an explicit
>   call to a virtual destructor break virtuality ?

It is ``suppressed''.

>
>   I think that the standard is very imprecise on this point.

If you want confirmation, check the Annotated C++ Reference Manual
Section 12.4 (``Destructors''), Page 280, first paragraph of the page:

 ``As usual, explicit qualification of a function name in a
          call suppresses the virtual function call mechanism.''

> --
> --------Etienne FREJAVILLE---Bull S.A   -------------------------------------
> BSP/OSO/MDW/LPS/TOPAS                  e-mail: E.Frejaville@frcl.bull.fr
> Rue Jean-Jaures, F6/1D/17, BP 53       tel: (33-1) 30806548
> 78340 Les Clayes-sous-Bois, France     Fax: (33-1) 30807950

--
    ********************************************************************
    *  Fariborz ``Skip'' Tavakkolian Claircom Communications Group  *
    *  fst@claircom.com   700 Fifth Ave, Suite 2100      *
    *  (206)389-7150   Seattle, WA.  98104            *
    ********************************************************************




Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Sat, 29 Jan 1994 22:48:41 GMT
Raw View
E.Frejaville@frcl.bull.fr (Etienne Frejaville) writes:

>ANSI DRAFT C++ (October 92) says that :
>
> 1. A destructor may be virtual (12.4).
> 2. Destructors may be invoked implicitly [... text skipped ]
>    and explicitly using the destructor's fully qualified name (12.4)
> 3. Explicit qualification with the scope operator suppresses the virtual
>    call mechanism (10.2)
>
> These three rules placed one next to the other bring the following
> question :
>
> Does explicit qualification with the scope operator on an explicit
> call to a virtual destructor break virtuality ?

Yes.

> I think that the standard is very imprecise on this point.

I don't think so, I think it follows naturally.
Why would it be different for destructors?
Unless otherwise stated, assume that a rule applies to all cases.

> Indeed as the particular case of virtual destructors is not mentioned
> at paragraph 10.2, one could understand that virtuality is also
> broken in that case.

Yes, this is correct.

> On the other hand if it was the case, this behaviour would appear as a
> loss of functionality (virtuality would be preserved only through
> implicit calls) due to the rule of paragraph 12.4 that is probably
> used to disambiguate calls like ~A() who could be either an explicit
> call to a destructor in the body of a member function (assuming this->~A())
> or the bitwise complement of the value returned by a call to a function A.

Perhaps you could quote the rule in question?  I'm working from the ARM,
not the committee's working papers.  I think you're talking about a
rule which disallows the use of plain `~A()' to call a destructor.
There is no loss of functionality.  You can use an explicit `this->~A()'
if you want to call the destructor without suppressing it's virtualness.
You don't need to use `this->~A::A()'.  See the example on page 280 of
the ARM.

>                 | p->A::~A()  |    p->~A()           |
> ------------------------------|----------------------|
> g++ 2.5.7       |  broken     | compiles. not broken |
> cfront 2.0      |  not broken | doesn't compile      |
> IBM's xlC 1.1.2 |  broken     | compiles. not broken |

["broken" => static call, "not broken" => dynamic virtual call]

Cfront 2.0 is wrong, g++ 2.5.7 and xlC 1.1.2 are right.

--
Fergus Henderson - fjh@munta.cs.mu.OZ.AU