Channels ▼

Walter Bright

Dr. Dobb's Bloggers

In A Module Far, Far Away Part 2

July 25, 2009

In the last installment, we talked about how changing a declaration in one module can unexpectedly change the behavior of another module, and how language features can mitigate that. Here are some more features of the D programming language designed for that purpose.

Final Switch

Given an enum declaration:

 enum E { A, B, C }

and in the remote module there's a switch statement:

 E e;
 ...
 switch (e)
 {  case A: ...
    case B: ...
    case C: ...
    default: assert(0);
 }

The declaration for E gets updated to add a member D:

 enum E { A, B, C, D }

and the switch statement, which is supposed to handle all the possibilities of E, is now incorrect. At least our intrepid programmer has anticipated this and put in a default that asserts. But this identifies the problem at runtime, if the test suites are thorough. We'd prefer to catch it at compile time in a guaranteed manner.

Enter the final switch statement:

 final switch (e)
 {  case A: ...
    case B: ...
    case C: ...
 }

In a final switch statement, all enum members must be represented in the case statements. A default statement has no point, and is not even allowed in a final switch. If we add an unrepresented member D, the compiler dings us in the final switch.


Override

Given a class C declared in one module:

 class C { }

and another module declares class D that derives from C, and declares a virtual method foo():

 class D : C { void foo(); }

Later, a method foo() is added to class C:

 class C { void foo(); }

Now, the call to C.foo() gets inadvertently hijacked by D.foo(), which may be quite unrelated. The solution is to mark intentional overriding with the override keyword:

 class B : A { override void bar(); }

Then, if a method overrides a base class method, but is not marked with override, the compiler issues an error.


Function Hijacking

In module A, there's a function:

 void foo(long x);

Module C imports A, and B and calls foo() with an int argument:

 import A;
 import B;
 ...
 foo(3);

Now, the designer of B, having no knowledge of A or that C imports A and B, adds the following declaration to B:

 void foo(int x);

Suddenly, C.foo(3) is calling B.foo(3) because B.foo(int) is a better match for 3 than A.foo(long). B.foo(int) is said to have hijacked the call to A.foo(long). In D, such overloading across modules would generate a compile time error if a call from C matches functions from more than one import. Overloading across imports must be done intentionally, not by default, by using an alias declaration:

 import A;
 import B;
 alias A.foo foo;
 alias B.foo foo;
 ...
 foo(3);  // calls B.foo(int)

There's a lot more to function hijacking.

Conclusion

It's a worthy goal of language design to be able to prevent changes in declarations in one module from producing unexpected bad behavior in another. While I know of no way to eliminate all such cases, D makes some major steps in closing common loopholes.

If you want to learn more about how real compilers work, I am hosting
a seminar in the fall on compiler construction.

Thanks to Jason House and Don Clugston for their helpful comments on this.

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video