在 C++11 环境中使用 VLA
Using VLAs in a C++11 environment
我得到 C-Code 已经存在并且使用了 C99 样式的 VLA。喜欢这个:
int foo(int n, double l[n][n], double a[n][n]);
我想在我的 C++11 项目中包含 header。由于 C++ 不允许此类构造,因此我使用 extern "C"
来包含这些 header 文件。
然而编译器根本不喜欢这样。
./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-standard 编译源代码。但我必须以某种方式包括 headers。有什么想法吗?
重写整个东西只是最后的手段。
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.
确实,这是一个问题,因为 C++11 没有 VLA。您可能想考虑用 C 编写一个包装器,将其编译为 C 并在 C++ 中使用它。
I think I read somewhere that VLAs became optional in C11. Does this mean that gcc got rid of it completely?
不,gcc 在将代码编译为 C11 时仍然支持 VLA。但是,这与您的问题无关,它是关于 C++11 的,一种完全不同的语言,不支持 VLA。
what can I do other than extern "C"?
仅 extern "C"
对您没有帮助,因为正如我所解释的那样,C++11 没有 VLA。考虑到在 C 中,数组是一个 连续 序列,这意味着它是 所有一个分配 并且 所有元素一个接一个地出现。因此,这样的 two-dimensional 数组被表示为 n * n
元素的 one-dimensional 数组。您的包装器也使用 extern "C"
,应将指向该展平数组第一个元素的 double *
转换为指向该展平数组第一个 n
元素的 double (*)[n]
。
这是 C11 中的类型转换,不需要暴露给 C++,因为接受 double *
的函数被编译为 C11 代码(不是 C++11) 并使用链接器链接到 C++11 项目。 C++11 不需要看到函数下面的 C11 代码。
因此您需要重写 header(您可以将其作为 .hpp
文件独立于 .h
文件进行维护),幸好它不是 完成重写。至少希望你已经了解到,C++ 并不是 C.
的严格超集
我得到 C-Code 已经存在并且使用了 C99 样式的 VLA。喜欢这个:
int foo(int n, double l[n][n], double a[n][n]);
我想在我的 C++11 项目中包含 header。由于 C++ 不允许此类构造,因此我使用 extern "C"
来包含这些 header 文件。
然而编译器根本不喜欢这样。
./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-standard 编译源代码。但我必须以某种方式包括 headers。有什么想法吗?
重写整个东西只是最后的手段。
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.
确实,这是一个问题,因为 C++11 没有 VLA。您可能想考虑用 C 编写一个包装器,将其编译为 C 并在 C++ 中使用它。
I think I read somewhere that VLAs became optional in C11. Does this mean that gcc got rid of it completely?
不,gcc 在将代码编译为 C11 时仍然支持 VLA。但是,这与您的问题无关,它是关于 C++11 的,一种完全不同的语言,不支持 VLA。
仅what can I do other than extern "C"?
extern "C"
对您没有帮助,因为正如我所解释的那样,C++11 没有 VLA。考虑到在 C 中,数组是一个 连续 序列,这意味着它是 所有一个分配 并且 所有元素一个接一个地出现。因此,这样的 two-dimensional 数组被表示为 n * n
元素的 one-dimensional 数组。您的包装器也使用 extern "C"
,应将指向该展平数组第一个元素的 double *
转换为指向该展平数组第一个 n
元素的 double (*)[n]
。
这是 C11 中的类型转换,不需要暴露给 C++,因为接受 double *
的函数被编译为 C11 代码(不是 C++11) 并使用链接器链接到 C++11 项目。 C++11 不需要看到函数下面的 C11 代码。
因此您需要重写 header(您可以将其作为 .hpp
文件独立于 .h
文件进行维护),幸好它不是 完成重写。至少希望你已经了解到,C++ 并不是 C.