我在C ++中编写一些需要调用C99编写的库的代码。该库在其函数参数中使用带有static
关键字的C99样式数组声明。即,如此:
void my_func(int n, int my_ints[static n]);
但是,在我的C ++项目中包含此库的标题时,编译器(clang)在使用-pedantic
标志时会发出警告:
> g++ -pedantic -c my_code.cpp
In file included from my_code.cpp:
./my_c_lib.h: warning: variable length arrays are a C99 feature [-Wvla-extension]
void my_func(int n, int my_ints[static n]);
在这种情况下,调用C库的正确/最佳方法是什么?除了关闭vla-extension
警告之外,是否还有一些方法可以不涉及重写库的头文件或编写中间C包装器?
最小的工作示例:
extern "C" {
void my_func(int n, int my_ints[static n]);
}
int main()
{
int* some_ints = new int[10];
my_func(10, some_ints);
delete[] some_ints;
return 0;
}
答案 0 :(得分:4)
事实是,C ++根本就没有像C99那样强大的VLA,它可能永远不会这样做;将VLA纳入语言所取得的进步受到严格限制,以至于它们几乎无用。
那就是说,你最好的选择是为你实际使用的库函数编写一些包装器,它们暴露出风格的接口
void my_func_wrap(int n, int* my_ints);
这些将在C99文件中实现,如下所示:
void my_func_wrap(int n, int* my_ints) {
my_func(n, my_ints);
}
C头和带有实现的文件都可以从库头自动生成,因为更改是琐碎的。现在,您可以从C ++代码中调用包装器,而不会发生任何类型冲突。
第二种可能的方法是编写脚本,从库头中删除所有[]
括号的内容,然后使用它。这将完美地工作,因为即使在C99中声明
void my_func_wrap(int n, int my_ints[static n]);
衰败成
void my_func_wrap(int n, int* my_ints);
这就是为什么我在上面的包装函数中不需要任何强制转换的原因(我知道这听起来很疯狂,但这是事实)。它只是你的C ++编译器,它不喜欢第一种语法变体。
答案 1 :(得分:0)
是否有一些解决方法,不涉及重写库的头文件或编写中间C包装器?
当然,您可以将整个c标头括在extern
语句中:
extern "C" {
#include "my_c_lib.h"
}