Ben sadece kötü dönüşüm getirmek için hiçbir döküm kullanılmasa bile, aşağıdaki snippet gibi kodun tanı olmadan derlemek için izin verir, tür sistemindeki çirkin deliğin onaylanmamış göstermek için döküm koymak:
double d;
void *p = &d;
int *q = p;
Keşke var olmasaydı (ve C ++ 'da yok) ve bu yüzden yaptım. Zevkimi ve programlama politikamı temsil ediyor. Sadece bir işaretçi değil, etkili bir şekilde, bir oy pusulası ve aptallık şeytanlarını atıyorum . Eğer gerçekten aptallık yapamıyorsam , en azından bunu bir protesto hareketiyle dile getirmeme izin ver.
Aslında, iyi bir uygulama, malloc
(ve arkadaşlarınızı) geri dönen işlevlerle unsigned char *
sarmaktır ve temelde asla void *
kodunuzda kullanılmaz. Herhangi bir nesneye genel bir işaretçi gerekiyorsa, bir char *
veya kullanın unsigned char *
ve her iki yönde de yayınlar yapın. Şımartılabilecek bir rahatlama, belki de, döküm gibi memset
ve memcpy
olmadan işlevler kullanmaktır .
Bunu kodunuzu yazarsanız döküm ve C ++ uyumluluğu konusunda, o C ve C hem ++ (bu durumda siz derler zorunda dönüş değer dağıtmak malloc
dışında bir şeye atarken void *
), çok yararlı yapabilirsiniz kendiniz için bir şey: C ++ olarak derlenirken C ++ stil dökümlerine dönüşen ancak C olarak derlerken C dökümüne indirgeyen döküm için makrolar kullanabilirsiniz:
/* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif
Bu makrolara bağlı kalırsanız, grep
bu tanımlayıcılar için kod tabanınızda yapılan basit bir arama size tüm yayınlarınızın nerede olduğunu gösterir, böylece bunlardan herhangi birinin yanlış olup olmadığını inceleyebilirsiniz.
Daha sonra, kodu düzenli olarak C ++ ile derlerseniz, uygun bir dökümün kullanımını zorlar. Örneğin, strip_qual
yalnızca bir const
veya öğesini kaldırmak için kullanırsanız volatile
, ancak program şimdi bir tür dönüştürmenin yer alacağı şekilde değişirse, bir tanı alırsınız ve istenen dönüşümü elde etmek için bir dizi kombinasyonu kullanmanız gerekir.
Bu makrolara uymanıza yardımcı olmak için, GNU C ++ (C! Değil) derleyicisinin güzel bir özelliği vardır: C stili yayınların tüm oluşumları için üretilen isteğe bağlı bir tanılama.
-Wold stili döküm (yalnızca C ++ ve Objective-C ++)
Boş olmayan bir türe dökülen eski bir stil (C stili) kullanılıyorsa uyar
C ++ programında. Yeni stil yayınları (dynamic_cast,
static_cast, reinterpret_cast ve const_cast) daha az savunmasız
istenmeyen etkileri ve aramak çok daha kolay.
C kodunuz C ++ olarak derleniyorsa, bu -Wold-style-cast
seçeneği (type)
, kodun içine girebilecek döküm sözdiziminin tüm örneklerini bulmak ve yukarıdaki makrolar (veya bir gerekirse kombinasyon).
Dönüşümlerin bu tedavisi, bir "Temiz C" de çalışmak için tek ve en büyük bağımsız teknik gerekçedir: kombine C ve C ++ lehçesi, bu da teknik olarak dönüş değerinin dökülmesini haklı çıkarır malloc
.