1

特定のツールチェーン(BlackBerry Playbook NDKに付属しているツールチェーン)を使用しています。GCC4.4.2に基づいていると思います。このツールチェーンを使用して特定のライブラリをコンパイルしようとすると、c++グローバル名前空間のものと思われるもので奇妙な問題が発生します。たとえば、次のようなエラーが発生します。

'::sprintf' has not been declared

GNU c ++標準ライブラリに対してリンクするときに、これらのエラーが発生することはありません。ただし、PlaybookNDKはデフォルトでDinkumwareC ++ライブラリを使用するため、常に各エラーを確認し、通常は同等のC(この場合はstdio.h)を追加する必要があります。私のコントロールが及ばない理由で、GNUc++標準ライブラリにリンクできません。GNUc++標準ライブラリにはこれらの問題はありません。

より大きなプロジェクトをコンパイルしようとすると、これらのエラーが何百も発生する可能性があります。ソースの編集を伴わない回避策はありますか?上記の例では、ファイルには通常、ヘッダーとして「cstdio」が含まれていますが、これは「std」名前空間でsprintfを宣言します。したがって、私が持っている唯一のオプションは、Cヘッダーを含めるか、std名前空間を追加することです。

4

3 に答える 3

3

実際、C ++標準では、標準ライブラリで宣言されたすべてのシンボル(<c....>ヘッダーにCライブラリを含む)がstd::名前空間でアクセス可能であることが義務付けられています。それらがグローバル名前空間にも表示されることを禁止するものではなく、libstdc++などのC++標準ライブラリの一部の実装では、下位互換性の理由からそれらをそこに配置することを選択しています。

いくつかの可能性があります。

  • 引き続きCヘッダーを直接(のように<stdio.h>)含めることができますが、C ++に対応しておらず、衝突が発生する可能性があるため、通常はお勧めしません(1)
  • 実用的ではないかもしれませんが、各呼び出しにプレフィックスを付けることができます
  • using std::printf;ファイルの先頭または各関数内で、使用する記号を選択できます。
  • using namespace std;率直に指示を出すことができます。しかし、あなたはたくさんのものを引っ張るでしょう...

私の個人的な推奨事項は、呼び出しのプレフィックスを付けるか、最もよく使用される関数を選択して、グローバルまたは現在の名前空間にインポートすることです。

移行に関して、1つの率直な可能性は、実際に標準ヘッダーを「ラップ」することです。

// cstdio.hpp

#include <cstdio>

#if defined(_DIRKUMWARE_) // note: you'll have to research the symbol to check
namespace yournamespace {
    using std::printf;
    using std::vptrinf;
} // namespace yournamespace
#endif // defined(_DIRKUMWARE_)

<stdio.h>次に、スクリプトを使用<cstdio>して、コードベース内のすべての出現箇所を<cstdio.hpp>(明らかにこのファイルを除いて)に置き換えます。このようにして、これらの関数を含むすべてのファイルで回避策を繰り返す代わりに、標準ライブラリの実装ごとにこのファイルを調整できます。

注(1):C標準では、機能が関数によって提供されるかマクロによって提供されるかは必須ではありません。通常、マクロの場合もminありmaxます。C ++標準では関数が義務付けられているため、通常はC++ヘッダーを使用する方が安全です。

于 2012-06-10T17:59:15.650 に答える
2

基本的にあなたは隅で立ち往生しています。

C ++標準によると:

含めるとcstdio、シンボル名がstd名前空間にインポートされ、場合によってはグローバル名前空間にインポートされます。

含めるstdio.hと、シンボル名がグローバル名前空間にインポートされ、場合によってはstd名前空間にインポートされます。

したがって、を含む特定の実装cstdioでグローバル名前空間にシンボルをインポートしない場合、唯一のオプションは、std名前空間に完全修飾名を使用することです。
これは、動作がC ++標準によって明確に定義されているため、あまり一般的には知られていません。

于 2012-06-10T17:52:35.077 に答える
0

ソースにインクルードする一般的なヘッダーファイルがいくつかある場合は、必要なインクルードでそれらを変更できます。

GCCには-include、残りのファイルがコンパイルされる前にソースファイルにファイルを含めるように強制できるコマンドラインオプションがあります。Makefileまたはプロジェクト構築スクリプトに相当するものを変更して、インクルージョンを行うことができます。

// c_includes.h
#include <stdio.h>
#include <stdlib.h>
//...

g++ -include c_includes.h ...
于 2012-06-10T17:57:46.827 に答える