"Fossies" - the Fresh Open Source Software Archive

Member "dmd2/html/d/articles/hijack.html" (20 Nov 2020, 31539 Bytes) of package /linux/misc/dmd.2.094.2.linux.tar.xz:


The requested HTML page contains a <FORM> tag that is unusable on "Fossies" in "automatic" (rendered) mode so that page is shown as HTML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 
    2 <!DOCTYPE html>
    3 <html lang="en-US">
    4 <!--
    5     Copyright (c) 1999-2020 by the D Language Foundation
    6     All Rights Reserved.
    7     https://dlang.org/foundation_overview.html
    8   -->
    9 <head>
   10 <meta charset="utf-8">
   11 <meta name="keywords" content="D programming language">
   12 <meta name="description" content="D Programming Language">
   13 <title>Hijack - D Programming Language</title>
   14 
   15 <link rel="stylesheet" href="../css/codemirror.css">
   16 <link rel="stylesheet" href="../css/style.css">
   17 <link rel="stylesheet" href="../css/print.css" media="print">
   18 <link rel="shortcut icon" href="../favicon.ico">
   19 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.1, maximum-scale=10.0">
   20 
   21 </head>
   22 <body id='Hijack' class='doc'>
   23 <script type="text/javascript">document.body.className += ' have-javascript'</script>
   24 <div id="top"><div class="helper"><div class="helper expand-container">    <div class="logo"><a href="."><img id="logo" alt="D Logo" src="../images/dlogo.svg"></a></div>
   25     <a href="../menu.html" title="Menu" class="hamburger expand-toggle"><span>Menu</span></a>
   26     
   27 <div id="cssmenu"><ul>    <li><a href='https://tour.dlang.org'><span>Learn</span></a></li>
   28     <li class='expand-container'><a class='expand-toggle' href='../documentation.html'><span>Documentation</span></a>
   29       
   30 <ul class='expand-content'>    <li><a href='../spec/spec.html'>Language Reference</a></li>
   31     <li><a href='../phobos/index.html'>Library Reference</a></li>
   32     <li><a href='../dmd.html'>Command-line Reference</a></li>
   33     <li class="menu-divider"><a href='../comparison.html'>Feature Overview</a></li>
   34     <li><a href='../articles.html'>Articles</a></li>
   35  </ul></li>
   36     <li><a href='../download.html'><span>Downloads</span></a></li>
   37     <li><a href='https://code.dlang.org'><span>Packages</span></a></li>
   38     <li class='expand-container'><a class='expand-toggle' href='../community.html'><span>Community</span></a>
   39       
   40 <ul class='expand-content'>    <li><a href='https://dlang.org/blog'>Blog</a></li>
   41     <li><a href='../orgs-using-d.html'>Orgs using D</a></li>
   42     <li><a href='https://twitter.com/search?q=%23dlang'>Twitter</a></li>
   43     <li><a href='../calendar.html'>Calendar</a></li>
   44     <li class="menu-divider"><a href='https://forum.dlang.org'>Forums</a></li>
   45     <li><a href='irc://irc.freenode.net/d'>IRC</a></li>
   46     <li><a href='https://discord.gg/bMZk9Q4'>Community Discord</a></li>
   47     <li><a href='https://wiki.dlang.org'>Wiki</a></li>
   48     <li class="menu-divider"><a href='https://github.com/dlang'>GitHub</a></li>
   49     <li><a href='../bugstats.html'>Issues</a></li>
   50     <li><a href='https://wiki.dlang.org/Get_involved'>Get involved</a></li>
   51     <li class="menu-divider"><a href='../foundation/contributors.html'>Contributors</a></li>
   52     <li><a href='../foundation/index.html'>Foundation</a></li>
   53     <li><a href='..//security.html'>Security Team</a></li>
   54     <li><a href='../foundation/donate.html'>Donate</a></li>
   55     <li><a href='../foundation/sponsors.html'>Sponsors</a></li>
   56  </ul></li>
   57     <li class='expand-container'><a class='expand-toggle' href='../resources.html'><span>Resources</span></a>
   58       
   59 <ul class='expand-content'>    <li><a href='https://tour.dlang.org'>Tour</a></li>
   60     <li><a href='https://wiki.dlang.org/Books'>Books</a></li>
   61     <li><a href='https://wiki.dlang.org/Tutorials'>Tutorials</a></li>
   62     <li class="menu-divider"><a href='https://wiki.dlang.org/Development_tools'>Tools</a></li>
   63     <li><a href='https://wiki.dlang.org/Editors'>Editors</a></li>
   64     <li><a href='https://wiki.dlang.org/IDEs'>IDEs</a></li>
   65     <li><a href='https://run.dlang.io'>run.dlang.io</a></li>
   66     <li><a href='http://rainers.github.io/visuald/visuald/StartPage.html'>Visual D</a></li>
   67     <li class="menu-divider"><a href='../acknowledgements.html'>Acknowledgments</a></li>
   68     <li><a href='../dstyle.html'>D Style</a></li>
   69     <li><a href='../glossary.html'>Glossary</a></li>
   70     <li><a href='../sitemap.html'>Sitemap</a></li>
   71  </ul></li>
   72 </ul></div>
   73     <div class="search-container expand-container">        <a href="../search.html" class="expand-toggle" title="Search"><span>Search</span></a>
   74         
   75     <div id="search-box">        <form method="get" action="https://google.com/search">
   76             <input type="hidden" id="domains" name="domains" value="dlang.org">
   77             <input type="hidden" id="sourceid" name="sourceid" value="google-search">
   78             <span id="search-query"><input id="q" name="q" placeholder="Search"></span><span id="search-dropdown"><span class="helper">                <select id="sitesearch" name="sitesearch" size="1">
   79                     <option value="dlang.org">Entire Site</option>
   80                     <option  value="dlang.org/spec">Language</option>
   81                     <option  value="dlang.org/phobos">Library</option>
   82                     <option  value="forum.dlang.org">Forums</option>
   83                     
   84                 </select>
   85             </span></span><span id="search-submit"><button type="submit"><i class="fa fa-search"></i><span>go</span></button></span>
   86         </form>
   87     </div>
   88     </div>
   89 </div></div></div>
   90 
   91 <div class="container">    
   92 <div class="subnav-helper"></div> <div class="subnav">    
   93     <div class="head">        <h2>Articles</h2>
   94         <p class="Articles, ../articles/index.html, overview">            <a href="../articles/index.html">overview</a></p>
   95     </div>
   96     <ul><li><a href='        ../articles/faq.html'>FAQ</a></li><li><a href='        ../articles/const-faq.html'>const(FAQ)</a></li><li><a href='        ../articles/d-floating-point.html'>Floating Point</a></li><li><a href='        ../articles/warnings.html'>Warnings</a></li><li><a href='        ../articles/rationale.html'>Rationale</a></li><li><a href='        ../articles/builtin.html'>Builtin Rationale</a></li><li><a href='        ../articles/ctod.html'>C to D</a></li><li><a href='        ../articles/cpptod.html'>C++ to D</a></li><li><a href='        ../articles/pretod.html'>C Preprocessor vs D</a></li><li><a href='        ../articles/code_coverage.html'>Code coverage analysis</a></li><li><a href='        ../articles/exception-safe.html'>Exception Safety</a></li><li><a href='        ../articles/hijack.html'>Hijacking</a></li><li><a href='        ../articles/intro-to-datetime.html'>Introduction to std.datetime</a></li><li><a href='        ../articles/lazy-evaluation.html'>Lazy Evaluation</a></li><li><a href='        ../articles/migrate-to-shared.html'>Migrating to Shared</a></li><li><a href='        ../articles/mixin.html'>Mixins</a></li><li><a href='        ../articles/regular-expression.html'>Regular Expressions</a></li><li><a href='        ../articles/safed.html'>SafeD</a></li><li><a href='        ../articles/templates-revisited.html'>Templates Revisited</a></li><li><a href='        ../articles/ctarguments.html'>Compile-time Sequences</a></li><li><a href='        ../articles/variadic-function-templates.html'>Variadic Templates</a></li><li><a href='        ../articles/d-array-article.html'>D Slices</a></li><li><a href='        ../articles/cppcontracts.html'>D's Contract Programming</a></li><li><a href='        ../articles/template-comparison.html'>Template Comparison</a></li><li><a href='        ../articles/dll-linux.html'>Writing Shared Libraries
   97     </a></li></ul>
   98 </div>
   99     <div class="hyphenate" id="content">        
  100 <div id="tools"><div >  <div class="tip smallprint">        <a href="https://issues.dlang.org/enter_bug.cgi?bug_file_loc=http%3A%2F%2Fdlang.org/&amp;component=dlang.org&amp;op_sys=All&amp;priority=P3&amp;product=D&amp;rep_platform=All&amp;short_desc=%5BHijack%5D&amp;version=D2&amp;bug_severity=enhancement">Report a bug</a>
  101         <div >          If you spot a problem with this page, click here to create a Bugzilla issue.
  102         </div>
  103     </div>
  104     <div class="tip smallprint">        <a href="https://github.com/dlang/dlang.org/edit/master/articles/hijack.dd">Improve this page</a>
  105         <div >          Quickly fork, edit online, and submit a pull request for this page.
  106             Requires a signed-in GitHub account. This works well for small changes.
  107             If you'd like to make larger changes you may want to consider using
  108             a local clone.
  109         </div>
  110     </div>
  111 </div></div>
  112         <h1>Hijack</h1>
  113         
  114         
  115 
  116 
  117 <div class="page-contents quickindex">    <div class="page-contents-header">        <b>Contents</b>
  118     </div>
  119     <ol>    <li><a href="#global-function-hijacking">Global Function Hijacking</a></li>
  120     <li><a href="#overload-sets">Overload Sets</a></li>
  121     <li><a href="#derived-class-members">Derived Class Member Function Hijacking</a></li>
  122     <li><a href="#base-class-member">Base Class Member Function Hijacking</a></li>
  123     <li><a href="#derived-class-member-function-2">Derived Class Member Function Hijacking #2</a></li>
  124     <li><a href="#conclusion">Conclusion</a></li>
  125     <li><a href="#references">References</a></li>
  126 </ol>
  127 </div>
  128 
  129 <p>As software becomes more complex, we become more reliant on module
  130 interfaces. An application may import and combine modules from multiple
  131 sources, including sources from outside the company. The module
  132 developers must be able to maintain and improve those modules without
  133 inadvertently stepping on the behavior of modules over which they cannot
  134 have knowledge of. The application developer needs to be notified if
  135 any module changes would break the application. This talk covers
  136 function hijacking, where adding innocent and reasonable declarations
  137 in a module
  138 can wreak arbitrary havoc on an application program in C++ and Java. We'll then
  139 look at how
  140 modest language design changes can largely eliminate the problem in the D
  141 programming language.
  142 </p>
  143 
  144 
  145 <h2><a class="anchor" title="Permalink to this section" id="global-function-hijacking" href="#global-function-hijacking">Global Function Hijacking</a></h2>
  146 <p>Let's say we are developing an application that imports two modules:
  147 X from the XXX Corporation, and Y from the YYY Corporation.
  148 Modules X and Y are unrelated to each other, and are used for completely
  149 different purposes.
  150 The modules look like:
  151 </p>
  152 
  153 <pre class="d_code notranslate"><span class="d_keyword">module</span> X;
  154 
  155 <span class="d_keyword">void</span> foo();
  156 <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  157 </pre>
  158 
  159 <pre class="d_code notranslate"><span class="d_keyword">module</span> Y;
  160 
  161 <span class="d_keyword">void</span> bar();
  162 </pre>
  163 
  164 <p>The application program would look like:
  165 </p>
  166 
  167 <pre class="d_code notranslate"><span class="d_keyword">import</span> X;
  168 <span class="d_keyword">import</span> Y;
  169 
  170 <span class="d_keyword">void</span> abc()
  171 {
  172     foo(1);  <span class="d_comment">// calls X.foo(long)
  173 </span>}
  174 
  175 <span class="d_keyword">void</span> def()
  176 {
  177     bar();   <span class="d_comment">// calls Y.bar();
  178 </span>}
  179 </pre>
  180 
  181 <p>So far, so good. The application is tested and works, and is shipped.
  182 Time goes by, the application programmer moves on, the application is
  183 put in maintenance mode. Meanwhile, YYY Corporation, responding to
  184 customer requests, adds a type <span class="d_inlinecode donthyphenate notranslate">A</span> and a function <span class="d_inlinecode donthyphenate notranslate">foo(A)</span>:
  185 </p>
  186 
  187 <pre class="d_code notranslate"><span class="d_keyword">module</span> Y;
  188 
  189 <span class="d_keyword">void</span> bar();
  190 <span class="d_keyword">class</span> A;
  191 <span class="d_keyword">void</span> foo(A);
  192 </pre>
  193 
  194 <p>The application maintainer gets the latest version
  195 of Y, recompiles, and no problems. So far, so good.
  196 But then, YYY Corporation expands the functionality of <span class="d_inlinecode donthyphenate notranslate">foo(A)</span>,
  197 adding a function <span class="d_inlinecode donthyphenate notranslate">foo(int)</span>:
  198 </p>
  199 
  200 <pre class="d_code notranslate"><span class="d_keyword">module</span> Y;
  201 
  202 <span class="d_keyword">void</span> bar();
  203 <span class="d_keyword">class</span> A;
  204 <span class="d_keyword">void</span> foo(A);
  205 <span class="d_keyword">void</span> foo(<span class="d_keyword">int</span>);
  206 </pre>
  207 
  208 <p>Now, our application maintainer routinely gets the latest version of Y,
  209 recompiles, and suddenly his application is doing something unexpected:
  210 </p>
  211 
  212 <pre class="d_code notranslate"><span class="d_keyword">import</span> X;
  213 <span class="d_keyword">import</span> Y;
  214 
  215 <span class="d_keyword">void</span> abc()
  216 {
  217     foo(1);  <span class="d_comment">// calls Y.foo(int) rather than X.foo(long)
  218 </span>}
  219 
  220 <span class="d_keyword">void</span> def()
  221 {
  222     bar();   <span class="d_comment">// calls Y.bar();
  223 </span>}
  224 </pre>
  225 
  226 <p>because <span class="d_inlinecode donthyphenate notranslate">Y.foo(int)</span> is a better overloading match than <span class="d_inlinecode donthyphenate notranslate">X.foo(long)</span>.
  227 But since <span class="d_inlinecode donthyphenate notranslate">X.foo</span> does something completely and totally different than
  228 <span class="d_inlinecode donthyphenate notranslate">Y.foo</span>, the application now has a potentially very serious bug in it.
  229 Even worse, the compiler offers NO indication that this happened and cannot
  230 because, at least for C++, this is how the language is supposed to work.
  231 </p>
  232 
  233 <p>In C++, some mitigation can be done by using namespaces or (hopefully)
  234 unique
  235 name prefixes within the modules
  236 X and Y. This doesn't help the application programmer, however, who probably
  237 has no control over X or Y.
  238 </p>
  239 
  240 <p>The first stab at fixing this problem in the D programming language was
  241 to add the rules:
  242 </p>
  243 
  244 <ol><li>by default functions can only overload against other functions in the same
  245 module</li>
  246 <li>if a name is found in more than one scope, in order to use it it must
  247 be fully qualified</li>
  248 <li>in order to overload functions from multiple modules together, an alias
  249 statement is used to merge the overloads</li>
  250 </ol>
  251 
  252 <p>So now, when YYY Corporation added the <span class="d_inlinecode donthyphenate notranslate">foo(int)</span> declaration, the
  253 application
  254 maintainer now gets a compilation error that foo is defined in both module
  255 X and module Y, and has an opportunity to fix it.
  256 </p>
  257 
  258 <p>This solution worked, but is a little restrictive. After all, there's no
  259 way <span class="d_inlinecode donthyphenate notranslate">foo(A)</span> would be confused with <span class="d_inlinecode donthyphenate notranslate">foo()</span> or <span class="d_inlinecode donthyphenate notranslate">foo(long)</span>,
  260 so why have the compiler
  261 complain about it? The solution turned out to be to introduce the notion
  262 of overload sets.
  263 </p>
  264 
  265 <h2><a class="anchor" title="Permalink to this section" id="overload-sets" href="#overload-sets">Overload Sets</a></h2>
  266 <p>An overload set is formed by a group of functions with the same name
  267 declared
  268 in the same scope. In the module X example, the functions <span class="d_inlinecode donthyphenate notranslate">X.foo()</span> and
  269 <span class="d_inlinecode donthyphenate notranslate">X.foo(long)</span> form a single overload set. The functions
  270 <span class="d_inlinecode donthyphenate notranslate">Y.foo(A)</span> and <span class="d_inlinecode donthyphenate notranslate">Y.foo(int)</span>
  271 form another overload set. Our method for resolving a call to foo becomes:
  272 </p>
  273 
  274 <ol><li>Perform overload resolution independently on each overload set</li>
  275 <li>If there is no match in any overload set, then error</li>
  276 <li>If there is a match in exactly one overload set, then go with that</li>
  277 <li>If there is a match in more than one overload set, then error</li>
  278 </ol>
  279 
  280 <p>The most important thing about this is that even if there is a BETTER match
  281 in one overload set over another overload set, it is still an error.
  282 The overload sets must not overlap.
  283 </p>
  284 
  285 <p>In our example:
  286 </p>
  287 
  288 <pre class="d_code notranslate"><span class="d_keyword">void</span> abc()
  289 {
  290     foo(1);  <span class="d_comment">// matches Y.foo(int) exactly, X.foo(long) with conversions
  291 </span>}
  292 </pre>
  293 
  294 <p>will generate an error, whereas:
  295 </p>
  296 
  297 <pre class="d_code notranslate"><span class="d_keyword">void</span> abc()
  298 {
  299     A a;
  300     foo(a);  <span class="d_comment">// matches Y.foo(A) exactly, nothing in X matches
  301 </span>    foo();   <span class="d_comment">// matches X.foo() exactly, nothing in Y matches
  302 </span>}
  303 </pre>
  304 
  305 <p>compiles without error, as we'd intuitively expect.
  306 </p>
  307 
  308 <p>If overloading of <span class="d_inlinecode donthyphenate notranslate">foo</span> between X and Y is desired, the following can be done:
  309 </p>
  310 
  311 <pre class="d_code notranslate"><span class="d_keyword">import</span> X;
  312 <span class="d_keyword">import</span> Y;
  313 
  314 <span class="d_keyword">alias</span> foo = X.foo;
  315 <span class="d_keyword">alias</span> foo = Y.foo;
  316 
  317 <span class="d_keyword">void</span> abc()
  318 {
  319     foo(1);  <span class="d_comment">// calls Y.foo(int) rather than X.foo(long)
  320 </span>}
  321 </pre>
  322 
  323 <p>and no error is generated. The difference here is that the user
  324 deliberately combined the overload sets in X and Y, and so presumably
  325 both knows what he's doing and is willing to check the <span class="d_inlinecode donthyphenate notranslate">foo</span>s when
  326 X or Y is updated.
  327 </p>
  328 
  329 
  330 
  331 
  332 
  333 <h2><a class="anchor" title="Permalink to this section" id="derived-class-members" href="#derived-class-members">Derived Class Member Function Hijacking</a></h2>
  334 <p>There are more cases of function hijacking. Imagine a class <span class="d_inlinecode donthyphenate notranslate">A</span> coming
  335 from AAA Corporation:
  336 </p>
  337 
  338 <pre class="d_code notranslate"><span class="d_keyword">module</span> M;
  339 
  340 <span class="d_keyword">class</span> A { }
  341 </pre>
  342 
  343 <p>and in our application code, we derive from <span class="d_inlinecode donthyphenate notranslate">A</span> and add a virtual
  344 member function <span class="d_inlinecode donthyphenate notranslate">foo</span>:
  345 </p>
  346 
  347 <pre class="d_code notranslate"><span class="d_keyword">import</span> M;
  348 
  349 <span class="d_keyword">class</span> B : A
  350 {
  351     <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  352 }
  353 
  354 <span class="d_keyword">void</span> abc(B b)
  355 {
  356     b.foo(1);   <span class="d_comment">// calls B.foo(long)
  357 </span>}
  358 </pre>
  359 
  360 <p>and everything is hunky-dory. As before, things go on, AAA Corporation
  361 (who cannot know about <span class="d_inlinecode donthyphenate notranslate">B</span>) extends <span class="d_inlinecode donthyphenate notranslate">A</span>'s functionality a bit by
  362 adding <span class="d_inlinecode donthyphenate notranslate">foo(int)</span>:
  363 </p>
  364 
  365 <pre class="d_code notranslate"><span class="d_keyword">module</span> M;
  366 
  367 <span class="d_keyword">class</span> A
  368 {
  369     <span class="d_keyword">void</span> foo(<span class="d_keyword">int</span>);
  370 }
  371 </pre>
  372 
  373 <p>Now, consider if we're using Java-style overloading rules, where base class
  374 member functions overload right alongside derived class functions. Now,
  375 our application call:
  376 </p>
  377 
  378 <pre class="d_code notranslate"><span class="d_keyword">import</span> M;
  379 
  380 <span class="d_keyword">class</span> B : A
  381 {
  382     <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  383 }
  384 
  385 <span class="d_keyword">void</span> abc(B b)
  386 {
  387     b.foo(1);   <span class="d_comment">// calls A.foo(int), AAAEEEEEIIIII!!!
  388 </span>}
  389 </pre>
  390 
  391 <p>and the call to <span class="d_inlinecode donthyphenate notranslate">B.foo(long)</span> was hijacked by the base class <span class="d_inlinecode donthyphenate notranslate">A</span>
  392 to call <span class="d_inlinecode donthyphenate notranslate">A.foo(int)</span>,
  393 which likely has no meaning whatsoever in common with <span class="d_inlinecode donthyphenate notranslate">B.foo(long)</span>.
  394 This is why I don't like Java overloading rules.
  395 C++ has the right idea here in that functions in a derived class hide
  396 all the functions of the same name in a base class, even if the functions
  397 in the base class might be a better match. D follows this rule.
  398 And once again, if the user desires them to be overloaded against each other,
  399 this can be accomplished in C++ with a using declaration, and in D with
  400 an analogous alias declaration.
  401 </p>
  402 
  403 
  404 
  405 
  406 <h2><a class="anchor" title="Permalink to this section" id="base-class-member" href="#base-class-member">Base Class Member Function Hijacking</a></h2>
  407 <p>I bet you suspected there was more to it than that, and you'd be right.
  408 Hijacking can go the other way, too. A derived class can hijack a base
  409 class member function!
  410 </p>
  411 
  412 <p>Consider:
  413 </p>
  414 
  415 <pre class="d_code notranslate"><span class="d_keyword">module</span> M;
  416 
  417 <span class="d_keyword">class</span> A
  418 {
  419     <span class="d_keyword">void</span> def() { }
  420 }
  421 </pre>
  422 
  423 <p>and in our application code, we derive from <span class="d_inlinecode donthyphenate notranslate">A</span> and add a virtual
  424 member function <span class="d_inlinecode donthyphenate notranslate">foo</span>:
  425 </p>
  426 
  427 <pre class="d_code notranslate"><span class="d_keyword">import</span> M;
  428 
  429 <span class="d_keyword">class</span> B : A
  430 {
  431     <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  432 }
  433 
  434 <span class="d_keyword">void</span> abc(B b)
  435 {
  436     b.def();   <span class="d_comment">// calls A.def()
  437 </span>}
  438 </pre>
  439 
  440 <p>AAA Corporation once again knows nothing about <span class="d_inlinecode donthyphenate notranslate">B</span>, and adds a
  441 function
  442 <span class="d_inlinecode donthyphenate notranslate">foo(long)</span> and uses it to implement some needed new functionality of
  443 <span class="d_inlinecode donthyphenate notranslate">A</span>:
  444 </p>
  445 
  446 <pre class="d_code notranslate"><span class="d_keyword">module</span> M;
  447 
  448 <span class="d_keyword">class</span> A
  449 {
  450     <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  451 
  452     <span class="d_keyword">void</span> def()
  453     {
  454         foo(1L);   <span class="d_comment">// expects to call A.foo(long)
  455 </span>    }
  456 }
  457 </pre>
  458 
  459 <p>but, whoops, <span class="d_inlinecode donthyphenate notranslate">A.def()</span> now calls <span class="d_inlinecode donthyphenate notranslate">B.foo(long)</span>.
  460 <span class="d_inlinecode donthyphenate notranslate">B.foo(long)</span> has hijacked
  461 the <span class="d_inlinecode donthyphenate notranslate">A.foo(long)</span>. So, you might say, the
  462 designer of A should have had the foresight for this, and make
  463 <span class="d_inlinecode donthyphenate notranslate">foo(long)</span> a non-virtual function. The problem is that <span class="d_inlinecode donthyphenate notranslate">A</span>'s
  464 designer
  465 may very easily have intended <span class="d_inlinecode donthyphenate notranslate">A.foo(long)</span> to be virtual, as it's a new
  466 feature of <span class="d_inlinecode donthyphenate notranslate">A</span>. He cannot have known about <span class="d_inlinecode donthyphenate notranslate">B.foo(long)</span>.
  467 Take this to the logical conclusion, and we realize that under this system
  468 of overriding, there is no safe way to add any functionality to <span class="d_inlinecode donthyphenate notranslate">A</span>.
  469 </p>
  470 
  471 <p>The D solution is straightforward. If a function in a derived class
  472 overrides a function in a base class, it must use the storage class
  473 override. If it overrides without using the override storage class
  474 it's an error. If it uses the override storage class without overriding
  475 anything, it's an error.
  476 </p>
  477 
  478 <pre class="d_code notranslate"><span class="d_keyword">class</span> C
  479 {
  480     <span class="d_keyword">void</span> foo();
  481     <span class="d_keyword">void</span> bar();
  482 }
  483 <span class="d_keyword">class</span> D : C
  484 {
  485     <span class="d_keyword">override</span> <span class="d_keyword">void</span> foo();  <span class="d_comment">// ok
  486 </span>    <span class="d_keyword">void</span> bar();           <span class="d_comment">// error, overrides C.bar()
  487 </span>    <span class="d_keyword">override</span> <span class="d_keyword">void</span> abc();  <span class="d_comment">// error, no C.abc()
  488 </span>}
  489 </pre>
  490 
  491 <p>This eliminates the potential of a derived class member function hijacking
  492 a base class member function.
  493 </p>
  494 
  495 
  496 
  497 
  498 <h2><a class="anchor" title="Permalink to this section" id="derived-class-member-function-2" href="#derived-class-member-function-2">Derived Class Member Function Hijacking #2</a></h2>
  499 <p>There's one last case of base member function hijacking a derived
  500 member function. Consider:
  501 </p>
  502 
  503 <pre class="d_code notranslate"><span class="d_keyword">module</span> A;
  504 
  505 <span class="d_keyword">class</span> A
  506 {
  507     <span class="d_keyword">void</span> def()
  508     {
  509         foo(1);
  510     }
  511 
  512     <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  513 }
  514 </pre>
  515 
  516 <p>Here, <span class="d_inlinecode donthyphenate notranslate">foo(long)</span> is a virtual function that provides a specific
  517 functionality.
  518 Our derived class designer overrides <span class="d_inlinecode donthyphenate notranslate">foo(long)</span> to replace that behavior
  519 with one suited to the derived class' purpose:
  520 </p>
  521 
  522 <pre class="d_code notranslate"><span class="d_keyword">import</span> A;
  523 
  524 <span class="d_keyword">class</span> B : A
  525 {
  526     <span class="d_keyword">override</span> <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  527 }
  528 
  529 <span class="d_keyword">void</span> abc(B b)
  530 {
  531     b.def();   <span class="d_comment">// eventually calls B.foo(long)
  532 </span>}
  533 </pre>
  534 
  535 <p>So far, so good. The call to <span class="d_inlinecode donthyphenate notranslate">foo(1)</span> inside <span class="d_inlinecode donthyphenate notranslate">A</span>
  536 winds up correctly calling
  537 <span class="d_inlinecode donthyphenate notranslate">B.foo(long)</span>. Now <span class="d_inlinecode donthyphenate notranslate">A</span>'s designer decides to optimize things, and
  538 adds
  539 an overload for <span class="d_inlinecode donthyphenate notranslate">foo</span>:
  540 </p>
  541 
  542 <pre class="d_code notranslate"><span class="d_keyword">module</span> A;
  543 
  544 <span class="d_keyword">class</span> A
  545 {
  546     <span class="d_keyword">void</span> def()
  547     {
  548         foo(1);
  549     }
  550 
  551     <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  552     <span class="d_keyword">void</span> foo(<span class="d_keyword">int</span>);
  553 }
  554 </pre>
  555 
  556 <p>Now,
  557 </p>
  558 
  559 <pre class="d_code notranslate"><span class="d_keyword">import</span> A;
  560 
  561 <span class="d_keyword">class</span> B : A
  562 {
  563     <span class="d_keyword">override</span> <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  564 }
  565 
  566 <span class="d_keyword">void</span> abc(B b)
  567 {
  568     b.def();   <span class="d_comment">// eventually calls A.foo(int)
  569 </span>}
  570 </pre>
  571 
  572 <p>Doh! <span class="d_inlinecode donthyphenate notranslate">B</span> thought he was overriding the behavior of <span class="d_inlinecode donthyphenate notranslate">A</span>'s
  573 <span class="d_inlinecode donthyphenate notranslate">foo</span>, but did not.
  574 <span class="d_inlinecode donthyphenate notranslate">B</span>'s programmer needs to add another function to <span class="d_inlinecode donthyphenate notranslate">B</span>:
  575 </p>
  576 
  577 <pre class="d_code notranslate"><span class="d_keyword">class</span> B : A
  578 {
  579     <span class="d_keyword">override</span> <span class="d_keyword">void</span> foo(<span class="d_keyword">long</span>);
  580     <span class="d_keyword">override</span> <span class="d_keyword">void</span> foo(<span class="d_keyword">int</span>);
  581 }
  582 </pre>
  583 
  584 <p>to restore correct behavior. But there's no clue he needs to do that.
  585 Compile time is of no help at all, as the compilation of <span class="d_inlinecode donthyphenate notranslate">A</span> has no
  586 knowledge of what <span class="d_inlinecode donthyphenate notranslate">B</span> overrides.
  587 </p>
  588 
  589 <p>Let's look at how <span class="d_inlinecode donthyphenate notranslate">A</span> calls the virtual functions, which it
  590 does through the vtbl[]. <span class="d_inlinecode donthyphenate notranslate">A</span>'s vtbl[] looks like:
  591 </p>
  592 
  593 <pre class="d_code notranslate">A.vtbl[0] = &amp;A.foo(<span class="d_keyword">long</span>);
  594 A.vtbl[1] = &amp;A.foo(<span class="d_keyword">int</span>);
  595 </pre>
  596 
  597 <p><span class="d_inlinecode donthyphenate notranslate">B</span>'s vtbl[] looks like:
  598 </p>
  599 
  600 <pre class="d_code notranslate">B.vtbl[0] = &amp;B.foo(<span class="d_keyword">long</span>);
  601 B.vtbl[1] = &amp;A.foo(<span class="d_keyword">int</span>);
  602 </pre>
  603 
  604 <p>and the call in <span class="d_inlinecode donthyphenate notranslate">A.def()</span> to <span class="d_inlinecode donthyphenate notranslate">foo(int)</span>
  605 is actually a call to vtbl[1].
  606 We'd really like <span class="d_inlinecode donthyphenate notranslate">A.foo(int)</span> to be inaccessible from a <span class="d_inlinecode donthyphenate notranslate">B</span> object.
  607 The solution is to rewrite <span class="d_inlinecode donthyphenate notranslate">B</span>'s vtbl[] as:
  608 </p>
  609 
  610 <pre class="d_code notranslate">B.vtbl[0] = &amp;B.foo(<span class="d_keyword">long</span>);
  611 B.vtbl[1] = &amp;error;
  612 </pre>
  613 
  614 <p>where, at runtime, an error function is called which will throw an
  615 exception. It isn't perfect since it isn't caught at compile time,
  616 but at least the application program won't blithely be calling the wrong
  617 function and continue on.
  618 </p>
  619 
  620 <p><i>Update: A compile time warning is now generated whenever the
  621 vtbl[] gets an error entry.</i>
  622 </p>
  623 
  624 
  625 
  626 <h2><a class="anchor" title="Permalink to this section" id="conclusion" href="#conclusion">Conclusion</a></h2>
  627 <p>Function hijacking is a pernicious and particularly nasty problem in
  628 complex C++ and Java programs because there is no defense against it
  629 for the application programmer. Some small modifications to the language
  630 semantics can defend against it without sacrificing any power or performance.
  631 </p>
  632 
  633 
  634 
  635 <h2><a class="anchor" title="Permalink to this section" id="references" href="#references">References</a></h2>
  636 <ul><li><a href="http://www.digitalmars.com/d/archives/digitalmars/D/Hijacking_56458.html">digitalmars.D - Hijacking</a></li>
  637 <li><a href="http://www.digitalmars.com/d/archives/digitalmars/D/Re_Hijacking_56505.html">digitalmars.D - Re: Hijacking</a></li>
  638 <li><a href="http://www.digitalmars.com/d/archives/digitalmars/D/aliasing_base_methods_49572.html#N49577">digitalmars.D - aliasing base methods</a></li>
  639 <li>Eiffel, Scala and C# use override or something analogous</li>
  640 </ul>
  641 
  642 <p>Credits:</p>
  643 
  644 <ul><li>Kris Bell</li>
  645 <li>Frank Benoit</li>
  646 <li>Andrei Alexandrescu</li>
  647 </ul>
  648 
  649 
  650 
  651 
  652 
  653 
  654         <div class="smallprint" id="copyright">Copyright &copy; 1999-2020 by the <a href="../foundation_overview.html">D Language Foundation</a> | Page generated by
  655 <a href="../spec/ddoc.html">Ddoc</a> on Fri Nov 20 21:58:03 2020
  656 </div>
  657     </div>
  658 </div>
  659 
  660     <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
  661     <script type="text/javascript">window.jQuery || document.write('\x3Cscript src="../js/jquery-1.7.2.min.js">\x3C/script>');</script>
  662     <script type="text/javascript" src="../js/dlang.js"></script>
  663     
  664     <script type="text/javascript" src="../js/codemirror-compressed.js"></script>
  665     <script type="text/javascript" src="../js/run.js"></script>
  666 
  667 
  668 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
  669 </body>
  670 </html>