2

我有一个需要双 NULL 终止符的可变参数函数。

人为的简化示例

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]
}

我想用来自 gcc的__attribute ((sentinel))__对其进行注释。但似乎使用 sentinel 属性,只有一个参数可以要求为 NULL,而不是所需的sentinel(0,1) [最后两个要求为 NULL]。

有没有办法让 gcc 强制执行双 NULL,或者......

鉴于 NULL 只能对两个参数之一强制执行,你会用sentinel(0)sentinel(1)装饰这个函数吗?为什么?这两个位置中的哪一个更容易捕获错误?

4

1 回答 1

1

在缺少任何两个标记的情况下,实现编译错误的唯一方法可能是使用 C99可变参数宏

#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,那么他/她将在忘记用两个空值终止参数列表的情况下出错。

于 2012-08-20T13:23:15.257 回答