<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Explicit Virtual Function Overrides</title>
    <base href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
<style type="text/css">
  p {text-align:justify}
  li {text-align:justify}
  ins {background-color:#FFFF99}
  del {background-color:#FF9999}
</style>
  </head>
  <body>
    document number: N2365=07-225<br />
    Jens Maurer &lt;Jens.Maurer@gmx.net&gt;<br />
    Alisdair Meredith &lt;public@alisdairm.net&gt;<br />
    2007-08-06
    
    <h1>Explicit Virtual Overides</h1>
    
    <h2>Problem Summary</h2>
    
    We would like to tighten the rules for overriding virtual functions, to
    detect these problems:
    <ul>
      <li>
        a base class <code>B</code> has a virtual function <code>f</code>, and
        the user declares their own <code>f</code> in derived class
        <code>D</code>, thereby accidentally overriding <code>B::f</code>.
      </li>
      <li>
        a base class <code>B</code> has a virtual function <code>f</code>, and
        the user wishes to override that function in the derived class
        <code>D</code>, but misspells the name as <code>D::foo</code>.
      </li>
      <li>
        a base class <code>B</code> has a virtual function <code>f</code>, and
        the user wishes to override that function in the derived class
        <code>D</code>, but inadvertently alters the parameter list.
      </li>
    </ul>

    We are deliberately not solving the problem that a base class
    <code>B1</code> has a virtual function <code>f</code>, another base class
    <code>B2</code> also has a virtual function <code>f</code> with the same
    signature, the user derives a class <code>D</code> from both
    <code>B1</code> and <code>B2</code> and declares <code>D::f</code> to
    override both <code>B1::f</code> and <code>B2::f</code>, one of which may
    have been inadvertent. (This is sometimes referred to as the Siamese Twins
    problem.)
    
    <p>
      The scope of the problem was reduced to the minimal necessary to solve
      the common real-world problems. This means it does not tackle ideas such
      as 'final overriders' or function renaming, both of which would be
      available if a scheme closer to the C++/CLI standard was pursued.
    </p>
    
    
    <h2>History</h2>
    
    <a href="2005/n1827.htm">N1827</a> was presented at the Mont Tremblant
    meeting as a first pass at this problem. Feedback was positive, but
    concerned about the 'viral' nature of that proposal. It marked the base
    class as special and implied that all descendants must be treated as
    special as well, even when not marked. This viral problem is resolved by
    marking the derived class instead, as that is more frequently under the
    developer's control.
    <p>
    <a href="2006/n2108.html">N2108</a> was presented at the Portland meeting
    and introduced the concept of an explicit polymorphic class as a
    refinement of the existing polymorphic class type. The virtual function
    syntax wording could then be updated to use the new class type, while
    deferring the final choice of syntax to mark the class as explicit to a
    later paper.  Feedback was to advance to Core once a suitable markup could
    be found.
    </p>
    <p>
    This paper adopts the notation of the attributes proposal for C++0x in
    <a href="2007/n2236.pdf">N2236</a>.  It also includes feedback since
    Portland to address name-hiding in addition to the virtual function
    issues.
    </p>
    
    
    <h2>Proposed Solution</h2>
    
    We propose to introduce a <code>[[check_names]]</code> attribute for class
    definitions.  Use of this attribute turns on additional checks that the
    member functions declared in the class do not conflict with the those of
    names in any base class.
    <p>
    In particular, the "virtual" keyword must be used when overriding virtual
    functions, and named declared in a base class cannot be hidden. Two
    further attributes are introduced that allow specific functions to disable
    the checks. <code>[[new]]</code> indicates that a virtual function is
    being introduced for the first time, and <code>[[hiding]]</code>
    indicates a deliberate attempt to hide names from a base class.
    </p>
    <p>
    This design meets three key compatibility requirements:
    <li>
      Use of the attributes does not depend on their being used in a base
      class
    </li>
    <li>
      Use of the attributes in a library class is invisible to users of that
      class
    </li>
    <li>
      The meaining of a program does not change if a compiler ignores the
      attributes
    </li>
    </p>
    <p>
    It also meets an additional goal that the number of attribute mark-ups in
    typical use is small, often no more than a single attribute on the class
    definition.  This is based on an assumption that name hiding is rarely
    intentional, and will be typically fixed with a using declaration.
    It is also assumed that virtual functions are more frequently overriden
    than introduced.  This is especially true with the common idiom of an
    'interface class' where only root-classes introduces virtual functions.
    Note that roots, having no base classes, should not be marked up in
    practice as there is nothing to check for classes without a base.
    </p>
    <h3>Implicit virtual and the Accidental Override</h3>
    <p>
    The 'simple' syntax for overriding virtual functions in C++ today is convenient, but potentially misleading.  Take the following example:
    </p>
<pre>
struct base {
  virtual void some_func();
};

struct derived {
  void some_func();
};

</pre>
    <p>
    Is the use of some_func in derived intentionally an override, or an accidental name clash? Without clear documentation or a detailed analysis of the use/implementation it is hard to be sure.<br />
    The common assumption is that all such use is deliberate, and to ignore the question.  Yet while it is reasonable to assume that competent developers would not accidentally make such a mistake, it is easily introduced by dependencies on third party libraries.  Maintenance of the base classes might introduce such a clash without clear notice in the code, and the ensuing bugs can be very hard to track down.  Worse, even a rigorous set of unit tests does not guarantee protection, as it is the base class, not the derived, that is changing behaviour and so the effects are not guaranteed to be covered by existing tests. Likewise, source analysis tools can offer little help here without an additional hint from the coder.  To that end, we offer the [[check_names]] attribute, and the requirement in a checked class that intentional overrides use the virtual keyword, which is remains optional when the attribute is not used.
    </p>
<pre>
struct base {
  virtual void some_func();
};

struct derived <ins>[[check_names]]</ins> {
  void some_func();  // error, accidental override with check_names attribute
  <ins>virtual</ins> void some_func(); // OK, override with <b>virtual</b> keyword
};

</pre>
    <p>
    </p>
    <h3>Mispellings and mistaken signature</h3>
    <p>
    A second set of problems arise when a user intends to override a function, but gets the signature wrong in some way.  Common examples are mis-spelling the name (transposing two characters, bad capitalization); using a the wrong datatype (double instead of float); or missing the cv-qualification.
    </p>
    <p>
    All these classes of errors can be detected in the same way.  When the virtual keyword is used in a class defined with the </code>[[check_names]]</code> attribute, a matching declaration <b>must</b> be found in one of the base classes for it to override.  In implementation terms it would suffice to check the inherited vtable, rather than search the full DAG of base classes looking for a match.
    </p>
    Note: This kind of problem should also be detected with a good set of unit tests.  It is hard to solve in a lexical analysis tool without a further hint, see next point!
    <p>
<pre>
struct base {
  virtual void some_func1();
  virtual void some_func2(float);
  virtual void some_func3() const;
  virtual long some_func4(int);
};

struct derived <ins>[[check_names]]</ins> {
  virtual void sone_func1();  // error, mis-spelled name
  virtual void some_func2(double); // error, no bad argument type
  virtual void some_func3(); // error, missing cv-qualification
  virtual int some_func4(int); // ill-formed: return type does not match B::h
};
</pre>
    </p>
    <h3>Introducing new virtual functions</h3>
    <p>
    The problem with checking for functions to override is that is becomes impossible to introduce a new virtual function into the hierarchy in a checked class.  We propose to solve this with the <code>[[new]]</code> attribute.  This is used with virtual function declations to:
    <li>allow a new virtual function to be introduced without failing the override check</li>
    <li>Check that the new signature does not accidentally override a base member</li>
    </p>
    The latter check will be diagnosed as ill-formed, rather than introducing a new function that hides the base.  This guarantees the feature does nothing more than name checking, and cannot produce a program with a different meaning if the attributes are ignored.
    </p>
    <p>
    This kind of check is hard to cover with unit tests, and can only be caught by lexical analysis tools with an additional mark-up, such as we propose here.
    </p>
    <p>
<pre>
struct base {
  virtual void some_func1();
};

struct derived <ins>[[check_names]]</ins> {
  virtual void some_func1(); <ins>[[new]]</ins> // error, accidental override
  virtual void some_func2(); <ins>[[new]]</ins> // OK, new virtual function introduced
};
</pre>
    </p>
    <h3>Deliberate name hiding</h3>
    <p>
    Another problem that catches people out when defining classes is that introducing a name will hide occurences of the same name from any bases classes.  Sometimes this is intentional, but there is little chance of a warning when it occurs accidentally.  The language-supplied workaround in those cases is a using declaration, but you only apply the workaround when you are aware of the problem.  The <code>[[check_names]]</code> attribute will require the compiler inform you of accidental hiding.  The <code>[[hiding]]</code> attribute will allow you to tell the compiler that the hiding is intentional, and the program remains well-formed.
    </p>
    <p>
      Example:
    </p>
<pre>
class B {
  virtual void f();
  virtual void h(int);
  void j(int);
 void k(int);
};

class D <ins>[[check_names]]</ins> : public B {
  using B::j;
  virtual void f();          // OK: overrides B::f
  virtual void g(long);      // ill-formed: new virtual function introduced
  void h(int);               // ill-formed: overriding without "virtual"
  virtual void h(long);      // ill-formed: new virtual function introduced
  virtual void h(double); <ins>[[new]]</ins> // ill-formed: new virtual function hides void h(int)
  virtual void h(char *); <ins>[[new, hiding]]</ins> // OK
  virtual   int j( double );           // OK, using declaration prevents hiding
  int k( double );           // ill-formed: name hiding and no using declaration
  double k( char * ) <ins>[[hiding]]</ins>; // OK, hiding is clearly indicated
};
</pre>


    <h2>Proposed Wording</h2>

    Add a new section 7.6.5 dcl.attr.checks:
    <blockquote>
      7.6.5 Attributes to check names of class members
      <p>
        The <em>attribute-token</em> <code>check_names</code> specifies that a
        class strictly  checks overriding and hiding of base member functions.
        It shall appear at most once in each <em>attribute-list</em> and no
        <em>attribute-argument-clause</em> shall be present. The
        attribute applies to a class definition, see 10.3 class.virtual.
      </p>
      <p>
        The <em>attribute-token</em> <code>new</code> specifies that a virtual
        member function does not override a function in a base class.
      </p>
      <p>
        The <em>attribute-token</em> <code>hiding</code> specifies that the
        name of a member function hides another member function in a base
        class.
      </p>
      <p>
        Each of the <em>attribute-token</em>s <code>new</code> and <code>
        hiding</code> shall appear at most once in each <em>attribute-list
        </em> and no <em>attribute-argument-clause</em> shall be present for
        either. The attributes apply to the function type of a member function
        declaration, but the type of the member function is unchanged. The
        <em>attribute-token</em> <code>new</code> applies only to the type of
        a virtual member function.
      </p>
    </blockquote>

    Replace in 10.3p2
    <blockquote>
      If a virtual member function vf is declared in a class <code>Base</code>
      and in a class <code>Derived</code>, derived directly or indirectly from
      <code>Base</code>, a member function <code>vf</code> with the same name,
      parameter-type-list (8.3.5), and cv-qualification as <code>Base::vf
      </code> is declared, then <code>Derived::vf</code> is also virtual (
      whether or not it is so declared) and it <em>overrides</em>
      <code>Base::vf</code>.
    </blockquote>

    by
    
    <blockquote>
      If a virtual member function <code>vf</code> is declared in a class
      <code>B</code> and in a class <code>D</code>, derived directly or
      indirectly from <code>B</code>, a member function <code>vf</code> with
      the same name is declared, <code>D::vf</code> may <em>override</em>
      <code>B::vf</code> as follows: If <code>D</code> is not marked with the
      <code>check_names</code> attribute and the parameter-type-list (8.3.5)
      and cv-qualification of <code>D::vf</code> are the same as those of
      <code>B::vf</code>, then <code>D::vf</code> is also virtual (whether or
      not it is so declared) and it <em>overrides</em> <code>B::vf</code>.
      If <code>D</code> is marked with the <code>check_names</code> attribute,
      then <code>D::vf</code> shall be declared virtual and, if the
      parameter-type-list (8.3.5) and cv-qualification of <code>D::vf</code>
      are the same as those of <code>B::vf</code>, <code>D::vf</code>
      overrides <code>B::vf</code>. In a class marked with the
      <code>check_names</code> attribute, a virtual member function shall be
      marked with the <code>new</code> attribute if and only if it does not
      override one in a base class .
    </blockquote>
    
    Add a new paragraph to 3.3.8 (basic.scope.hiding)
    <blockquote>
    If a <em>member-declaration</em> hides a member that would otherwise be visible in a base class, that <em>member-declaration</em> shall be decorated  with the <code>hiding</code> attribute (7.6.5 dcl.attr.checks). [Note: A using directive makes the potentially hidden name visible, avoiding the need for the <code>hiding</code> attribute.]
    </blockquote>
  </body>
</html>
