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))__で注釈を付けたいと思います。しかし、センチネル属性を使用すると、目的のセンチネル(0,1) [最後の2つはNULLである必要がある]とは対照的に、引数の1つだけがNULLである必要があるようです。

gcc に double-NULL を適用するように依頼する方法はありますか、それとも...

NULL は 2 つのパラメーターの 1 つにのみ適用できることを考えると、この関数をsentinel(0)またはsentinel(1)で装飾しますか? またその理由は? 2 つのポジションのうち、バグをキャッチする可能性が高いのはどれですか?

4

1 に答える 1

1

おそらく、2 つのセンチネルのいずれかが欠落している場合にコンパイル エラーを発生させる唯一の方法は、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場合、2 つの null で引数リストを終了するのを忘れると、エラーが発生します。

于 2012-08-20T13:23:15.257 に答える