Strlen () compile time optimization

A few days ago, I discovered that you can find strlen compile time using something like this:

 template<size_t N> constexpr size_t strlen_(const char (&data)[N]) noexcept{ return N - 1; } 

If it is compiled, then everything will be fine. You can add this overload:

 size_t strlen_(const char *s) noexcept{ return strlen(s); } 

Then it always compiles.

My question is that C ++ <cstring> uses something like this, and if not, why?

+7
c ++ string arrays c ++ 11
source share
5 answers

No, it is not. Because he gives the wrong answer.

 char x[10] = "abc"; int correct_length = std::strlen(x); // 3 int incorrect_length = strlen_(x); // 9 

In addition, with two overloads, the template will never be called. Custom that takes a const char* will always be preferable.

This does not mean that strlen cannot be computed at compile time with some compiler magic. But this cannot be done using the language itself.

+8
source share

Your strlen_ returns the size of the data array, not the size of the zero-terminated string. Correct implementation:

 constexpr size_t ct_strlen( const char* s ) noexcept { return *s ? 1 + ct_strlen(s + 1) : 0; } 
+4
source share

Your code is defective.

The correct way to optimize compile time on strlen() , oddly enough, just calls strlen() . a modern compiler like clang will optimize unnecessary strlen() when it knows the length at compile time.

In addition, in most cases, sizeof comes in handy when you, the programmer, use it correctly if the variable contains literal strings. as:

 const char foo[] = "Hello World"; size_t len = sizeof(foo)-1; // 11 

Note that this has some kind of assumption, and if you do this, you make problems, but don't make your life simple:

 const char foo[] = "Hello World\01234"; size_t len = sizeof(foo)-1; // 16 

EDITED: to make the obvious more like an answer.

+2
source share

Your strlen _ is not working: http://ideone.com/PNNeaX

Also: I know that visual studio 2015 optimizes all kinds of strlen calls, even in situations where I had doubts that went away when I checked the output of the assembly that runtime strlen did not generate.

And as @Calvin says, Klang seems to be doing the same. Therefore, there is no reason for this.

+2
source share

Subsequent response from ZDF response.

I tested, and this seems like premature optimization.

The code:

 #include <cstdio> #include <cstring> constexpr unsigned MAX = 1000 * 1000 * 250; constexpr size_t strlen_c(const char* s) noexcept{ return *s ? 1 + strlen_c(s + 1) : 0; } int main(){ constexpr const char *s = "Hi, my name is Malcolm and I am very good boy..."; unsigned sum = 0; for(unsigned i = 0; i < MAX; ++i){ sum += strlen(s) + i; } return sum; } 

Results:

The code was compiled with:

 gcc x.cc -std=c++11 -Wall -Wpedantic gcc x.cc -std=c++11 -Wall -Wpedantic -O3 clang x.cc -std=c++11 -Wall -Wpedantic clang x.cc -std=c++11 -Wall -Wpedantic -O3 

and this is how long it took:

 ------------------------------------ | | GCC | CLANG | ------------------------------------ | len | 0m1.506s | 0m0.743s | | len O3 | 0m0.001s | 0m0.002s | | lenc | 1m5.476s | 0m56.871s | | lenc O3 | 0m12.267s | 0m0.060s | ------------------------------------ 

Clang looks a little faster, but with full optimization constexpr strlen_c() did not pay off.

Let me know if I did something wrong in the code.

+2
source share

All Articles