Open chen3feng opened 3 years ago
可变长度数组(Variable Length Array,简称 VLA)是 C99 开始支持的一种语法:
void f(int size) { char tmp[size]; ... }
和普通数组最大的区别是,数组的大小是由一个运行期间才知道值的变量决定的。
Gcc很早就以非标准扩展方式支持 VLA(包括在C++中),ANSI C90 及标准 C++ 都不支持可变长度数组。
VLA 看上去很方便,也很符合直觉,所以不少对 C/C++ 不够熟悉的程序员在代码中不知不觉就用上了。但是其实 VLA 带来的问题更多:
因此,C++代码规范禁用了 VLA,Linux内核也禁用了VLA。
和 VLA 类似的是 alloca 函数,也在禁用之列。
如果已知数组长度不会超过某个不太大的值,可以用固定长度的数组代替:
void f(int size) { if (size > MAX_SIZE) return; char tmp[MAX_SIZE]; ... }
否则可以用动态分配代替(C++中则应该用 string, vector 等封装好的容器避免内存泄漏)。 如果这段代码的性能非常重要,这两种方式还可以结合起来使用:
void f(int size) { if (size <= MAX_SIZE) { char tmp[MAX_SIZE]; ... } else { std::vector<char> tmp(MAX_SIZE); ... } }
GCC 默认是允许 VLA 的,通过设置 -Werror=Vla 参数,可以在编译时禁用 VLA。 对于一些不想改代码的第三方库,如果 VLA 出现在头文件中,可以通过GCC 的 pragma diagnostic局部允许。
-Werror=Vla
可变长度数组的风险与解决方式
什么是 VLA
可变长度数组(Variable Length Array,简称 VLA)是 C99 开始支持的一种语法:
和普通数组最大的区别是,数组的大小是由一个运行期间才知道值的变量决定的。
Gcc很早就以非标准扩展方式支持 VLA(包括在C++中),ANSI C90 及标准 C++ 都不支持可变长度数组。
VLA 的问题
VLA 看上去很方便,也很符合直觉,所以不少对 C/C++ 不够熟悉的程序员在代码中不知不觉就用上了。但是其实 VLA 带来的问题更多:
因此,C++代码规范禁用了 VLA,Linux内核也禁用了VLA。
和 VLA 类似的是 alloca 函数,也在禁用之列。
VLA 的替代方案
如果已知数组长度不会超过某个不太大的值,可以用固定长度的数组代替:
否则可以用动态分配代替(C++中则应该用 string, vector 等封装好的容器避免内存泄漏)。 如果这段代码的性能非常重要,这两种方式还可以结合起来使用:
编译时禁用 VLA
GCC 默认是允许 VLA 的,通过设置
-Werror=Vla
参数,可以在编译时禁用 VLA。 对于一些不想改代码的第三方库,如果 VLA 出现在头文件中,可以通过GCC 的 pragma diagnostic局部允许。