2016-06-28 3 views
3

У меня есть C-Code, который уже существует и использует VLA в стиле C99. Нравится этот:Использование VLA в среде C++ 11

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

Я хотел бы включить заголовки в свой проект на C++ 11. Поскольку C++ не разрешает такие конструкции, я использую extern "C" для включения этих файлов заголовков. Однако компилятору это совсем не нравится.

./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-стандартом. Но я должен как-то включить заголовки. Есть идеи?

Переписывание всего этого было бы только методом последней инстанции.

+0

У вас нет никакой альтернативы компиляции источника с помощью компилятора C, поскольку C++ не имеет массивы переменной длины. Я думаю, что массив переменной длины передается как указатель на первый элемент. Следовательно, если вы объявляете свою последнюю функцию «extern» C "{void foo (int n, double * l, double * x, double * b); } 'в вашем коде на C++, его нужно вызвать правильно. (Это, однако, только предположение.) – JohnB

+0

Возможно, вы захотите использовать '--std = gnu ++ 14', который позволяет использовать функции C++ 14, а не' --std == C++ 14', что включает возможности C++ 14 ** и отключает все расширения g ++ ** –

+0

VLA недействительны в стандартном C++ и необязательно в C из C11. Независимо от того, поддерживаются ли они на C или нет, лучше не пытаться использовать их на C++. Вам нужно будет написать «extern» C-оболочку, которая предоставляет интерфейс, приемлемый для C++, и передает (или копирует) свои аргументы на вашу функцию, которая использует VLA. Эта оболочка должна быть реализована (и, следовательно, скомпилирована) как C, но важно, чтобы она предоставляла подпись (тип возвращаемого типа и типы аргументов), которая является допустимой C++. Лично я переписывал функцию как C++ и делал с ней. – Peter

ответ

2

Я хотел бы включить заголовки в свой проект на C++ 11. Поскольку C++ не разрешает такие конструкции, я использую extern «C» для включения этих файлов заголовков. Однако компилятору это совсем не нравится.

Действительно, это проблема, как 11 C++ не имеет Власа. Возможно, вам стоит подумать о написании обертки в C, скомпилируя ее как C и используя ее в C++.


Я думаю, что я где-то читал, что Власа стал необязательным C11. Означает ли это, что gcc полностью избавился от этого?

Нет, gcc по-прежнему поддерживает VLA при компиляции кода как C11. Однако это не имеет отношения к вашему вопросу, который касается C++ 11, совершенно другого языка, который не поддерживает VLA.


, что я могу сделать, кроме ехЬегп "C"?

extern "C" только вам не поможет, поскольку, как я уже говорил, C++ 11 не имеет VLA. Считайте, что в C массив является последовательной последовательностью, то есть все одно выделение и все элементы происходят один за другим. Следовательно, такой двумерный массив представляется сплюснутым как одномерный массив из n * n элементов. Ваша обертка, также использующая extern "C", должна перевести double *, указывая на первый элемент этого сплющенного массива на double (*)[n], указывающий на первые n элементы этого сплющенного массива.

Это напечатанный в С11, который не должен быть подвержен C++, так как функция, которая принимает double *, функция компилируется как C11 код (не C++ 11) и связан с C + +11 с использованием компоновщика. C++ 11 не нужно видеть код C11 под функцией.

Так что вам нужно переписать заголовок (который вы могли бы поддерживать независимо от файла .h как .hpp файл), который, к счастью, не является полным переписывают. По крайней мере, надеюсь, вы узнали, C++ не является строгим надмножеством C.