Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Bug++ of the Month


March 2001/Bug++ of the Month

Bug++ of the Month

Ron Burk


Templates are the crucial ingredient for a new style of C++ coding: generic programming. For many programmers, the dream of C++ is one of creating reusable code, but it has been a largely unrealized dream. People who tried to write “the only string class you’ll ever need,” for example, were quickly confronted with the reality that different customers of a class have different needs. (I need it fast; you may need it small; etc.)

The dream of achieving high degrees of code reuse in C++ is far from dead, however, having been re-energized by the STL (Standard Template Library). The STL was an impressive demonstration of a programming style that lets you use templates to solve a class of problems and write reusable code that can adapt to the different needs of different customers. It was an impressive enough development that the Standards committee decided to make it part of the C++ Standard late in the game when they were trying (with limited success) to limit new additions.

The STL seems very interesting to me, but I don’t use it. I’ve heard expert C++ programmers say that template implementations are now mature enough that there’s no excuse any more for not using them. I don’t know if they’re living on a different planet from me, or if they simply don’t use the same compilers as me. What I do know, from observing the stream of bug submissions to this column, is that if I declared that we would henceforth only accept template-related compiler bugs, we would still have plenty of submissions. Until recently, I’ve actively avoided using template bugs in this column, but I think it’s time to start taking them on. Templates are an important part of C++, their definition has now been specified for years, and it’s time to start expecting compiler vendors to get their implementations debugged.

This Month’s Bug

This month’s feature is one of those relatively rare Visual C++ bugs that Microsoft has actually decided to reveal to customers via their website. I wanted to feature it anyway, because I think it’s representative of the current state of templates, at least as far as most Windows programmers are concerned, since they by and large are Visual C++ users.

Reader (and dedicated bug submitter) John O’Halloran provided bug.cpp (Listing 1), which shows the problem code. It’s obviously boiled down to the point of absurdity, but you can guess how this arose in real-life code. There are two distinct classes that each have a static function named Fn(). There is a template function that can operate on any class that has a static function named Fn(). This is an essential part of generic programming — being able to write code that will operate correctly on any class that satisfies a fairly minimal set of requirements.

The code here is completely legal, and Visual C++ compiles it. The only problem is that the generated code is completely incorrect. The output is:

B static
B static

All invocations of the template function operate on class B, no matter what class was actually specified in the template function invocation.

This is a pretty good example of why I still haven’t started making much use of templates in my C++ code. The main reason I would want to use templates is to build libraries of reusable code, but I can’t get too excited about building a library that I’m going to have to litter with workarounds for bugs in Visual C++. I sincerely hope that Visual C++ 7 (should I live long enough to see it released) will be a lot closer to implementing templates correctly. Until that happens, or until my code doesn’t have to support Visual C++, templates will remain a back burner feature for me.

Microsoft’s Response

Kerry Loynd of Microsoft provided this response for us:

This is a known bug in all versions of Visual C++. See

support.microsoft.com/support/kb/articles/Q240/8/71.ASP

This bug will be fixed in Visual C++ 7.0.

The URL he mentions goes on to say:

The bug is the result of the way the compiler decorates template function names. Name Decoration uses the arguments and return type and doesn’t use the explicitly specified template argument type. Therefore, all [...] template function instantiations receive the same decorated name [...].

It’s pretty rare that Microsoft will actually commit to a bug being fixed in a specific release, so I’m guessing they know this is a really unacceptable bug and actually have it fixed already in-house. Will the many other Visual C++ template bugs be fixed in the next release? I’ll hope for the best.

Summary

How about you? Have you tried to use templates to create reusable code in your own Windows programming? How important or unimportant is template support in Visual C++ 7 going to be to you? Share your template thoughts with me and other readers by sending a note to [email protected]. Or, if you’ve got a stack of template bugs you’ve been saving for the day we started covering them, now’s your chance. Just boil it down to the smallest possible example, explain what’s going wrong (remember, I’m not a template expert), and fire it off to [email protected].

Visual C++ 7 could ship tomorrow, or it could ship five years from now. I’m betting on sooner, and I’m really tired of VC++ 6 bugs, so I’ll offer the following bounty to the first person to send us a bona fide new VC++ 7 bug. To make the challenge less trivial, the bug has to be a bug that did not exist in VC++ 6 and (as usual) has to be a language bug in the compiler itself (compiles but shouldn’t, should compile but doesn’t, crashes the compiler, or generates bad code). In addition to the usual WDJ T-shirt, the winner will also get a year’s extension added to their WDJ subscription and a free copy of the WDJ CD-ROM of back issues.

Reader Feedback

From: [email protected]
Subject: Apparant “goto” bug in Visual C++ 6.0

I did not discover this bug myself. A member of the [email protected] (Kevin Palmer) posted it. A lively discussion ensued; the general consensus of which was, “It sure looks like a bug, walks like a bug, and quacks like a bug, but the compiler has no bugs, and if they did, the Microsoft people are so smart we would never find it, so it must not be a bug.” Since I’m not convinced that any significant code, much less Visual Studio, is bug free, and I doubt that the people at Microsoft are somehow inherently smarter than me, I believe this is a bug. It also reportedly does not occur in Visual C++ 4.0. I couldn’t find it documented on Microsoft’s website.

The issue arises if a function has a conditional control path, using a goto, which does not have a valid return statement for all paths. Admittedly, using a goto in this manner is probably a poor design decision, but it would be nice if the compiler handled it correctly. The example that Kevin (the original poster on msvc) gave was this:

int func(void)
{
  int a = 0;
  bool error = false;

  if(error)
    goto Quit;

  if(a==2)
    return 3;

Quit:
  a=a;
  // forgot to return nnnn
}

As you can see, the function falls through this code to a=a. The program hangs when func() is called. A quick step through in the debugger and it becomes apparent that it loops back, infinitely, to the quit label. No warning or error is generated. (Well, in warning level 4, the compiler notes that the line containing return 3 is unreachable code.)

I shoved a breakpoint in the program and looked at the disassembly: sure enough, the compiler generates an unconditional jmp after the assignment. The disassembly window looks like this:

17:
18:   Quit:
19:     a=a;
0040105E   mov      ecx,dword ptr [ebp-4]
00401061   mov      dword ptr [ebp-4],ecx
20:     // forgot to return nnnn
21:   }
00401064   jmp      Quit (0040105e)
00401066   pop      edi
00401067   pop      esi
00401068   pop      ebx
00401069   mov      esp,ebp
0040106B   pop      ebp
0040106C   ret

Note the jmp Quit at the top of the function clean-up code.

Continuing the exploration, I found that renaming the file .c (to invoke the C compiler) generates what I would expect from C code — the function falls through and returns zero. Also, for kicks, I added a return 9 after the a=a assignment, and while the function exited correctly, the jmp was still present. (The return jumped around it.)

I telnetted into my Linux box at home and tried the code there. egcs let the function fall through, returning garbage. Curiously, egcs did not report an error or warning, by default, although with the -Wall option (to enable all warnings), it correctly noted that not all control paths returned a value.

Now, since I haven’t used a goto since giving up Applesoft in favor of Turbo Pascal 1.0 on a Z80 running CP/M, I’m not completely certain what the rules regarding gotos are in C++. My main reference notes that it’s an error to have a label immediately before a brace, and that it’s an error to use goto to jump over declarations (because constructors won’t get called), but neither of those situations exists in this case. To whit: it looks like a bug, walks like a bug, and quacks like a bug.

I was almost sold on this one, but fortunately you included an assembly language dump. That started some synapses firing, tickling some dim memories of the past, and, after interminable searching, I discovered that I believe your bug is identical to the bug we reported back in June 1999. I can’t fault you for not knowing that, because I could barely remember myself. As the years between Visual C++ upgrades continue to pile up, it gets harder and harder to remember all the bugs featured here that will be “fixed in a future release.”

Ron Burk is the editor of Windows Developer’s Journal. You can reach him at [email protected]. Send compiler bug candidates to [email protected].


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.