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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么std :: string没有空指针?相关的知识,希望对你有一定的参考价值。

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

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

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

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

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

答案

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

有人刚提议改变这个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]构建''已经是一种低性能解决方案;你已经在编译时获得了字符串的大小,然后将它放在地面上,然后在运行时遍历缓冲区以找到std::string字符(除非进行优化;如果是这样,则null检查同样可以优化)。高性能解决方案包括了解长度并告诉'',而不是从std::string(NULL)终止缓冲区复制。

另一答案

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

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

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

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

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

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

以上是关于为什么std :: string没有空指针?的主要内容,如果未能解决你的问题,请参考以下文章

为什么std :: string_view :: data不包含空终止符?

java String.valueOf(null)为啥会报空指针

如何将 std::vector<std::string> 转换为 C api 的 char*[] [重复]

C++ 将 std::string 复制到没有空终止的 char 数组

防止核心转储使用空指针初始化字符串

对“std::vector<int, std::allocator<int>>”类型空指针的引用绑定