2011-09-13 19 views
6

我是(被)使用__FILE____LINE__宏從我的代碼中打印診斷消息。當使用GCC和make時,這種方式效果很好,該文件與您在命令行中指定的一樣短。我最近轉而使用CodeLite,它在構建時使用完全限定的文件名(至少在windows下)。突然間,我的診斷輸出幾乎不可讀。如何在預處理器中獲取文件名?

有沒有辦法在預處理器中只獲取文件名的文件組件?我可以與非便攜式GCC特定解決方案一起生活。 (我將回退到普通__FILE__其他情況。)

當然,我可以通過函數傳遞的__FILE__的內容,而只提取文件組件,但字符串操作是不是我所想的是不應該改變的診斷消息運行時行爲...

注意:我使用GNU使用它的方式使用文件名。 Path是文件名的集合,文件名是文件的相對或絕對標識符。文件名可以由目錄組件和文件組件組成。

+0

診斷確實會改變運行時行爲(否則不會有診斷),並且您是否調用一個額外的函數幾乎沒有什麼區別,因爲輸出本身調用庫函數來完成輸出。 – eudoxos

+0

除了數十個字符串操作之外,打印診斷消息通常還涉及一些不那麼良性的文件I/O操作。出於某種原因,似乎沒有人擔心這一點。爲什麼要擔心增加對僅影響診斷消息的無副作用功能的調用? –

+0

你們都是對的,加入診斷不是免費的。我是這樣實現的,我讓它通過一個函數。我更懷疑它是否存在。這當然不是標準的,但是找到關於這方面的文檔並不完美。 (甚至gcc手冊也沒有概述每個預定義的宏。) – rioki

回答

3

沒有提供該功能的已知預處理器宏。通過功能接縫__FILE__像唯一明智的選擇。

+0

對於gcc,有[\ _ \ _ BASE_FILE \ _ \ _](https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html)。 – fret

+1

@fret:對我而言,'__BASE_FILE__'與'__FILE__'輸出相同。如果您閱讀鏈接到的文檔,它會使用'main'函數(不是當前文件,甚至是)提供文件的名稱(不一定是基本名稱)。 – JellicleCat

+1

@JellicleCat你是對的... – fret

8

如果您使用的是GNU Make,那麼您可以在編譯的預處理階段簡單地傳遞-D BASE_FILE_NAME = \「$ *。c \」(如果您正在單獨執行,或者在編譯時階段,這是常態)。

這取決於您確定文件名的方式。我來自一個普通文件名的列表,並在後面的階段使用makefile中的函數作爲前綴。

IE瀏覽器,這對我很好,但你的里程可能會有所不同! :-)

我使「代碼」的簡化版本:

CLASSES = main.c init.c 

PREPROCESSED = $(patsubst %.c,$(PPCDIR)/%.pp.c,$(CLASSES)) 

$(PREPROCESSED): $(PPCDIR)/%.pp.c: %.c $(ALLH) 
    $(GCC) $(GCCOPTS) -D BASE_FILE_NAME=\"$*\" -E $< > [email protected] 

在爲你喜歡:-)

+0

不幸的是我正在與CodeLite合作,爲我生成makefiles。使用CodeLite非常棒,直到你想做一些超出規範的東西。仍然不錯的ideea,+1 – rioki

+0

在Visual Studio中可以使用相同的想法。在Visual Studio 2008中:右鍵單擊項目文件(.vcproj) - >屬性 - >配置屬性 - > C/C++ - >預處理器 - >預處理器定義。添加__BASE_FILE __ = \「$(InputFileName)\」。您可以在源文件中使用__BASE_FILE__而不是__FILE__。 – user720594

4

在回答上面FredCooke你的代碼只需使用BASE_FILE_NAME,你可以交換這條線:

-D BASE_FILE_NAME=\"$*.c\" 

有了:

-D BASE_FILE_NAME=\"$(<F)\" 

這將爲您提供正確的文件名擴展,對於.cpp也是如此。

相關問題