相关疑难解决方法(0)

将空指针传递给placement new

默认的放置new运算符在18.6 [support.dynamic]1中声明,带有非抛出异常规范:

void* operator new (std::size_t size, void* ptr) noexcept;
Run Code Online (Sandbox Code Playgroud)

这个函数没有任何作用,除非return ptr;它是合理的noexcept,但是根据5.3.4 [expr.new]15这意味着编译器必须检查它在调用对象的构造函数之前不返回null:

-15-
[ 注意:除非使用非抛出异常规范(15.4)声明分配函数,否则它表示无法通过抛出std::bad_alloc异常来分配存储(第15,18.6.2.1节); 否则返回非空指针.如果使用非抛出异常规范声明分配函数,则返回null以指示无法分配存储,否则返回非空指针.-end note ]如果分配函数返回null,则不进行初始化,不应调用解除分配函数,并且new-expression的值应为null.

在我看来(特别是对于放置new,而不是一般)这个空检查是一个不幸的性能命中,尽管很小.

我一直在调试一些代码,其中new在一个性能敏感的代码路径中使用了放置,以改进编译器的代码生成,并在程序集中观察到null检查.通过提供new使用抛出异常规范声明的特定于类的放置重载(即使它不可能抛出),删除了条件分支,这也允许编译器为周围的内联函数生成更小的代码.说放置new函数的结果可能会抛出,即使它不能,也是可测量的更好的代码.

所以我一直想知道是否真的需要进行空检查new.它返回null的唯一方法是将它传递给null.尽管写下来是可能的,而且显然是合法的:

void* ptr = nullptr;
Obj* obj = new (ptr) Obj();
assert( obj == nullptr );
Run Code Online (Sandbox Code Playgroud)

我不明白为什么这将是有益的,我认为它会更好,如果程序员有明确使用放置前检查null new

Obj* obj = ptr ? new (ptr) Obj() : nullptr;
Run Code Online (Sandbox Code Playgroud)

有没有人需要放置new来正确处理空指针的情况?(即不添加作为ptr有效内存位置的显式检查.)

我想知道禁止将空指针传递给默认的放置 …

c++ placement-new micro-optimization noexcept

42
推荐指数
1
解决办法
3350
查看次数

在定义明确的c ++中,从引用获取的指针是否可以为null?

这个问题是由于检查指针值nullptr受到clang和gcc 的不均衡处理而引起的。因为this它们都发出警告,但是对于address-of在对象上使用运算符获取的指针,它们保持安静。

我很确定这样的指针应该一直有效,因为现代编译器从快乐的90年代实际上取消了对c ++代码的检查,导致了我们遇到的错误。

令我感到困惑的是,为什么编译器在一般情况下保持安静。是否可以通过某种方式if触发,或者这仅仅是两个主要编译器中的设计决策?在开始编写补丁或调试编译器开发人员之前,我想确保我没有错过任何内容。

玩具示例

#include <iostream>
class A {
    void f(){
        if(!this) {
            std::cout << "This can't trigger, and compilers warn about it.";
        }
    }
};

void f(A& a){
    A* ptr = &a;
    if(ptr == nullptr) {
        std::cout << "Can this trigger? Because gcc and clang are silent.";
    }
}
Run Code Online (Sandbox Code Playgroud)

尽管这个问题看起来很愚蠢,但我发现它很实用。如果使用臭代码工作,则此优化将导致致命的结果,因此警告将是非常有用的诊断。

以补充情况。clang和gcc都知道检查具有不变的评估能力,因为即使对于干净的代码:

void g(A* a){
    A* ptr = a;
    if(ptr == nullptr) {
        std::cout << "Gee, can …
Run Code Online (Sandbox Code Playgroud)

c++ pointers reference null-pointer language-lawyer

4
推荐指数
1
解决办法
130
查看次数