non-constant 大小的字符串数组编译不明确?
Ambiguous compiling of string array with non-constant size?
我的 mingw64 8.1.0 的 gcc 编译器不允许编译以下内容,因为 var 必须是常量值:
int var=3;
string str[var];
int main(){
但是,在 main() 中执行相同操作不会显示任何错误:
int main(){
int var;
cin >> var;
string str[var];
为什么会有歧义?
我的编译命令很简单:g++ main.cpp
这些是 headers 我在开始时为这两种情况添加的内容:
#include <iostream>
#include <string>
#include <sstream>
However, doing the same within main() doesn't show any errors
如果你正确调用它,它会告诉你这段代码不是正确的 C++:
g++ -Wpedantic t.cpp
产生此警告:
t.cpp: In function ‘int main()’:
t.cpp:3:16: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
int arr[var];
对于这个 t.cpp 文件:
int main(){
int var = 3;
int arr[var];
}
根据您的编译标志,它们都是“错误”:
代码:
#include <string>
int i = 3;
std::string s1[i];
int main ()
{
int j = 3;
std::string s2[j];
return 0;
}
g++ -o tmp3 -g -pedantic -Wall tmp3.cpp
tmp3.cpp:4:17: error: array bound is not an integer constant before ‘]’ token
std::string s1[i];
^
tmp3.cpp: In function ‘int main()’:
tmp3.cpp:9:19: warning: ISO C++ forbids variable length array ‘s2’ [-Wvla]
std::string s2[j];
记住 VLA 是一项 'C' 功能(在 C++ 中“不鼓励”,仅作为“扩展”支持),规则如下:
https://en.cppreference.com/w/c/language/array
Declarator for VLA of unspecified size (can appear in function
prototype scope only) where expression
any expression other than
comma operator, designates the number of elements in the array
qualifiers
any combination of const, restrict, or volatile
qualifiers, only allowed in function parameter lists; this qualifies
the pointer type to which this array parameter is transformed
重要的是:
Objects of any variably-modified type may only be declared at block
scope or function prototype scope.
这正是第一个例子是“错误”的原因;第二个是“警告”。 VLA 必须 是 stack-allocated 个变量。
GCC 接受可变长度数组 (VLA) 作为语言扩展,但仅在某些情况下(强调我的):
These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits
As an extension, GCC accepts variable-length arrays as a member of a structure or a union.
You can also use variable-length arrays as arguments to functions:
在块范围之外(即在全局内存区域中)创建数组不是 VLA 接受的 use-cases 之一。见 documentation.
请注意,正如其他人提到的,VLA 是 GCC 扩展,不是 C++ 标准的一部分。例如 MSVC 根本不会编译它们。
我的 mingw64 8.1.0 的 gcc 编译器不允许编译以下内容,因为 var 必须是常量值:
int var=3;
string str[var];
int main(){
但是,在 main() 中执行相同操作不会显示任何错误:
int main(){
int var;
cin >> var;
string str[var];
为什么会有歧义?
我的编译命令很简单:g++ main.cpp
这些是 headers 我在开始时为这两种情况添加的内容:
#include <iostream>
#include <string>
#include <sstream>
However, doing the same within main() doesn't show any errors
如果你正确调用它,它会告诉你这段代码不是正确的 C++:
g++ -Wpedantic t.cpp
产生此警告:
t.cpp: In function ‘int main()’:
t.cpp:3:16: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
int arr[var];
对于这个 t.cpp 文件:
int main(){
int var = 3;
int arr[var];
}
根据您的编译标志,它们都是“错误”:
代码:
#include <string>
int i = 3;
std::string s1[i];
int main ()
{
int j = 3;
std::string s2[j];
return 0;
}
g++ -o tmp3 -g -pedantic -Wall tmp3.cpp
tmp3.cpp:4:17: error: array bound is not an integer constant before ‘]’ token
std::string s1[i];
^
tmp3.cpp: In function ‘int main()’:
tmp3.cpp:9:19: warning: ISO C++ forbids variable length array ‘s2’ [-Wvla]
std::string s2[j];
记住 VLA 是一项 'C' 功能(在 C++ 中“不鼓励”,仅作为“扩展”支持),规则如下:
https://en.cppreference.com/w/c/language/array
Declarator for VLA of unspecified size (can appear in function prototype scope only) where expression
any expression other than comma operator, designates the number of elements in the array qualifiers
any combination of const, restrict, or volatile qualifiers, only allowed in function parameter lists; this qualifies the pointer type to which this array parameter is transformed
重要的是:
Objects of any variably-modified type may only be declared at block scope or function prototype scope.
这正是第一个例子是“错误”的原因;第二个是“警告”。 VLA 必须 是 stack-allocated 个变量。
GCC 接受可变长度数组 (VLA) 作为语言扩展,但仅在某些情况下(强调我的):
These arrays are declared like any other automatic arrays, but with a length that is not a constant expression. The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits
As an extension, GCC accepts variable-length arrays as a member of a structure or a union.
You can also use variable-length arrays as arguments to functions:
在块范围之外(即在全局内存区域中)创建数组不是 VLA 接受的 use-cases 之一。见 documentation.
请注意,正如其他人提到的,VLA 是 GCC 扩展,不是 C++ 标准的一部分。例如 MSVC 根本不会编译它们。