为什么<cstring>中的所有函数都不能有constexpr?

时间:2017-02-20 18:45:28

标签: c++ constexpr c++17

我刚注意到D0202R2建议所有<cstring>函数不得拥有constexpr。我想了解为什么,在杰克逊维尔会议期间,决定采用这样的解决方案。

采用std::strchr之类的功能。我真的没有任何理由不被constexpr。实际上,编译器可以在编译时轻松优化某些dummy code like this(即使我从参数中看到我删除内置函数)。但是,与此同时,不可能在constexpr上下文中使用这些函数或使用静态断言。

我们显然可以重新实现一些<cstring>函数作为constexpr(就像我在this other dummy code中所做的那样),但我不明白为什么它们在标准中不能有constexpr库。

我错过了什么?

PS:Builtins!

一开始我很困惑,因为constexpr功能使用了一些<cstring>功能刚刚工作,然后我明白这只是归功于GCC内置。实际上,如果您添加-fno-builtin参数,则只能使用std::strlen而不是函数的自定义版本。

1 个答案:

答案 0 :(得分:3)

在对此进行更多回顾,并更多地思考C ++ 14放宽围绕constexpr的规则的含义时,我有不同的答案。

<cstring>标头是一堆C函数的包装器。 C没有constexpr概念,虽然它可能对它有用,但它很可能不会很快成长。因此,以这种方式标记这些功能将非常麻烦并且需要大量#ifdef s。

另外(我认为这是最重要的原因)当这些函数不是编译器内在函数时,它们在C中实现并作为目标代码存储在库文件中。库中的对象代码不是C ++编译器可在编译时进行评估的表单。它们不是内联的。像模板代码一样。

最后,他们所做的大部分真正有用的事情都可以很容易地用C ++ <algorithm>库来实现。 strlen(s) = (::std::string_view(s)).length()memcpy(a, b, len) = ::std::copy(b, b + len, a)等等。 D0202R2建议制作这些算法constexpr。而且,正如您所指出的,它还建议在::std::string_view constexpr中创建函数,这些函数也提供相同的功能。因此,鉴于前面提到的令人头疼的问题,似乎为constexpr函数实现<cstring>会带来可疑的好处。

作为附注,有::std::copy::std::move::std::copy_backward::std::move_backward,您可以自行决定你需要打电话。如果有一个函数能够确定xx_backwardmemmove这样的特定情况下是否需要,那就太好了。但是,由于迭代器的定义方式,使用一个迭代器并将其与另一个迭代器进行比较,而迭代器可能根本不会迭代同一个对象,这在C ++中是不可能的,即使它们是随机的访问迭代器。