Reputation: 21
I am building an R package that contains a c++ program. The checking runs fine, but I am getting this message : warning: ISO C++ forbids variable length array ‘s1’ [-Wvla]
The CRAN's maintainer says that the error is in this part of the code is shown below. I am thinking that the argument "nrows" is redundant , but I wonder if there is another way to solve the problem
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;
}
Upvotes: 2
Views: 2236
Reputation: 149155
Variable Length Arrays is for a long time a feature from gcc. It has been accepted in C99 but not in C++11 (nor in any following C++ version I know).
An easy and clean solution would be to compile that function as C because it does not use any specific C++ feature, simply array manipulation. In fact, this function is plain C that happens to be accepted by g++ but is not correct C++ hence the warning.
My advice is :
.c
file and compile it in C99 modedeclare it as extern "C" double entCI(double input[], int cMatrix[], double partition,
int nrows, int begin, int end)
in other C++ module, or better write the include file declaring it as
#ifdef C++
extern "C" {
#endif
double entCI(double input[], int cMatrix[], double partition,
int nrows, int begin, int end)
#ifdef C++
}
#endif
Upvotes: 0
Reputation: 238431
Indeed, the error is on these lines:
double s1[nrows], s2[nrows], entropy;
int cs1[nrows], cs2[nrows];
They declare arrays, whose size depend on the nrows
argument. The value of nrows
is determined at runtime and therefore the arrays must be variable length. Such array variables are not allowed by the c++ standard as told to you by the warning.
I am thinking that the argument "nrows" is redundant
I don't see how that is. It's used in the function.
but I wonder if there is another way to solve the problem
There are ways to solve the problem. If the size of the array needs to be determined at runtime, it must be allocated dynamically. The simplest and safest way to do that is to use std::vector
.
Upvotes: 3
Reputation: 76
Generally you should use dynamic memory allocation to create array out of variable: double* s1 = new double[nrows]; Then, remember to delete that array.
Other solution is to use std::vector instead of plain array.
Upvotes: 0