web-dev-qa-db-ja.com

C ++ 1yモードのClang> = 3.3は、<cstdio>ヘッダーを解析できません

C++ 11モードでg ++ 4.8.1およびclang> = 3.3で正しくコンパイルおよび実行されるプロジェクトがあります。ただし、実験的な-std=c++1yモードに切り替えると、Boost.Testによって間接的に含まれている<cstdio>ヘッダーでclang3.3(g ++ではない)がチョークします(自分で簡単に変更することはできません)。

// /usr/include/c++/4.8/cstdio
#include <stdio.h>

// Get rid of those macros defined in <stdio.h> in lieu of real functions.
// ...
#undef gets
// ...    

namespace std
{
// ...
using ::gets; // <-- error with clang++ -std=c++1y
// ...
}

次のエラーメッセージが表示されます。

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/cstdio:119:11:エラー:グローバルに「gets」という名前のメンバーがありません名前空間

このチュートリアル 最新のC++環境をセットアップする方法について、max_align_tで同様のルックアップの問題が発生します。 sedスクリプトを使用して、不明なシンボルを#ifdef __clang__マクロで囲むことをお勧めしますが、これは脆弱なアプローチのようです。

セットアップ:プレーン64ビットLinux Mint 15

g ++(Ubuntu 4.8.1-2ubuntu1〜13.04)4.8.1

Ubuntu clangバージョン3.3-3〜raring1(branches/release_33)(LLVM 3.3に基づく)

質問

  • この侵食の原因は何ですか?問題のコードの近くには__clang__マクロはなく、c ++ 11モードのclangはまったく問題ありません。
  • それは言語の問題ですか(C++ 14はC互換シンボルをグローバルからstd名前空間にインポートすることについてC++ 11以外のことを言っていますか)?
  • インクルードパスで何かを変更する必要がありますか? (私はCMakeを使用してヘッダーパスを自動的に選択し、CMakeLists.txt内でモードを切り替えます)
  • Clangにはこれを解決するためのスイッチがありますか?
42
TemplateRex

getsマンページのこのメモは関連しているように見えます。

ISO C11はC言語からgets()の仕様を削除し、バージョン2.16以降、_ISOC11_SOURCE機能テストマクロが定義されている場合、glibcヘッダーファイルは関数宣言を公開しません。

おそらく

#if !_ISOC11_SOURCE
using ::gets;
#endif
23
Ben Voigt