如何使用C ++中的C99样式数组函数签名来最佳地调用函数

时间:2016-01-11 20:31:04

标签: c++ c

我在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;
}

2 个答案:

答案 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"
}