Incorrect C++ compiler behavior in Visual Studio

[Note: Special credit for this post goes to my colleague Yuliy Gerchikov, who first discovered this issue]

As most C++ programmers know, an object that has been constructed via the new expression must be destroyed by calling delete. The delete-expression invokes the object’s destructor which in turn is responsible for clean up tasks. For instance, here’s some sample code that shows object creation, and then freeing it up via delete:

	Foo *pF = new Foo();
	// Do some work
	delete pF;

The C++ Specification for delete has this to say:

The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.

delete-expression:
::opt delete cast-expression
::opt delete [ ] cast-expression

The first alternative is for non-array objects, and the second is for arrays. The operand shall have a pointer type, or a class type having a single conversion function (12.3.2) to a pointer type. The result has type void. (emphasis mine)

So, given that the delete expression has the return type void, what do you think the C++ compiler should do when it sees the following code:

	Foo *pF = new Foo();
	// Do some work
	delete delete pF;

But delete returns void, so it is reasonable to assume that the C++ compilers would throw a fit on the above code, right? Right? Unfortunately, that’s not always the case.

Let’s look at some C++ code. I have two user defined types Foo and Bar. The difference between the two types is that I declare and define an explicit destructor for Foo.

#include <iostream>
class Foo {
	public: ~Foo() { std::cout<<"In dtor"<<std::endl; }
};

class Bar {};

int main(){
	Foo *pf = new Foo();
    delete delete pf;

    Bar *pb = new Bar();
    delete delete pb;

    return 0;
}
Listing-1

When I compile this using Microsoft’s cl compiler as it ships with Visual Studio 2010 (Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64) here’s what I get:

test.cpp(13) : error C2541: 'delete' : cannot delete
 objects that are not pointers

And here’s the screen shot:

Screen shot-1

What is going on? Why doesn’t the compiler complain at both lines 10 and 13? It turns out, if a user-defined type has an explicit destructor, then the Visual Studio compiler happily compiles the double delete expression. It appears that in such a case the compiler violates the C++ specifications as the “delete ptr-to-type” returns a non-void pointer instead of void.

Suppose I get my code to compile by getting rid of the offending Bar object (code shown below). When I run my program, it is guaranteed to crash as we are calling delete on a ptr to unallocated space!

#include <iostream>
class Foo {
	public: ~Foo() { std::cout<<"In dtor"<<std::endl; }
};

int main(){
	Foo *pf = new Foo();
    delete delete pf;		//Uh Oh!

    std::cout<<"Hello world"<<std::endl;
    return 0;
}
Listing-2

And here’s the screen shot of the crash. Notice that as expected, the “Hello world” line never gets executed.

Screen shot-2

I tried out the same code in gcc (i686-apple-darwin10-gcc-4.2.1), and gcc behaves correctly, i.e. it errors out on both lines 10 and 13 in the listing-1 above.

I am not sure if this behavior of the Visual Studio compiler is intentional. What do you think? Have you encountered any weird C++ compiler behaviors? Please share your thoughts in the comments below.

About these ads

1 Comment

Filed under Programming, Tools

One response to “Incorrect C++ compiler behavior in Visual Studio

  1. Pingback: Incorrect C++ compiler behavior in Visual Studio

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s