编译无serna包时出现以下错误:
build/buildd-serna-free_4.3.0.20110221-2-i386-pAsDoD/serna-free-4.3.0.20110221/
sfworks/common/RefCntStorage.h:76:10:
error: non-placement deallocation function 'static void
StringPrivate::RefCntData<E>::operator
delete(void*,StringPrivate::size_type) [with E = QChar,
StringPrivate::size_type = unsigned int]'
/build/buildd-serna-free_4.3.0.20110221-2-i386-pAsDoD/serna-free-4.3.0.20110221/
sfworks/common/RefCntStorage.h:135:9:
error: selected for placement delete
Run Code Online (Sandbox Code Playgroud)
代码如下:
void operator delete(void* p, size_type)
{
::operator delete(p);
}
Run Code Online (Sandbox Code Playgroud)
我认为问题来自规范中的措辞:
如果类T没有声明这样的运算符删除,但确实声明了一个名为operator delete的成员释放函数,只有两个参数,第二个类型为std :: size_t(18.1),则此函数是通常的释放函数
这意味着,如果你试图声明一对operator new,并operator delete认为采取了size_t作为第二个参数,编译器会认为你operator delete与此签名:
void operator delete (void* memory, size_t arg)
Run Code Online (Sandbox Code Playgroud)
是标准(非放置)解除分配器而不是应该匹配的放置解除分配器operator new(void*, size_t).
有什么奇怪的是,在规范中没有任何地方说它会导致编译器错误.事实上,规范只是说如果你有这个错误,那么如果自定义new抛出异常,那么内存就不会被清除.如果有人知道为什么g++报告这是一个错误,我很想知道为什么(特别是如果我错了,这真的应该是非法的).
编辑:啊!问题似乎来自C++ 0x.根据新标准的最新草案,§3.5.4/ 20:
如果查找找到通常的释放函数(3.7.4.2)的双参数形式,并且该函数(被认为是放置释放函数)将被选择作为分配函数的匹配,则该程序是错误的.
它特别列出了这样做作为导致破损的一个例子.事实上,这是C++ 0x中的新功能,这可以解释为什么错误只会在最新版本中突然出现g++.