การเข้าใจรหัส C

รหัส C ที่มักมีอายุหลายทศวรรษ มักจะมีโครงสร้างหลักของระบบที่ฝังตัวอยู่นับไม่ถ้วน ระบบปฏิบัติการ และโปรแกรมขององค์กรต่างๆ

ก่อนจะแตะต้องบรรทัดเดียว ความเข้าใจของระบบที่มีอยู่นั้นไม่สัมพันธ์กัน โปรดอ่านเอกสาร (หากมี), สัมภาษณ์ผู้เชี่ยวชาญโดเมน, และประมวลผลโค้ดโดยใช้ตัวดีบั๊ก เพื่อตรวจสอบการประมวลผลของตัวมัน คลิกที่ตําแหน่งเชื่อมโยงและสังเกตว่าส่วนไหนของฮาร์ดแวร์ หรือระบบปฏิบัติการที่ระบุได้ยาก เฟสนี้ป้องกันการแตกและช่วยในการปรับเปลี่ยนข้อมูล

การ ใช้ มาตรการ เพื่อ ให้ การ ค้ําจุน ที่ มี ประสิทธิภาพ

กลยุทธ์ ต่อ ไป นี้ เป็น โครง สร้าง ที่ เป็น ระบบ สําหรับ การ ปรับ ปรุง รหัส C ที่ มี ค่า นิยม ใหม่.

1. นํารหัสรหัสที่อ่านเข้าใจได้

การตรวจสอบรหัส ระบุว่ามีความเจ็บปวดที่แม่นยํา ใช้เครื่องมือวิเคราะห์แบบคงที่ เพื่อตรวจจับบั๊ก, ความปลอดภัย, และการละเมิดมาตรฐานการเขียนแบบสมัยใหม่ ตัวอย่างเช่น [FLT: 0] Cppck จับภาพ point de points, foots, และตัวแปรที่ไม่ได้ใช้โดยอัตโนมัติ [FTL: 2] Cstignigrictor [FLT: 3] ให้การตรวจสอบเส้นทางที่ละเอียดกว่านี้ โดยผ่านอุปกรณ์เหล่านี้ หลังจากมีการเปลี่ยนแปลงไม่มีตัวแปรใดๆ ที่ถูกนําเข้ามา

ระหว่างการตรวจสอบนี้ ยังทําการตรวจสอบระบบการสร้างอีกด้วย สร้างแฟ้มแบบสมัยใหม่ หรือ CGGLList เพื่อสนับสนุนการประกอบรูปแบบการประกอบและเปิดใช้งานคําเตือนแบบรวมประเภท เช่น [FLT: 0] เอกสารเอกสารและสร้างกราฟเชื่อมโยง -- นี้จะนําทางการปรับเปลี่ยนโครงสร้างในภายหลัง

2. กําหนด มาตรฐาน การ ทํา เหมือง ใน ปัจจุบัน

รับเอามาตรฐานการเขียนโค้ดที่ยอมรับได้ เพื่อนําความสอดคล้องข้ามโค๊ดฐาน [FLT: 0] แนวกํากับ MSRAC [FLT: 1] (ปกติจะใช้ในระบบย่อยและระบบความปลอดภัยที่นิยามไม่ได้) ลดความสามารถและปรับปรุงความเหมาะสมในการอ่านได้ดีขึ้น โครงการเพิ่มเติมเพิ่มเติมเพิ่มเติมของ C (C) รุ่นล่าสุด -- อย่างน้อย C11, C17. นี่ให้สิทธิ์ในการเข้าถึงคุณสมบัติเช่น [FLT: 1], โครงสร้างที่ไม่มีชื่อ, และแบบ C (11).

กําหนดสถานที่ตั้งชื่อ (เช่น สําหรับฟังก์ชันและตัวแปร สําหรับแมโคร), ระยะเยื้อง (tabs vs. ช่องว่าง), และรูปแบบหมายเหตุ (ใช้ Doxygen หรือคล้าย ๆ กัน). บังคับใช้กฏเหล่านี้ผ่านทาง Linters เช่น [FLT: 0] Lang-ti (FLT: 1] ในระบบเชื่อมต่อแบบต่อเติมข้อมูลแบบต่อเนื่องของคุณ

3. ปรับรหัส

PROTECT C มักจะมีฟังก์ชัน Proups ที่ครอบคลุมหลายร้อยหรือพันบรรทัด แบ่งเป็นฟังก์ชันย่อย ๆ, cohelpive ที่แต่ละคนทําหนึ่งอย่าง ใช้ส่วนหัวเพื่อประกาศส่วนติดต่อสาธารณะและแหล่งย่อยต่าง ๆ ของแฟ้ม ตัวอย่างเช่น แบ่งแฟ้มที่จัดการทั้งเครือข่ายและแฟ้ม I/O ให้เป็นโมดูลแยก (FT: 4) /[FT: 5] และ[FLTT: 6/[FL]][FT]/[FT]]].

การแบ่งประเภทหมายถึงลดตัวแปรทั้งระบบด้วย แทนที่ด้วยสถานะท้องถิ่นที่ผ่านการใช้อาร์กิวเมนต์ของฟังก์ชัน หรือ [FLT: 8] คําแนะนํานี้จะทําให้การทดสอบแบบต่อตรงและแบบหน่วย ATH เป็นไปได้ โดยขอแนะนําให้ใช้ส่วนหัว (ประกาศล่วงหน้า) นิยามเฉพาะแฟ้ม[FLT: 9] เพื่อปกปิดรายละเอียด

// Before: monolithic, global state
int buffer[256];
int index = 0;
void process_data() { /* manipulates global buffer and index */ }

// After: encapsulated module
// buffer.h
typedef struct Buffer Buffer;
Buffer* buffer_create(size_t size);
int buffer_push(Buffer* b, int value);
void buffer_destroy(Buffer* b);

// buffer.c
struct Buffer {
 int* data;
 size_t size;
 size_t index;
};
Buffer* buffer_create(size_t size) { ... }

4. แทนที่ฟังก์ชันที่หมดอายุและไม่ปลอดภัย

ไลบรารีมาตรฐาน C มีฟังก์ชันที่ไม่ปลอดภัยหลายแบบ ซึ่งอาจจะถูกเพิกถอนหรือถูกปิดกั้นในการเข้ารหัสแบบความปลอดภัยในปัจจุบัน

  • [FLT: 11] ⁇
  • ⁇ หรือ
  • ⁇ หรือ
  • ⁇ [FLT: 22]
  • [FLT: 23] ⁇
  • [FLT: 25]] +[FLT: 27] มีข้อจํากัดสนาม

การเปลี่ยนแปลงเหล่านี้ได้ขจัดความพัฟเฟอร์ที่ท่วมท้น ซึ่งเป็นแหล่งหลักของการไม่มั่นคงของความปลอดภัย นอกจากนี้ ยังปิดการทํางานเดิม ๆ ด้วยการกําหนด [FLT: 28] บนวินโดว์ส หรือใช้ธงของคอมโพซิฟที่ทําหน้าที่ลดความบกพร่องลงเป็นข้อผิดพลาด [FLT: 0] Croting Standard (FLT: 1) จัดทํารายการตัวเลือกความปลอดภัยให้ครอบคลุม

5. ปรับปรุงการจัดการหน่วยความจํา

การจองหน่วยความจําแบบไม่ตายตัวของ C มักจะเป็นข้อผิดพลาดของปัญหาทั่วไป รวมถึงการลืมหน่วยความจําอิสระ, ลูกศรสองชั้นฟรี และตัวชี้จับการลาก

  • ใช้[FLT: 29] แทน [FLT: 30] เมื่อต้องการหน่วยความจําแบบเป็นศูนย์ (0-intialized).
  • Check value value value ของฟังก์ชันการเรียง [FLT: 31]. สืบค้นเมื่อ 7 December 2015.
  • สร้างฟังก์ชันห่อกระดาษที่ทําการเรียงร่องเพลง (เช่น ที่ยกเลิกเมื่อล้มเหลว)
  • รับเอาแบบจําลองความเป็นเจ้าของอย่างสม่ําเสมอ: เอกสารที่ฟังก์ชันเป็นเจ้าของหน่วยความจํา และมีหน้าที่รับผิดชอบในการปล่อยข้อมูล
  • ใช้เครื่องมือเช่น [FLT: 0] Valgrind[FLT: 1) (mem check) หรือ address San (ASA) เพื่อตรวจสอบการรั่วไหลและการติดต่อจากเครือข่ายระหว่างการทดสอบ

ในส่วนของการแสดงแบบ continuation โปรดพิจารณาใช้บัฟเฟอร์แบบคงที่ หรือ แอ ลบูโซโทปในเวทีเพื่อหลีกเลี่ยงการแยกชิ้นส่วนและการครอบงํา ระบบที่ฝังตัวด้วยหน่วยความจําที่จํากัด ให้แทนที่การวางตัวแบบไดนามิกด้วยสระที่ถูกจองไว้ก่อน

6. การใช้เครื่องช่วยจํานําความปลอดภัย

ผู้ชี้เป้าคือดาบสองคม ปรับความทันสมัยในการลดโอกาสของแมลง

  • ใช้ [FLT: 33] สําหรับพารามิเตอร์ของฟังก์ชันที่ไม่แก้ไข ซึ่งจะทําให้สัญญามีความชัดเจน และช่วยปรับส่วนปรับแต่งให้เหมาะสมที่สุด
  • ส่วนเสริมแบบ Quificate toวัตถุที่ไม่มีชื่อ (C99 translation) นี้จะทําให้การตั้งเวกเตอร์ดีขึ้น
  • หลีกเลี่ยงการคัด [FLT: 35] โดยไม่จําเป็น เมื่ออ่านจากกระแส byte ให้ใช้[FLT: 36] แทนการหล่อเพื่อหลีกเลี่ยงการฝ่าฝืนชื่อปลอมอย่างเข้มงวด
  • แทนที่ตัวชี้ของฟังก์ชัน ซึ่งใช้ตัวชี้ของฟังก์ชันพิมพ์อย่างถูกต้อง เพื่อป้องกันพฤติกรรมที่นิยามไม่ได้
  • ใช้สมาชิกอาร์เรย์ที่ยืดหยุ่นได้ (C99) แทน (ขนาดอาร์เรย์ที่ปลายของโครงสร้าง).
// Avoid: casting void* to misaligned type
int value = *(int*)(byte_buffer + offset); // potential UB

// Prefer: memcpy
int value;
memcpy(&value, byte_buffer + offset, sizeof(value));

7. ปรับ ปรุง ความ ผิด พลาด ให้ ดี ขึ้น

Expression C มักจะใช้ , รหัสส่งกลับ และสถานะข้อผิดพลาดระดับโลก การตั้งค่าการผิดพลาดไม่ได้ ตรงกับรูปแบบที่สอดคล้องกัน ตัวเลือกรวม:

  • ใช้ชนิดการตอบกลับที่เรียงตามตัวอักษรสําหรับฟังก์ชัน (เช่น [FLT: 40]).
  • หลีกเลี่ยงการคืน [FLT: 41] สําหรับรหัสข้อผิดพลาด; จํานวนจํานวนเต็มที่เซ็นต์รับรองไว้ อนุญาตให้ค่าลบสําหรับข้อผิดพลาดได้
  • สําหรับระบบที่ซับซ้อนนี้ จงกําหนดรูปแบบการยกเว้นแบบเบา โดยใช้ / (แต่ใช้อย่างประหยัด ในขณะที่มันควบคุมการไหลได้ยากขึ้น).
  • บันทึกข้อผิดพลาดในระดับสูง และลดการรวมทรัพยากรที่สะอาด โดยใช้รูปแบบ (ดูเป็นระบบ) เพื่อหลีกเลี่ยงการล้างโค้ดซ้ํา

8. ทดสอบหน่วยแนะนํา

การ ทดสอบ โดย ไม่ มี การ ทดสอบ การ สร้าง ภูมิ คุ้ม กัน นั้น น่า กลัว.

  • [FLT: 0] Unitity - เบา อุดมคติสําหรับระบบฝังตัว (FLT:1).
  • [FLT: 0]. ค.ค็อคกา – รวมการเยาะเย้ยการสนับสนุนสําหรับโมดูลแยกเดี่ยว.
  • CAUIT - แบบดั้งเดิมแต่ใช้ได้

เขียนการทดสอบหน่วยสําหรับโมดูลที่ได้รับผลทดสอบแต่ละตัว ใช้การพัฒนาแบบทดสอบ (TDD) ที่มีประสิทธิภาพ: เขียนการทดสอบที่กําหนดพฤติกรรมที่ต้องการ แล้วทําอีกครั้งจนกว่าการทดสอบจะผ่านไป การทดสอบการรับข้อมูลภายในระบบนั้นควรจะดําเนินการทั้งระบบด้วยค่าป้อนข้อมูล และคาดว่าจะมีผลการทดสอบอัตโนมัติทั้งหมดในสภาพแวดล้อม CI เพื่อจับความถดถอยทันที

9 การ พิจารณา อย่าง ละเอียด

การปรับเปลี่ยนบ่อยครั้งที่จะช่วยให้มีประสิทธิภาพดีขึ้น แต่มันยังสามารถแนะนําค่าประกอบการ (เช่น ฟังก์ชันอื่น ๆ เรียกค่า, ค่าจัดอันดับหน่วยความจําที่มากกว่า, ค่าโพรไฟล์ก่อนและหลังการเปลี่ยนรูปแบบเช่น [FLT: 45], , หรือค่า XCode ได้เพิ่มค่านิยมของเส้นทางที่นิยมใช้บนเส้นทางที่ร้อน, เปิดใช้งานฟังก์ชันที่ปรับแต่งให้ทันสมัย (FLT: 47) หรือ[FT: 48] และเครื่องหมาย สถาปัตยกรรม (FT: F.C]. แทนที่ด้วยแพลตฟอร์มแบบรวมเข้ากับคอมโพเนชันแบบมาตรฐาน หรือแบบมาตรฐาน (FT: FT: 49). รองรับเมื่อมีการใช้งานมาตรฐาน --

การ ตรวจ สอบ และ การ ตรวจ สอบ

กลยุทธ์ ใน การ ทดสอบ ระยะ ยาว เป็น เรื่อง สําคัญ เมื่อ ทํา รหัส มรดก ที่ ได้ รับ การ ยกย่อง.

  1. [FLT: 0] การทดสอบความถดถอย - เรียกใช้ห้องทดสอบที่มีอยู่ (ถ้ามี) ก่อนจะทําการเปลี่ยนแปลงเพื่อสร้างพื้นฐาน หากไม่มีการทดสอบ ให้เขียนการทดสอบควันที่ออกกําลังกายหลัก
  2. [FLT: 0] การตรวจสอบความถูกต้องเชิงรุก – ชดเชย 1 มอดูล แต่ละครั้ง หลังจากเปลี่ยนแต่ละช่วง จะรวมเข้ากับธงที่เข้มงวดและทํางานหน่วย (เช่น Guit) ด้วยขนาดเล็ก ปฏิสสาร apprition เพื่อที่คุณจะได้ย้อนกลับได้อย่างง่ายดาย
  3. [FLT: 0] การรวมการวิเคราะห์แบบสตวิ ทําหน้าที่ – เพิ่ม Cpp check and Clang-tidi to CI PTlor. ปฏิบัติต่อคําเตือนเป็นข้อผิดพลาดเพื่อบังคับใช้คุณภาพ.
  4. [FLT: 0] วิเคราะห์เชิงลึก – ดําเนินการภายใต้ Valgrind หรือ Asan ระหว่างคืนสร้างการตรวจสอบปัญหาความจําแนะนําโดยสร้างใหม่ (พ.ศ.
  5. [FLT: 0] การทดสอบการรับผู้ใช้งาน - การลดระบบการรับสัญญาณไปยังสภาพแวดล้อมการตกแต่งและมีผู้เชี่ยวชาญในโดเมนทําการทดสอบผลสุดท้ายต่อปลาย. เทียบการวางจําหน่าย, เวลา และการใช้ทรัพยากรกับระบบเดิม

การปรับค่าขั้นเหล่านี้อัตโนมัติด้วยเซิร์ฟเวอร์ CI (การปฏิบัติการของ GitHub, Jenkin, GitLab CI) ลดค่าหัวด้วยตนเอง และสร้างความมั่นใจในกระบวนการสร้างหลอดเลือด

รูปแบบการวน

การหาพิกัดรหัส C ไม่ได้เป็นโครง คุณใช้รหัสที่เป็นมรดกแบบเดียว แต่เป็นการบังคับอย่างต่อเนื่อง โดยดําเนินการตรวจสอบอย่างละเอียด