为什么std :: string没有空指针?

问题描述 投票:1回答:2

我最近传递了一个指向std::string构造函数的空指针,并得到了未定义的行为。我确信这是成千上万的程序员在我之前所做的事情,同样的错误毫无疑问地破坏了无数的程序。当使用char*从使用std::string的代码转换为使用std::string的代码时会出现很多问题,并且它是在编译时无法捕获的东西,并且在运行时单元测试中很容易被遗漏。

我很困惑的是以这种方式指定std::string(NULL)==""的原因。

为什么不定义std::string(NULL)

效率损失可以忽略不计,我怀疑它在真实程序中是否可以衡量。

有谁知道使a month ago undefined的可能原因是什么?

c++ string std null-pointer
2个回答
2
投票

据我所知,没有充分的理由。

有人刚提议改变这个std::string。我鼓励你支持它。

不是做得好的标准化的最好例子。最初标准化的版本无法实施;对它们的要求彼此不一致。

在某些时候,不一致是固定的。

std::string中,改变了防止COW(写入时复制)实现的规则,这打破了现有合理的stds的ABI。我不记得这种变化可能已经解决了不一致的问题。

它的API与std的其他容器不同,因为它不是来自相同的pre-std::string STL。

std::string的这种遗留行为视为考虑性能成本的某种合理决策是不现实的。如果进行了任何这样的测试,那就是20多年前的非标准兼容(char const*)0(因为没有一个可以存在,标准是不一致的)。

由于惯性,它仍然是通过nullptrstd::string的UB,并将继续这样做,直到有人提出建议并证明成本很小而利益不是。

从文字char const[N]构建'\0'已经是一种低性能解决方案;你已经在编译时获得了字符串的大小,然后将它放在地面上,然后在运行时遍历缓冲区以找到std::string字符(除非进行优化;如果是这样,则null检查同样可以优化)。高性能解决方案包括了解长度并告诉'\0',而不是从std::string(NULL)终止缓冲区复制。


3
投票

唯一的原因是:运行时性能。

确定std::string导致空字符串确实很容易。但它需要额外检查来自const char *的每个qazxswpoi的构造,这可以加起来。

在绝对最大性能和便利性之间取得平衡,C ++始终追求绝对最大性能,即使这会损害程序的稳健性。

最着名的例子是默认情况下不在类中初始化POD成员变量:尽管99%的情况下程序员都希望初始化所有POD成员变量,但C ++决定不这样做以允许所有类的1%实现稍高的运行时性能。这种模式在C ++中遍布各处。表现优于其他一切。

在C ++中没有“性能影响可以忽略不计”。 :-)

(请注意,我个人不喜欢C ++中的这种行为。我会这样做,以便默认行为是安全的,并且必须明确请求未经检查和未初始化的行为,例如使用额外的关键字。未初始化的变量是仍然是2018年很多项目中的一个主要问题。)

© www.soinside.com 2019 - 2024. All rights reserved.