2009-08-11 5 views
6

Değişken sayıda argüman alan C dilinde bir işlev yazıyorum.C varargs - va_copy sayıları

size_t myprintf(char *fmt, ...); 

Şimdiye kadar çok iyi. Right Way ™ 'i bir şeyler yapmak ve değişken argümanlar alan bir versiyon yapmak ve bir va_list alan başka bir versiyona karar verdim.

size_t myprintf(char *fmt, ...); 
size_t myvprintf(char *fmt, va_list args); 

Yapılması zor değil. my_vprintf() dışında, args'un iki farklı fonksiyona göndermesi gerekir (önce ne kadar alana ihtiyacımız olduğunu belirlemek için 0 ile snprintf() arasında, o kadar çok oda tahsis ettikten sonra sprintf()). Bunu va_copy ile yapıyorum.

size_t myvprintf(char *fmt, va_list args) 
{ 
    va_list args2; 
    va_copy(args, args2); 
    // do stuff with args2 
    va_end(args2); 
    // do more stuff with args 
} 

Her şey yolunda ve iyi ama C99 biraz zayıf uygulandı. Mümkünse, kodumun C89'da da çalışmasını ve mümkün olduğunca çok sayıda derleyici ile çalışmasını istiyorum. Şu anda #include <stddef.h> sonra bu var ama herhangi kodundan önce:

#ifndef va_copy 
# ifdef __va_copy 
# define va_copy(a,b) __va_copy(a,b) 
# else /* !__va_copy */ 
# define va_copy(a,b) ((a)=(b)) 
# endif /* __va_copy */ 
#endif /* va_copy */ 

Ben ((a)=(b)) güvenilmez olduğunu ve belki memcpy() veya benzer bir şey kullanması gerektiğini o inanıyoruz yol, ama bu "Eğer düzeyine hala C99'u desteklemeyin, umarım "yerine" yerine "C99'u desteklemezseniz, asla korkmayın" (istediğim şey). Bu sınırlamayı aşmanın iyi bir yolu var mı? Bir çözüm ve yineleme, va_list'u iki ayrı kopyanın yapılması, vb. Geçirerek geçen iki çözüm - va_list işlevini gördüm - ama ne kadar iyi çalışacaklarını bilmiyorum (ve yinelemeli çözüm kazandı " Şimdi sadece vsnprintf()'u aramak istersem, o kadar iyi olur mu?).

Size göre, StackOverflow Kullanıcısı. C89 uyumluluğunu sağlamak için yapabileceğim başka bir şey var mı, yoksa va_copy ve __va_copy olmayan kullanıcılar (kabul edilebilecek kadar az ve çok uzak) sadece emmek ve almak zorunda mı?

+0

2009. Neden hala C89 uyumluluğuna ihtiyacınız var? – stepancheg

+0

Çünkü VC++ bunu desteklemiyor (ve muhtemelen desteklemiyor). Ve sahip olmak isterim. Bence bu iyi bir şey. –

+0

Bence MS, C99 için gitme niyetinde olmadıklarını söylemek için rekor seviyeye geldiler. Müşterilerin istediği tuhaf özellikleri seçmek ve seçmek dışında. – KTC

cevap

3

(a)=(b), güvenilmezdir. Hatta va_list gibi bir şey olabildiğince (kamu fonksiyonu basit bir sarmalayıcı olurdu) olduğu iki va_list geçen:

typedef __va_list_impl va_list[1]; 

hangi birinde bir va_arg yapan başka değiştirmek olacaktır (Ben Solaris böyle kullanmak olduğunu hatırlamak görünüyor tür bir şey, ah, kayıt penceresi ...). Ne yazık ki, istediğini yapmak için emin bir yol bilmiyorum.

+0

Bundan korkuyordum. Oh iyi.Yapacağım uygun şeyin hack-'va_copy'm '#error 'olarak değiştirileceğini düşünüyorum.' ' –

+0

Bu özel durumda, bir dizi atayamayacağınız için va_copy makrosunda atama başarısız olur. başka bir. – caf