2011-10-03 29 views
7

gnu's C ile ilgili belgeler, işlev __attribute__((sentinel)) ise, işlevin son bağımsız değişken olarak NULL olması gerektiğini belirtir.Özel sentinel değeriyle değişken bir işlev nasıl oluşturulur?

Bağımsız değişken listesinin sonlandırılması için başka herhangi bir değere sahip olabilir mi?

+1

Böyle bir işlev oluştururken, açıkça _can_ yapın. Argümanların keyfi varargs şemaları için doğru olduğunu kontrol etmek için herhangi bir GNU kapsamı bilmiyorum. Hatta bir parametrenin kaç argümanın verildiğini "saymak" için bir özniteliği bile yoktur, böylece derleyici doğru aldıklarını kontrol edebilir. –

cevap

3

Bağımsız değişkenler listesinin sonuna işaretlemek istediğiniz değeri, argüman listesinden almak için yeterli olduğunu düşünüyorsanız, kullanabilirsiniz. Derleyici normalde, seçtiğiniz işlevin aslında işleve çağrıldığında iletildiğini kontrol etmeyecektir, bu yüzden ona dikkat etmeniz gerekir.

Esasen alışılmış şekilde bir değişkenlik işlevi yaratırsınız ve işlevin içinde, göndereninize uyan bir okuduğunuzda bağımsız değişkenleri okumayı durdurursunuz - özellikle yapılması gereken özel bir şey yoktur, ancak hangi türlerin gerektiğini bilmeniz gerekir. okunacak argümanlar. Örneğin

:

#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 önce gerçekleşen tüm argumanlarini sayar. Yine de, listede bir yere 5 iletmezseniz veya int olmayan argümanları iletirseniz kötü şeyler olabilir.

bir sentinel lenf nodu son parametre olarak kullanarak, daha önce olduğu gibi geçirilir ve işaretçiler, bir diğer örnek: Bu

/* 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; 
} 
+1

GCC'nin __attribute __ ((sentinel)) 'ile derleyici _can_ argüman listesinin verilen değerle bittiğini kontrol edin. Sadece izin verdiği tek değer 'NULL' - derleyicinin doğrulaması için başka bir değer seçmenize izin vermez. –

+1

Sadece, keyfi sentinel değerleri için __attribute __ ((sentinel)) 'gibi bir şey olup olmadığını bilmek istiyorsa, o zaman cevap çok yararlı değildir .. ama __attribute __ ((sentinel))' ile ilgili şeyler varsa NULL olmayan sentinellerin hiç kullanılamayacağını, bunu temizlemeliydi. – Dmitri

0

(düzenlenmiş bir versiyonu aşağı) Elma kullanışlı NS_REQUIRES_NIL_TERMINATION nasıl tanımlar önceden derleme onay, yani neyi differenc

+ (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 

oldukça emin değil ... bazı yöntemi ile bir nil nöbetçi gerektirecek e bu iki derleyici direktifleri arasındadır .. ama bu yapının "diğer", "özel" sentinellerle kullanılabileceğini farz ediyorum. NSNotFound - XX_REQUIRES_NSNOTFOUND_TERMINATION veya buna benzer bir şey mi var?

İlgili konular