[cfe-dev] [patch] eliminate noisy warning on MSVC
Howard Hinnant
hhinnant at apple.com
Sat Jun 13 12:13:39 PDT 2009
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 still think it worth taking the patch as:
>
> i/ one forward declaration eliminates around 5500 warnings, totally
> swamping
> signal-to-noise in MSVC.
> ii/ it is generally good practice to provide such overloads in
> pairs, and
> I'm more comfortable following the general rule than grokking the
> code to
> see why this is a special case - AFAICT there is no benefit/
> optimization
> from not supplying the overload.
>
> It is also an easy way for me to see how the patch submission
> process works
> ;¬)
>
> BTW, among other things I am working on a doc patch for "building
> Clang on
> Windows" which might make MSVC warnings more of an issue (if
> successful!)
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
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
-Howard
More information about the cfe-dev
mailing list