std::strlen 在内部是如何工作的?

How does std::strlen wоrk internally?

我一直在努力理解 std::strlen() 但徒劳无功:

AFAIK strlen() returns 以字节为单位的空终止常量字符串中的字符数。如果它不是空终止的,则行为未定义。除此之外,还可以。

所以:std::strlen(""); 是 0。

但是,因为我在 www.cppreference.com 上读到了它,所以我找到了一个可能的实现方式:

// This is from:   https://en.cppreference.com/w/cpp/string/byte/strlen

std::size_t strlen(const char* start) {
     const char* end = start;
     while(*++end != 0);// I think this causes UB
     return end - start;
  }

但如果我 运行 它:

int main()
{
    const char cp1[] = "";
    const char cp2[] = "[=12=]";
    const char cp3[] = "[=12=]Hello";
    const char cp4[] = "H[=12=]ello";
    const char cp5[1] = {};// UB?
    const char cp6[] = {'[=12=]'};
    const char cp7[] = {'H', '[=12=]'};

    cout << std::strlen(cp1) << " " << sizeof(cp1) << endl;// 0 1 OK
    cout << strlen(cp1) << " " << sizeof(cp1) << endl;// 1 1  is UB?

    cout << "\nDone!\n";
}

所以我看到的是网站上实现的版本触发了未定义的行为:循环在其条件下结合了预递增运算符和取消引用运算符,正如我们所知,运算符具有相同的优先级他们是从右到左评估的。因此,首先增加指针然后取消引用它。在空字符串的情况下,指针指向最后一个字符(空字符)之后的一个然后取消引用它,据我所知这是 UB。

您说得对,可能的实现具有未定义的行为。 *++end 递增然后取消引用,这是空字符串上的 UB,因为您取消引用了结束元素。

可能的实现从 been changed

std::size_t strlen(const char* start) {
   const char* end = start;
   while(*end++ != 0);
   return end - start - 1;
}

这是一个正确的实现。

像这样 post inc,

std::size_t strlen(const char* const start) {
     const char* end = start;
     while(*end++ != 0);   // fixing I think this causes UB
     return --end - start;
  }