2

Cにはあります__STDC__が、一部の拡張 C++ 方言を認識する標準的な方法はないようです。したがって、私が使用するポータブルコードの場合

#define __is_extended                                   \
    ((__GNUG__   &&!__STRICT_ANSI__)  ||                \
     (_MSC_VER   && _MSC_EXTENSIONS && __cplusplus)  || \
     (__IBMCPP__ && __EXTENDED__))

これは、これまでのところ gcc、XLC、および Visual C++ で機能します。

ISO/ANSI 準拠をコンパイラごとに個別にテストする必要がありますよね? もしそうなら、動作することが証明されている他のコンパイラについて提案できますか?

編集: このようなテストの賛否については非常に多くの議論があったため、ここに実際の例を示します。複数のプロジェクトの複数のコンパイラで広く使用されているヘッダーstuff.hがあるとします。stuff.hは、いくつかのコンパイラ固有vsnprintf(C++11 より前に標準化されていない)、いくつかcopy_if<>( C++98 ではなぜか見逃していた)、独自のミューテックス ガードなどを使用します。クリーンな C++11 バリアントを実装する際に、古い (ただし信頼できる) 実装をいくつか#if __is_extended(より良い:__is_idosyncraticまたは!__is_ANSI_C11) でラップします。新しい C++11 は#else. まだ C++0x または C++98 としてコンパイルされる翻訳単位にstuff.hが含まれている場合何も変わっていません。コンパイル エラーはなく、実行時の動作も異なりません。C++11 は実験的なままです。コードはメイン ブランチに安全にコミットでき、同僚はそれを研究し、そこから学び、コンポーネントに技術を適用できます。

4

3 に答える 3

2

コンパイラによってサポートされている非標準の拡張機能は、そのコンパイラに固有のものであり、多くの場合、特定のコンパイラのバージョンに固有であるという点で、各コンパイラが定義する非標準のマクロと同様に、検出できるため、質問は実際には逆です。 .

通常の手法は逆です。必要な機能を指定し、それをマクロに関連付けます。関連付けられたマクロが定義されている場合は、その機能を使用するコードのみを記述します。

サポートされているファンキーな機能があるとしましょう - Visual C++ 11 と g++ バージョン 3.2.1 でまったく同じ方法でサポートされていますが、他のコンパイラ (Visual C++ または g++ の他のバージョンでさえ) ではサポートされていません。

//  in some header that detects if the compiler supports all sorts of features    

#if ((defined(__GNUG__) && __GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1) || (defined(_MSC_VER) && _MSC_VER == 1700))

#define FUNKY_FEATURE

#endif

// and, in subsequent user code ....

#ifdef FUNKY_FEATURE

  // code which uses that funky feature

 #endif

この種の手法を使用する自由に利用できる汎用ライブラリがたくさんあります (明らかに、マクロの命名がより適切です)。頭に浮かぶ 1 つの例は、移植性マクロのセットを持つACE (Adaptive Communication Environment) フレームワークです。ここで文書化されています。

どのコンパイラ (またはライブラリ) のどのバージョンが各機能をサポートしているかを理解し、その機能を更新する必要があることを考えると、非標準機能の大規模なセットについて懸念している場合、そのようなマクロを使用することは気弱な人の仕事ではありません。新しいコンパイラ、新しいライブラリ、さらにはパッチがリリースされるたびにマクロ。

また、これらのマクロに名前を付ける際に予約済みの識別子を使用しないようにし、マクロ名が一意であることを確認する必要があります。2 つのアンダースコアで始まる識別子は予約されています。

于 2015-07-19T14:14:56.557 に答える
1

一般に、非準拠のコンパイラに依存している場合、標準ルールのみを要求する標準化された方法がないため、これを行うのは困難です (非標準コンパイラの動作は標準で指定されていません)。

あなたができることは、追加のビルドステップまたはコミットフックを追加し、特定の厳密な適合オプションを使用して特定のポータブルコンパイラ (g++ など) にコードを渡すことです。

于 2015-07-19T09:58:05.560 に答える