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
有關的「這是錯誤」的發射。
這種行爲是否正常?
有趣;令人興奮 - 爲什麼這是實踐中的問題?當你進行預處理時,你是否會收到類似'''cpp13.c:15:11:error:'這是一個錯誤'和' '''「ISVOID(E):」ISVOID(E)'''確定爲錯誤的位置?在Mac(macOS Sierra 10.12.3)上運行GCC 6.3.0的cpp,這是輸出的一部分,當然寫入標準錯誤。當然,預處理器報告失敗(退出狀態1)。 –
這是我的[HWA項目](http://github.com/duparq)在實踐中的一個問題。這是一組通過通用接口訪問硬件的宏。我需要檢測並處理錯誤(大部分是拼寫錯誤),以發出關於錯誤來源的禮貌和信息性消息,而不是編譯器在宏擴展中拋出的錯誤信息。由於用戶可以在源代碼和指令中使用HWA定義,因此無論上下文如何,我都需要_Pragma以相同方式處理。 – duparq
我也有'cpp13.c:15:11:錯誤:這是一個錯誤'位於''ISVOID(E):「ISVOID(E)'。 我有與avr-cpp(GCC)4.9.2相同的結果。 – duparq