2012-08-20 38 views
2

我有一個可變參數函數,需要一個雙NULL終結符。gcc:Double NULL sentinel屬性?

做作,簡單的例子

void makeLine(char *name, ...) { 
    ... accepts (x,y) coordinates until (0,0) is found, 
    ... assume that any coordinate except (0,0) is legal 
      [i.e. (0,1) or (1,0) should not trigger a stop condition] 
} 

而且我想和__attribute ((sentinel))__ from gcc進行註解。但似乎用sentinel屬性,只有其中一個參數可能是NULL,而不是所需的sentinel(0,1) [後兩個必須爲NULL]。

有沒有辦法問GCC強制執行雙無效,或...

鑑於NULL只能執行兩個參數中的一個,你會裝點這個函數定點( 0) or sentinel(1)爲什麼?這兩個職位中哪一個更容易發現bug?

+0

請澄清你的例子是如何做作和簡化! '__attribute __((sentinel))'根本不適合用於檢查整數0 - 在編譯器不知道類型的上下文中,它不一定與空指針相同可變參數函數)。正如你鏈接到的文檔所說:「這個函數屬性確保了函數調用中的參數是一個明確的NULL。[...] *在這種情況下,一個有效的NULL被定義爲零,並且具有任何指針類型。 * [...]「。 – 2012-08-20 01:10:37

+0

很明顯,他們應該是指針,而不是整數。目的是澄清NULL不會被解釋爲合法座標(因爲值爲0的指針和值爲0的整數對於可變參數函數是無法區分的)。我試圖提出這個問題 - 並不意味着在這個過程中引入混淆。 – Pat 2012-08-20 01:17:36

+0

再次閱讀假設'任何法律x或y不能爲0',並認爲你真的需要兩個空值? – 2012-08-20 06:24:40

回答

1

可能實現編譯錯誤,在任意兩個哨兵是缺失情況下,唯一的辦法 - 就是用C99 variadic macros

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 

#pragma GCC diagnostic error "-Wformat" 

void checkSentinel0(char * name, ...) __attribute__ ((sentinel(0))); 
void checkSentinel1(char * name, ...) __attribute__ ((sentinel(1))); 

void checkSentinel0(char * name, ...) { 
    (void)name; 
} 
void checkSentinel1(char * name, ...) { 
    (void)name; 
} 

#define MY_VARIADIC(name, ...) do {checkSentinel0(name, __VA_ARGS__);\ 
            checkSentinel1(name, __VA_ARGS__);\ 
             myVariadic(name, __VA_ARGS__);}\ 
           while(0); 

void myVariadic(char * name, ...) { 
    // your code messing with coordinates and etc. 
    (void)name; 
} 

int main() { 

MY_VARIADIC("test", 1,2,3,4, NULL, NULL); // Ok 

MY_VARIADIC("test", 1,2,3,4, 14,  15); // not compilable 
MY_VARIADIC("test", 1,2,3,4, NULL, 15); // not compilable 
MY_VARIADIC("test", 1,2,3,4, 15, NULL); // not compilable 

return 0; 
} 

因此,如果用戶僅暴露於宏MY_VARIADIC那麼他/她將在忘記用兩個null結束參數列表的情況下得到錯誤。