2008-11-05 77 views
25

有沒有辦法定義一個宏,其中可能包含指令在其正文中的#include 指令?包含#include指令的宏定義

如果我只是把 的 「#include」,它給了錯誤

C2162: "expected macro formal 

參數」

因爲在這裏我沒有使用#連接字符串。
如果我使用 「\# include」那麼我收到以下兩個錯誤:

error C2017: illegal escape sequence 
error C2121: '#' : invalid character : possibly the result of a macro expansion 

有什麼幫助?

回答

1

宏爲什麼需要#include?如果你#包含宏的任何文件,你可以將#include放在宏的上面,幷包含#include語句的其餘部分,並且所有內容都應該很好,並且很花哨。

我看不出有什麼理由讓宏包含任何不能包含在文件中的東西。

5

我相信C/C++預處理器只會對代碼進行一次遍歷,所以我認爲這不會起作用。你可能會得到一個「#include」被宏放在代碼中,但編譯器會窒息它,因爲它不知道該怎麼做。對於你要做的工作,預處理器必須對文件進行第二遍處理,以獲取#include。

-7

傳染性是正確的 - 如果你正在做的:

myfile.c文件:

#include "standardAppDefs.h" 
#myStandardIncludeMacro 

standardAppDefs.h:

#define myStandardIncludeMacro #include <foo.h> 

爲什麼不直接說:

myFile.c:

#include "standardAppDefs.h" 

standardAppDefs.h:

#include <foo.h> 

,忘記了宏?

3

我認爲你是在沒事這項任務似乎是不可能的,因爲我也是從

http://groups.google.com/group/comp.lang.c++/browse_thread/thread/03d20d234539a85c#

沒有得到,在C++ (和C)預處理指令是不反光。

帕維爾Dziepak

不管怎麼說,這背後的嘗試的原因是,我想作以下 反覆使用的代碼段宏:

void foo(AbstractClass object) 
{ 
    switch (object.data_type()) 
    { 
    case AbstractClass::TYPE_UCHAR : 
     { 
     typedef unsigned char PixelType; 
     #include "snippets/foo.cpp" 
     } 
     break; 
    case AbstractClass::TYPE_UINT: 
     { 
     typedef unsigned int PixelType; 
     #include "snippets/foo.cpp" 
     } 
     break; 
    default: 
     break; 
    } 
} 

另一項任務,我需要具有類似的功能

void bar(AbstractClass object) 

我在哪裏將

#include "snippets/bar.cpp" 

當然,它是在寫入任務特定代碼的「snippets/foo.cpp」和「snippets/bar.cpp」中。

+2

你應該看看模板(如stbuton建議)。你當然應該避免需要這樣做。 – 2008-11-05 22:42:55

+0

作爲一般規則,您應該將所有#include語句放在同一個地方(通常是頂部)。它使維護和調試代碼更簡單。 – helloandre 2008-11-06 01:30:20

+0

我有一個基本上你想做的事情(使用預處理器)有點瘋狂的方式;請參閱我的回答:) http://stackoverflow.com/a/27830271/1447953 – 2015-01-07 23:17:27

9

我不會說優點吧,但FreeType的(www.freetype.org)執行以下操作:

#include FT_FREETYPE_H 

他們定義FT_FREETYPE_H別處

+8

這是在標準中明確允許的,因此只要FT_FREETYPE_H擴展爲或「header.h」形式,便攜便攜。 – 2008-11-05 22:42:11

0

我不知道你是什麼實際試圖做,但它看起來像你可能想要的是模板功能。

這樣PixelType只是代碼塊的模板參數。

4

我也想做到這一點,和這裏的原因:

一些頭文件(特別的openmpi mpi.h)的工作方式不同,如果你是使用C或C++編譯。我正在鏈接到來自C++程序的C MPI代碼。要包含頭,我做平常:

extern "C" { 
#include "blah.h" 
} 

但由於__cplusplus甚至在C鏈接仍然定義這不起作用。這意味着由blah.h包含的mpi.h開始定義模板,並且編譯器會死掉,說你不能使用C鏈接模板。

因此,我有什麼在blah.h做是

#ifdef __cplusplus 
#undef __cplusplus 
#include <mpi.h> 
#define __cplusplus 
#else 
#include <mpi.h> 
#endif 

更換

#include <mpi.h> 

值得注意的是它不只是mpi.h,這是否病態的東西。因此,我想定義一個宏INCLUDE_AS_C,它爲指定的文件做了上述操作。但我想這是行不通的。

如果有人可以找出另一種方法來完成這一點,請讓我知道。

6

由於宏擴展,C和C++語言明確禁止形成預處理器指令。這意味着您不能在宏替換列表中包含預處理器指令。如果你試圖通過串聯(和類似的技巧)「構建」一個新的預處理器指令來欺騙預處理器,那麼行爲是不確定的。

14

所以像其他人說的那樣,不可以在宏中包含#include語句,因爲預處理器只會傳遞一次。但是,您可以使預處理器使用最近發現自己使用的粗糙技巧來做基本相同的事情。

認識到預處理器指令不會在宏內執行任何操作,但它們會在文件中執行某些操作。所以,你可以將你想要改變的代碼塊粘貼到一個文件中,把它看作是一個宏定義(可以用其他宏修改),然後在不同的地方包含這個僞宏文件(make確定它沒有包括警衛!)。它的行爲不像一個宏,但它可以實現一些非常類似宏的結果,因爲#include基本上只是將一個文件的內容轉儲到另一個文件中。

例如,考慮包含許多類似命名的標頭,這些標頭會分組。將它們全部寫出來,或者甚至它們是自動生成的都很乏味。

輔助宏頭:

/* tools.hpp */ 

#ifndef __TOOLS_HPP__ 
#def __TOOLS_HPP__ 

// Macro for adding quotes 
#define STRINGIFY(X) STRINGIFY2(X)  
#define STRINGIFY2(X) #X 

// Macros for concatenating tokens 
#define CAT(X,Y) CAT2(X,Y) 
#define CAT2(X,Y) X##Y 
#define CAT_2 CAT 
#define CAT_3(X,Y,Z) CAT(X,CAT(Y,Z)) 
#define CAT_4(A,X,Y,Z) CAT(A,CAT_3(X,Y,Z)) 
// etc... 

#endif 

僞宏文件

/* pseudomacro.hpp */ 

#include "tools.hpp" 
// NO INCLUDE GUARD ON PURPOSE 
// Note especially FOO, which we can #define before #include-ing this file, 
// in order to alter which files it will in turn #include. 
// FOO fulfils the role of "parameter" in this pseudo-macro. 

#define INCLUDE_FILE(HEAD,TAIL) STRINGIFY(CAT_3(HEAD,FOO,TAIL)) 

#include INCLUDE_FILE(head1,tail1.hpp) // expands to #head1FOOtail1.hpp 
#include INCLUDE_FILE(head2,tail2.hpp) 
#include INCLUDE_FILE(head3,tail3.hpp) 
#include INCLUDE_FILE(head4,tail4.hpp) 
// etc.. 

#undef INCLUDE_FILE 

源文件

/* mainfile.cpp */ 

// Here we automate the including of groups of similarly named files 

#define FOO _groupA_ 
#include "pseudomacro.hpp" 
// "expands" to: 
// #include "head1_groupA_tail1.hpp" 
// #include "head2_groupA_tail2.hpp" 
// #include "head3_groupA_tail3.hpp" 
// #include "head4_groupA_tail4.hpp" 
#undef FOO 

#define FOO _groupB_ 
#include "pseudomacro.hpp" 
// "expands" to: 
// #include "head1_groupB_tail1.hpp" 
// #include "head2_groupB_tail2.hpp" 
// #include "head3_groupB_tail3.hpp" 
// #include "head4_groupB_tail4.hpp" 
#undef FOO 

#define FOO _groupC_ 
#include "pseudomacro.hpp" 
#undef FOO 

// etc. 

這些包括可能您可以通過做這樣的事情部分自動將其列入甚至是在你想重複的代碼塊的中間(用FOO修改),就像一個由冰堅請求:macro definition containing #include directive

我還沒有廣泛使用這個技巧,但它使我的工作完成。顯然,它可以根據需要擴展爲具有儘可能多的「參數」,並且您可以在其中運行您喜歡的任何預處理器命令,並生成實際的代碼。你不能使用它創建的東西作爲另一個宏的輸入,就像你可以使用普通的宏一樣,因爲你不能將include包含在宏中。但它可以進入另一個僞宏:)。

其他人可能對其他限制有一些評論,並可能出錯:)。