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;
}
NS_REQUIRES_NIL_TERMINATION
これは、Apple が便利なコンパイル前チェックをどのように定義しているか (の編集版)です。
+ (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
これら2つのコンパイラディレクティブの違いはよくわかりません..しかし、この構成は「他の」「カスタム」センチネルで使用できると思います..私は考えていますNSNotFound
-XX_REQUIRES_NSNOTFOUND_TERMINATION
またはそれに似た何か?