[cfe-dev] [patch] eliminate noisy warning on MSVC

AlisdairM(public) public at alisdairm.net
Sat Jun 13 12:37:57 PDT 2009


> -----Original Message-----
> From: Howard Hinnant [mailto:hhinnant at apple.com]
> Sent: 13 June 2009 20:14
> To: AlisdairM (public)
> Cc: cfe-dev at cs.uiuc.edu
> Subject: Re: [cfe-dev] [patch] eliminate noisy warning on MSVC
> 
> On Jun 13, 2009, at 11:40 AM, AlisdairM(public) wrote:
> 
>>> The attached patch eliminates a noisy warning building Clang with 
>>> Visual C++.

>>> Essentially, if MSVC sees an operator new overload, it expects to 
>>> see the matching operator delete in case an exception is thrown and 
>>> it needs to reclaim the storage.  In this case the warning is 
>>> redundant, as the operator new overload is declared with an empty 
>>> throw specification.

> I believe you'll need a definition.  This helloworld:
> 
> #include <new>
> #include <cstdlib>
> #include <string>
> 
> class A {};
> 
> void* operator new(std::size_t s, const A&) throw() {
>      return std::malloc(s);
> }
> 
> void operator delete(void*, const A&) throw();
> 
> int main()
> {
>      std::string* p = new (A()) std::string("some text"); }
> 
> doesn't link on g++ platforms:
> 
> Undefined symbols:
>    "operator delete(void*, A const&)", referenced from:
>        _main in ccqdNwOY.o
> ld: symbol(s) not found
> collect2: ld returned 1 exit status

Note that both operator new and operator delete *are* defined, but in both
cases the definition is found in ASTContext.h.

> The definition is not unneeded if the object being constructed can 
> throw in its constructor.  A "nothrow" new expression *can* throw, and 
> this is when the matching placement delete is called:
> 
> #include <new>
> #include <cstdlib>
> #include <iostream>
> 
> class A {};
> 
> int new_called = 0;
> int delete_called = 0;
> 
> void* operator new(std::size_t s, const A&) throw() {
>      ++new_called;
>      return std::malloc(s);
> }
> 
> void operator delete(void* p, const A&) throw() {
>      ++delete_called;
>      free(p);
> }
> 
> struct B
> {
>      B() {throw 1;}
> };
> 
> int main()
> {
>      try
>      {
>          new (A()) B;
>      }
>      catch (...)
>      {
>      }
>      std::cout << "new_called = " << new_called << '\n';
>      std::cout << "delete_called = " << delete_called << '\n'; }
> 
> new_called = 1
> delete_called = 1

In that case, my patch may be more than theoretical, and I should Either
update or remove the comment on the delete operator.

AlisdairM





More information about the cfe-dev mailing list