2017-03-02 57 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 

gcc -E -std=c1x -Wall -Wextra -Wpedantic main.c >output處理此。

我得到這個命令行(基本正常)上:

main.c:16:11: error: This is an error 
"ISVOID(E):" ISVOID(E) 
     ^

,這在輸出:

# 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)擴展到1#if指令外,並擴展到0裏面,這意味着_Pragma("GCC error")#if指令內部和外部的處理方式不同。

而且,不存在與#if ISVOID(E) == 1有關的「這是錯誤」的發射。

這種行爲是否正常?

+0

有趣;令人興奮 - 爲什麼這是實踐中的問題?當你進行預處理時,你是否會收到類似'''cpp13.c:15:11:error:'這是一個錯誤'和' '''「ISVOID(E):」ISVOID(E)'''確定爲錯誤的位置?在Mac(macOS Sierra 10.12.3)上運行GCC 6.3.0的cpp,這是輸出的一部分,當然寫入標準錯誤。當然,預處理器報告失敗(退出狀態1)。 –

+0

這是我的[HWA項目](http://github.com/duparq)在實踐中的一個問題。這是一組通過通用接口訪問硬件的宏。我需要檢測並處理錯誤(大部分是拼寫錯誤),以發出關於錯誤來源的禮貌和信息性消息,而不是編譯器在宏擴展中拋出的錯誤信息。由於用戶可以在源代碼和指令中使用HWA定義,因此無論上下文如何,我都需要_Pragma以相同方式處理。 – duparq

+0

我也有'cpp13.c:15:11:錯誤:這是一個錯誤'位於''ISVOID(E):「ISVOID(E)'。 我有與avr-cpp(GCC)4.9.2相同的結果。 – duparq

回答

相關問題