2010-08-20 41 views
2

我發現一些奇怪的C++預處理器的條款,如:「#define FOO(模板)」是做什麼的?

#define COMPILER_FLOAT_ENTRIES_DO(template) 

#define COMPILER_FLOAT_ENTRIES_DO(template) \ 
    template(jvm_fadd) \ 
    template(jvm_fsub) \ 
    template(jvm_f2d) 

什麼是合格的 「模板」 保留字到的#define,並調用模板(東西)是什麼意思?我在Google找不到任何東西;可能是因爲「#define」和「template」是真正常用的單詞。

整個代碼是https://phoneme.dev.java.net/source/browse/phoneme/components/cldc/trunk/src/vm/share/ROM/ROMWriter.hpp?rev=19839&view=markup

+2

在胡亂猜測英語句子,儘管出現涉及到C++,這個宏集本身起源於C環境下的特定文件,其中'template' ISN」一個保留字。即使在C++中,它也不是真的保留在預處理器階段,但是由於可能存在混淆,在此使用保留字作爲宏名稱或形式參數通常被認爲是不好的做法。 – RBerteig 2010-08-20 22:33:47

回答

6
#define COMPILER_FLOAT_ENTRIES_DO(template) 

因此COMPILER_FLOAT_ENTRIES_DO(x)被替換爲''。換句話說,它從代碼中刪除該宏。

#define COMPILER_FLOAT_ENTRIES_DO(template) \ 
    template(jvm_fadd) \ 
    template(jvm_fsub) \ 
    template(jvm_f2d) 

所以COMPILER_FLOAT_ENTRIES_DO(x)獲取與x(jvm_fadd) x(jvm_fsub) x(jvm_f2d)取代。

如果一切都失敗,您可以使用g++ -E -o foo.cpp將宏預處理的輸出保留在foo.cpp中,以查看宏中發生了什麼。當然,你還需要通過命令行傳入的所有其他編譯標誌(特別是-D和-I標誌)。

9

「模板」一詞在這裏是巧合。這種預處理器對保留字不敏感,因爲它大部分只是文本操作。

這是一個標準的宏,它將函數名稱作爲它的參數,並用這些參數調用該函數三次。它的第一個版本看起來像一個調試版本或其他一些版本,旨在使其在某些情況下無法運行。

3

您經常在數據驅動的編程設計模式中找到這種類型的編碼。

當您想要包含幾次相同的文件(數據),但宏被替換爲不同的代碼或其他數據時,這很方便。

假設某些屬性,有各個類型:

/// @file data.h 
my_attribute(color, int) 
my_attribute(volume, float) 

編碼部分可以使用數據,甚至無需知道數量。作爲一個例子,讓我們打印一些信息。

/// @file main.c 
void help() 
{ 
    #define my_attibute(name,type) cout << #name << ": " << #type << endl; 
    cout << "available attributes:" << endl; 
    #include "data.h" 
    #undef my_attribute 
} 

(注意#name用於獲取文本字符串「顏色」,而不是一個值color

這樣你代碼是獨立於數據

編輯:修復錯字,並根據@RBerteig

+0

根據我的經驗,我會說「經常」而不是「通常」。它是您演示技術的基本不可缺少的部分。但它並不是帶參數的宏的唯一用途,而OP的情況更可能是針對特定硬件體系結構的某種優化,其中操作在一個體繫結構中不需要,並且最好通過類似於三函數調用(但可能是三個'asm'-ish語句)在其他一些體系結構中。 – RBerteig 2010-08-20 22:37:55

相關問題