2016-01-11 5 views
10

C99で書かれたライブラリを呼び出す必要のあるコードをC++で書いています。このライブラリは、関数パラメータにstaticキーワードを指定したC99形式の配列宣言を使用します。など、すなわち、:私のC++のプロジェクトでこのライブラリのヘッダを含むとき-pedanticフラグを使用している場合C99スタイルの配列関数のシグネチャを使って関数を呼び出す方法

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

しかし、コンパイラ(打ち鳴らす)が警告をスロー:

は何
> 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; 
} 
+0

'-pedantic'フラグを使ってコンパイルする必要がありますか?それは、あなたがANSI標準を忠実に固守するように設計されていることを示すフラグです。すでに厳密に厳格な '-ANSI'フラグだけです。 C99機能を使用することにより、標準を踏襲するようにコーディングすることはありません。 –

+0

@JoeTyman私は移植性を確保する手段としてペディティック・フラグを使用していますが、それはトップにあるかもしれません。 VLAは明らかにC99の機能であり、 'g ++'はそれを正しく警告します。したがって、私の質問です。ライブラリ自体は 'gcc -c -std = c99 -pedantic'を使ってコンパイルされます。この場合、VLAはうまくいくはずですか? –

+0

あなたは先月16歳になり、4年前に置き換えられた標準でうまくいくと思います(実際にどのプラットフォームをプログラミングしているのか分かりません)。あなたが本当にその極端な移植性を心配しているのであれば、C99 VLAを標準のものに取り替える必要があります。 –

答えて

4

真実は、C++は単にC99のものとほぼ同じくらい強力でのVLA、そしてそれを持っていないということですおそらく決してしません。 VLAを言語に含めるように進められている進歩は非常に制限されており、かなり無駄である。

:これらはそうのようなC99ファイルに実装されるだろう

void my_func_wrap(int n, int* my_ints); 

スタイルのインタフェースを公開され、あなたの最善の策は、あなたが実際に使用するライブラリ関数のためのいくつかのラッパーを書くことは可能性がある、と述べた

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

Cヘッダーと実装されたファイルの両方を、ライブラリヘッダーから自動的に生成することができます。これは、変更が簡単になるためです。これで、タイプの競合なしにC++コードからラッパーを呼び出すことができます。


第二の可能なアプローチは、ライブラリヘッダから全て[]ブラケットの内容を取り除きスクリプトを作成し、代わりにそれを使用することであろう。でもC99に宣言

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

これは(私はこれは非常識な音を知っての上に、私はラッパー関数内の任意のキャストを必要としなかった理由です

void my_func_wrap(int n, int* my_ints); 

に崩壊ので、これは、完璧に動作しますそれは真実です)。最初の構文の変種が気に入らないのはあなたのC++コンパイラだけです。

+0

まさに、構文の違いだけです。意味的には同じです。 C++がVLAを持っていなくても、関数シグネチャのポインタがCで実行されたときのVLA宣言を崩壊させることは問題ではないようです。 –

+1

_ "C++はC99よりも強力なVLAを持っていません" 、まったく。 –

+0

@LightnessRacesinOrbit Afaik C++ *は、非常に制限された意味ではあるが、C++ 17でVLAの概念をいくつか持ちます。だから私は実際にC++ 11のためにもっと強力な言葉を使用することができたにしても、言葉を少し開いたままにしています。要点は、C++は今後20年以内に有用なVLA実装を採用する可能性は低いと思われます。 – cmaster

0

は、ライブラリのヘッダを書き換えるか、中間のCラッパーを書く含まないその周りにいくつかの方法がありますか?

確かに、あなただけのextern文の中で全体のCヘッダを囲むことができます。

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

ありがとうございます。しかし、私はあなたが私を誤解したかもしれないと思います。最小限の例を見て、関数の署名を別のヘッダーに移動し、それを含めると(あなたの提案に沿ったものになります)、警告は削除されません。 –

+0

@FredrikSavjeうーん、私はそれを見逃してしまった。私は、GCCがcとC++の2つの '-std ='オプションを同時に取り除くかどうかは分かりません。 VLAはGCCのサポートされている拡張機能です(C++の場合も同様です)。したがって、正しく動作することを確認しても、警告は無視されます。 –

+0

これは魔法のようにC言語に切り替えるものではありません。確かにVLAを魔法に使うことはありません!! –

関連する問題