Как лучше всего вызывать функции с подписями функций массива в стиле C99 из С++

Я пишу код на С++, который должен вызывать библиотеку, написанную на C99. Эта библиотека использует объявления массива типа C99 с ключевым словом static в своих функциональных параметрах. I.e. как таковой:

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

Однако при включении заголовков этой библиотеки в мой проект на С++ компилятор (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;
}

Ответ 1

Правда в том, что на С++ просто нет VLA, которые почти такие же мощные, как у C99, и это, скорее всего, никогда не произойдет; прогресс, который делается для включения ВЛА на язык, настолько сильно ограничен, что они практически бесполезны.

Тем не менее, ваш лучший выбор, скорее всего, напишет некоторые обертки для используемых вами функций библиотеки, которые выставляют интерфейсы стиля

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, так и файл с реализациями могут быть автоматически сгенерированы из заголовков вашей библиотеки, так как изменение рядом с тривиальным. Теперь вы можете вызывать оболочки из вашего кода на С++ без конфликта типов.


Вторым возможным подходом было бы написать script, который разбивает содержимое всех скобок [] из заголовков библиотек и использует их вместо этого. Это будет работать отлично, потому что даже в C99 объявление

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

распадается на

void my_func_wrap(int n, int* my_ints);

Вот почему я не нуждался в каком-либо приведении в вышеописанную оболочку (я знаю, это звучит безумно, но это правда). Это просто ваш компилятор на С++, который не любит первый вариант синтаксиса.

Ответ 2

существует ли какой-то способ, который не включает переписывание заголовков библиотеки или запись промежуточной оболочки C?

Конечно, вы можете просто заключить весь заголовок c в инструкции extern:

extern "C" {
    #include "my_c_lib.h"
}