ชุมชนโปรแกรมเมอร์กำลังมีการถกเถียงอย่างเข้มข้นเกี่ยวกับบทบาทของ C++ ในการพัฒนาซอฟต์แวร์สมัยใหม่ โดยเฉพาะในเรื่องความกังวลด้านความปลอดภัยและความซับซ้อนของภาษา ในขณะที่ผู้สนับสนุนโต้แย้งว่าภาษาอายุ 40 ปีนี้ยังคงทรงพลังและมีความเกี่ยวข้อง นักวิจารณ์ชี้ไปที่ปัญหาการออกแบบพื้นฐานที่ภาษาใหม่อย่าง Rust ได้แก้ไขได้อย่างมีประสิทธิภาพมากกว่า
ไทม์ไลน์และบริบทของ C++
- เปิดตัว: ปี 1985 (40 ปีของการพัฒนาอย่างต่อเนื่อง)
- มาตรฐานล่าสุด: C++20 (2020), C++23 (2023)
- เปรียบเทียบ: เก่ากว่า Windows 1.0 4 ปี เก่ากว่า Linux 6 ปี
- ภาษาเก่าแก่สำหรับอ้างอิง: COBOL (อายุ 66 ปี), Fortran (อายุ 68 ปี)
ความขัดแย้งของความซับซ้อน
นักพัฒนา C++ เผชิญกับความท้าทายที่เป็นเอกลักษณ์ซึ่งได้จุดประกายการถกเถียงอย่างมาก ภาษานี้เสนอหลายวิธีในการทำงานเดียวกัน สร้างสิ่งที่หลายคนมองว่าเป็นเส้นโค้งการเรียนรู้ที่ท่วมท้น การสนทนาในชุมชนเผยให้เห็นว่าแม้แต่โปรแกรมเมอร์ที่มีประสบการณ์ยังต่อสู้กับแนวคิดต่างๆ เช่น move semantics, template instantiation และวิธีการ initialization ต่างๆ ที่มีอยู่ใน C++ สมัยใหม่
ข้อสังเกตที่น่าสนใจอย่างหนึ่งจากชุมชนเน้นย้ำปัญหานี้: ทุกคนใช้เพียง 20% ของ C++ ปัญหาคือทุกคนใช้ 20% ที่ต่างกัน การแตกแยกนี้หมายความว่าแม้แต่นักพัฒนา C++ ที่มีประสบการณ์อาจพบว่าตัวเองไม่สามารถทำงานได้อย่างมีประสิทธิภาพกับ codebase ที่เขียนโดยเพื่อนร่วมงาน แม้ว่าทั้งสองฝ่ายจะคล่องแคล่วในภาษานี้ก็ตาม
สถานการณ์จะซับซ้อนมากขึ้นเมื่อทำงานกับไลบรารีและเฟรมเวิร์กที่มีอยู่ นักพัฒนามักไม่สามารถยึดติดกับ C++ ที่เรียบง่ายและอ่านง่ายได้เพราะพวกเขาต้องปรับตัวให้เข้ากับรูปแบบการเขียนโค้ดและ paradigm ที่เลือกโดยผู้เขียนไลบรารี สิ่งนี้เห็นได้ชัดเจนโดยเฉพาะในการพัฒนาเกมกับ engine อย่าง Unreal ซึ่งละทิ้ง standard library โดยสิ้นเชิงเพื่อใช้การ implementation แบบกำหนดเอง
ปัญหาด้านความปลอดภัยที่สำคัญที่ระบุได้
- ปัญหาความปลอดภัยของหน่วยความจำแม้จะมี smart pointers
- ปัญหา Lambda capture และ stack escape
- ไม่มีการตรวจสอบขอบเขตเริ่มต้นใน std::array
- ความซับซ้อนในการ debug template instantiation
- วิธีการ initialization หลายแบบที่สร้างความสับสน
- บั๊ก use-after-return ในฟีเจอร์ modern C++
ความกังวลด้านความปลอดภัยยังคงมีอยู่แม้จะมีฟีเจอร์สมัยใหม่
การถกเถียงเรื่องความปลอดภัยรอบๆ C++ ได้ทวีความรุนแรงขึ้นเมื่อทางเลือกที่ปลอดภัยจากหน่วยความจำได้รับความนิยมมากขึ้น ในขณะที่ผู้เขียนบทความโต้แย้งว่า smart pointer และฟีเจอร์ C++ สมัยใหม่สามารถทำให้ภาษาปลอดภัยขึ้นได้ ความคิดเห็นจากชุมชนชี้ให้เห็นว่าแนวทางนี้มีข้อจำกัดที่สำคัญ นักพัฒนารายงานว่าแม้จะมี smart pointer แล้ว รูปแบบทั่วไปอย่าง lambda capture ยังคงสามารถนำไปสู่ use-after-return bug ได้
ชุมชนได้ระบุหลายพื้นที่ที่ C++ ยังคงนำเสนอความท้าทายด้านความปลอดภัย ฟีเจอร์ standard library อย่าง std::array
ไม่ให้การตรวจสอบขอบเขตโดยค่าเริ่มต้น ต้องการให้นักพัฒนาเรียกใช้เมธอดพิเศษอย่างชัดเจนเพื่อความปลอดภัย ฟังก์ชัน Lambda สามารถ capture stack reference และหลุดออกจาก scope ของมัน นำไปสู่ bug ที่ละเอียดแต่อันตราย แม้แต่นักพัฒนาที่มีประสบการณ์ยอมรับว่าสร้างปัญหาความปลอดภัยของหน่วยความจำแม้จะพยายามอย่างดีที่สุดแล้ว
C++ มี developer experience ที่แย่มาก ตั้งแต่ syntax และไปจนถึง package management นักพัฒนา C++ รู้สึกติดอยู่กับยุคก่อนที่พวกเขาจะเกิด
คำถามเปรียบเทียบกับ Rust
การสนทนารอบๆ C++ หลีกเลี่ยงไม่ได้ที่จะเกี่ยวข้องกับการเปรียบเทียบกับ Rust โดยเฉพาะเรื่องความปลอดภัยของหน่วยความจำ ในขณะที่บางคนโต้แย้งว่าประโยชน์ของการ rewrite ด้วย Rust มาจากกระบวนการ rewrite เองมากกว่าการเลือกภาษา ความรู้สึกของชุมชนชี้ให้เห็นว่ามุมมองนี้ทำให้สถานการณ์เรียบง่ายเกินไป นักพัฒนาที่ทำงานกับทั้งสองภาษาสังเกตว่า compiler ของ Rust ป้องกันหมวดหมู่ทั้งหมดของ bug ที่ C++ อนุญาตให้ผ่านไปได้อย่างแข็งขัน
การถกเถียงขยายไปเกินกว่าแค่ความปลอดภัยของหน่วยความจำ ระบบ type และ ownership model ของ Rust ช่วยป้องกันไม่เพียงแต่ปัญหาที่เกี่ยวข้องกับหน่วยความจำเท่านั้น แต่ยัง logic error ที่สามารถเกิดขึ้นในภาษาใดๆ ได้ แนวทางความปลอดภัยที่ครอบคลุมนี้แสดงถึงความแตกต่างพื้นฐานในปรัชญาของภาษามากกว่าแค่การปรับปรุงแบบค่อยเป็นค่อยไป
ความท้าทายของ Ecosystem และ Tooling
นักพัฒนา C++ ยังคงต่อสู้กับงานพัฒนาพื้นฐานที่ภาษาอื่นได้ปรับปรุงให้เรียบง่ายแล้ว ความซับซ้อนของระบบ build ยังคงเป็นจุดเจ็บปวดที่สำคัญ โดยนักพัฒนาต้องเข้าใจ makefile, linker และเครื่องมือ package management เพียงเพื่อคอมไพล์โปรแกรมง่ายๆ การขาด package manager ที่เป็นมาตรฐานหมายถึงการต้องจัดการกับการติดตั้งแบบ global และความขัดแย้งของเวอร์ชัน
ชุมชนมีความรู้สึกผสมผสานเกี่ยวกับไลบรารียอดนิยมอย่าง Boost โดยบางคนมองว่าจำเป็น ในขณะที่คนอื่นแนะนำให้หลีกเลี่ยงโดยสิ้นเชิงเนื่องจากความซับซ้อนและความกังวลด้านการบำรุงรักษา ความไม่เห็นด้วยนี้สะท้อนปัญหาที่กว้างขึ้นกับ ecosystem ของ C++ ที่แม้แต่การตัดสินใจเครื่องมือพื้นฐานก็กลายเป็นเรื่องที่ขัดแย้งกัน
ความท้าทายของเครื่องมือพัฒนา
- ระบบ Build: ต้องใช้ Make และต้องเข้าใจ linker
- การจัดการ Package: ไม่มีโซลูชันมาตรฐาน ต้องติดตั้งแบบ global
- ความซับซ้อนของ Compiler: ต้องระบุ search path ด้วยตนเอง
- เครื่องมือภายนอก: จำเป็นต้องใช้ pkg-config สำหรับการจัดการ library
- การรองรับ IDE: คุณภาพแตกต่างกันไปในแต่ละสภาพแวดล้อม
- การจัดรูปแบบ: clang-format เป็นตัวเลือกหลัก แต่มีประสิทธิภาพจำกัด
มองไปข้างหน้า
แม้จะมีการวิจารณ์ C++ ยังคงรักษาตำแหน่งในแอปพลิเคชันที่ต้องการประสิทธิภาพสูงและระบบ legacy ภาษานี้ยังคงพัฒนาต่อไปด้วยมาตรฐานใหม่อย่าง C++20 และ C++23 โดยนำเสนอฟีเจอร์ที่แก้ไขปัญหาที่มีมายาวนานบางอย่าง อย่างไรก็ตาม ความตึงเครียดพื้นฐานระหว่างการรักษา backward compatibility และการปรับปรุงความปลอดภัยและความใช้งานง่ายยังคงไม่ได้รับการแก้ไข
การสนทนาในชุมชนเผยให้เห็นภาษาที่อยู่ในจุดเปลี่ยนผ่าน ในขณะที่ C++ ยังคงทรงพลังและใช้กันอย่างแพร่หลายอย่างไม่ต้องสงสัย การปรากฏของทางเลือกที่แก้ไขจุดอ่อนหลักของมันได้เปลี่ยนการสนทนาจากว่าปัญหาเหล่านี้มีอยู่หรือไม่ไปเป็นว่าปัญหาเหล่านี้สามารถแก้ไขได้อย่างเพียงพอภายในกรอบงานที่มีอยู่ของ C++ หรือไม่
อ้างอิง: In Defense of C++