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?
答
可能实现编译错误,在任意两个哨兵是缺失情况下,唯一的办法 - 就是用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结束参数列表的情况下得到错误。
请澄清你的例子是如何做作和简化! '__attribute __((sentinel))'根本不适合用于检查整数0 - 在编译器不知道类型的上下文中,它不一定与空指针相同可变参数函数)。正如你链接到的文档所说:“这个函数属性确保了函数调用中的参数是一个明确的NULL。[...] *在这种情况下,一个有效的NULL被定义为零,并且具有任何指针类型。 * [...]“。 – 2012-08-20 01:10:37
很明显,他们应该是指针,而不是整数。目的是澄清NULL不会被解释为合法坐标(因为值为0的指针和值为0的整数对于可变参数函数是无法区分的)。我试图提出这个问题 - 并不意味着在这个过程中引入混淆。 – Pat 2012-08-20 01:17:36
再次阅读假设'任何法律x或y不能为0',并认为你真的需要两个空值? – 2012-08-20 06:24:40