Scindix
Scindix

Reputation: 1294

Using VLAs in a C++11 environment

I got C-Code that already exists and that makes use of C99-style VLAs. Like this one:

 int foo(int n, double l[n][n], double a[n][n]);

I'd like to include the headers in my C++11 project. As C++ doesn't allow these kind of constructs I'm using extern "C" to include these header files. However the compiler doesn't like this at all.

./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]);
                                 ^~~~~~

I think I read somewhere that VLAs became optional in C11. Does this mean that gcc got rid of it completely? If so what can I do other than extern "C"? Of course I can compile the source with an older C-standard. But I have to include the headers somehow. Any idea?

Rewriting the whole thing would only be a method of last resort.

Upvotes: 3

Views: 624

Answers (1)

autistic
autistic

Reputation: 15642

I'd like to include the headers in my C++11 project. As C++ doesn't allow these kind of constructs I'm using extern "C" to include these header files. However the compiler doesn't like this at all.

Indeed, this is a problem, as C++11 doesn't have VLAs. You might want to consider writing a wrapper in C, compiling that as C and using it in C++.


I think I read somewhere that VLAs became optional in C11. Does this mean that gcc got rid of it completely?

No, gcc still supports VLAs when compiling code as C11. However, that's irrelevant to your question, which is about C++11, a completely different language, which has no support for VLAs.


what can I do other than extern "C"?

extern "C" alone won't help you, because as I explained C++11 doesn't have VLAs. Consider that in C, an array is a contiguous sequence, meaning it's all one allocation and all elements occur one after the other. Hence, such a two-dimensional array is represented flattened as a one-dimensional array of n * n elements. Your wrapper, also using extern "C", should translate a double * pointing to the first element of that flattened array to a double (*)[n] pointing to the first n elements of that flattened array.

That's a typecast in C11, which doesn't need to be exposed to C++ because the function that takes a double *, the function is compiled as C11 code (not C++11) and linked to the C++11 project using the linker. C++11 doesn't need to see the C11 code underneath the function.

So you'll need to rewrite the header (which you could maintain independently from the .h file as a .hpp file), which thankfully isn't a complete rewrite. At least hopefully you've learnt, C++ isn't a strict superset of C.

Upvotes: 3

Related Questions