Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to best call functions with C99-style array function signatures from C++

Tags:

c++

c

I'm writing some code in C++ that needs to call a library written in C99. This library uses C99-style array declarations with the static keyword in its function parameters. I.e., as such:

void my_func(int n, int my_ints[static n]);

However, when including the headers of this library in my C++ project, the compiler (clang) throws an warning when using the -pedantic flag:

> 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]);

What is the correct/best way to call the C library in this case? Besides turning off the vla-extension warning, is there some way around it that does not involve rewriting the library's headers or writing an intermediate C wrapper?

Minimal working example:

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;
}
like image 696
Fredrik Savje Avatar asked Jan 11 '16 20:01

Fredrik Savje


1 Answers

The truth is that C++ simply does not have VLAs that are nearly as powerful as the C99 ones, and it will likely never do; the advances that are being made to include VLAs into the language are so heavily restricted that they are pretty much useless.

That said, your best bet is likely to write some wrappers for the library functions that you actually use, which expose interfaces of the style

void my_func_wrap(int n, int* my_ints);

These would be implemented in a C99 file like so:

void my_func_wrap(int n, int* my_ints) {
    my_func(n, my_ints);
}

Both the C header and the file with the implementations can be auto-generated from your library headers as the change is next to trivial. Now you can call the wrappers from your C++ code without any type conflict.


A second possible approach would be to write script that strips the contents of all [] brackets from the library headers, and use that instead. This would work perfectly, because even in C99 the declaration

void my_func_wrap(int n, int my_ints[static n]);

decays into

void my_func_wrap(int n, int* my_ints);

This is the reason why I didn't need any cast in the wrapper function above (I know this sounds insane, but it's the truth). It's just your C++ compiler that does not like the first syntax variant.

like image 105
cmaster - reinstate monica Avatar answered Oct 22 '22 17:10

cmaster - reinstate monica