dodomorandi
dodomorandi

Reputation: 1153

Why all function in <cstring> must not have constexpr?

I just noticed that D0202R2 propose that all <cstring> functions must not have constexpr. I would like to understand why, during Jacksonville meeting, it was decided for a solution like this.

Take a function like std::strchr. I really do not see any reason for not being constexpr. Indeed, a compiler can easily optimize some dummy code like this at compile-time (even if I remove builtins, as you can see from the parameters). However, at the same time, it is not possible to rely on these functions within constexpr contexts or using static assertions.

We could obviously re-implement some of <cstring> functions to be constexpr (as I did in this other dummy code), but I do not understand why they must not have constexpr in the standard library.

What am I missing?


PS: Builtins!

At the beginning I was confused because constexpr functions using some <cstring> capabilities just worked, then I understood it was only thanks to GCC builtins. Indeed, if you add the -fno-builtin parameter, you can just use std::strlen instead of the custom version of the function.

Upvotes: 4

Views: 705

Answers (1)

Omnifarious
Omnifarious

Reputation: 56048

Upon reviewing this more, and thinking more about the implications of the C++14 relaxation of rules surrounding constexpr, I have a different answer.

The <cstring> header is a wrapper around a bunch of C functions. C has no constexpr concept, and while it might be useful for it to have one, it's not likely to grow one anytime soon. So marking up those functions in that way would be cumbersome and require a lot of #ifdefs.

Also (and I think this is the most important reason) when those functions are not compiler intrinsics they are implemented in C and stored in a library file as object code. Object code in a library is not a form accessible to the C++ compiler to evaluate at compile time. They are not 'inline' like template code is.

Lastly, most of the really useful things they do can easily be implemented in terms of the C++ <algorithm> library. strlen(s) = (::std::string_view(s)).length(), memcpy(a, b, len) = ::std::copy(b, b + len, a) and so on. And D0202R2 proposes to make those algorithms constexpr. And, as you pointed out, it also proposes to make functions in ::std::string_view constexpr and these also give equivalent functionality. So, given the previously mentioned headaches, it seems that implementing constexpr for the <cstring> functions would be of dubious benefit.

As a side note, there's ::std::copy, ::std::move, ::std::copy_backward, and ::std::move_backward and it's up to you to figure out which you need to call. It would be nice if there was a function that could figure out whether or not x or x_backward was needed in that particular case like memmove does. But, because of the way iterators are defined, taking one iterator and comparing it to another iterator that may not be iterating over the same object at all just isn't possible to do in C++, even if they're random access iterators.

Upvotes: 3

Related Questions