簡體   English   中英

VC ++與GCC預處理器

[英]VC++ vs GCC preprocessor

長話短說,gcc和vc ++預處理器具有相同輸入的不同輸出。 如果傳遞給另一個宏,vc ++中的變量宏似乎不會進行“參數匹配”(如果它是正確的術語)。 例如:

#define MACRO(a, ...)        head:a, tail:MACRO_OTHER(__VA_ARGS__)
#define MACRO_OTHER(a, ...)  head:a, tail:__VA_ARGS__

MACRO(1, 2, 3, 4, 5)

gcc輸出:

head:1, tail:head:2, tail:3,4,5

vc ++輸出:

head:1, tail:head:2,3,4,5, tail:

顯然aMACRO_OTHER中, 2,3,4,5是空的可變參數部分。 考慮到這一點,有沒有辦法創建一個vc ++替代以下的宏(這與gcc很好)

#define VA_TYPES_WITH_ARGS(...) __VA_TYPES_WITH_ARGS(VA_NUM_ARGS(__VA_ARGS__),##__VA_ARGS__)
#define __VA_TYPES_WITH_ARGS(n, ...) _VA_TYPES_WITH_ARGS(n,##__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS(n, ...) _VA_TYPES_WITH_ARGS_##n(__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS_0()
#define _VA_TYPES_WITH_ARGS_1(type     ) type _arg1
#define _VA_TYPES_WITH_ARGS_2(type, ...) type _arg2, _VA_TYPES_WITH_ARGS_1(__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS_3(type, ...) type _arg3, _VA_TYPES_WITH_ARGS_2(__VA_ARGS__)
// etc

它基本上為每個參數附加_argK

例:

VA_TYPES_WITH_ARGS(int, bool, float)

將擴大到

int _arg3, bool _arg2, float _arg1

任何幫助將不勝感激。


相關的預處理器問題:

gcc和Microsoft預處理器之間的區別

GCC和VC ++預處理器的意外行為

您可以通過使用Boost以合理的交叉編譯方式(並接受更多參數而無需額外的工作來啟動)來執行此操作,我可以告訴您花費這么多時間查看標題,有很多解決方法可以使用這些問題:

#define VA_TYPES_WITH_ARGS(...)   \
    BOOST_PP_ENUM(                \
        BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),    \
        VA_TYPES_WITH_ARGS_MACRO,               \
        BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__) \
    )

#define VA_TYPES_WITH_ARGS_MACRO(z, n, data)       \
    BOOST_PP_TUPLE_ELEM(n, data) BOOST_PP_CAT(     \
        _arg,                                      \
        BOOST_PP_SUB(BOOST_PP_TUPLE_SIZE(data), n) \
    )                                              

VA_TYPES_WITH_ARGS(int, bool, float) //int _arg3 , bool _arg2 , float _arg1

第一個宏枚舉可變參數的( ENUM ),為每個參數調用第二個並添加連接逗號。 它從可變參數數據形成一個元組,以提供給第二個宏。

第二種形式是元素( TUPLE_ELEM ),后跟_arg連接( CAT ), size - nSUB ),其中size是可變參數數據中的元素數(作為元組賦予宏)( TUPLE_SIZE )。

看得出來了。

一個適用於VC ++的獨立方法,與GCC打破,是:

#define EXPAND(...) __VA_ARGS__
#define LPAREN (
#define RPAREN )

現在,不要使用像x(__VA_ARGS__)這樣的宏,而是像這樣使用它: EXPAND(x LPAREN __VA_ARGS__ RPAREN)

這會強制VC ++預處理器比通常更晚掃描參數。

您應該能夠將兩個表單組合在一起,將特定於編譯器的位放在一個位置。

請注意,雖然沒有標准的C ++答案:依賴於x()是一個沒有參數的宏調用。 這不是預處理器在標准C ++中的工作方式:如果x是可變參數宏,則x()使用單個參數調用宏,並且該單個參數為空。 此外,您依賴於能夠省略可變參數:標准C ++也不允許這樣做。 如果宏被定義為#define FOO(x,...) ,則將其調用為FOO(1)無效。 由於不存在標准方法,希望對您來說不是一個問題,因為各種方法必然是編譯器特定的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM