2017-03-02 8 views
1

前処理が_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に関連する「これはエラーです。

この動作は正常ですか?

+0

興味深い。心の吹き消し - それはなぜ実際に問題になるのですか?前処理をすると、 '' 'cpp13.c:15:11:error:これはエラー' 'となり、 ' '' ISVOID(E): "ISVOID(E)' ''というメッセージが表示されます。エラーの場所として識別されますか?もちろん、Mac OS XのGCC 6.3.0(MacOS Sierra 10.12.3)からcppを実行しています。これは出力の一部で、標準エラーに書き込まれています。プリプロセッサはもちろん、失敗を報告します(終了ステータス1)。 –

+0

これは私の[HWAプロジェクト](http://github.com/duparq)の実際の問題です。これは、汎用インターフェースを介してハードウェアへのアクセスを提供する一連のマクロです。コンパイラがマクロ拡張のエラーについて投げるメッセージの代わりに、エラーの起源について礼儀正しく有益なメッセージを出すために、エラー(主にタイプミス)を検出して処理する必要があります。ユーザーはソースとディレクティブの両方でHWA定義を使用できるため、コンテキストを問わず同じ方法で_Pragmaを処理する必要があります。 – duparq

+0

私は 'cpp13.c:15:11:error:これはエラーです'、ISVOID(E): "ISVOID(E)"にあります。 私はavr-cpp(GCC)4.9.2で同じ結果を得ました。 – duparq

答えて

関連する問題