ข้อเสนอสัญญาภาษา C Programming Language จุดประกายการถกเถียงเรื่องความปลอดภัยกับความเรียบง่าย

ทีมชุมชน BigGo
ข้อเสนอสัญญาภาษา C Programming Language จุดประกายการถกเถียงเรื่องความปลอดภัยกับความเรียบง่าย

ข้อเสนอใหม่ที่จะนำฟีเจอร์ contract programming มาสู่ภาษา C ได้จุดประกายการอภิปรายอย่างเข้มข้นในชุมชนโปรแกรมเมอร์ ข้อเสนอนี้ซึ่งได้รับแรงบันดาลใจจากงาน contracts ที่กำลังดำเนินการอยู่ใน C++ มีเป้าหมายเพิ่ม preconditions และ postconditions ให้กับฟังก์ชัน C แต่นักพัฒนาแบ่งฝ่ายกันอย่างชัดเจนว่าการเพิ่มเติมดังกล่าวจะช่วยหรือทำร้ายภาษานี้

Contract Primitives ที่เสนอสำหรับ C:

  • contract_assert(COND, "message") - คล้ายกับ assert ที่มีอยู่แต่ทำงานอยู่เสมอ (ไม่มี NDEBUG)
  • contract_assume(COND, "message") - ใช้ undefined behavior ผ่าน unreachable() เพื่อการปรับปรุงประสิทธิภาพ
  • Preconditions: require: (condition) - ตรวจสอบเมื่อเข้าสู่ฟังก์ชัน
  • Postconditions: ตรวจสอบเมื่อฟังก์ชันส่งค่ากลับ

ชุมชนแตกแยกเรื่องปรัชญาการพัฒนาภาษา

ข้อเสนอนี้ได้เปิดเผยความแตกแยกพื้นฐานในชุมชน C programming เกี่ยวกับทิศทางอนาคตของภาษา นักพัฒนาบางคนโต้แย้งว่า C ต้องพัฒนาเพื่อให้ยังคงมีความเกี่ยวข้องในยุคที่ภาษาที่ปลอดภัยต่อหน่วยความจำอย่าง Rust กำลังได้รับความนิยม พวกเขาชี้ให้เห็นว่าภาษาอื่นๆ ได้พัฒนาสำเร็จในขณะที่ยังคงรักษาอัตลักษณ์หลักไว้

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

ความกังวลของชุมชน:

  • ความปลอดภัย: พฤติกรรมที่ไม่ได้กำหนดไว้เมื่อสัญญาล้มเหลว เทียบกับการจัดการข้อผิดพลาดที่คาดเดาได้
  • ความซับซ้อน: ความเสี่ยงที่ C จะกลายเป็นภาษาที่ซับซ้อนเหมือน C++ สมัยใหม่
  • การพัฒนา: มี compiler C++ คุณภาพดีเพียง 3 ตัว เทียบกับ compiler C หลายร้อยตัว
  • ปรัชญา: วิวัฒนาการของภาษา เทียบกับการรักษาความเรียบง่ายแบบดั้งเดิมของ C

ข้อกังวลทางเทคนิคเกี่ยวกับความปลอดภัยในการนำไปใช้

ระบบ contract ที่เสนอมานั้นพึ่งพา undefined behavior อย่างมากผ่าน macro unreachable() ใหม่ใน C23 เมื่อสมมติฐานของ contract ล้มเหลว มันจะทริกเกอร์ undefined behavior ซึ่งช่วยให้คอมไพเลอร์ปรับแต่งโค้ดได้ แต่สร้างความเสี่ยงด้านความปลอดภัยที่อาจเกิดขึ้น นักวิจารณ์โต้แย้งว่าแนวทางนี้แทนที่การจัดการข้อผิดพลาดที่คาดเดาได้ด้วยการทำลายโปรแกรมที่คาดเดาไม่ได้

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

คุณสมบัติ C23/อนาคตที่จำเป็น:

  • คำสั่ง defer พร้อม defer_return_value สำหรับเงื่อนไขหลังการดำเนินการ
  • ตัวดำเนินการ typeof สำหรับการคัดลอกต้นแบบฟังก์ชัน
  • มาโคร unreachable() สำหรับการปรับปรุงประสิทธิภาพพฤติกรรมที่ไม่ได้กำหนด
  • การสนับสนุน function inlining สำหรับการจัดวาง contract

การถกเถียงระหว่าง Panic กับการจัดการข้อผิดพลาด

จุดขัดแย้งหลักอยู่ที่ปรัชญาการจัดการข้อผิดพลาด ระบบ contract แนะนำพฤติกรรมคล้าย panic เข้ามาใน C ซึ่งการละเมิด contract จะทำให้โปรแกรมหยุดทำงานทันทีแทนที่จะส่งคืนรหัสข้อผิดพลาด นักวิจารณ์โต้แย้งว่าสิ่งนี้เอาการควบคุมออกจากนักพัฒนาที่อาจต้องการจัดการข้อผิดพลาดอย่างสง่างาม

คุณได้แนะนำ panic เข้ามาใน C แล้ว และ panics นั้นแย่ Panics เป็นเหมือนกับดักระเบิดที่รอสถานการณ์โชคร้ายบางอย่างเพื่อทำให้แอปของคุณขัดข้องอย่างไม่คาดคิด ซึ่งคุณไม่สามารถควบคุมได้เพราะการควบคุมการจัดการข้อผิดพลาดถูกแย่งไปจากคุณแล้ว

ผู้สนับสนุนโต้แย้งว่าการขัดข้องใกล้แหล่งที่มาของข้อผิดพลาดพร้อมข้อความที่ชัดเจนนั้นดีกว่าการขัดข้องจาก undefined behavior ที่ลึกลับซึ่งเกิดขึ้นช้ากว่ามากในการดำเนินการ

โซลูชันทางเลือกและเครื่องมือที่มีอยู่

สมาชิกชุมชนหลายคนได้ชี้ไปที่โซลูชันที่มีอยู่ซึ่งตอบสนองความต้องการที่คล้ายกันโดยไม่ต้องเปลี่ยนแปลงภาษา บางคนแนะนำว่า hygenic macros ที่เพิ่มเข้าไปใน header assert.h ที่มีอยู่สามารถให้ฟังก์ชันการทำงานส่วนใหญ่ที่ต้องการได้ คนอื่นๆ อ้างอิงเครื่องมืออย่างฟีเจอร์ bounds-safety ของ Clang หรือภาษาอย่าง Ada/SPARK ที่มีระบบ contract ที่เป็นผู้ใหญ่แล้ว

การอภิปรายยังเน้นให้เห็นว่า Digital Mars C++ ได้รวม contracts ไว้ตั้งแต่ต้นทศวรรษ 1990 ทำให้เกิดคำถามว่าทำไมฟีเจอร์ดังกล่าวจึงไม่ได้รับการยอมรับอย่างกว้างขวางในระบบนิเวศ C/C++ แม้จะมีมาหลายทศวรรษแล้ว

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

อ้างอิง: Contracts for C