回答:
これは元のクエリから長い時間が経過していることを知っていますが、それでもまだ役立つ場合があります。
これは、GCCで文字列化演算子「#」を使用して実行できますが、2つの段階が必要です。
#define XSTR(x) STR(x)
#define STR(x) #x
マクロの値は、次のようにして表示できます。
#pragma message "The value of ABC: " XSTR(ABC)
参照:gccオンラインドキュメントの3.4文字列化。
使い方:
プリプロセッサは引用符付きの文字列を理解し、通常のテキストとは異なる方法で処理します。文字列の連結は、この特別な処理の例です。メッセージプラグマには、引用符付きの文字列である引数が必要です。引数に複数のコンポーネントがある場合、それらはすべて文字列でなければならず、文字列連結を適用できます。プリプロセッサは、引用符で囲まれていない文字列が引用符で囲まれているかのように処理されると想定することはできません。もしそうなら:
#define ABC 123
int n = ABC;
コンパイルされません。
今検討してください:
#define ABC abc
#pragma message "The value of ABC is: " ABC
これは
#pragma message "The value of ABC is: " abc
これにより、abc(引用符で囲まれていない)を先行する文字列と連結できないため、プリプロセッサ警告が発生します。
ここで、プリプロセッサのstringizeを検討します(以前はstringificationと呼ばれていましたが、ドキュメント内のリンクは、変更された用語を反映するように変更されています。両方の用語は、偶然にも同じように嫌われます。正しい用語は、もちろんstringifactionです。更新する準備をしてくださいあなたのリンク。))演算子。これはマクロの引数にのみ作用し、展開されていない引数を二重引用符で囲まれた引数に置き換えます。したがって:
#define STR(x) #x
char *s1 = "abc";
char *s2 = STR(abc);
s1とs2に同じ値を割り当てます。gcc -Eを実行すると、出力でこれを確認できます。おそらく、STRはENQUOTEのような名前にした方がよいでしょう。
これにより、引用符で囲まれていないアイテムを引用符で囲むという問題が解決されます。問題は、引数がマクロの場合、マクロが展開されないことです。これが、2番目のマクロが必要な理由です。XSTRは引数を展開してから、STRを呼び出して、展開された値を引用符で囲みます。
__IPHONE_9_3
ます。
BOOST_PP_STRINGIZE
C ++の優れたソリューションのようですが、通常のCのソリューションではありません。
これがGNU CPPの私の解決策です:
/* Some test definition here */
#define DEFINED_BUT_NO_VALUE
#define DEFINED_INT 3
#define DEFINED_STR "ABC"
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
/* Some example here */
#pragma message(VAR_NAME_VALUE(NOT_DEFINED))
#pragma message(VAR_NAME_VALUE(DEFINED_BUT_NO_VALUE))
#pragma message(VAR_NAME_VALUE(DEFINED_INT))
#pragma message(VAR_NAME_VALUE(DEFINED_STR))
上記の定義の結果:
test.c:10:9: note: #pragma message: NOT_DEFINED=NOT_DEFINED
test.c:11:9: note: #pragma message: DEFINED_BUT_NO_VALUE=
test.c:12:9: note: #pragma message: DEFINED_INT=3
test.c:13:9: note: #pragma message: DEFINED_STR="ABC"
「intergerと定義」、「文字列として定義」、および「定義されたが、何の価値」変数は、彼らがうまく動作しません。「未定義」変数についてのみ、元の変数名とまったく同じように表示されました。あなたはそれに慣れなければなりません-あるいは多分誰かはより良い解決策を提供することができます。
DEFINED_INT=(sizeof(MY_STRUCT))
、sizeof
演算子が評価されずにを生成するようです。
sizeof
これを達成するための賢い方法があるかどうかはまだ気になります。)
#define masks {0xff, 0xaf, 0x0f}
Visual C ++を使用している場合は、以下を使用できます#pragma message
。
#include <boost/preprocessor/stringize.hpp>
#pragma message("BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION))
編集:リンクのLBに感謝
どうやら、GCCと同等のものは(テストされていません):
#pragma message "BOOST_VERSION=" BOOST_PP_STRINGIZE(BOOST_VERSION)
BOOST_PP_STRINGIZE
含まれていて、短くて、コピー/貼り付けが可能であれば、いいでしょう。
私が知る限り、「#error」は文字列のみを出力しますが、実際には引用符を使用する必要さえありません。
「BOOST_VERSION」を使用して、意図的に正しくないさまざまなコードを記述してみましたか?おそらく "blah [BOOST_VERSION] = foo;"のようなものでしょう。「文字列リテラル1.2.1は配列アドレスとして使用できません」のようなものを教えてくれます。これはかなりのエラーメッセージではありませんが、少なくとも関連する値が表示されます。値を伝えるコンパイルエラーが見つかるまで、試してみることができます。
std::vector<BOOST_VERSION>;
gcc 4.4.1の次のステートメントで確認できました。ありがとう!
ブーストなし:
同じマクロを再度定義すると、コンパイラHIMSELFが警告を出します。
警告から、前の定義の場所を確認できます。
以前の定義のviファイル。
ambarish@axiom:~/cpp$ g++ shiftOper.cpp
shiftOper.cpp:7:1: warning: "LINUX_VERSION_CODE" redefined
shiftOper.cpp:6:1: warning: this is the location of the previous definition
#define LINUX_VERSION_CODE 265216
#define LINUX_VERSION_CODE 666
int main ()
{
}
__cplusplus
。
Microsoft C / C ++では、組み込みを使用して_CRT_STRINGIZE()
定数を出力できます。私のstdafx.h
ファイルの多くはこれらのいくつかの組み合わせを含んでいます:
#pragma message("_MSC_VER is " _CRT_STRINGIZE(_MSC_VER))
#pragma message("_MFC_VER is " _CRT_STRINGIZE(_MFC_VER))
#pragma message("_ATL_VER is " _CRT_STRINGIZE(_ATL_VER))
#pragma message("WINVER is " _CRT_STRINGIZE(WINVER))
#pragma message("_WIN32_WINNT is " _CRT_STRINGIZE(_WIN32_WINNT))
#pragma message("_WIN32_IE is " _CRT_STRINGIZE(_WIN32_IE))
#pragma message("NTDDI_VERSION is " _CRT_STRINGIZE(NTDDI_VERSION))
このようなものを出力します:
_MSC_VER is 1915
_MFC_VER is 0x0E00
_ATL_VER is 0x0E00
WINVER is 0x0600
_WIN32_WINNT is 0x0600
_WIN32_IE is 0x0700
NTDDI_VERSION is 0x06000000
#define a <::BOOST_VERSION>
#include a
MSVC2015:致命的なエラーC1083:インクルードファイルを開けません: ':: 106200':そのようなファイルまたはディレクトリはありません
場合でも動作しpreprocess to file
、無効なトークンが存在する場合であっても、ISは有効:
#define a <::'*/`#>
#include a
MSVC2015:致命的なエラーC1083:インクルードファイルを開けません: '::' * / `# ':そのようなファイルまたはディレクトリはありません
GCC4.x:警告:終了文字'がありません[-Winvalid-pp-token]
#define a <:: '* / `#>
Build error: #include expects "FILENAME" or <FILENAME>
。はぁ。
'
:*** WARNING C318 IN LINE 2 OF test.c: can't open file '::*/`'
何方をお探しですか
#if BOOST_VERSION != "1.2"
#error "Bad version"
#endif
BOOST_VERSIONが文字列である場合は、私が想定したように大きくはありませんが、メジャー番号、マイナー番号、リビジョン番号に個別の整数が定義されている場合もあります。
#if VARIABLE == 123
...その場で声明をし、構文の強調表示は、それが私はそれがあるかどうかだと思い値のかどうか私に語った
BOOST_VERSION
ビルドシステムの一部として、印刷してコンパイルし、実行するプログラムを作成できます。そうでなければ、あなたは運が悪いと思います。
マクロの使用方法については、Boostのドキュメントもご覧ください。
を参照してBOOST_VERSION
、http://www.boost.org/doc/libs/1_37_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.boost_helper_macrosから:
ブーストバージョン番号をXXYYZZ形式で記述します。
(BOOST_VERSION % 100)
は、サブマイナーバージョン、マイナーバージョン、および メジャーバージョンです。((BOOST_VERSION / 100) %
1000)
(BOOST_VERSION / 100000)