: 警告: ISO C++ 禁止变长数组‘s1’ [-Wvla]
Posted
技术标签:
【中文标题】: 警告: ISO C++ 禁止变长数组‘s1’ [-Wvla]【英文标题】:: warning: ISO C++ forbids variable length array ‘s1’ [-Wvla] 【发布时间】:2015-11-19 12:13:43 【问题描述】:我正在构建一个包含 c++ 程序的 R 包。检查运行良好,但我收到此消息 : 警告:ISO C++ 禁止变长数组‘s1’ [-Wvla]
CRAN 的维护人员说错误出在这部分代码中,如下所示。我认为“nrows”这个论点是多余的,但我想知道是否有另一种方法来解决这个问题
double entCI(double input[], int cMatrix[], double partition,
int nrows, int begin, int end)
double s1[nrows], s2[nrows], entropy;
int cs1[nrows], cs2[nrows];
int s1Count=0, s2Count=0, sCount=0;
while(input[begin]<partition)
cs1[s1Count]=cMatrix[begin];
s1[s1Count++]=input[begin++];
while(begin<end)
cs2[s2Count]=cMatrix[begin];
s2[s2Count++]=input[begin++];
sCount=s1Count+s2Count;
entropy=(s1Count/double(sCount))*ent(s1,cs1,s1Count)
+(s2Count/double(sCount))*ent(s2,cs2,s2Count);
return entropy;
【问题讨论】:
你的目标是什么?让它起作用?或者让它可移植正确的C++?使其工作的简单选择是禁用或忽略警告。该代码使用了在 C++ 中无效的 C99 功能,但您的 C++ 编译器支持该功能。要使其成为有效的可移植代码,您应该将本地数组更改为 unique_ptr 拥有的动态数组。 @JSF 这应该是一个答案。 【参考方案1】:确实,错误出在以下几行:
double s1[nrows], s2[nrows], entropy;
int cs1[nrows], cs2[nrows];
他们声明数组,其大小取决于nrows
参数。 nrows
的值是在运行时确定的,因此数组必须是可变长度的。警告告诉您,c++ 标准不允许此类数组变量。
我认为参数“nrows”是多余的
我不明白这是怎么回事。在函数中使用。
但我想知道是否有其他方法可以解决问题
有解决问题的方法。如果需要在运行时确定数组的大小,则必须动态分配。最简单、最安全的方法是使用std::vector
。
【讨论】:
【参考方案2】:通常你应该使用动态内存分配来创建变量数组: 双* s1 = 新双[nrows]; 然后,记得删除那个数组。
其他解决方案是使用 std::vector 代替普通数组。
【讨论】:
非常感谢。你的建议是正确和最简单的。埃德加【参考方案3】:可变长度数组长期以来一直是 gcc 的一个特性。它已在 C99 中被接受,但在 C++11 中没有被接受(也没有在我所知道的任何后续 C++ 版本中)。
一个简单而干净的解决方案是将该函数编译为 C,因为它不使用任何特定的 C++ 功能,只是数组操作。事实上,这个函数是纯 C 语言,恰好被 g++ 接受,但不是正确的 C++,因此会出现警告。
我的建议是:
将函数放入.c
文件中,并以C99模式编译
在其他 C++ 模块中将其声明为extern "C" double entCI(double input[], int cMatrix[], double partition,
int nrows, int begin, int end)
,或者更好地编写包含文件将其声明为
#ifdef C++
extern "C"
#endif
double entCI(double input[], int cMatrix[], double partition,
int nrows, int begin, int end)
#ifdef C++
#endif
【讨论】:
以上是关于: 警告: ISO C++ 禁止变长数组‘s1’ [-Wvla]的主要内容,如果未能解决你的问题,请参考以下文章
PyArg_ParseTupleAndKeywords 抛出警告:ISO C++ 禁止将字符串常量转换为‘char*’ [-Wwrite-strings]