gnu 的 C 文档指出,如果函数具有,则__attribute__((sentinel))
它必须NULL
作为函数的最后一个参数。
是否可以有任何其他值作为结束参数列表的标记?
gnu 的 C 文档指出,如果函数具有,则__attribute__((sentinel))
它必须NULL
作为函数的最后一个参数。
是否可以有任何其他值作为结束参数列表的标记?
您可以使用任何想要标记参数列表末尾的值,只要您对它有足够的了解即可从参数列表中抓取它。但是,编译器通常不会检查您选择的值是否在调用函数时实际传递,因此您需要注意它。
本质上,您只需以通常的方式创建一个可变参数函数,并且在函数内部,当您读取与您的哨兵匹配的参数时,您将停止读取参数——没有什么特别需要做的,但您需要知道要读取的参数类型。
例如:
#include <stdarg.h>
/* Count arguments up to the number 5 */
int countArgsTilFive(int first, ...)
{
int res = 1;
va_list ap;
if (first == 5) return 0;
va_start(ap,first);
while (va_arg(ap,int) != 5) res++;
va_end(ap);
return res;
}
...将计算它之前发生的所有论点5
。但是,如果您没有将它传递给5
列表中的某处,或者如果您传递的参数不是int
.
另一个带有指针的示例,其中哨兵节点作为第一个参数传递,再作为最后一个参数传递:
/* Count arguments, excluding the first, until the first occurs again */
int countPtrs(void *sentinel, ...)
{
int res = 0;
va_list ap;
va_start(ap,sentinel);
while (va_arg(ap,void *) != sentinel) res++;
va_end(ap);
return res;
}
这是 Apple 如何定义方便的NS_REQUIRES_NIL_TERMINATION
预编译检查的(一个经过编辑的版本),即通过某种方法要求一个 nil 哨兵......
+ (NSArray*)arrayWithRects:(NSR)rect,...NS_REQUIRES_NIL_TERMINATION;
#if !defined(NS_REQUIRES_NIL_TERMINATION)
#if defined(__APPLE_CC__) && (__APPLE_CC__ >= 5549)
#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0,1)))
#else
#define NS_REQUIRES_NIL_TERMINATION __attribute__((sentinel))
#endif
#endif
不太确定这两个编译器指令之间有什么区别。但我认为这个结构可以与“其他”、“自定义”哨兵一起使用。我在想NSNotFound
——XX_REQUIRES_NSNOTFOUND_TERMINATION
或者类似的东西?