|Finding Bugs In The First C++ Compiler - What does Bjarne Think!|
|Written by Andrey Karpov|
|Thursday, 26 November 2015|
C++ celebrated its 30th anniversary last month and this prompted the PVS-Studio team to use its static code analysis tool to look for bugs in the very first C++ compiler, Cfront. This may seem like a strange way to celebrate, especially when they confronted C++ founder, Bjarne Stroustrup, with his bugs. See what he said in return.
(Extract from 30 Years of C++, click to see more.)
When it was originally developed by Bjarne Stroustrup, C++ was known as "C with Classes". This extract from a timeline celebrating 30 Years of C++ reveals that work on the language started in 1979 and that it was released on October 14, 1985 together with the first edition of Stroustrup's book, The C++ Programming language.
The timeline also reveals that, having has its first release in 1985 Cfront had another three releases before being abandoned in 1993.
Cfront, based on CPre, had a complete parser, symbol tables, and built a tree for each class, function, etc. Many of the obscure corner cases in C++ are related to the Cfront implementation limitations. The reason is that Cfront performed translation from C++ to C. In short, Cfront is a sacred artifact for a C++ programmer. So I just couldn't help checking such a project with PVS-Studio and decided to look at the first version since it was the one that turned 30 this year.
I contacted Bjarne Stroustrup to get the source code of Cfront. For some reason I thought it would be a long story of getting the code. But it turned out to be quite easy.
This source code is open, available for everybody and can be found at:
Please remember this is *very* old software designed to run on a 1MB 1MHz machine and also used on original PCs (640KB). It was also done by one person (me) as only part of my full time job.
As it turned out checking such a project was impossible. At that time, for instance, to separate a class name from a function name they used a simple dot (.) instead of double colon (::). For example:
Our PVS-Studio analyzer wasn't ready for this. So I had to ask our colleague to look through the code and correct such spots manually. It really helped, although there still were some troubles. When the analyzer was checking some fragments, at times it got quite confused and was refusing to do the analysis.
Nevertheless, we did manage to check the project.
I should say right away, I haven't found anything crucial and I think there are three reasons why PVS-Studio hasn't found serious bugs:
However in order not to disappoint readers who are here to see at least one error of THE Stroustrup, let's have a look at the code.
PVS-Studio warning: V595 The 'cl' pointer was utilized before it was verified against nullptr. Check lines: 927, 928. expr.c 927
The 'cl' pointer can be equal to NULL. The if (cl == 0) check indicates that. What's worse is that this pointer gets dereferenced before this check. It occurs in the PERM macro.
So if we open the macro, we get:
The same here. The pointer was dereferenced and only then it was checked:
PVS-Studio warning: V595 The 'b' pointer was utilized before it was verified against nullptr. Check lines: 608, 615. norm.c 608
PVS-Studio warning: V563 It is possible that this 'else' branch must apply to the previous 'if' statement. error.c 164
I am not sure if there is an error here or not, but the code is formatted incorrectly. 'Else' refers to the closest 'if'. That's why the code doesn't execute in the way it should.
If we format it, then we'll have:
PVS-Studio warning: V576 Incorrect format. A different number of actual arguments is expected while calling 'fprintf' function. Expected: 3. Present: 4. generic.c 8
Note the format specifiers: "%s". The string will be printed, but the 'n' variable won't be used.
Unfortunately (or may be vice versa) I cannot show you anything else that look like real errors. The analyzer issued some warnings, that could be worth looking at, but they not really serious.
For example, the analyzer didn't like some global variable names:
PVS-Studio warning: V707 Giving short names to global variables is considered to be bad practice. It is suggested to rename 'Nn' variable. cfront.h 50
Another example: to print pointer values by means of fprintf() function Cfront uses the "%i" specificator. In the modern version of the language we have "%p". But, as far as I understand, there was no "%p" 30 years ago and the code was totally correct.
My attention was drawn by the fact that previously 'this' pointer was used in a different way. Here are a couple of examples:
As you see, it wasn't forbidden to change 'this' value. Now it's prohibited not only to change the pointer, but to compare 'this' to null, as this comparison has completely lost its sense.
I've also came across an interesting fragment that I particularly liked:
Bjarne Stroustrup's response
So how did Bjarne respond to being contrfronted with errrors committed 30 years ago? Here is the list of comments he sent back.
It's really hard to estimate significance of Cfront. It influenced the development of a whole sphere of programming and gave this world an everlasting C++ language which continues developing. I am really grateful to Bjarne for all the work that he has done in creating and developing C++. In my turn I was really glad to dig into the code of this wonderful compiler.
Andrey Karpov is a co-founder and CTO of Program Verification Systems, a company whose main activity is the development of the static code analysis tool, PVS-Studio. Andrey has received four Microsoft MVP awards as a Visual C++ expert and runs the C++ Hints website.
Also by Andrey Karpov on IProgrammer:
or email your comment to: firstname.lastname@example.org
|Last Updated ( Thursday, 26 November 2015 )|