まず、「const」は「pure」のより厳密なバージョンであるため、コンパイラが「const」を実装していない場合、「pure」をフォールバックとして使用できることに注意してください。
他の人が述べたように、MSVC には実際には似たようなものはありませんが、多くのコンパイラが GCC 構文を採用しています__GNUC__
。
-
バージョンを確認したい場合に備えて、 GCC は 2.96 以降の pure と 2.5.0 以降の const をサポートして
い
ます
。
- Clang は両方をサポートします。と を使用
__has_attribute(pure)
し
__has_attribute(const)
てそれらを検出できますが、おそらく clang 設定だけに頼っても問題ありません__GNUC__
。これには、emscripten や XL C/C++ 13+ などの clang に基づくコンパイラーも含まれます。
- Intel C/C++ Compiler は両方をサポートしていますが、ドキュメントがひどいので、いつ追加されたのかわかりません。16.0+ は確かに安全です。
- Oracle Developer Studio 12.2+は両方をサポートします。
- ARM C/C++ コンパイラ 4.1+ (およびおそらくそれより古い) は、
pure
と
constの両方をサポートします。
- 少なくとも10.1以降の IBM XL C/C++ 。
- TI 8.0+
- --gcc を指定したTI 7.3+
( で検出
__TI_GNU_ATTRIBUTE_SUPPORT__
) は両方をサポートします。
- PGIはそれを文書化していませんが(AFAICT)、両方の属性が機能します(または少なくとも静かに無視されます)。17.10+ は安全ですが、おそらくずっと以前から受け入れられていました。
これらのうち、clang は常に__GNUC__
および フレンドを定義します (現在は 4.2、IIRC まで)。Intel は__GNUC__
デフォルトで (-no-gcc で抑制することができますが) C++ モードで PGI を定義します (C モードでは定義しません)。それ以外は手動で確認する必要があります。
Oracle Developer Studio は、 Forte Developer 6として知られて以来、プラグマもサポートしています。関数名を指定する必要があるため、使用方法が少し異なります。
/* pure: */
#pragma does_not_write_global_data (funcname)
/* const; SPARC-only until 12.2 */
#pragma no_side_effect (funcname)
TI 6.0+ (少なくとも) は、#pragma FUNC_IS_PURE;
C++ モードでのみプラグマをサポートします。Cモードでは、#pragma FUNC_IS_PURE(funcname);
.
これのほとんどは、マクロの背後に隠すことができます。これは、私が
Hedleyで行ったことです。
#if \
HEDLEY_GNUC_HAS_ATTRIBUTE(pure,2,96,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
HEDLEY_PGI_VERSION_CHECK(17,10,0)
# define HEDLEY_PURE __attribute__((__pure__))
#elif HEDLEY_TI_VERSION_CHECK(6,0,0) && defined(__cplusplus)
# define HEDLEY_NO_RETURN _Pragma("FUNC_IS_PURE;")
#else
# define HEDLEY_PURE
#endif
#if HEDLEY_GNUC_HAS_ATTRIBUTE(const, 2, 5, 0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
HEDLEY_PGI_VERSION_CHECK(17,10,0)
# define HEDLEY_CONST __attribute__((__const__))
#else
# define HEDLEY_CONST HEDLEY_PURE
#endif
これには、関数名を引数として必要とするバリアントは含まれていませんが、依然として大多数のユーザーをカバーしており、どこでも安全に使用できます。
Hedley (単一のパブリック ドメイン/CC0 ヘッダー) を使用したくない場合は、内部バージョンのマクロを置き換えるのは難しくありません。そうすることを選択した場合は、この回答ではなく、Hedley リポジトリに基づいてポートを作成する必要があります。これは、最新の状態に保つ可能性が高いためです。