我刚刚遇到项目dcraw中导致Visual Studio 2012编译器失败的代码。它的形式如下:
void CLASS cubic_spline (const int *x_, const int *y_, const int len)
{
float A[2*len][2*len], b[2*len], c[2*len], d[2*len];
...
问题是在堆栈上创建这些可变长度数组。我从来没有真正看到这样的代码 - 是否可以在Visual Studio编译器中编译它?
答案 0 :(得分:2)
有允许这样做的有效编译器扩展(例如Clang's one和GCC's one),但它不是标准的。
在C ++ 11中,如果数值恒定,您还可以使用constexpr
。最后提交了a proposal来标准化它。
如果x_
和y_
是数组,您只需使用std::array
,如下所示:
template<std::size_t size>
void CLASS cubic_spline (std::array<int, size> const& x, std::array<int, size> const& y)
{
using float_array = std::array<float, 2 * size>;
std::array<float_array, 2 * size> A;
float_array b, c, d;
// ...
}
这样,您可以在编译时确保传递的数组维度相等。
否则,您可以使用std::vector
清除它:
void CLASS cubic_spline (std::vector<int> const& x, std::vector<int> const& y)
{
std::vector<std::vector<float>> A(2 * x.size());
std::vector<float> b, c, d;
// ...
}
答案 1 :(得分:2)
如前所述,VLA(可变长度数组)是一个C功能,更重要的是Visual Studio不支持的C99功能。在Linux上,Clang和Gcc都支持C99(我认为是C11)并允许在C ++中使用这种语法作为扩展。
在C ++中,您可以通过切换到所有简单数组的std::vector<float>
来轻松转换代码。只有A
才需要更多工作:
std::vector< std::vector<float> >
,但是你会失去邻居和地点std::vector<float> A(2*len*2*len);
,但您将失去A[i][j]
的访问权限,而A[i*2*len + j]
必须转换为<{1}} 在任何情况下,您都需要更新此代码以使其在Visual Studio上运行。
编辑:根据您的评论:
该函数在代码中调用两次,一次调用
cubic_spline(cx, cf, 9);
,一次调用cubic_spline(cx, cf, 18);
。在第一个示例中,cx
和cy
为int[9]
,在第二个示例中,他们为int[18]
。
在这种情况下,您实际上可以将该功能设为模板:
template <size_t len>
void CLASS cubic_spline(int const (&x)[len], int const (&y)[len]) {
float A[2*len][2*len], b[2*len], c[2*len], d[2*len];
}
请注意,我删除了最后一个参数,因为不再需要它。 x
和y
的类型为int const (&)[len]
,它是int const
长度为len
的数组的引用。
答案 2 :(得分:1)
这是特定于GCC的编译器扩展,请参阅Arrays of Variable Length。我不知道任何编译器选项使它们在VC中开箱即用。如果这是一个非常孤立的问题,请尝试使用预处理器#ifdef
来向VC提供不同的代码。