2014-01-16 77 views
2

宏是否可以使用傳遞給它的定義的值而不是定義文本本身?間接預處理器替換C

這是一個奇怪的例子,我預計可能與預處理器。

Ç文件稱爲test.c其包括本身兩次,以限定其由main稱爲兩種不同的功能。

#ifndef IS_INDIRECT 
#define IS_INDIRECT 

/* int */ 
#define NUMTYPE int 
#define PREFIX int_ 

#include "test.c" 

#undef NUMTYPE 
#undef PREFIX 

/* short */ 
#define NUMTYPE float 
#define PREFIX float_ 

#include "test.c" 

#undef NUMTYPE 
#undef PREFIX 

#include <stdio.h> 

int main(int argc, const char **argv) 
{ 
    printf("test int %d\n", int_squared(4)); 
    printf("test float %f\n", float_squared(2.5)); 

    return 0; 
} 

#else 

/* function body */ 

#define fn(prefix, id) prefix ## id 

NUMTYPE fn(PREFIX, squared)(NUMTYPE val) 
{ 
    return val * val; 
} 

#endif 

提供了以下錯誤:

In file included from test.c:18:0: 
test.c:37:12: error: conflicting types for 'PREFIXsquared' 
NUMTYPE fn(PREFIX, squared)(NUMTYPE val) 
      ^
test.c:35:24: note: in definition of macro 'fn' 
#define fn(prefix, id) prefix ## id 
         ^
In file included from test.c:9:0: 
test.c:37:12: note: previous definition of 'PREFIXsquared' was here 
NUMTYPE fn(PREFIX, squared)(NUMTYPE val) 
      ^
test.c:35:24: note: in definition of macro 'fn' 
#define fn(prefix, id) prefix ## id 

我想有宏觀擴展PREFIX到它被定義爲價值,所以我得到int_squaredPREFIXsquared

回答

5

它是類似的東西您正在尋找?

#define _CONCAT(x,y) x##y 
#define CONCAT(x, y) _CONCAT(x, y) 


#define function(type, operation, prm) type CONCAT(operation, type) (type prm) 

function (int, square_, value) // int square_int (int value) 
{ 
    return value * value; 
} 

間接使用##允許定義使用級聯(function在我們的例子)的宏。 CONCAT膨脹到_CONCAT當宏是定義
並決定x##y當宏是調用

編輯:添加由於各個提供者:

+0

太好了,這是有效的,如果我想讀一下這個預處理器的具體用法,是否有一些常用術語與宏調用宏需要的情況相關? – ideasman42

+0

我不太瞭解這個技巧背後的理論。當我第一次遇到這個問題的時候,互聯網並沒有像程序員一樣友好(至少從法國來看),所以我必須自己解決。但是K&R是一個傑作,如果你仔細閱讀,解決方案就在那裏:)。我發現[這個相當透徹和有趣的文章](http://www.altdevblogaday.com/2011/07/12/abusing-the-c-preprocessor/),雖然它似乎不依賴於特定理論。 –

+1

這個原因起作用的原因是有一個預處理可以處理擴展 - 但沒有第二個預掃描。這是如此,如果有宏嵌套調用的事情工作。我懷疑這只是...的利用:)。你可以在這裏閱讀更多關於這方面的信息:http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html#Argument-Prescan –

1

你也可以用X-Macros來做到這一點:

funcs_x.h

/* N.B. no guard macro */ 
FUNC(int) 
FUNC(float) 

的main.c

#define FUNC(x_) static x_ x_ ## _squared (x_ val) { return val * val; } 
#include "funcs_x.h" 
#undef FUNC 


int main(int argc, const char **argv) { ... } 

這似乎是你正在嘗試做的。