前処理が_Pragma("GCC error")
の異常な動作が発生しています。_Pragma( "GCCエラー")は、#if指令の内部と外部で別々に処理されます
avr-gcc(GCC)4.9.2とgcc 5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1〜16.04.4)と同じ結果が得られます。
ソースコード:
#define E _Pragma("GCC error \"This is an error\"")
#define _IS_VOID_ , 1
/* Return "1" if <c> is "", return "0" otherwise.
*/
#define ISVOID(c) _ISVOID2(c)
#define _ISVOID2(c) _ISVOID3(_IS_VOID_##c,0,)
#define _ISVOID3(...) _ISVOID4(__VA_ARGS__)
#define _ISVOID4(v,x,...) x
"ISVOID(something):" ISVOID(something)
"ISVOID():" ISVOID()
"ISVOID(E):" ISVOID(E)
#if ISVOID(something) == 1
"ISVOID(something)==1: true"
#else
"ISVOID(something)==1: false"
#endif
#if ISVOID() == 1
"ISVOID()==1: true"
#else
"ISVOID()==1: false"
#endif
#if ISVOID(E) == 1
"ISVOID(E)==1: true"
#else
"ISVOID(E)==1: false"
#endif
Iはgcc -E -std=c1x -Wall -Wextra -Wpedantic main.c >output
でこれを処理します。
私は、コマンドライン(ほぼ正常)にこれを取得する:
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.c"
# 14 "main.c"
"ISVOID(something):" 0
"ISVOID():" 1
"ISVOID(E):"
# 16 "main.c"
# 16 "main.c"
1
"ISVOID(something)==1: false"
"ISVOID()==1: true"
"ISVOID(E)==1: false"
その後、ISVOID(E)
は#if
ディレクティブ外1
に展開し、それが次のように拡張されます
main.c:16:11: error: This is an error
"ISVOID(E):" ISVOID(E)
^
と出力で、この0
が内部にあり、_Pragma("GCC error")
が#if
指令の内部と外部で異なって処理されることを意味します。
また、#if ISVOID(E) == 1
に関連する「これはエラーです。
この動作は正常ですか?
興味深い。心の吹き消し - それはなぜ実際に問題になるのですか?前処理をすると、 '' 'cpp13.c:15:11:error:これはエラー' 'となり、 ' '' ISVOID(E): "ISVOID(E)' ''というメッセージが表示されます。エラーの場所として識別されますか?もちろん、Mac OS XのGCC 6.3.0(MacOS Sierra 10.12.3)からcppを実行しています。これは出力の一部で、標準エラーに書き込まれています。プリプロセッサはもちろん、失敗を報告します(終了ステータス1)。 –
これは私の[HWAプロジェクト](http://github.com/duparq)の実際の問題です。これは、汎用インターフェースを介してハードウェアへのアクセスを提供する一連のマクロです。コンパイラがマクロ拡張のエラーについて投げるメッセージの代わりに、エラーの起源について礼儀正しく有益なメッセージを出すために、エラー(主にタイプミス)を検出して処理する必要があります。ユーザーはソースとディレクティブの両方でHWA定義を使用できるため、コンテキストを問わず同じ方法で_Pragmaを処理する必要があります。 – duparq
私は 'cpp13.c:15:11:error:これはエラーです'、ISVOID(E): "ISVOID(E)"にあります。 私はavr-cpp(GCC)4.9.2で同じ結果を得ました。 – duparq