Incorrect C++ compiler behavior in Visual Studio
Join the DZone community and get the full member experience.
Join For Free[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:
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.
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.
Published at DZone with permission of Umair Saeed. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
What I Learned From Crawling 100+ Websites
-
How To Scan and Validate Image Uploads in Java
-
Building a Java Payment App With Marqeta
-
Testing, Monitoring, and Data Observability: What’s the Difference?
Comments