Question

I have a variadic function that requires a double-NULL terminator.

Contrived, Simplified Example

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

And I'd like to annotate it with __attribute ((sentinel))__ from gcc. But it seems that with the sentinel attribute, only one of the arguments can be required NULL as opposed to the desired sentinel(0,1) [last two required to be NULL].

Is there a way to ask gcc to enforce a double-NULL, or...

Given that the NULL can only be enforced for one of the two parameters, would you decorate this function with sentinel(0) or sentinel(1) and why? Which of the two positions would be more likely to catch bugs?

Was it helpful?

Solution

Probably the only way to achieve compilation error in case of any of TWO sentinels is missing - is to use 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;
}

So if user is only exposed to your macro MY_VARIADIC then he/she will get error in case forgetting to terminate argument list with two null's.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top