C++将 new 放置到 NULL 中的不寻常用法
在 以下 C++98 语句中:
multiThreadService[nextBuffer] = new (NULL) MultiThreadService(binder);
这样说是否正确:
- 这是“placement new”,
- 该对象将被创建(以某种方式为 NULL?)并被丢弃,并且
multiThreadService[nextBuffer]
现在将为 NULL?
我还被告知这可能是 UB - 是这样吗?
In the following C++98 statement:
multiThreadService[nextBuffer] = new (NULL) MultiThreadService(binder);
Would it be correct to say:
- this is "placement new",
- the object will be created (at NULL, somehow?) and thrown away, and
multiThreadService[nextBuffer]
will now be NULL?
I was also told this could be UB - is that the case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,它不一定是调用全局非分配placement-new
operator new
重载void*operator new(std::size_t size, void* ptr)
(什么是通常表示“placement new”。)因为 new 表达式未限定为
::new
,所以它可能更喜欢operator new 的类内重载
是否存在合适的以及类型NULL
不是void*
,而是std::nullptr_t
或整型(前者在 C++98 中不可能) 。因此,即使在全局情况下,重载解析也存在一些潜在的替代结果。在项目中搜索
operator new
重载,可以在 https://github.com/aneto0/MARTe2/blob/master/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h#L85,即使放置参数(第二个函数参数)是一个空指针。如果所选重载确实是全局非分配放置新
operator new
,那么它基本上是 C++98 中的 noop,导致空指针。如果operator new
返回空指针,则new
表达式需要不执行任何初始化。但是,CWG 1748 对此进行了更改,现在如果全局非分配placement-new运算符new返回空指针值。这也可能被认为是针对 C++98 的缺陷(我不知道),在这种情况下
-std=c++98
不会阻止当前编译器上的未定义行为。First, it is not necessarily calling the global non-allocating placement-new
operator new
overloadvoid* operator new(std::size_t size, void* ptr)
(What is commonly meant by "placement new".)Because the new-expression is not qualified as
::new
, it may prefer an in-class overload ofoperator new
if a suitable one exists and furthermore the type ofNULL
is notvoid*
, but eitherstd::nullptr_t
or an integral type (the former not being possible in C++98). Therefore there are some potential alternative results of overload resolution even in the global case.Searching the project for
operator new
overloads one can find at least one possible candidate at https://github.com/aneto0/MARTe2/blob/master/Source/Core/BareMetal/L2Objects/CLASSREGISTER.h#L85, which seems to return a valid pointer even if the placement argument (second function argument) is a null pointer.If the selected overload is really the global non-allocating placement-new
operator new
, then it was basically a noop in C++98 resulting in a null pointer.new
expressions were required to not do any initialization ifoperator new
returns a null pointer.However this was changed with CWG 1748 and now the behavior is undefined if the global non-allocating placement-new
operator new
returns a null pointer value. This may have been considered a defect against C++98 as well (I don't know), in which case-std=c++98
will not prevent the undefined behavior on a current compiler.