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;
}