遵守下列程序:#include文件來自宏__FILE__?
#include __FILE__
main(){}
預處理卡在無限循環,包括其自身內部的自身的拷貝,並抱怨main()
已經被定義。
如果我可以使用宏,包括文件, 可以推導出我基於__FILE__
文件名,包括它?
例如,我想包括"foo.h"
,而裏面"foo.cpp"
,但是從__FILE__
得到它。
可以將其與預處理器來完成?
遵守下列程序:#include文件來自宏__FILE__?
#include __FILE__
main(){}
預處理卡在無限循環,包括其自身內部的自身的拷貝,並抱怨main()
已經被定義。
如果我可以使用宏,包括文件, 可以推導出我基於__FILE__
文件名,包括它?
例如,我想包括"foo.h"
,而裏面"foo.cpp"
,但是從__FILE__
得到它。
可以將其與預處理器來完成?
C標準規定三種形式的#include
:
#include <file>
#include "file"
#include ANYTHING ELSE
在前兩種情況下,沒有宏擴展發生,所以沒有辦法改變行爲。在第三種情況下,C99表示(§6.10.2p4):
The preprocessing tokens after
#include
in the directive are [macro-expanded]. The directive resulting after all replacements shall match one of the two previous forms [footnote: Note that adjacent string literals are not concatenated into a single string literal]. The method by which a sequence of preprocessing tokens between a < and a > preprocessing token pair or a pair of " characters is combined into a single header name preprocessing token is implementation-defined.
略有不同,但實際上等同,措詞出現在C++ 98§16.2p4。
與「應」在它規定一個硬性要求的任何一句話:在這種情況下,形成不良的程序,如果ANYTHING ELSE
擴大到什麼,但與<
開始,以>
結束,或開始和結束標記序列"
。該序列標記的確切解釋是實現定義的,但請注意,腳註特別禁止字符串連接。
所以,作爲__FILE__
擴張是一個字符串常量,唯一的方法來使用它在#include
被
#include __FILE__
其中,因爲你發現,導致無限遞歸,和
#define LT <
#define GT >
#include LT __FILE__ etc GT
這對我可以方便測試的所有編譯器都有趣,但沒用,影響。假設上述是在一個名爲test.c
文件:
"test.c" etc
文件,用引號和逐字記錄包括空間。LT
(這是我經過深思熟慮後認爲,這是一個符合違例),抱怨是沒有匹配>
,然後嘗試打開一個名爲__FILE__ etc GT
文件。(GCC's behavior is documented here,你是你自己做別的事情。)
TL;博士:有沒有辦法做你從預處理裏面想要的東西。我建議從你的編譯系統中找出待編譯文件的名稱,並用-D
開關通知編譯器(在Unixy系統上,你需要雙引號,-DINCLUDEME='"includeme.h"'
;我不會說CMD)
構建系統。謝謝 –
我想出的最好的是這樣的:
#define foo(x) #x
#include foo(x)
prog.cpp:2:16: error: x: No such file or directory
您不能編輯文件名,並且在翻譯的階段6中出現相鄰字符串文字的拼接,但是預處理髮生在階段4中,因此您不能使用字符串拼接。這意味着無法構建預處理器可以從'__FILE__'中包含的文件名。 –