【发布时间】:2016-10-31 07:49:12
【问题描述】:
我得到了已经存在的 C 代码,它使用了 C99 风格的 VLA。喜欢这个:
int foo(int n, double l[n][n], double a[n][n]);
我想在我的 C++11 项目中包含标题。由于 C++ 不允许这种结构,我使用 extern "C" 来包含这些头文件。
但是编译器根本不喜欢这样。
./header.h:23:42: error: use of parameter outside function body before ‘]’ token
void foo(int n, double l[n][n], double x[n], double b[n]);
^
./header.h:23:45: error: use of parameter outside function body before ‘]’ token
void foo(int n, double l[n][n], double x[n], double b[n]);
^
./header.h:23:46: error: expected ‘)’ before ‘,’ token
void foo(int n, double l[n][n], double x[n], double b[n]);
^
./header.h:23:48: error: expected unqualified-id before ‘double’
void foo(int n, double l[n][n], double x[n], double b[n]);
^~~~~~
我想我在某处读到 VLA 在 C11 中成为可选的。这是否意味着 gcc 完全摆脱了它?如果是这样,除了extern "C",我还能做什么?当然,我可以使用较旧的 C 标准编译源代码。但我必须以某种方式包含标题。有什么想法吗?
重写整个事情只是万不得已的方法。
【问题讨论】:
-
除了使用 C 编译器编译源代码之外,您别无选择,因为 C++ 没有可变长度数组。无论如何,我认为可变长度数组作为指向第一个元素的指针传递。因此,如果您在 C++ 代码中将最后一个函数声明为
extern "C" { void foo(int n, double * l, double * x, double * b); },则应该正确调用它。 (不过,这只是一个猜测。) -
您可能希望使用启用 C++14 功能的
--std=gnu++14,而不是启用 C++14 功能并禁用所有 g++ 扩展的--std==c++14 -
VLA 在标准 C++ 中无效,在 C11 中的 C 中是可选的。无论 C 是否支持它们,最好避免尝试在 C++ 中使用它们。您将需要编写一个
extern "C"包装函数,该函数提供 C++ 可接受的接口,并将其参数传递(或复制)到使用 VLA 的函数。该包装器需要作为 C 来实现(并因此被编译),但它必须提供一个有效的 C++ 签名(返回类型和参数类型)。就我个人而言,我会将函数重写为 C++,然后就可以完成了。 -
gcc 在 C11 模式下继续支持 C 代码中的 VLA (
-std=c11);它没有定义宏__STDC_NO_VLA__。 (这与 C++ 代码无关。) -
VLA 从来都不是 C++ 的一部分,
extern "C"并不会神奇地使它们如此,无论版本如何(这里只是说明显而易见的)。
标签: c++ c++11 c99 c11 variable-length-array