获取常量char数组的字符串长度函数(strlen)不是常量表达式

时间:2021-11-06 16:04:53

Let's see the simplified code directly (compiled by: GCC 6.3.0)

让我们直接看一下简化的代码(编译:GCC 6.3.0)

#include<iostream>
#include<cstring>

using namespace std;

int main(int arga, char* argv[]) {

    const char cs[] = "Hello";//define a constant c-style string 
    constexpr size_t newSize = strlen(cs) + strlen(" ");//Error

    return 0;
}

Compiler yielded an error: strlen(((const char*)(& cs))) is not a constant expression

编译器产生错误:strlen(((const char *)(&cs)))不是常量表达式

However, when I move the c-string definition to the global scope, then the problem is off.

但是,当我将c字符串定义移动到全局范围时,问题就会消失。

.... 
const char cs[] = "Hello";

int main(int arga, char* argv[]) {
    constexpr size_t newSize = strlen(cs) + strlen(" ")//No Error
 ....
}

Can someone explain what happened? Why strlen() sees a globally defined constant c-string as a constant expression, but not the one in the stack?

有人能解释发生了什么吗?为什么strlen()将全局定义的常量c-string视为常量表达式,而不是堆栈中的那个?

1 个解决方案

#1


6  

Standard strlen is not constepxr, therefore, it cannot be used in constexpr context. However, GCC knows about strlen, therefore it is able to compute the length of the string, in some circumstances - even if it is not mandated/permitted by the standard.

标准strlen不是constepxr,因此,它不能在constexpr上下文中使用。但是,GCC知道strlen,因此在某些情况下它能够计算字符串的长度 - 即使它没有被标准强制/允许。

If you are concerned only by arrays, you can use std::size to get their size:

如果您只关心数组,可以使用std :: size来获取它们的大小:

template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
    return N;
}

#1


6  

Standard strlen is not constepxr, therefore, it cannot be used in constexpr context. However, GCC knows about strlen, therefore it is able to compute the length of the string, in some circumstances - even if it is not mandated/permitted by the standard.

标准strlen不是constepxr,因此,它不能在constexpr上下文中使用。但是,GCC知道strlen,因此在某些情况下它能够计算字符串的长度 - 即使它没有被标准强制/允许。

If you are concerned only by arrays, you can use std::size to get their size:

如果您只关心数组,可以使用std :: size来获取它们的大小:

template <class T, std::size_t N>
constexpr std::size_t size(const T (&array)[N]) noexcept
{
    return N;
}