: 警告: 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]

ISO C++ 禁止可变大小数组(编译错误)

错误:ISO C++ 禁止在新数组中初始化

ISO C++ 禁止指针和整数之间的比较 [-fpermissive]| [c++]

C++内存分配及变长数组的动态分配

ISO C++禁止指针和整数之间的比较?