考虑以下代码:
#include <iostream>
using namespace std;
int main()
{
int x = 3;
const int i[] = { 1, 2, 3, 4 };
float f[i[3]];
struct S { int i, j; };
const S s[] = { { 1, 2 }, { 3, 4 } };
double d[s[1].j];
}
它运行没有错误。但是,以下内容:
#include <iostream>
using namespace std;
int x = 3;
const int i[] = { 1, 2, 3, 4 };
float f[i[3]]; // error: array bound is not an integer constant before ']' token|
struct S { int i, j; };
const S s[] = { { 1, 2 }, { 3, 4 } };
double d[s[1].j]; // error: array bound is not an integer constant before ']' token|
int main()
{
return 0;
}
不会,因为它会将错误突出显示为注释。任何人都可以向我解释为什么会这样吗?
答案 0 :(得分:18)
很可能,编译器在函数中允许它的原因是由于编译器扩展:可变长度数组。它们允许在函数内声明的数组具有非constexpr长度。但它仅在函数内 ,而不是在全局范围内。
答案 1 :(得分:16)
您必须使用constexpr
代替const
constexpr int i[] = { 1, 2, 3, 4 };
constexpr S s[] = { { 1, 2 }, { 3, 4 } };
const
适用于变量,并阻止在代码中修改它们。
constexpr
告诉编译器该表达式在编译时常量值中产生,因此可以在数组长度等地方使用,分配给const变量等。
它在funcion中编译的原因是VLA。无法在全球范围内宣布VLA。
6.7.6.2数组声明符
2如果标识符被声明为具有可变修改类型,则为 应为普通标识符(如6.2.3中所定义),否则 链接,并具有块范围或函数原型范围。如果 标识符声明为具有静态或线程的对象 存储持续时间,它不应具有可变长度的数组类型。