Topic: Suggestion for a compile-time error if a virtual


Author: wsemmelink@gmail.com
Date: Mon, 24 Mar 2014 09:21:53 -0700 (PDT)
Raw View
------=_Part_219_9465112.1395678113110
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

=20

This suggestion is not intended on changing the language specification as=
=20
such, but to suggest that a means be found/specified for compilers to check=
=20
at compile-time for the virtual destructor. I am a developer by profession,=
=20
and C++ is no longer our main language, so I argue perhaps from ignorance,=
=20
and I apologize if this has been suggested and evaluated before.   =20

Current best practice if the base class is intended to be polymorphic, is=
=20
to make the destructor virtual as well [Stroustrup IV, 17.2.5]. But=20
programmers forget to do this just as they forget to delete after new. For=
=20
the latter problem, research the last two or decades (or longer?) led to=20
smart pointers, garbage collectors, and tool support (like overloaded new a=
nd=20
delete in debug builds that increment a reference counter on new and=20
decrement on delete). However for polymorphic classes the programmer is on=
=20
her/his own, and has to remember to type virtual.  Forgetfulness,=20
ignorance, or maintenance of a complex system can lead to overlooking the=
=20
virtual destructor and the resulting resource leaks can be hard to discover=
=20
and fix. =20

Therefore this suggestion is for an ideal to have a compiler throw a=20
compile-time error on a polymorphic base class without a virtual=20
destructor. This of course begs the question how the compiler can discover=
=20
the intent to override such base class polymorphically. My suggestions may=
=20
be idealistic, or ignorant, but I would like to give it a go. =20

* The presence of at least one virtual function is a good, but not=20
fail-safe indication. Common standard practice is the advice that=20
programmers should make a class destructor virtual if at least one function=
=20
in it is virtual. Certainly a compiler can check that, but it may be a too=
=20
harsh check as existing code could break, especially classes not intended=
=20
to be deleted via a base pointer (treated further below). Could one=20
implement a #pragma switch to bypass the check if need be? =20

* In order to refine the check, the evaluation can be on the derived class.=
=20
When a function fx in a derived class overrides the virtual function fx of=
=20
the base class, we have a base class being overloaded, and that base class=
=20
has at least one virtual function. In the spirit of the advice =E2=80=9Cif =
your=20
base class has at least one virtual method, make the destructor virtual=E2=
=80=9D a=20
compiler can be made to check if such a base class has a virtual=20
destructor.=20

* *Both the* above suggestions assume the programmer will in fact call=20
delete on a base class pointer. This may not be the case, and the above=20
checks may therefore be over keen, especially for old code. Now the ideal=
=20
will be to catch the error where it is made. So what if the compiler can at=
=20
the point where delete is called, determine a base class pointer is used to=
=20
destroy a derived class, and then issue a check if the base class has a=20
virtual destructor. Here I make a huge assumption that such a condition can=
=20
be checked at compile time (we're talking about runtime polymorphism now),=
=20
so I can imagine compiler developers frowning at this suggestion. But here=
=20
I am at the limit of what I can think to suggest.=20

A push beyond my intent to not modify the language may be to venture=20
exactly there. Perhaps the definition I found below could be made more=20
specific a =E2=80=9Csyntax error=E2=80=9D instead of "undefined behaviour" =
to make=20
compilers throw a compile-time error on the issue.

* =E2=80=9CDeleting an object through pointer to base invokes undefined beh=
avior=20
unless the destructor in the base class is virtual:=E2=80=9D [*
http://en.cppreference.com/w/cpp/language/destructor]


Thanks for reading.=20

Willem Semmelink, Software developer.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_219_9465112.1395678113110
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><!--[if gte mso 9]><xml>
 <o:OfficeDocumentSettings>
  <o:RelyOnVML/>
  <o:AllowPNG/>
 </o:OfficeDocumentSettings>
</xml><![endif]-->

<p class=3D"MsoNormal">This suggestion is not intended on changing the lang=
uage
specification as such, but to suggest that a means be found/specified for c=
ompilers to
check at compile-time for the virtual destructor. I am a developer by profe=
ssion, and C++ is no longer our main language, so I argue perhaps from igno=
rance, and I apologize if this has been suggested and evaluated before. &nb=
sp;&nbsp; <br></p>

<p class=3D"MsoNormal">Current best practice if the base class is intended =
to be
polymorphic, is to make the destructor virtual as well  [Stroustrup IV, 17.=
2.5]<span style=3D"mso-spacerun:yes"></span>. But programmers forget
to do this just as they forget to <span style=3D"font-size:9.0pt;line-heigh=
t:
115%;font-family:Consolas">delete </span>after <span style=3D"font-size:9.0=
pt;
line-height:115%;font-family:Consolas">new</span>. For the latter problem, =
research
the last two or decades (or longer?) led to smart pointers, garbage collect=
ors,
and tool support (like overloaded <span style=3D"font-size:9.0pt;
line-height:115%;font-family:Consolas">new </span>and <span style=3D"font-s=
ize:9.0pt;line-height:
115%;font-family:Consolas">delete </span>in debug builds that increment
a reference counter on new and decrement on delete). However for polymorphi=
c
classes the programmer is on her/his own, and has to remember to type <span=
 style=3D"font-size:9.0pt;
line-height:115%;font-family:Consolas">virtual</span>.<span style=3D"mso-sp=
acerun:yes">&nbsp; </span>Forgetfulness, ignorance, or
maintenance of a complex system can lead to overlooking the virtual destruc=
tor
and the resulting resource leaks can be hard to discover and fix.&nbsp; <br=
></p>

<p class=3D"MsoNormal">Therefore this suggestion is for an ideal to have a =
compiler throw a compile-time error on a polymorphic
base class without a virtual destructor. This of course begs the question h=
ow the compiler can discover the intent to
override such base class polymorphically. My suggestions may be idealistic,=
 or ignorant, but I would like to give it a go. <span style=3D"mso-spacerun=
:yes">&nbsp;</span></p>

<p class=3D"MsoNormal">* The presence of at least one virtual function is a=
 good,
but not fail-safe indication. Common standard practice is the advice that
programmers should make a class destructor virtual if at least one function=
 in
it is virtual. Certainly a compiler can check that, but it may be a too har=
sh check as existing
code could break, especially classes not intended to be deleted via a base =
pointer (treated further below). Could one implement a #pragma switch to by=
pass the check if need be? <span style=3D"mso-spacerun:yes">&nbsp;</span></=
p>

<p class=3D"MsoNormal">* In order to refine the check, the evaluation can b=
e on the derived class. When a function fx in a derived class overrides the
virtual function fx of the base class, we have a base class being overloade=
d, and that base class has at least one virtual function. In the spirit of =
the advice =E2=80=9Cif
your base class has at least one virtual method, make the destructor virtua=
l=E2=80=9D a compiler can be made to check if such a base class has a virtu=
al destructor. </p>

<p class=3D"MsoNormal">* <i>Both the</i> above suggestions assume the progr=
ammer
will in fact call delete on a base class pointer. This may not be the case,=
 and
the above checks may therefore be over keen, especially for old code. Now
the ideal will be to catch the error where it is made. So what if the compi=
ler can at the point where <span style=3D"font-size:9.0pt;line-height:
115%;font-family:Consolas">delete </span>is called, determine
a base class pointer is used to destroy a derived class, and then issue a
check if the base class has a virtual destructor. Here I make a
huge assumption that such a condition can be checked at compile time (we're=
 talking about runtime polymorphism now), so I
can imagine compiler developers frowning at this suggestion. <span style=3D=
"mso-spacerun:yes">But here I am at the limit of what I can think to sugges=
t. <br></span></p>

<p class=3D"MsoNormal">A push beyond my intent to not modify the language m=
ay be to venture exactly there. Perhaps the definition I found below could =
be made more
specific a =E2=80=9Csyntax error=E2=80=9D instead of "undefined behaviour" =
to make compilers throw a compile-time error on the
issue.</p>

<p class=3D"MsoNormal"><i><span style=3D"mso-spacerun:yes">&nbsp;</span>=E2=
=80=9CDeleting an
object through pointer to base invokes undefined behavior unless the destru=
ctor
in the base class is virtual:=E2=80=9D [</i>http://en.cppreference.com/w/cp=
p/language/destructor]</p><p class=3D"MsoNormal"><br></p><p class=3D"MsoNor=
mal">Thanks for reading. <br></p><p class=3D"MsoNormal">Willem Semmelink, S=
oftware developer.<br></p>

<!--[if gte mso 9]><xml>
 <w:WordDocument>
  <w:View>Normal</w:View>
  <w:Zoom>0</w:Zoom>
  <w:TrackMoves/>
  <w:TrackFormatting/>
  <w:PunctuationKerning/>
  <w:ValidateAgainstSchemas/>
  <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
  <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
  <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
  <w:DoNotPromoteQF/>
  <w:LidThemeOther>EN-ZA</w:LidThemeOther>
  <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
  <w:LidThemeComplexScript>HE</w:LidThemeComplexScript>
  <w:Compatibility>
   <w:BreakWrappedTables/>
   <w:SnapToGridInCell/>
   <w:WrapTextWithPunct/>
   <w:UseAsianBreakRules/>
   <w:DontGrowAutofit/>
   <w:SplitPgBreakAndParaMark/>
   <w:DontVertAlignCellWithSp/>
   <w:DontBreakConstrainedForcedTables/>
   <w:DontVertAlignInTxbx/>
   <w:Word11KerningPairs/>
   <w:CachedColBalance/>
  </w:Compatibility>
  <m:mathPr>
   <m:mathFont m:val=3D"Cambria Math"/>
   <m:brkBin m:val=3D"before"/>
   <m:brkBinSub m:val=3D"&#45;-"/>
   <m:smallFrac m:val=3D"off"/>
   <m:dispDef/>
   <m:lMargin m:val=3D"0"/>
   <m:rMargin m:val=3D"0"/>
   <m:defJc m:val=3D"centerGroup"/>
   <m:wrapIndent m:val=3D"1440"/>
   <m:intLim m:val=3D"subSup"/>
   <m:naryLim m:val=3D"undOvr"/>
  </m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
 <w:LatentStyles DefLockedState=3D"false" DefUnhideWhenUsed=3D"true"
  DefSemiHidden=3D"true" DefQFormat=3D"false" DefPriority=3D"99"
  LatentStyleCount=3D"267">
  <w:LsdException Locked=3D"false" Priority=3D"0" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Normal"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"heading 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 7"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 8"/>
  <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D"=
heading 9"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 7"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 8"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" Name=3D"toc 9"/>
  <w:LsdException Locked=3D"false" Priority=3D"35" QFormat=3D"true" Name=3D=
"caption"/>
  <w:LsdException Locked=3D"false" Priority=3D"10" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Title"/>
  <w:LsdException Locked=3D"false" Priority=3D"1" Name=3D"Default Paragraph=
 Font"/>
  <w:LsdException Locked=3D"false" Priority=3D"11" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Subtitle"/>
  <w:LsdException Locked=3D"false" Priority=3D"22" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Strong"/>
  <w:LsdException Locked=3D"false" Priority=3D"20" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Emphasis"/>
  <w:LsdException Locked=3D"false" Priority=3D"59" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Table Grid"/>
  <w:LsdException Locked=3D"false" UnhideWhenUsed=3D"false" Name=3D"Placeho=
lder Text"/>
  <w:LsdException Locked=3D"false" Priority=3D"1" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"No Spacing"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 1"/>
  <w:LsdException Locked=3D"false" UnhideWhenUsed=3D"false" Name=3D"Revisio=
n"/>
  <w:LsdException Locked=3D"false" Priority=3D"34" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"List Paragraph"/>
  <w:LsdException Locked=3D"false" Priority=3D"29" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Quote"/>
  <w:LsdException Locked=3D"false" Priority=3D"30" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Intense Quote"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 1"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 2"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 3"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 4"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 5"/>
  <w:LsdException Locked=3D"false" Priority=3D"60" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Shading Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"61" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light List Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"62" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Light Grid Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"63" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 1 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"64" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Shading 2 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"65" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 1 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"66" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium List 2 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"67" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 1 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"68" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 2 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"69" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Medium Grid 3 Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"70" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Dark List Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"71" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Shading Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"72" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful List Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"73" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" Name=3D"Colorful Grid Accent 6"/>
  <w:LsdException Locked=3D"false" Priority=3D"19" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Subtle Emphasis"/>
  <w:LsdException Locked=3D"false" Priority=3D"21" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Intense Emphasis"/>
  <w:LsdException Locked=3D"false" Priority=3D"31" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Subtle Reference"/>
  <w:LsdException Locked=3D"false" Priority=3D"32" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Intense Reference"/>
  <w:LsdException Locked=3D"false" Priority=3D"33" SemiHidden=3D"false"
   UnhideWhenUsed=3D"false" QFormat=3D"true" Name=3D"Book Title"/>
  <w:LsdException Locked=3D"false" Priority=3D"37" Name=3D"Bibliography"/>
  <w:LsdException Locked=3D"false" Priority=3D"39" QFormat=3D"true" Name=3D=
"TOC Heading"/>
 </w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
 /* Style Definitions */
 table.MsoNormalTable
 {mso-style-name:"Table Normal";
 mso-tstyle-rowband-size:0;
 mso-tstyle-colband-size:0;
 mso-style-noshow:yes;
 mso-style-priority:99;
 mso-style-qformat:yes;
 mso-style-parent:"";
 mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
 mso-para-margin-top:0cm;
 mso-para-margin-right:0cm;
 mso-para-margin-bottom:10.0pt;
 mso-para-margin-left:0cm;
 line-height:115%;
 mso-pagination:widow-orphan;
 font-size:11.0pt;
 font-family:"Calibri","sans-serif";
 mso-ascii-font-family:Calibri;
 mso-ascii-theme-font:minor-latin;
 mso-fareast-font-family:"Times New Roman";
 mso-fareast-theme-font:minor-fareast;
 mso-hansi-font-family:Calibri;
 mso-hansi-theme-font:minor-latin;}
</style>
<![endif]--></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_219_9465112.1395678113110--

.


Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 24 Mar 2014 12:40:43 -0400
Raw View
On 2014-03-24 12:21, wsemmelink@gmail.com wrote:
> [...]
> Therefore this suggestion is for an ideal to have a compiler throw a
> compile-time error on a polymorphic base class without a virtual
> destructor.

At least gcc already has a flag to do this: -Werror=3Dvirtual-dtor.

> Could one implement a #pragma switch to bypass the check if need be?

I've never tried / needed to do so, but I imagine you could temporarily=20
disable the above long enough to declare an "intentionally offending"=20
dtor. (I think the utility of such a dtor is questionable however; sure,=20
you can concoct scenarios where you will never delete a derived class=20
except via a pointer to the actual type, but I think those are rare, and=20
the cost of a virtual dtor is not that high.)

> * In order to refine the check, the evaluation can be on the derived clas=
s.
> When a function fx in a derived class overrides the virtual function fx o=
f
> the base class, we have a base class being overloaded, and that base clas=
s
> has at least one virtual function. In the spirit of the advice =E2=80=9Ci=
f your
> base class has at least one virtual method, make the destructor virtual=
=E2=80=9D a
> compiler can be made to check if such a base class has a virtual
> destructor.

I'm unconvinced of the wisdom of deferring the check. What if the=20
derived class is e.g. a plugin in a separate 'project unit'? The error=20
would then exist in a file that lives outside the project where it is=20
diagnosed, with no chance to diagnose it in the project that actually=20
contains the error.

> A push beyond my intent to not modify the language may be to venture
> exactly there. Perhaps the definition I found below could be made more
> specific a =E2=80=9Csyntax error=E2=80=9D instead of "undefined behaviour=
" to make
> compilers throw a compile-time error on the issue.
>
> * =E2=80=9CDeleting an object through pointer to base invokes undefined b=
ehavior
> unless the destructor in the base class is virtual:=E2=80=9D [*
> http://en.cppreference.com/w/cpp/language/destructor]

The compiler cannot be reasonably expected to know this at compile time=20
(see also 'halting problem').

--=20
Matthew

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 24 Mar 2014 11:55:30 -0500
Raw View
--047d7b66f637d7a87004f55d1cbf
Content-Type: text/plain; charset=ISO-8859-1

On 24 March 2014 11:21, <wsemmelink@gmail.com> wrote:

>  Current best practice if the base class is intended to be polymorphic,
> is to make the destructor virtual as well
>

That is one possibility.  Another is to declare the destructor protected.
 Yet another is to use a type erased smart pointer (such as shared_ptr).  I
don't see a reason to favor one in particular over any of the others.


> Perhaps the definition I found below could be made more specific a "syntax
> error" instead of "undefined behaviour" to make compilers throw a
> compile-time error on the issue.
>

Unless you have a abstract class (at least one virtual function declared "=
0", that is in general impossible to determine at compile time.
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--047d7b66f637d7a87004f55d1cbf
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On 24 March 2014 11:21,  <span dir=3D"ltr">&lt;<a href=3D"=
mailto:wsemmelink@gmail.com" target=3D"_blank">wsemmelink@gmail.com</a>&gt;=
</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex">

<div dir=3D"ltr">

<p class=3D"MsoNormal">Current best practice if the base class is intended =
to be
polymorphic, is to make the destructor virtual as well</p></div></blockquot=
e><div><br></div><div>That is one possibility. &nbsp;Another is to declare =
the destructor protected. &nbsp;Yet another is to use a type erased smart p=
ointer (such as shared_ptr). &nbsp;I don&#39;t see a reason to favor one in=
 particular over any of the others.</div>

<div>&nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><p class=
=3D"MsoNormal">Perhaps the definition I found below could be made more
specific a &ldquo;syntax error&rdquo; instead of &quot;undefined behaviour&=
quot; to make compilers throw a compile-time error on the
issue.<br></p></div></blockquote><div><br></div><div>Unless you have a abst=
ract class (at least one virtual function declared &quot;=3D 0&quot;, that =
is in general impossible to determine at compile time.</div></div>-- <br>

&nbsp;Nevin &quot;:-)&quot; Liber&nbsp; &lt;mailto:<a href=3D"mailto:nevin@=
eviloverlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;&nbsp; (8=
47) 691-1404
</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--047d7b66f637d7a87004f55d1cbf--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Mon, 24 Mar 2014 10:28:12 -0700 (PDT)
Raw View
------=_Part_278_10525088.1395682092562
Content-Type: text/plain; charset=UTF-8

On Monday, March 24, 2014 5:21:53 PM UTC+1, wsemm...@gmail.com wrote:
>
> * *Both the* above suggestions assume the programmer will in fact call
> delete on a base class pointer. This may not be the case, and the above
> checks may therefore be over keen, especially for old code. Now the ideal
> will be to catch the error where it is made. So what if the compiler can at
> the point where delete is called, determine a base class pointer is used
> to destroy a derived class, and then issue a check if the base class has a
> virtual destructor. Here I make a huge assumption that such a condition can
> be checked at compile time (we're talking about runtime polymorphism now),
> so I can imagine compiler developers frowning at this suggestion. But here
> I am at the limit of what I can think to suggest.
>
What about warning when the type being deleted has virtual functions but
does not have a virtual destructor? Should be easy and I think false
positives would be rare. Best of all, compilers could do this without it
being required in the ISO standard.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_278_10525088.1395682092562
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, March 24, 2014 5:21:53 PM UTC+1, wsemm...@gmail=
..com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">

<p class=3D"MsoNormal">* <i>Both the</i> above suggestions assume the progr=
ammer
will in fact call delete on a base class pointer. This may not be the case,=
 and
the above checks may therefore be over keen, especially for old code. Now
the ideal will be to catch the error where it is made. So what if the compi=
ler can at the point where <span style=3D"font-size: 9pt; line-height: 115%=
; font-family: Consolas;">delete </span>is called, determine
a base class pointer is used to destroy a derived class, and then issue a
check if the base class has a virtual destructor. Here I make a
huge assumption that such a condition can be checked at compile time (we're=
 talking about runtime polymorphism now), so I
can imagine compiler developers frowning at this suggestion. But here I am =
at the limit of what I can think to suggest.</p></div></blockquote><div>Wha=
t about warning when the type being deleted has virtual functions but does =
not have a virtual destructor? Should be easy and I think false positives w=
ould be rare. Best of all, compilers could do this without it being require=
d in the ISO standard.</div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_278_10525088.1395682092562--

.


Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Mon, 24 Mar 2014 10:30:36 -0700 (PDT)
Raw View
------=_Part_1010_24454614.1395682236824
Content-Type: text/plain; charset=UTF-8

What about making the destructor virtual automatically when other virtual
functions are present?

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1010_24454614.1395682236824
Content-Type: text/html; charset=UTF-8

<div dir="ltr">What about making the destructor virtual automatically when other virtual functions are present?<div><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_1010_24454614.1395682236824--

.


Author: Greg Marr <gregmmarr@gmail.com>
Date: Mon, 24 Mar 2014 12:37:42 -0700 (PDT)
Raw View
------=_Part_679_16811194.1395689862680
Content-Type: text/plain; charset=UTF-8

On Monday, March 24, 2014 12:40:43 PM UTC-4, Matthew Woehlke wrote:
>
> On 2014-03-24 12:21, wsemm...@gmail.com <javascript:> wrote:
> > [...]
> > Therefore this suggestion is for an ideal to have a compiler throw a
> > compile-time error on a polymorphic base class without a virtual
> > destructor.
>
> At least gcc already has a flag to do this: -Werror=virtual-dtor.
>

MSVC++ as well, since at least 2003.
C4265: 'class' : class has virtual functions, but destructor is not virtual

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_679_16811194.1395689862680
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, March 24, 2014 12:40:43 PM UTC-4, Matthew Woehl=
ke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2014-03-24 12:21, =
<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"oTpQJ9JR=
KokJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D"thi=
s.href=3D'javascript:';return true;">wsemm...@gmail.com</a> wrote:
<br>&gt; [...]
<br>&gt; Therefore this suggestion is for an ideal to have a compiler throw=
 a
<br>&gt; compile-time error on a polymorphic base class without a virtual
<br>&gt; destructor.
<br>
<br>At least gcc already has a flag to do this: -Werror=3Dvirtual-dtor.
<br></blockquote><div><br></div><div>MSVC++ as well, since at least 2003.</=
div><div>C4265: 'class' : class has virtual functions, but destructor is no=
t virtual<br></div><div><br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_679_16811194.1395689862680--

.


Author: Willem Semmelink <wsemmelink@gmail.com>
Date: Mon, 24 Mar 2014 13:07:35 -0700 (PDT)
Raw View
------=_Part_380_32417083.1395691655854
Content-Type: text/plain; charset=UTF-8




>> At least gcc already has a flag to do this: -Werror=virtual-dtor.
>>
>
> MSVC++ as well, since at least 2003.
> C4265: 'class' : class has virtual functions, but destructor is not virtual
>
> Thanks everyone for your replies.

 I am really glad to learn this is actually implemented in gcc and MSVC. I
did not know that.
 I tried a quick test in VC2013 Express, but it compiled successfully (also
no warnings). Is it something that I have to enable in MSVC?

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
class Animal {
    string name;
public:
    Animal(string n) :name(n){}
   //virtual ~Animal{}
    ~Animal() {}            // deliberately cause error to test compiler
    virtual void MakeNoise() = 0;
};

class Dog : public Animal {
public:
    Dog() :Animal("Dog"){}
    //virtual ~Dog();
    virtual void MakeNoise() override { cout << "Bark"; };
};

int _tmain(int argc, _TCHAR* argv[])
{
    Animal* pA = new Dog();
    pA->MakeNoise();
    delete pA;

    Dog d;
    Animal& rA = d;
    rA.MakeNoise();

    int x;
    cin >> x;
    return 0;
}

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_380_32417083.1395691655854
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br><blockquote class=3D"gmail_quote" style=3D"margin:=
 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div =
dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>At least gcc already has a flag to do this: -Werror=3Dvirtual-dtor.
<br></blockquote><div><br></div><div>MSVC++ as well, since at least 2003.</=
div><div>C4265: 'class' : class has virtual functions, but destructor is no=
t virtual<br></div><div><br></div></div></blockquote><div>Thanks everyone f=
or your replies.&nbsp; <br>&nbsp;</div><div>&nbsp;I am really glad to learn=
 this is actually implemented in gcc and MSVC. I did not know that. <br>&nb=
sp;I tried a quick test in VC2013 Express, but it compiled successfully (al=
so no warnings). Is it something that I have to enable in MSVC?<br><br>#inc=
lude "stdafx.h"<br>#include &lt;iostream&gt;<br>#include &lt;string&gt;<br>=
using namespace std;<br>class Animal {<br>&nbsp;&nbsp;&nbsp; string name;<b=
r>public:<br>&nbsp;&nbsp;&nbsp; Animal(string n) :name(n){}<br>&nbsp;&nbsp;=
 //virtual ~Animal{}<br>&nbsp;&nbsp;&nbsp; ~Animal() {}&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // deliberately cause error =
to test compiler&nbsp; <br>&nbsp;&nbsp;&nbsp; virtual void MakeNoise() =3D =
0;<br>};<br><br>class Dog : public Animal {<br>public:<br>&nbsp;&nbsp;&nbsp=
; Dog() :Animal("Dog"){}<br>&nbsp;&nbsp;&nbsp; //virtual ~Dog();<br>&nbsp;&=
nbsp;&nbsp; virtual void MakeNoise() override { cout &lt;&lt; "Bark"; };<br=
>};<br><br>int _tmain(int argc, _TCHAR* argv[])<br>{<br>&nbsp;&nbsp;&nbsp; =
Animal* pA =3D new Dog();<br>&nbsp;&nbsp;&nbsp; pA-&gt;MakeNoise();<br>&nbs=
p;&nbsp;&nbsp; delete pA;<br><br>&nbsp;&nbsp;&nbsp; Dog d;<br>&nbsp;&nbsp;&=
nbsp; Animal&amp; rA =3D d;<br>&nbsp;&nbsp;&nbsp; rA.MakeNoise();<br>&nbsp;=
&nbsp;&nbsp; &nbsp;<br>&nbsp;&nbsp;&nbsp; int x;<br>&nbsp;&nbsp;&nbsp; cin =
&gt;&gt; x;<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_380_32417083.1395691655854--

.


Author: wsemmelink@gmail.com
Date: Mon, 24 Mar 2014 13:13:21 -0700 (PDT)
Raw View
------=_Part_1102_19325127.1395692002049
Content-Type: text/plain; charset=UTF-8

 >>  Is it something that I have to enable in MSVC?
hmm I only had to read MSDN. They say it's off by default.
http://msdn.microsoft.com/en-us/library/wzxffy8c.aspx


--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1102_19325127.1395692002049
Content-Type: text/html; charset=UTF-8

<div dir="ltr">&nbsp;&gt;&gt;&nbsp; Is it something that I have to enable in MSVC?<br>hmm I only had to read MSDN. They say it's off by default. <br>http://msdn.microsoft.com/en-us/library/wzxffy8c.aspx<br>&nbsp;</div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />

------=_Part_1102_19325127.1395692002049--

.