gcc:Double NULL sentinel属性?

gcc:Double NULL sentinel属性?

问题描述:

我有一个可变参数函数,需要一个双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

可能实现编译错误,在任意两个哨兵是缺失情况下,唯一的办法 - 就是用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结束参数列表的情况下得到错误。