簡體   English   中英

如何創建宏來檢測類型並自動打印數字?

[英]How to create a macro to detect the type and print a number automatically?

我有一個宏:

#define assert_equal(x, y) do {\
    typeof(x) evalx = x;\
    typeof(y) evaly = y;\
    _assert(evalx == evaly, __LINE__, __FILE__,\
        EVAL_TYPE_FORMATER(evalx)" != "EVAL_TYPE_FORMATER(evaly), evalx, evaly\
    )\
} while (0)

它應該測試 x 和 y 是否相等,如果不相等則打印兩個值。 _assert() function 看起來像這樣:

void _assert(bool condition, size_t line, const char* file, char* format, ...);

我需要幫助來創建宏EVAL_TYPE_FORMATER() 我最初的想法是檢查#iftypeof()我必須使用什么格式字符串。 但這不起作用,因為我不能在宏擴展中使用#if

這是我的初步想法:

#define EVAL_TYPE_FORMATER(exp)\
    #if typeof(exp) == char ||\
        typeof(exp) == short ||\
        typeof(exp) == int\
        "%d"\
    #elif typeof(exp) == long\
        "%ld"\
    ...

但是正如您所看到的,is 有很多錯誤。 我該怎么做才能解決這個問題?

編輯:

較新的方法是使用_Generic (感謝@Someprogrammerdude)。


#define EVAL_TYPE_FORMATER(exp) (_Generic((exp), \
        char: "%d", \
        short: "%d", \
        int: "%d", \
        long: "%ld", \
        ...
    ))

但是_Generic的結果不能用於將它與常量連接起來。 EVAL_TYPE_FORMATER(evalx)" != "EVAL_TYPE_FORMATER(evaly)現在無法編譯。 有辦法解決嗎?

編輯 2:

通過將_assert()更改為現在采用 3 char* arguments 並在運行時連接格式字符串來解決。

使用您當前的設計:

通過將 _assert() 更改為現在采用 3 char* arguments 並在運行時連接格式字符串來解決。

如果您打算使用 printf,這正是您必須要做的。


有辦法解決嗎?

當然:創建所有類型的所有可能組合並在一個表達式中計算它們:

#define assert_equal(x, y) do {\
    typeof(x) evalx = x;\
    typeof(y) evaly = y;\
    _assert(evalx == evaly, __LINE__, __FILE__,\
        EVAL_TYPE_FORMATER(evalx, evaly), evalx, evaly\
    )\
} while (0)

#define EVAL_TYPE_FORMATER(a, b) \
   _Generic(+(a) \
   , int: _Generic(+(b) \
      , int: "%d != %d" \
      , long: "%d != %ld" \
      , double: "%d != %f" \
      ) \
   , long etc....

注意:使用+運算符,您可以對您的論點應用 integer 促銷,而不是處理char short某些情況。 我喜歡把,放在前面以便很好地縮進。

附言。 你可能也對我的項目yio感興趣,有了它你就可以做_assert(evalx == evaly, __LINE__, __FILE__, evalx, ",= ", evaly) 但它的作用與“傳遞 3 個參數”相同 - 對於每個參數,傳遞一個特殊的 function 以打印參數的類型 -> evalx, ",= ", evaly變為六個 arguments。

問題是預處理器語義不允許它知道 C 種類型。 預處理器就是一個宏處理器,它不知道 C 語言(只是識別 C 語言標記),而是擴展充滿宏定義和宏擴展的文本文件。

當(在編譯器中)分析類型時,預處理器已經完成了編譯單元的那部分,然后它不能根據編譯器收集/生成的信息 go 返回並以不同方式擴展宏。

即使您考慮了 C 語言可以支持的所有可能類型,預處理器也不知道 C 類型是什么。 它在鏈中首先運行。

暫無
暫無

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

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