1

C99 プログラムで使用するために作成されたヘッダー ファイルがあります。このヘッダーにはすべての関数定義が含まれており、ソース ファイルとは対になっていません。私はそれをC++ファイルに含めています。

私の C++ コンパイラ フラグには が含ま-pedantic -std=c++11れており、「ISO C++ は複合リテラルを禁止しています」や「ISO C++ は可変長配列を禁止しています」などのさまざまな警告をヘッダー ファイルに表示します。明らかに、C++ コンパイラは C99 コードを C++ として扱っています。2 つの質問:

  1. これは、異なるコンパイラを使用してさまざまなプラットフォームで正しく実行されるコードを作成しようとするときに潜在的な問題になりますか?
  2. 警告を解決し、標準準拠のコードを生成する良い方法は何ですか? gcc を使用してプリコンパイル済みヘッダー ファイルを作成することを考えていましたが、C++ ソースに C プリコンパイル済みヘッダーをインクルードすることによって意図しない結果が生じないことを保証するプロセスについて十分に知りません。

ありがとう

4

2 に答える 2

5

これは、異なるコンパイラを使用してさまざまなプラットフォームで正しく実行されるコードを作成しようとするときに潜在的な問題になりますか?

はい。GCC は警告を表示するだけかもしれませんが、他のコンパイラ (Visual Studio や他のオプションを指定した GCC など) はエラーを表示する可能性があります。

警告を解決し、標準準拠のコードを生成する良い方法は何ですか?

問題を解決する正しい方法は、ヘッダーを C および C++ の共通サブセットで記述することです。C99 機能 (可変長配列や複合リテラルなど) を使用する関数とオブジェクト定義は、別の C ソース ファイル (C コンパイラでコンパイルされます!) に移動する必要があります。

于 2013-01-19T19:36:06.077 に答える
4

純粋な C ヘッダー ファイル (*) を C++ プロジェクトに含めるには、include ステートメントをextern "C"ブロックでラップする必要があります。

// C++
extern "C" {
// C-code goes here
#include "foo.h"
}

これは、オーバーロードが機能するように、C++ がすべての関数名に対して名前マングリングを実行するためです。C は名前マングリングを使用しないため、C++ は名前マングリングを使用して C 関数シグネチャ解析します。

extern "C"コンパイラを「Cモード」にしないことに注意してください(そのようなモードはありませんが、この命令を誤ってそのように考えるかもしれません)、関数名を台無しにしません(+呼び出し規約を変更し、オーバーロードを禁止します;これらのことを指摘してくれたdoomsterに感謝します)。

ただし、関数がこの場合は異なります。

そうは言っても、ヘッダー ファイルには C と C++の共通サブセットを使用し、これらの関数の実装を C++ ではなく C コンパイラで個別に抽出してコンパイルする必要があります。次に、(できれば) 両方のパーツをリンクできます。多くの C ライブラリには、C++ と互換性のあるヘッダーが既に含まれているため、これは一般的な手順です。

(*): 一部のヘッダー ファイルは、言語機能の共通サブセットを使用し、すべてを条件付き extern "C"ブロックでラップすることにより、C 言語と C++ 言語の両方と互換性を持つように既に作成されています。このようなヘッダーには、このメソッドを使用しないでください。そのようなブロックが含まれていないヘッダーにのみ使用してください。

于 2013-01-19T19:48:59.600 に答える