让我们直接看简化后的代码(编译器: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;
}
编译器报错: strlen(((const char*)(& cs))) 不是一个常量表达式。但是,当我将C字符串定义移到全局范围时,问题就解决了。
....
const char cs[] = "Hello";
int main(int arga, char* argv[]) {
constexpr size_t newSize = strlen(cs) + strlen(" ")//No Error
....
}
有人能解释一下发生了什么吗?为什么 strlen() 将一个全局定义的常量字符串视为常量表达式,但不是栈中的那个?
constexpr
了解不多,只是好奇当字符串本身不是constexpr
时,它的大小如何可以是constexpr
。 - 463035818_is_not_a_numberstrlen
,它会被视为内置函数,除非你传递一个标志来禁用它。也许这只适用于具有静态存储期的字符串。 - chrisconst int i = 5; int arr[i];
中的i
一样,在常量表达式中使用,尽管没有constexpr
关键字。给定一个constexpr
形式的strlen
函数,为了使指针转换正确工作,字符串必须具有静态存储期。如果你避免该转换(例如通过自己编写接受const char(&)[N]
的strlen
函数),我认为它无论存储期如何都可以正常工作。我希望得到一个有坚实支持的答案,而我目前无法做到这一点。 - chris