ฉันใส่นักแสดงเพียงเพื่อแสดงความไม่พอใจของรูน่าเกลียดในระบบพิมพ์ซึ่งอนุญาตให้โค้ดเช่นตัวอย่างต่อไปนี้รวบรวมโดยไม่มีการวินิจฉัยแม้ว่าจะไม่มีการใช้ casts เพื่อทำให้เกิดการแปลงที่ไม่ดี:
double d;
void *p = &d;
int *q = p;
ฉันหวังว่าจะไม่มีอยู่ (และมันไม่ได้อยู่ใน C ++) และดังนั้นฉันจึงเลือก มันแสดงถึงรสนิยมของฉันและการเมืองการเขียนโปรแกรมของฉัน ฉันไม่ได้เป็นเพียงตัวชี้หล่อ แต่มีประสิทธิภาพการหล่อการลงคะแนนเสียงและขับผีออกของความโง่เขลา ถ้าฉันไม่สามารถจริง โยนออกความโง่เขลาแล้วอย่างน้อยให้ฉันแสดงความต้องการที่จะทำเช่นนั้นกับท่าทางของการประท้วง
ในความเป็นจริงการปฏิบัติที่ดีคือการห่อmalloc
(และเพื่อน) ด้วยฟังก์ชั่นที่ส่งคืนunsigned char *
และโดยทั่วไปจะไม่ใช้void *
ในรหัสของคุณ หากคุณต้องการตัวชี้แบบทั่วไปไปยังวัตถุใด ๆ ให้ใช้char *
หรือunsigned char *
และได้ปลดเปลื้องในทั้งสองทิศทาง การผ่อนคลายอย่างหนึ่งที่สามารถผ่อนคลายได้คือการใช้ฟังก์ชั่นเหมือนmemset
และmemcpy
ไม่ได้ปลดเปลื้อง
ในหัวข้อของการแคสติ้งและความเข้ากันได้ของ C ++ ถ้าคุณเขียนโค้ดของคุณเพื่อให้คอมไพล์เป็นทั้ง C และ C ++ (ในกรณีที่คุณต้องส่งคืนค่าmalloc
เมื่อกำหนดให้กับสิ่งอื่นที่ไม่ใช่void *
) คุณสามารถทำประโยชน์ได้มาก สิ่งที่คุณต้องทำเอง: คุณสามารถใช้มาโครในการคัดเลือกนักแปลที่แปลเป็นสไตล์ C ++ เมื่อคอมไพล์เป็น C ++ แต่ลดลงเป็น C cast เมื่อคอมไพล์เป็น C:
/* 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
หากคุณปฏิบัติตามมาโครเหล่านี้การgrep
ค้นหาฐานรหัสของคุณอย่างง่าย ๆสำหรับตัวระบุเหล่านี้จะแสดงให้คุณเห็นว่าคาสต์ทั้งหมดของคุณอยู่ในตำแหน่งใดดังนั้นคุณสามารถตรวจสอบได้ว่าส่วนใดไม่ถูกต้อง
ถ้าคุณคอมไพล์โค้ดเป็นประจำด้วย C ++ มันจะบังคับใช้การร่ายที่เหมาะสม ตัวอย่างเช่นหากคุณใช้strip_qual
เพียงเพื่อลบconst
หรือvolatile
แต่โปรแกรมเปลี่ยนไปในลักษณะที่การแปลงประเภทเกี่ยวข้องกับตอนนี้คุณจะได้รับการวินิจฉัยและคุณจะต้องใช้การรวมกันของ cast เพื่อรับการแปลงที่ต้องการ
เพื่อช่วยให้คุณปฏิบัติตามมาโครเหล่านี้คอมไพเลอร์ GNU C ++ (ไม่ใช่ C!) มีคุณสมบัติที่สวยงาม: การวินิจฉัยเสริมซึ่งถูกสร้างขึ้นสำหรับการโยนสไตล์ C ทุกครั้ง
-Wold-style-cast (C ++ และ Objective-C ++ เท่านั้น)
เตือนถ้ามีการใช้งานคาสต์แบบเก่า (แบบ C) ในแบบที่ไม่ใช่โมฆะ
ภายในโปรแกรม C ++ casts สไตล์ใหม่ (dynamic_cast
static_cast, reinterpret_cast และ const_cast) มีความเสี่ยงน้อยกว่า
เพื่อเอฟเฟกต์ที่ไม่ตั้งใจและง่ายต่อการค้นหา
หากรหัส C ของคุณคอมไพล์เป็น C ++ คุณสามารถใช้-Wold-style-cast
ตัวเลือกนี้เพื่อค้นหา(type)
ไวยากรณ์การส่งทั้งหมดที่อาจคืบคลานเข้าไปในรหัสและติดตามการวินิจฉัยเหล่านี้โดยแทนที่ด้วยตัวเลือกที่เหมาะสมจากมาโครด้านบน (หรือ รวมกันหากจำเป็น)
การรักษาของการแปลงนี้เป็นที่ใหญ่ที่สุดแบบสแตนด์อโลนเหตุผลทางเทคนิคเดียวสำหรับการทำงานใน "Clean C": รวม C และ C ++ ภาษาซึ่งในทางกลับกันในทางเทคนิค justifies malloc
หล่อค่าตอบแทนของ