2012-11-21 52 views
2

我已經創建了一個用於錯誤跟蹤的宏。 下面是一個簡化的版本:如何爲多行宏調用獲取宏名稱__LINE__?

#include <stdio.h> 

#define ERR(...)         \ 
    printf("error @ %d\n", __LINE__) 

int main() 
{ 
    return ERR(1,    /* line 7 */ 
       2,    /* line 8 */ 
       3);    /* line 10 */ 
} 

當被執行時,它打印:

error @ 10 

然而,在印刷線路號與grep輸出(grep -n ERR test.c)匹配,我需要ERR串的行數(line 7)。

這樣的事情有可能嗎?有任何想法嗎?

附加說明: 宏應該看起來像一個函數調用(所以我可以做return ERR(...);)。 編譯器是GCC版本4.4.5。可以使用C99 + GNU擴展。

回答

2

根據@cwyang命題,在定義和昏迷操作符中使用帶有不匹配括號的宏。

#define ERR (LINEINFO, HANDLEARGS 
#define HANDLEARGS(...) __LINE__) 
#define LINEINFO printf("error @ %d: ", __LINE_) 

return ERR(x, 
      y, 
      z); 

將擴大到

return (printf("error @ %d: ", 5), 7); 

與海灣合作委員會。

+0

這似乎是做我需要的。謝謝! – LRipa

+0

哦,C預處理器的樂趣。 – Qix

2

如何如下:

#define VOID_MACRO(...) (void) 0 
#define ERR printf("err @ %d\n", __LINE__); VOID_MACRO 
+0

它有一個問題:當'ERR'被用作'return'值時,'VOID_MACRO'永遠不會被調用(參見問題中的附加註釋)。然而,它應該總是被調用 - 有一些功能使用了可變參數(它在我的簡化示例中沒有顯示)。 – LRipa

+0

這部分解決了返回問題#define ARG_MACRO(...)returns1_and_processes_args(__ VA_ARGS__) #define ERR printf(「error @%d:」,__LINE__)* ARG_MACRO'。然而,這並非完美的解決方案。 – LRipa

0

這也許是一種選擇?

#define ERR(line,...)    \ 
    printf("error @ %d\n", line) 

ERR(__LINE__ 
    blah, 
    blah, 
    blah); 
+0

(簡單/合理的解決方案是根本不使用可變參數宏) – Lundin

+0

在非簡化版本中,變量參數宏用於錯誤打印 - 它們無法避免。 – LRipa

+0

將'__LINE__'寫到所有地方(無論ERR宏是什麼)是不需要的。宏應該儘可能少地爭論。 – LRipa