30 คะแนน โดย GN⁺ 2025-12-09 | 8 ความคิดเห็น | แชร์ทาง WhatsApp
  • วิดีโอที่อธิบายว่าเหตุใด ซอฟต์แวร์เครื่องบินขับไล่และจรวด ที่ทำงานด้วยความเร็วระดับมัค 1 ซึ่ง บั๊กเพียงบรรทัดเดียวอาจนำไปสู่ผลลัพธ์ร้ายแรง จึงตัดฟีเจอร์ส่วนใหญ่ของ C++ ออกไป เหลือไว้เฉพาะโค้ดที่คาดการณ์พฤติกรรมได้
  • สรุปประวัติของสงครามภาษาสำหรับงานทหารและการพองตัวของโค้ด ตั้งแต่คอมพิวเตอร์ทิ้งระเบิดแบบกลไกของ F-4, ไมโครโปรเซสเซอร์ลับของ F-14 ไปจนถึง Jovial·CMS-2·Ada ซึ่งนำไปสู่ความจำเป็นของภาษาความปลอดภัยแบบเดียวและมาตรฐานที่เข้มงวด
  • สาธิตด้วยโค้ดจริงว่า มาตรฐาน JSF C++ ที่ Lockheed สร้างขึ้นเพื่อโน้มน้าวให้ใช้ C++ แทน Ada ในโครงการพัฒนา F-35 สั่งห้าม exception, recursion และ dynamic memory allocation และแทนที่ด้วย return code, ลูปวนซ้ำ และการจองหน่วยความจำล่วงหน้าอย่างไร
  • พร้อมทั้งอธิบายว่ามิชชันคอมพิวเตอร์ F-35 รุ่นแรกใช้ สถาปัตยกรรมตระกูล PowerPC และเปรียบเทียบให้เห็นผ่านการเชื่อม X-Plane 12 กับ MFD ที่สร้างเองว่า โค้ดที่ละเมิดกฎ JSF กับโค้ดที่ทำตามกฎให้ผลต่างกันอย่างไรระหว่างการบินจริง
  • สรุปว่าในเวลาต่อมา มาตรฐาน JSF ได้ส่งอิทธิพลต่อมาตรฐานความปลอดภัยอย่าง NASA F-Prime·MISRA·AutoSAR และปัจจุบันแนวทางที่เหมาะสมกว่าคือการใช้ C++ Core Guidelines และ Modern C++ บนมรดกดังกล่าว

แนะนำผู้บรรยาย

  • นักพัฒนาที่เคยเขียนโค้ด C++ สำหรับระบบอากาศยานและอวกาศ พร้อมมีประสบการณ์ สาธิตให้กองทัพอากาศ
    • อธิบายโดยอิงจากประสบการณ์จริงในการใช้ C++ กับระบบที่มีข้อกำหนดด้านความปลอดภัยสูง
    • ใช้ MFD (จอแสดงผลอเนกประสงค์) ที่สร้างขึ้นเองเป็นสภาพแวดล้อมเดโม โดยประกอบด้วย X-Plane 12, Web API, Python UI และ C++ backend

ซอฟต์แวร์การบินกับสภาพแวดล้อมที่ความล้มเหลวไม่อาจยอมรับได้

  • ในแอปพลิเคชันทั่วไป การแครชมักจบลงที่การรีสตาร์ต แต่สำหรับ เครื่องบินขับไล่และจรวดระดับมัค 1 ความล้มเหลวเพียงครั้งเดียวอาจกลายเป็นหายนะได้ทันที
    • ประโยค “ที่มัค 1 ไม่มีเวลารอ garbage collector” ถูกยกมาเพื่อเน้นความต้องการด้านเรียลไทม์
    • ในสถานการณ์ที่โค้ดผิดเพียงบรรทัดเดียวอาจนำไปสู่ผลลัพธ์ถึงชีวิต การเลือกใช้ฟีเจอร์ของภาษาจึงต้องทำหน้าที่เป็นกลไกป้องกันความปลอดภัยด้วย
  • ยกเหตุการณ์ Ariane 5 ระเบิดในปี 1996 เป็นกรณีตัวแทน
    • เกิด exception ระหว่างการแปลงค่าความเอนเอียงแนวนอนแบบ floating point 64 บิตเป็นจำนวนเต็ม 16 บิต และ exception นี้ไม่ได้รับการจัดการ
    • ภาษาทำงานตามสเปกโดยรายงานข้อผิดพลาด แต่ระบบไม่สามารถจัดการ exception นั้นได้ จึงนำไปสู่ผลลัพธ์คือ จรวดมูลค่าราว 500 ล้านดอลลาร์ถูกทำลายในทันที
  • จากกรณีนี้ ทีมออกแบบ F-35 จึงเลือกแนวทาง ตัดฟีเจอร์ของภาษาออกไปตั้งแต่ต้น เพื่อไม่ให้ทำผิดซ้ำแบบเดิม

ประวัติซอฟต์แวร์ทางทหารและสงครามภาษา

  • ในยุคของเครื่องบินขับไล่รุ่นแรกอย่าง F-4 Phantom แทบจะยังไม่มีซอฟต์แวร์จริงจัง
    • คอมพิวเตอร์ทิ้งระเบิดเป็นอุปกรณ์กลไกความแม่นยำสูงที่ประกอบด้วยเฟืองและลูกเบี้ยว และ “โค้ด” ก็คือรูปร่างของลูกเบี้ยวโลหะนั่นเอง
  • สถานการณ์เปลี่ยนไปในโครงการลับเครื่องบินครองอากาศของกองทัพเรือ VFX (F-14 Tomcat)
    • ภายหลังมีการเปิดเผยว่า Garrett AiResearch ได้ออกแบบไมโครโปรเซสเซอร์สำหรับ F-14 ตั้งแต่ก่อน Intel 4004 ซึ่งมักถูกสอนว่าเป็น “ไมโครโปรเซสเซอร์ตัวแรก”
    • เพื่อควบคุมปีกปรับองศาได้ของ F-14 ให้เหมาะสมที่สุด จำเป็นต้องใช้ไมโครโปรเซสเซอร์ประสิทธิภาพสูง และมีการบรรจุ ไมโครโค้ดราว 2500 บรรทัด เพื่อคำนวณพหุนาม
  • ต่อมาแต่ละเหล่าทัพเลือกใช้คนละภาษา ทำให้เกิด ความยุ่งเหยิงของภาษา
    • กองทัพอากาศใช้ Jovial (Jules Own Version of the International Algorithmic Language) ซึ่งอยู่ในสายตระกูล ALGOL
    • กองทัพเรือไม่ต้องการใช้ภาษาของกองทัพอากาศ จึงเลือก CMS-2 สำหรับ F-18
    • เมื่อใช้ภาษาและสถาปัตยกรรมฮาร์ดแวร์ต่างกัน การนำโค้ดกลับมาใช้ซ้ำและการตรวจสอบยืนยันจึงแทบเป็นไปไม่ได้
  • ขณะเดียวกัน ขนาดซอฟต์แวร์ต่อเครื่องบินก็ เพิ่มขึ้นแบบทวีคูณ
    • มีการยกตัวเลขตัวอย่างว่า F-16A มีราว 125,000 บรรทัด, B-1 ราว 1 ล้านบรรทัด และ F-35 ยุคปัจจุบันราว 9 ล้านบรรทัด
    • รายงานจากกระทรวงกลาโหมยังระบุว่ามีการใช้งาน ภาษาโปรแกรมมากกว่า 450 ภาษา และแทบไม่มีภาษาที่มีมาตรฐานเหมาะสมอย่างแท้จริง

การบังคับใช้ Ada และข้อจำกัดของมัน

  • เพื่อแก้ปัญหาความแตกกระจายนี้ กระทรวงกลาโหมจึงสร้างภาษา Ada ขึ้นเป็นภาษาระดับสูงเพียงภาษาเดียว และบังคับใช้อย่างเข้มงวด
    • หากโครงการใหม่ไม่ต้องการใช้ Ada จะต้อง พิสูจน์ให้ได้ว่าเหตุใด Ada จึงทำไม่ได้ มิฉะนั้นก็ ไม่สามารถชนะสัญญาโครงการ ได้
  • Ada ถูกนำเสนอว่าเป็นภาษาที่เหมาะมากกับงานด้านความปลอดภัยและความน่าเชื่อถือ
    • มีการเน้นว่า Ada ถูกออกแบบมาเพื่อรับประกันความปลอดภัยของหน่วยความจำและชนิดข้อมูลในระบบวิกฤตต่อความปลอดภัยอย่างงานอากาศยานและอวกาศ
  • แต่พอเข้าสู่ยุค 90 ก็เริ่มเห็นว่า ไม่สอดคล้องกับโลกความจริง
    • อีกด้านหนึ่ง โลกกำลังถูกขับเคลื่อนด้วยอินเทอร์เน็ต, Windows 95 และเกมเชิงพาณิชย์ที่สร้างด้วย C++
    • นักศึกษาและนักพัฒนาจึงไหลไปหา GCC ฟรีและ C++ อย่างเป็นธรรมชาติ แทน Ada compiler ราคาแพง
    • Ada compiler มีราคาหลายพันดอลลาร์ ทำให้คนทั่วไปเข้าถึงได้ยาก และส่งผลให้จำนวนบุคลากรที่เชี่ยวชาญ Ada ลดลงตามไปด้วย

F-35 และการถือกำเนิดของมาตรฐาน JSF C++

  • F-35 (Joint Strike Fighter) ถูกออกแบบมาตั้งแต่แรกให้เป็นอากาศยานที่พึ่งพาซอฟต์แวร์อย่างมาก
    • การคำนวณซับซ้อนอย่าง sensor fusion กลายเป็นหัวใจสำคัญของการใช้งานเครื่อง
  • Lockheed Martin จึงเสนอให้กระทรวงกลาโหม อนุญาตให้ใช้ C++ สำหรับความต้องการลักษณะนี้
    • นี่แทบจะเป็นการขอให้ผ่อนคลายนโยบายบังคับใช้ Ada เดิม และหากจะโน้มน้าวให้ยอมรับ ก็จำเป็นต้องมีวิธีควบคุมความเสี่ยงของ C++
  • มีการกล่าวถึงว่า Bjarne Stroustrup ผู้สร้าง C++ ก็เข้ามามีบทบาทเป็นที่ปรึกษาในการออกแบบกฎ JSF C++ ด้วย
    • เขาระบุเองว่าได้มีส่วนช่วยเขียนกฎ JSF โดยตรง และยอมรับด้วยว่าตนเองอาจ “มีอคติ” ต่อมาตรฐานนี้
  • แนวคิดหลักคือการมองแบบเดียวกับป้าย “remove before flight”
    • เช่นเดียวกับป้ายที่ต้องถอดออกก่อนบิน ฟีเจอร์อันตรายใน C++ ก็ถูกถอดทิ้งในระดับภาษา เหลือเพียง subset ที่คาดการณ์ได้
    • วิธีนี้ทำให้ได้ความปลอดภัยระดับใกล้เคียง Ada ขณะเดียวกันนักพัฒนาก็ยังใช้พลังการแสดงออกของ C++ ได้บางส่วน

ฮาร์ดแวร์จริงและการเปรียบเทียบกับ GameCube

  • F-35 รุ่นบล็อกแรก ๆ ใช้ มิชชันคอมพิวเตอร์ที่อิงกับโปรเซสเซอร์ Motorola G4 PowerPC
    • ข้อมูลนี้เปิดเผยในบทความของ Aviation Today ปี 2003 เป็นต้น
  • GameCube เองก็ใช้โปรเซสเซอร์ตระกูล PowerPC เช่นกัน จึงน่าสนใจในแง่ที่เป็น ฮาร์ดแวร์คนละผลิตภัณฑ์แต่มีระดับชุดคำสั่งใกล้เคียงกัน
    • แม้หากต้องการเทียบรุ่นให้ตรงยิ่งขึ้นอาจมีคอนโซลอื่นที่ใกล้กว่า แต่การยก GameCube มาเปรียบก็เพียงพอสำหรับทำความเข้าใจหลักการ

สภาพแวดล้อมเดโม JSF C++: X-Plane 12 + MFD

  • มีการสร้าง สภาพแวดล้อมจำลองการบิน บนพื้นฐานของ X-Plane 12 โดยใช้ F-35B add-on (AOA Simulations)
    • โครงสร้างคือ subscribe ข้อมูลการบินแบบเรียลไทม์ผ่าน Web API ใหม่ของ X-Plane แล้วนำไปแสดงบน MFD
  • ฝั่ง frontend เขียนด้วย Python ส่วน backend เป็นปลั๊กอิน C++ ที่ใช้สำหรับสาธิตเปรียบเทียบโค้ดที่ทำตามหรือฝ่าฝืนกฎ JSF
    • แสดงข้อมูลอย่างระดับความสูง ความเร็ว ลม ขอบเขตการบิน และข้อมูลนำร่องต่าง ๆ จากผลการคำนวณของ C++
  • ระหว่างการบิน มีการรัน โค้ด C++ แบบนอกมาตรฐานที่จงใจ throw exception เพื่อแสดงให้เห็นว่า MFD ดับและการบินมีปัญหา จากนั้นจึงค่อย ๆ แก้ด้วยกฎ JSF

ข้อจำกัดหลัก 3 ข้อของ JSF: exception, recursion, dynamic memory

  • ข้อจำกัดสำคัญ 3 ข้อที่มาตรฐาน JSF C++ เน้นคือ exception, recursion และ dynamic memory allocation
    • นอกจากนี้ยังมีการกำหนดเพดานของ Cyclomatic Complexity (ความซับซ้อนเชิงกิ่งก้าน) ของฟังก์ชันด้วย

1) ห้าม exception – AV Rule 208

  • JSF AV Rule 208: “ห้ามใช้ exception (exceptions shall not be used)”
    • คีย์เวิร์ดที่เกี่ยวข้องกับ exception เช่น try, catch, throw ถูกห้ามทั้งหมด
  • เหตุผลหลักคือ ความไม่เป็นเชิงกำหนดของ control flow
    • เช่นในกรณี Ariane 5 เมื่อเกิด exception ขึ้น หากการจัดการตกหล่นหรือจังหวะเวลาไม่ตรง ระบบทั้งระบบอาจพังอย่างคาดเดาไม่ได้
  • แม้ Bjarne จะสนับสนุน exception handling ของ Modern C++ แต่เขาอธิบายว่าในช่วงที่ JSF ถูกออกแบบนั้น ความพร้อมของเครื่องมือและปัญหาการรับประกันเรียลไทม์ ยังทำให้ไม่สามารถรองรับ exception ได้

    “JSF++ มีไว้สำหรับแอปพลิเคชัน hard real-time และวิกฤตต่อความปลอดภัย (การควบคุมการบิน) ดังนั้นถ้าการคำนวณใช้เวลานานเกินไป คนอาจตายได้ และคุณไม่สามารถรับประกันเวลาในการตอบสนองด้วย exception ได้”

  • ใน JSF ใช้ return code แทน exception
    • ในตัวอย่างการคำนวณ density altitude จะกำหนด return code คนละค่าให้แต่ละเงื่อนไขผิดพลาด แล้วให้ผู้เรียกตีความและจัดการต่อ
    • ต่อให้การคำนวณล้มเหลวหรือหมดเวลา โปรแกรมทั้งหมดก็ไม่พัง และฝั่งที่เรียกใช้ยังสามารถแสดง “สถานะผิดพลาด” ได้อย่างปลอดภัย

2) ห้าม recursion – AV Rule 119

  • AV Rule 119 ห้ามฟังก์ชัน เรียกตัวเองไม่ว่าทางตรงหรือทางอ้อม หรือก็คือ recursion
    • เพราะทุกครั้งที่ recursive call เกิดขึ้น จะมี stack frame ใหม่ถูกสร้าง และมักยากจะรู้ขีดจำกัดสูงสุดของความลึก จึงเพิ่มความเสี่ยงต่อ stack overflow
  • ยกตัวอย่าง สัมประสิทธิ์ทวินาม (binomial coefficient) ที่ใช้ในการคำนวณสนามบินสำรองระหว่างการวางแผนการบิน
    • เวอร์ชันนอกมาตรฐานใช้ recursion ในรูป C(n, k) = C(n-1, k-1) + C(n-1, k)
    • ปัญหาคือความลึกของการเรียกขึ้นกับอินพุต ทำให้คาดการณ์ขีดจำกัดหน่วยความจำได้ยาก
  • เวอร์ชันที่สอดคล้องกับ JSF จึงเปลี่ยนการคำนวณเดียวกันให้เป็น การเขียนแบบ iterative ด้วยลูป
    • แม้โค้ดจะยาวกว่าและไม่สง่างามเท่า แต่เพราะไม่ได้เรียกตัวเอง จึงให้ผลลัพธ์เดียวกันได้โดยไม่ใช้ recursion
    • ทำให้อนุมานความลึกของการเรียกฟังก์ชันและขีดจำกัดการใช้หน่วยความจำแบบสถิตได้ง่ายขึ้น

3) ห้าม dynamic memory allocation – AV Rule 206

  • AV Rule 206: หลังการเริ่มต้นระบบแล้ว ห้าม allocate หรือ deallocate หน่วยความจำ
    • ระหว่างรันไทม์ห้ามใช้การจัดสรรบน heap เช่น new, delete หรือแม้แต่ new ภายในที่เกิดผ่าน smart pointer
  • เหตุผลมีอยู่ 2 ประเด็นหลัก
    • การจัดสรรบน heap มี ความไม่เป็นเชิงกำหนดด้านเวลา เพราะไม่มีใครรู้แน่ว่าจะใช้เวลานานเท่าไร
    • หาก heap เกิด fragmentation ต่อให้ยังมีความจุรวมเหลืออยู่ ก็อาจหา block ต่อเนื่องขนาดใหญ่พอไม่เจอและทำให้ allocation ล้มเหลว
  • ตัวอย่างที่ยกมาคือโค้ดนอกมาตรฐานที่สร้าง บัฟเฟอร์ประวัติ IAS (indicated airspeed) สำหรับคำนวณ gust โดยใช้ std::unique_ptr + อาร์เรย์แบบ dynamic
    • รูปแบบนี้ละเมิดกฎ JSF เพราะมีการจัดสรรอาร์เรย์ใหม่ระหว่างรันไทม์
  • ในเวอร์ชันที่สอดคล้องกับ JSF จะเปลี่ยนไปใช้ อาร์เรย์ขนาดคงที่ที่กำหนดขนาดสูงสุดเป็นค่าคงที่
    • กำหนดค่าคงที่อย่าง MAX_IAS_HISTORY แล้วจองหน่วยความจำเพียงครั้งเดียวตอนเริ่มต้น จากนั้นหมุนใช้งานด้วยการเลื่อนดัชนี
    • วิธีนี้ทำให้ระหว่างรันไทม์ไม่เกิด allocation เพิ่มอีกเลย จึงคาดการณ์ได้ทั้งด้านเวลาและหน่วยความจำ

4) เพดาน Cyclomatic Complexity – AV Rule 3

  • AV Rule 3 กำหนดว่า Cyclomatic Complexity (ความซับซ้อนเชิงกิ่งก้าน) ของฟังก์ชันต้องไม่เกิน 20
    • ตัวประกาศฟังก์ชันเองนับ 1 คะแนน และ if, while, for, switch รวมถึงตรรกะ AND/OR ต่างก็เพิ่มความซับซ้อนอย่างละ 1
  • มีการใช้ตัวอย่าง implementation แบบ iterative ของสัมประสิทธิ์ทวินามเพื่อแสดงให้เห็นว่า if, การดำเนินการเชิงตรรกะ และลูป for แต่ละส่วนเพิ่มคะแนนความซับซ้อนอย่างไร
    • ยิ่งความซับซ้อนสูง การทดสอบ การตรวจสอบยืนยัน และการวิเคราะห์ก็ยิ่งยาก จึงเป็นเป้าหมายของมาตรฐานที่จะควบคุมให้อยู่ต่ำกว่าขีดจำกัดที่กำหนด

มรดกของ JSF: NASA F-Prime, MISRA, AutoSAR

  • แนวคิดของมาตรฐาน JSF C++ ได้แพร่ต่อไปยังงานด้านความปลอดภัยวิกฤตอื่น ๆ
    • เฟรมเวิร์กซอฟต์แวร์การบินของ NASA อย่าง F-Prime เปิดเผยในปี 2017 และใช้กฎคล้ายกัน เช่น ห้าม dynamic memory allocation, ห้าม exception, ห้าม recursion
  • อุตสาหกรรมยานยนต์ก็เดินไปในทิศทางคล้ายกัน
    • เกิดมาตรฐานอย่าง MISRA C++ และ AutoSAR (Automotive Open System Architecture) เพื่อกำหนดกฎความปลอดภัยสำหรับซอฟต์แวร์ยานยนต์
    • มีการกล่าวว่าแนวทาง AutoSAR C++14 อ้างอิง JSF อย่างชัดเจน แสดงให้เห็นว่าอิทธิพลของ JSF ขยายไปถึงซอฟต์แวร์รถยนต์ด้วย
  • เมื่อรถยนต์สมัยใหม่แทบจะเป็น “คอมพิวเตอร์ติดล้อ” subset ของภาษาและกฎการเขียนโค้ดเช่นนี้จึงกลายเป็นรากฐานสำคัญที่ค้ำจุนความปลอดภัย

บทสรุป: ถ้าวันนี้จะใช้ C++ ควรยึดอะไร

  • มาตรฐาน JSF C++ ถูกนำเสนอว่าเป็น ความสำเร็จเชิงวิศวกรรมที่ย่อภาษาซับซ้อนให้เหลือ subset ที่คาดการณ์ได้ เพื่อให้ได้ความปลอดภัยระดับการควบคุมการบินของเครื่องบินขับไล่ ตามมาตรฐานของยุคนั้น
  • ขณะเดียวกัน Bjarne Stroustrup ก็แนะนำให้นักพัฒนายุคปัจจุบันยึด C++ Core Guidelines และ Modern C++
    • เพราะทั้งภาษา C++ และ toolchain พัฒนามามากในช่วงหลายทศวรรษที่ผ่านมา และวันนี้ก็มีสภาพแวดล้อมที่เอื้อต่อการใช้ฟีเจอร์อย่าง exception และ smart pointer อย่างปลอดภัยมากขึ้นแล้ว
  • ถึงอย่างนั้น JSF ก็ยังคงเป็นตัวอย่างสำคัญของ วิธีคิดในการควบคุมภาษาโดยการ “ตัดออก” ไม่ใช่เพิ่มเข้าไป
    • ปิดท้ายด้วยสารสำคัญว่า สำหรับระบบวิกฤตต่อความปลอดภัย สิ่งสำคัญไม่ใช่แค่ว่าจะใส่อะไรเพิ่ม แต่คืออะไรบ้างที่ควรถูกใส่ไว้ในรายการ remove before flight

8 ความคิดเห็น

 
lostid 2025-12-10

อาจเป็นเพราะมีวัตถุประสงค์ทางการทหาร จึงลงเอยด้วยการใช้ C++ ซึ่งเป็นผลลัพธ์ของการหาสมดุลระหว่างสเปกฮาร์ดแวร์ที่ต่ำกับฟีเจอร์ขั้นสูงก็ได้

 
regentag 2025-12-10
  1. Ada มีคอมไพเลอร์โอเพนซอร์สชื่อ GNAT ที่พัฒนาบนพื้นฐานของ gcc ปัจจุบันก็มี gnat-llvm ที่พัฒนาบนพื้นฐานของ llvm ด้วย และยังมี IDE โอเพนซอร์สให้ใช้อีกด้วย

นักเรียนกับนักพัฒนาไม่ได้เรียนเพราะมันเป็นภาษาของกระทรวงกลาโหมและมีความต้องการใช้น้อย ไม่ใช่เพราะเครื่องมือมีราคาแพงน่าจะมากกว่าครับ

  1. ผมคิดว่าการใช้ Ada น่าจะตรงกับวัตถุประสงค์มากกว่าการใช้ Cpp แบบ "ควบคุม" โดยเฉพาะในงานที่เป็น Safety-Critical นั้น Cpp ดูเหมือนจะมีช่องให้พลาดได้มากเกินไปครับ
 
iepics 2025-12-10
  1. สถานการณ์ในตอนที่พัฒนาอาจแตกต่างออกไปก็ได้ครับ
 
m00nny 2025-12-09

โดยรวมแล้วเป็นเนื้อหาเกี่ยวกับแนวทางการเขียนโค้ดให้มีพฤติกรรมที่คาดการณ์ได้
แม้จะยก C++ มาเป็นกรณีศึกษา แต่ประเด็นเดียวกันนี้ก็ใช้ได้กับส่วนที่เป็นปัญหามากกว่าในภาษาอื่นอย่าง GC ด้วย จึงน่าเสียดายที่อาจทำให้เข้าใจได้เหมือนกำลังพูดถึงข้อจำกัดของ C++
ถ้าจะไม่ใช้เทคนิคอย่างการจัดสรรหน่วยความจำแบบไดนามิกหรือการจัดการข้อยกเว้นของ C++ ก็ยังคงมีคำถามค้างอยู่ว่า ใช้ C แล้วเขียนตามหลักการข้างต้นน่าจะทั้งง่ายและเร็วกว่าไม่ใช่หรือ

 
ndrgrd 2025-12-09

จริงด้วยนะครับ ผมก็ไม่แน่ใจว่าเพราะอะไรถึงใช้ C++ แทนที่จะเป็น C

 
tsboard 2025-12-09

C++ สมัยใหม่มีความเสถียรมากจริง ๆ แต่ถ้าไม่จำเป็นต้องเป็น C++ โดยเฉพาะ ก็น่าจะคุ้มที่จะพิจารณาภาษาอื่นที่เสถียรกว่า

 
coremaker 2025-12-09

มาใช้ไวยากรณ์ของ RUST แบบ STRICT กันเถอะ!

 
GN⁺ 2025-12-09
ความคิดเห็นจาก Hacker News
  • เอกสารมาตรฐานการเขียนโค้ด C++ ของ F-35 อยู่ที่นี่
    ยาว 142 หน้า และทำให้เห็นข้อจำกัดที่มีอยู่จริงในการพัฒนาซอฟต์แวร์สำหรับอากาศยาน
    • ลองไล่อ่านผ่าน ๆ ไปไม่กี่บทแล้ว ดูเป็นกฎที่สมเหตุสมผลพอควร
      แต่ก็สงสัยเรื่องข้อยกเว้นของกฎประเภท “shall” อยู่เหมือนกัน ในโปรเจ็กต์ขนาดใหญ่นี้ เคสยกเว้นต่างหากที่แสดงให้เห็นว่ามาตรฐานใช้งานได้จริงแค่ไหน
    • ในระบบเรียลไทม์มีกฎว่า ห้ามจัดสรรหน่วยความจำแบบไดนามิกระหว่างการทำงาน
      สำหรับปี 2005 น่าจะโอเค แต่ก็สงสัยว่าจะเอาไปใช้กับสภาพแวดล้อมอย่าง โดรนที่ขับเคลื่อนด้วย AI ในปัจจุบันได้อย่างไร
    • สงสัยว่ากฎพวกนี้บังคับใช้ผ่านเครื่องมือวิเคราะห์สแตติกหรือเปล่า หรือว่านักพัฒนาต้องจำและทำตามกันเอง
    • กำลังคิดว่ากฎแบบนี้ยังใช้ได้กับซอฟต์แวร์สำหรับอุปกรณ์ฝังตัวหรืออุปกรณ์สเปกต่ำหรือไม่
      โดยเฉพาะข้อห้าม stdio.h นี่ดูแปลก แต่พออ่านไปก็รู้สึกว่า “อืม ก็มีเหตุผลนะ”
    • ตอนเห็นเอกสารนี้ครั้งแรก มีคนยกตัวอย่างว่า “C++ สำหรับ Arduino Uno ก็ยังคงเป็น C++ อยู่ดี”
  • ทำให้นึกถึงโค้ดอย่าง a = a; ที่เคยเห็นในโค้ด MISRA
    มันเป็นลูกเล่นเพื่อไม่ให้ลบพารามิเตอร์ที่ไม่ได้ใช้ออกไป แต่ก็ไม่แน่ใจว่ากฎแบบนี้รับประกันคุณภาพโค้ดที่ดีได้จริงหรือไม่
    • ถ้าดูงานวิจัยเกี่ยวกับ MISRA จะพบว่าบางกฎช่วยลดบั๊ก แต่บางกฎกลับเพิ่มบั๊ก
      แนวทาง JSF เป็นเอกสารจากปี 2005 จึงมีข้อจำกัดตามยุคสมัย
      ที่ Bjarne Stroustrup เพิ่งเสนอแนวคิดเรื่อง “C++ profiles” ก็น่าสนใจ
      ท้ายที่สุดแล้ว style guide แบบนี้อาจเป็นเรื่องของรสนิยมด้านความงามก็ได้
    • ใน C ถ้าต้องการแค่อ้างถึงตัวแปร วิธีมาตรฐานคือใช้ (void)a;
    • เคยเขียนโค้ดที่มีความสำคัญต่อความปลอดภัยอยู่มากพอสมควร และหลายครั้งกฎการเขียนโค้ดกลับทำให้คุณภาพโดยรวมแย่ลง
      สิ่งที่รับประกันความปลอดภัยจริง ๆ คือ คุณภาพของการออกแบบและโครงสร้าง fail-safe
    • ใน Zig ใช้ _ = a; เพื่อระบุอย่างชัดเจน
      มีประเด็นที่เกี่ยวข้องด้วย
    • มาตรฐานแบบนี้ไม่ได้มาแทนการรีวิวโค้ด
      แต่ทำหน้าที่เป็นเกณฑ์ร่วมกันสำหรับใช้อ้างอิงตอนรีวิวมากกว่า
  • ซอฟต์แวร์ดาวเทียมก็มีลักษณะคล้ายกัน โดยห้ามใช้ STL
    แก่นสำคัญคือ mission assurance
    ถ้าใช้สแตกหรือฮีป ที่อยู่หน่วยความจำของตัวแปรจะเปลี่ยนไป และถ้าเซลล์บางจุดเสียก็จะเกิดปัญหา
    หากตัวแปรทั้งหมดมีที่อยู่คงที่ ก็สามารถย้ายเฉพาะเซลล์ที่เสียด้วยแพตช์แล้วให้ภารกิจทำงานต่อได้
    • แต่ใน C++ จะไม่ใช้สแตกเลยนั้นเป็นไปไม่ได้
      ตัวแปรภายในฟังก์ชัน พารามิเตอร์ และที่อยู่สำหรับคืนค่าล้วนต้องใช้สแตกอยู่ดี
      การเรียกซ้ำก็จะทำไม่ได้ และตัวแปรชั่วคราวก็ถูกจำกัด
      เพราะงั้นข้ออ้างนี้จึงไม่สมจริง
    • ถ้าเทียบกับแนวทางแบบแมนนวลนี้ วิธีอัตโนมัติอย่าง หน่วยความจำ ECC หรือ การเข้ารหัส Reed-Solomon ดูมีประสิทธิภาพกว่า
    • ถ้าอย่างนั้นคือต้องเก็บตัวแปรไว้เป็นโกลบอลหรือ? แล้วตรวจจับข้อผิดพลาดของเซลล์หน่วยความจำกันอย่างไร
    • ในทางปฏิบัติก็ยังใช้สแตกอยู่ ฮีปอาจถูกจำกัดแต่ใช้ memory pool แทน
      เราอาจกำหนดช่วงที่อยู่ของสแตกและฮีปให้คงที่ได้ แต่ก็ยังไม่แน่ใจว่านี่เป็นเหตุผลที่น่าเชื่อถือหรือไม่
    • ถ้าอย่างนั้นก็สงสัยว่าพารามิเตอร์ in/out ของฟังก์ชันจัดการกันอย่างไร
  • มีกฎว่า “ทุก if และ else if ต้องมี else หรือมีคอมเมนต์กำกับ”
    ฉันเองก็ชอบใส่ล็อกทำนองว่า “กรณีนี้ไม่ควรเกิดขึ้นเด็ดขาด”
    ในระบบขนาดใหญ่ การบันทึกเหตุการณ์กรณียกเว้นแบบนี้มีประโยชน์มากต่อการดีบัก
    • คำสั่ง match ของ Rust ดีในเรื่องนี้
      เพราะบังคับให้จัดการทุกกรณีอย่างชัดเจน และถ้ามีการเพิ่มค่า enum คอมไพเลอร์ก็จะเตือน
    • ฉันยังชอบเพิ่มแมโคร _STOP หรือ _CRASH เพื่อหยุดดีบักทันทีด้วย
      มันช่วยบังคับให้แก้ปัญหาตรงนั้นเดี๋ยวนั้น
  • มีบทความของหัวหน้าทีมวิศวกรรมที่อธิบายว่าทำไมถึงเลือก C++ แทน Ada
    สรุปคือ “ขาดทั้งนักพัฒนา Ada และ toolchain”
    แต่ตอนนี้ดูเหมือนจะเปิดกว้างต่อ ความหลากหลายของภาษา มากขึ้น จึงรู้สึกว่า Ada อาจได้รับการยอมรับมากกว่าเดิม
    การที่ NVidia เลือกใช้ SPARK ก็ดูเหมือนเป็น สัญญาณการคืนชีพ ของ Ada
    • ฉันไม่ชอบตรรกะที่ว่า “นักพัฒนา Ada มีไม่พอ”
      ถ้า DoD บังคับใช้ Ada มหาวิทยาลัยและบริษัทก็คงปรับตาม
      สุดท้ายแล้ว ภาษาก็เรียนรู้กันได้ และถ้าใช้ Ada จริง ความน่าเชื่อถือของ F-35 ก็น่าจะสูงกว่านี้
    • ตอนนี้ก็ยังมีบริษัทที่ขายคอมไพเลอร์ Ada อยู่ถึง 7 แห่ง
      ได้แก่ AdaCore, GHS, PTC ApexAda, DDC-I, Irvine, OC Systems, RR Software
      ในอดีตคอมไพเลอร์ Ada มักเป็นตัวเลือกแบบเสียเงิน ขณะที่ C/C++ มาพร้อมให้ใช้เป็นค่าเริ่มต้น จึงทำให้มหาวิทยาลัยและบริษัทเลือก C++
      AdaCore มีส่วนช่วยอย่างมากต่อการทำมาตรฐาน ISO และการขยายตัวของโอเพนซอร์ส
    • ฉันเองก็หวังให้ Ada กลับมารุ่งเรืองอีกครั้ง
      เมื่อก่อนมันถูกวิจารณ์แรงเกินไป แต่ตอนนี้กลับรู้สึกว่ามันน่าสนใจทีเดียว
    • แต่พอได้ลองใช้ Ada จริง ๆ ก็ไม่ชอบไวยากรณ์ของมันนัก
      โครงสร้างไฟล์และแฟล็กการบิลด์ก็ค่อนข้างซับซ้อน และในอันดับภาษาของ RedMonkก็ไม่มี Ada
      บางฟีเจอร์ก็น่าสนใจ แต่ก็ยังไม่ใช่ประสบการณ์ภาษาแบบทันสมัยอย่าง Rust
  • เคยสงสัยว่าวงการ avionics ใช้ MISRA C/C++ กันหรือไม่
    • มาตรฐานการเขียนโค้ดเป็นแค่ส่วนหนึ่งเท่านั้น แกนหลักคือ การจัดทำเอกสารกระบวนการที่ตรวจสอบย้อนหลังได้
      กรอบการรับรองอย่าง DO-178C ต่างหากที่สำคัญ
    • แต่ละบริษัทก็ไม่เหมือนกัน บางที่ใช้ C ที่สร้างจาก Matlab/Simulink autocode ตรง ๆ
      ในทางหนึ่ง นี่อาจเป็นวิธีที่ ถูกต้องในการเขียนโค้ดความน่าเชื่อถือสูงก็ได้
    • แต่ละภูมิภาคก็แตกต่างกัน สหรัฐฯ ใช้มาตรฐาน MIL, ยุโรปใช้ ECSS, อากาศยานใช้ DO-178C และ MISRA ก็ถูกใช้อย่างแพร่หลาย
  • ช่อง YouTube ของ LaurieWired ยอดเยี่ยมมาก
    • โดยเฉพาะซีรีส์สอน ARM assemblyที่โดดเด่นมาก
  • ขอแนะนำวิดีโออื่น ๆ ของ Laurie ด้วย
    ครอบคลุมหัวข้อหลากหลายอย่าง reverse engineering, obfuscation, compiler และอีกมากมาย
  • พอเห็นกฎว่า “อย่า dereference null pointer” (AV Rule 174, MISRA Rule 107)
    ก็รู้สึกว่าเรื่องแบบนี้ยังต้องเขียนระบุไว้ด้วยหรือ
  • แล้วก็สงสัยว่าเวลา build โค้ด F-35 จริง ๆ ใช้คอมไพเลอร์ตัวไหน
    LM ทำขึ้นเองหรือใช้ผลิตภัณฑ์เชิงพาณิชย์กันแน่