C++ สนุกจริง ๆ
(learncodethehardway.com)- หลัง C++11 ภาษาและระบบนิเวศของ C++ เปลี่ยนไปอย่างมาก และกลายเป็นภาษาที่ปลุก ความสนุกของการเขียนโปรแกรม ให้กลับมา ผ่านกระบวนการลงมือสร้างและทดลองด้วยตัวเอง
- ครั้งหนึ่ง C++ เคยถูกจดจำในหมู่นักพัฒนาจำนวนมากว่าเป็นภาษาที่ชวนเหนื่อย เพราะ template metaprogramming ที่มากเกินไป รวมถึงวัฒนธรรมที่ยึดมาตรฐานและแพตเทิร์นเป็นศูนย์กลาง
- การเปลี่ยนแปลงอย่าง
auto,nullptr,range-for, lambda,<chrono>, smart pointer และ<thread>เปลี่ยน สไตล์การเขียนโค้ด ของ C++ ไปอย่างมาก - C++ สมัยใหม่มีตัวเลือกกว้าง ตั้งแต่ filesystem, package management, GUI/TUI, graphics, คณิตศาสตร์, AI ไปจนถึงการเข้าถึง OS API ทำให้ง่ายต่อการสร้างสิ่งที่ต้องการด้วยตัวเอง
- ข้อเสียอย่าง error จาก compiler, เครื่องมือ build, การปฏิบัติตามมาตรฐาน, ความซับซ้อนจากประวัติศาสตร์ และ RAII ยังมีอยู่ แต่ ความเป็นไปได้ในการสร้างสรรค์ มีมากพอจะเหนือกว่าความไม่สะดวกเหล่านั้น
เหตุผลที่ C++ กลับมาสนุกอีกครั้ง
- ระหว่างสร้างเกม roguelike ขนาดเล็ก ผู้เขียนใช้ Dijkstra algorithm ในการสร้างแผนที่ เพื่อทำอุโมงค์เชื่อมห้องต่าง ๆ และในกระบวนการนั้น C++ ไม่ได้ขัดขวางการทดลองมากนัก
- ยังสามารถทดลองวาดส่วนติดต่อผู้ใช้ของ FTXUI ลงบน render window ของ SFML ได้โดยตรง และระหว่างนั้นก็ได้เรียนรู้ การจัดการ Unicode ของ C++
- งานเหล่านี้ไม่ใช่งานง่าย แต่ทำได้จริง และความรู้สึกว่า “ไอเดียนี้ทำงานได้จริง” คือสิ่งที่ทำให้ C++ สนุก
- เหตุผลที่เริ่มเขียนโปรแกรมไม่ใช่เพื่อหาเงินเพิ่มให้มหาเศรษฐี ไม่ใช่เพื่อต่อสู้กับ rendering engine หรือเพื่อทำให้กลุ่มผู้นำของโปรเจกต์โอเพนซอร์สพอใจ แต่เป็น ความสนุกของการทำไอเดียให้เป็นจริง
ความเหนื่อยล้าในยุค template metaprogramming
- ตั้งแต่ปลายทศวรรษ 1990 ถึงต้นทศวรรษ 2000 C++ มีบรรยากาศที่พยายามนำ template metaprogramming ไปใช้กับทุกอย่างอย่างเข้มข้น และช่วงนี้ถูกมองว่าเป็นจุดเปลี่ยนที่ทำให้ C++ หมดสนุก
- มีกรณีที่พูดกันว่าการบวกตัวเลขสองตัวด้วย template เร็วกว่าการบวกโดยตรง แต่ผลลัพธ์ assembly จริงกลับเหมือนกัน
- ความรับรู้ว่า C++ standards committee ไม่ค่อยกระตือรือร้นในการมอบ usability ที่ดีให้โปรแกรมเมอร์ ก็ยิ่งทำให้ประสบการณ์เชิงลบเพิ่มขึ้น
- ในเวลานั้น C++ ถูกจดจำว่าเป็นภาษาที่มีวงเล็บมุม
<>และไวยากรณ์ซับซ้อนจำนวนมาก แต่ได้ประโยชน์น้อย - Java เองในตอนแรกก็ดูน่าสนใจเพราะ garbage collector และความเป็นมิตรต่อนักพัฒนา แต่ภายหลังก็ก่อให้เกิดความเหนื่อยล้าคล้ายกันจาก boilerplate และ design pattern ที่มากเกินไป
C++11 เปลี่ยนความรู้สึกของภาษาอย่างไร
- ฟีเจอร์ที่เพิ่มเข้ามาใน C++11 ถูกมองว่าเป็นการเปลี่ยนแปลงที่เปลี่ยนภาพจำของ C++ อย่างมาก
- ฟีเจอร์หลักมีดังนี้
auto: คีย์เวิร์ด อนุมานชนิดข้อมูลอัตโนมัติ ที่ช่วยลดภาระการเขียนชื่อ type เดิมซ้ำ ๆnullptr: การแทนค่า null pointer ที่ช่วยแก้ปัญหาของNULLในภาษา Crange-for: ลูปที่ทำให้การวนผ่าน container ง่ายขึ้นเมื่อใช้ร่วมกับautolambda expressions: lambda ที่สามารถเปลี่ยนการออกแบบ API และ usability ได้อย่างมาก<chrono>: ไลบรารีเวลาที่ type-safe และเขียนนิพจน์อย่าง100msได้<regex>: ฟังก์ชัน regular expression ที่รวมอยู่ใน standard libraryunique_ptr,shared_ptr: smart pointer สำหรับจัดการ ownership และ reference counting<thread>: ฟีเจอร์ที่ทำให้ multithreading เป็นส่วนหนึ่งของระบบนิเวศภาษาพื้นฐาน
- C++11 เปลี่ยน ปรัชญาและสไตล์ ของภาษาโดยไม่ทิ้งวิธีเดิม และในแง่นี้จึงถูกมองคล้าย ES6 ของ JavaScript
ตัวเลือกในระบบนิเวศ C++ สมัยใหม่
- C++ รุ่นใหม่มีฟีเจอร์จำนวนมากที่คาดหวังได้จากภาษาอื่น
- ตัวอย่างเครื่องมือและไลบรารีที่ยกมามีดังนี้
- การวนผ่าน filesystem:
filesystem - การจัดการแพ็กเกจ: Conan, Meson WrapDB, vcpkg
- ไลบรารีเมทริกซ์: Eigen
- AI: TensorFlow C++ API
- graphics: SFML
- GUI: Qt, wxWidgets, ImGui
- TUI: FTXUI
- การวนผ่าน filesystem:
- คุณภาพของระบบนิเวศแตกต่างกันไปในแต่ละรายการ แต่โดยรวมถูกประเมินว่าสูงกว่าประสบการณ์ที่เคยเจอใน JavaScript และ Python
- โดยเฉพาะ FTXUI และ STL ถูกยกเป็นตัวอย่างของการออกแบบและ usability ที่ดี
ความเป็นไปได้ในการสร้างที่กว้างขวาง ซึ่งทำให้ “สนุก”
- เหตุผลที่ C++ สนุกไม่ได้มีแค่การเพิ่มฟีเจอร์สมัยใหม่ แต่ยังอยู่ที่ ความเป็นไปได้ในการลงมือทำ ที่แทบจะสร้างอะไรก็ได้
- แอปเดสก์ท็อปสามารถสร้างได้ด้วย fenster, SFML, Qt หรือจะจัดการ OS API โดยตรงก็ได้
- ด้านเสียงมีตัวเลือกกว้าง ตั้งแต่ทางเลือกที่รวดเร็วอย่าง SFML ไปจนถึงเครื่องมือเชิงพาณิชย์อย่าง Wwise
- 3D graphics มีตัวเลือกหลากหลาย เช่น OpenGL, Vulkan, Direct3D, Ogre3D
- ด้านคณิตศาสตร์มีไลบรารีอย่าง BLAS, Eigen, GMTL
- แม้ไม่มีไลบรารีที่ต้องการ ก็ยังสามารถเข้าถึง C หรือ C++ ABI และ API ของระบบปฏิบัติการโดยตรงเพื่อสร้างเองได้ และกระบวนการลงมือสร้างโดยตรงนี้เองก็เป็นส่วนหนึ่งของความสนุก
เสรีภาพในการสร้างสรรค์ของภาษาที่อยู่นอกกระแส
- C++ มีคุณภาพของภาษาและระบบนิเวศสูง แต่ไม่ใช่ภาษาที่กำลังเป็นกระแสในปัจจุบัน จึงถูกมองว่าได้รับความสนใจจากกลุ่มที่ทำให้ภาษาเสียหายน้อยกว่า
- ชุมชน C++ ถูกวาดภาพว่าเป็นบรรยากาศที่ไม่ค่อยเข้ามายุ่งมากนัก ไม่ว่าจะสร้างอะไรก็ตาม
- สามารถลองทำโปรเจกต์อย่างไลบรารีเมทริกซ์, ไลบรารี GUI, game engine หรือเกมประหลาด ๆ ได้อย่างอิสระ
- งานสร้างสรรค์ต้องมีทั้งขั้นที่ดึงไอเดียออกมาก่อน และขั้นต่อมาที่วิจารณ์อย่างเยือกเย็นเพื่อยกระดับคุณภาพ
- ในภาษาอื่น องค์กร ภาวะผู้นำ และแรงกดดันจากชุมชนถูกประเมินว่าเป็นสิ่งที่ขัดขวางการทดลองในช่วงกลางของการสร้างสรรค์
- ความเป็นไปได้ที่กว้างของ C++ และวัฒนธรรมที่ค่อนข้างไม่ทำให้รู้สึกอับอาย สามารถสร้าง ประสบการณ์เชิงสร้างสรรค์ ได้
จุดแข็งของ cppreference.com
- cppreference.com ถูกประเมินว่าอยู่ในระดับดีที่สุดในบรรดาเอกสารภาษาโปรแกรมที่เคยใช้
- ข้อดีมีดังนี้
- คีย์เวิร์ดและไลบรารีทั้งหมดถูกจัดทำเป็น เอกสารอ้างอิง
- รายการส่วนใหญ่มีตัวอย่างที่ทำงานได้จริง
- แสดงเวอร์ชันมาตรฐาน C++ ที่แต่ละฟีเจอร์ถูกนำเข้ามา
- เชื่อมโยงไปยังเอกสารมาตรฐานและเอกสารอ้างอิงที่เกี่ยวข้อง
- มีช่องค้นหาที่ใช้ DuckDuckGo ทำให้ค้นหาได้ง่ายแม้สะกดผิดหรือไม่รู้คำที่แน่ชัด
- อธิบายแนวคิดสำคัญอย่าง Copy elision พร้อมตัวอย่าง
- จุดที่ยังขาดคือไม่มีวิธีติดตั้ง compiler บนแพลตฟอร์มต่าง ๆ
- เนื่องจากจำนวน C++ compiler และแพลตฟอร์มมีไม่มากนัก จึงยังมีพื้นที่ให้เพิ่ม guide สำหรับเริ่มต้นได้
ปัญหาของ C++ ที่ยังคงอยู่
- นี่ไม่ได้หมายความว่า C++ เป็นภาษาที่สมบูรณ์แบบ และเช่นเดียวกับภาษาอื่น มันมีจุดที่ไม่สะดวกอยู่มาก
- บน Windows การตั้งค่า compiler และเครื่องมือพัฒนาผ่านเส้นทางติดตั้งที่ไม่ใช่ของ Microsoft ทำได้ยาก และเพื่อเรื่องนี้ผู้เขียนจึงสร้าง สคริปต์ติดตั้ง PowerShell ขึ้นมาเอง
- ความไม่สะดวกหลักที่รู้สึกในปัจจุบันมีดังนี้
- มากกว่า 95% ของ ข้อความ error จาก compiler ถูกประเมินว่าแย่ที่สุดในอุตสาหกรรม
- เครื่องมือ build ใช้งานยาก และ Meson ก็เคยมีปัญหาที่ไม่สนใจคำสั่งเกี่ยวกับแพ็กเกจที่ติดตั้งไว้ แล้วไปใช้ system library ที่เสียแทน
- มีแรงจูงใจไม่เพียงพอที่จะทำให้ผู้ผลิต compiler ปฏิบัติตามมาตรฐาน
- C++ ซับซ้อนมากเพราะประวัติศาสตร์ของมัน โดยมีหลายสไตล์อยู่ร่วมกัน ทั้งสไตล์เก่าที่เน้น heap allocation และ raw pointer, สไตล์ template metaprogramming, สไตล์หลัง C++11 ที่เน้น stack และสไตล์ใหม่กว่าที่เน้น
struct - RAII มักเป็นอุปสรรคในสถานการณ์ตั้งค่าจริง และมองว่าจำเป็นต้องมีจุดกึ่งกลางระหว่าง constructor แบบ initialization ของภาษาอื่นกับ RAII ในปัจจุบัน
- แม้มีข้อเสียเหล่านี้ ความไม่สะดวกของ C++ ก็ไม่ได้ถึงขั้นทำลายความสนุก และ C++ เปลี่ยนไปจากภาพจำเดิมที่เป็นภาษาซึ่งเน้นวงเล็บมุมและ pointer เป็นศูนย์กลาง
- โค้ด layout ของ FTXUI GUI เป็นตัวอย่างที่แสดงไวยากรณ์สมัยใหม่ จนถ้าไม่รู้ว่าเป็น C++ ก็อาจดูเหมือนภาษาอื่นได้
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ผมค่อนข้างเป็น คนเกลียด C++ แต่เหตุผลคือไม่ชอบที่ต้องจัดการ C++ ในโค้ดงานที่ต้องการความน่าเชื่อถือ ร่วมกับเพื่อนร่วมงานที่ไว้ใจได้ยากเต็มที
สำหรับโปรเจกต์ส่วนตัว มันเป็นหนึ่งในสภาพแวดล้อมการเขียนโค้ดที่น่าพอใจที่สุดเท่าที่เคยลองมา และความสามารถในการควบคุมการทำงานได้ละเอียดมาก ๆ นั้นน่าตื่นเต้นจริง ๆ
ผมเลิกใช้ C++ ไปเมื่อราว 10 ปีก่อนและไม่คิดจะกลับไป แต่สำหรับโปรเจกต์ของผมในทุกวันนี้ ความน่าเชื่อถือระยะยาวสำคัญที่สุด ดังนั้น Rust + CI/CD จึงพอดีมาก
ถึงอย่างนั้น ผมก็ยังคิดถึงความรู้สึกสะใจเวลาที่ได้ออกแบบและทำให้โปรแกรมรันตรงตามวิธีที่ผมตั้งใจไว้ และนั่นเป็นเพราะความเชี่ยวชาญกับวิจารณญาณของผมเอง
ถ้าถามว่าอยากให้คนที่ทำงานด้วยกันขับเคลื่อนด้วยแรงจูงใจแบบนั้นไหม บอกเลยว่าไม่ แต่โดยส่วนตัวแล้วมันเป็นความสนุกที่ลืมไม่ลง
ระบบ build กับการจัดการแพ็กเกจเป็นฝันร้าย, preprocessor เหมือนมุกตลกซาดิสต์, syntax ก็เลวร้าย และใน runtime ยังมีเศษซากมากมายที่ต้องอาศัยประสบการณ์หลายปีเพื่อไม่ให้ยิงเท้าตัวเองด้วยปืนกล
แต่ในแง่หนึ่ง ความเจ็บปวดเหล่านี้กลับยิ่งทำให้ความสุขตอนปล่อย executable ที่ห่อหุ้มด้วยความฉลาดและน้ำตาเลือดออกมาได้ในที่สุดนั้นมากขึ้น
เคยใช้ C/C++ ทำงานอยู่หลายปี และไม่อยากกลับไปอีก
ใช้เวลาไปมากเกินไปกับการ debug โค้ดคนอื่น เจอปัญหา integration คลุมเครือ และหมุนวนกับ สปาเกตตีของระบบ build
ในช่วง 10 ปีที่ผ่านมา อุตสาหกรรมเทคโนโลยีดูเหมือนจะสูญเสียความคิดนี้ไป และผมโทษบริษัทเทคโนโลยียักษ์ใหญ่ที่เอาคนเก่ง ๆ ไปขังไว้ในคุกผู้ใหญ่ที่มีอาหารดี ๆ กับเก้าอี้นุ่ม ๆ
สตาร์ตอัปก็สนุกน้อยลง และวงการ VC ก็ส่งเสริมกรอบความคิดที่แคบ ทำให้มีสตาร์ตอัปโคลนที่ทำของเหมือน ๆ กันกับกระแสมากเกินไป
เหตุผลที่ผมใช้ C++ กับโปรเจกต์ใหม่ทุกโปรเจกต์คือ ผมมั่นใจว่าถ้าต้องสร้างเองก็สร้างได้
โดยเฉพาะเมื่อต้องแตะส่วนแกนหลักของโปรเจกต์ framework มักไม่ทำงานในแบบที่ต้องการ จนไม่อยากใช้ต่อ
ถ้าสร้างเองได้ก็สร้างเอง ถ้าไม่ได้ก็ค่อยใช้ framework
ถ้าคุณสร้างเองได้ C++ เป็นเครื่องมือที่ยอดเยี่ยมซึ่งทำอะไรก็ได้ และไม่ขวางทางในแง่ที่สำคัญ
ภาษาอย่าง Rust อาจบ่นว่าผมกำลังทำสิ่งอันตราย แต่ใน C++ ผมสามารถถ่ายทอดโมเดลในหัวออกมาได้โดยตรง
บางครั้งผมก็คิดเป็น pointer และ pointer ก็เป็นเครื่องมือที่ดีจริง ๆ
เอาความสนุกกลับคืนมาเถอะ ไม่ใช่แค่ในชีวิตส่วนตัว แต่ในงานด้วย
บทความนี้ดูค่อนข้างสับสน
พูดถึงหลายประเด็น แต่ยากที่จะดึงออกมาได้ว่ามันนำไปสู่ข้อสรุปว่า C++ สนุกขึ้นหรือน้อยลงอย่างไร
การบอกว่า C++ สมัยใหม่มี คุณภาพสูงอย่างยิ่ง พร้อมกับพูดถึงปัญหา legacy กว้างขวางและเครื่องมือที่แย่มากก็ชวนงง
บอกว่า
unique_ptrยอดเยี่ยม แต่กลับบอกว่า RAII น่ารังเกียจจริง ๆ และข้ออ้างที่ว่า metaprogramming เมื่อก่อนมีอยู่ทุกที่แต่ตอนนี้ไม่ใช่แล้วก็แปลกถ้าดู
conceptsก็ไม่ได้เป็นอย่างนั้น และคำกล่าวที่ว่า C++ มีไลบรารีกราฟิกที่ดีที่สุด หรือการติดตั้ง Python ยากกว่า C++ ก็ดูเหมือนความหมกมุ่นส่วนตัวของผู้เขียนที่ไม่ค่อยเกี่ยวกับประเด็นหลักท้ายที่สุด ผู้เขียนน่าจะสนุกกับ C++ เพราะการผสมผสานของปัจจัยส่วนตัวหลายอย่าง ซึ่งตัวมันเองก็ไม่เป็นไร
ผมเองก็เคยเขียนโปรแกรมได้สนุกที่สุดด้วย C++ เพราะ performance และลักษณะทางเทคนิคของมัน แต่ในการพัฒนาซอฟต์แวร์จริง C++ ไม่ค่อยดีด้วยเหตุผลมากมายที่เรารู้กัน
C++ เป็นภาษาที่ขัดแย้งในตัวเองอย่างลึกซึ้ง ซึ่งบอบช้ำจาก legacy และการเมืองหลายทศวรรษ และการเพิกเฉยต่อความจริงของ C++ คือความผิดพลาดที่ใหญ่ที่สุดในการถกเถียงเรื่อง C++
ท่าทีของผมต่อ C++ ทุกวันนี้ใกล้เคียงกับความเหนื่อยล้า และผมไม่อยากกระโดดข้ามอุปสรรคที่ C++ โยนใส่มาหลายปีอีกแล้ว
ไม่จำเป็นต้องตีม้าตายที่ตายมานานเกินไปแล้วต่อไป และปล่อยให้ C++ เป็น C++ ไปก็พอ
ในมุมผม บทความไม่ได้สับสนเท่าไร แต่ใกล้เคียงกับว่าผู้เขียนกำลังสนุกและพยายามแบ่งปันความสุขนั้นให้มากที่สุด
มันไม่ใช่บทความเชิงโต้แย้งที่ตั้งใจโน้มน้าวอย่างจริงจัง แต่ใกล้กับ “ถ้าไม่ต้องโน้มน้าวก็ยังรู้สึกร่วมได้ คุณก็อาจสนุกกับมันเหมือนกัน” มากกว่า
ถ้าคุณอยู่ในจุดที่เหนื่อยจากการถูกความจริงของงานเชิงพาณิชย์เล่นงาน ก็เข้าใจได้เต็มที่ว่าจะรู้สึกว่ามันไม่สมเหตุสมผล
ช่วงนี้ผมเองก็ดันสนุกกับการใช้ JavaScript มาก ๆ ถ้าเขียนบทความคล้าย ๆ กัน คนที่เหนื่อยกับ JavaScript เชิงพาณิชย์มาตลอด 10 ปีคงอ่านแล้วรู้สึกแย่พอ ๆ กัน
ถึงอย่างนั้นก็ดีใจที่ผู้เขียนกำลังสนุก และเลือกจะแบ่งปันความสนุกนั้น
ผมใช้เวลา 3 วันไปกับการทำ static link dependency ของ third-party ในโปรเจกต์ C++ ให้ทำงานบน Linux/Windows/macOS
แพ็กเกจนั้นไม่มีใน conan/vcpkg มีแค่ repo GitHub ที่มี Makefile/cmake ผสมกันประหลาด ๆ
ผมห่างไกลจากการเป็นผู้เชี่ยวชาญ cmake/cpp แต่ในภาษาสมัยใหม่ส่วนใหญ่ เรื่องแบบนี้ไม่เป็นปัญหาด้วยวิธีอย่าง
pip install,cargo add,npm install,go getต่อให้อ่านรายละเอียด semantic ของ C++ ตั้งแต่ต้นจนจบเป็นเล่ม การทำงานกับโปรเจกต์จริงก็ยังเจ็บปวดอยู่ดี
น่าประหลาดใจที่สุดท้ายมันไปถึงสิ่งที่เหมือน autotools เวอร์ชัน JavaScript
การ build โค้ดคนอื่นแบบ static หรือปรับให้ build บนแพลตฟอร์มอื่นได้ บางทีก็ยุ่งยาก แต่ตัวการ link เองปกติก็แค่ระบุ include directory, library path และ library เท่านั้น
ถ้าไม่มีใครทำแพ็กเกจ vcpkg/conan ไว้ ก็มีโอกาสสูงว่าจะไม่มีใน pip/cargo/npm เช่นกัน
ถ้าลำบากใน C++ ในภาษาอื่นอาจลำบากยิ่งกว่ามาก
แต่ก็แสดงให้เห็นตรงนี้ด้วยว่า บางส่วนของ C++ ในเชิงประวัติศาสตร์ โดยเฉพาะ เรื่อง build อยู่ในสภาพที่แย่มาก
ถ้ามันอยู่ใน vcpkg แล้ว ความยากในการติดตั้งก็จะเหมือนกับ ecosystem อื่น ๆ ทุกประการ
ผมลองเปลี่ยนจาก C มาเขียนด้วย C++ เป็นระยะ ๆ แต่ทุกครั้งก็เป็นแพตเทิร์นคล้ายเดิม
ได้รู้เทคนิค C++ ใหม่ ๆ เขียนโค้ดเพราะคิดว่าน่าจะทำให้อะไรดีขึ้น เจอ error จากคอมไพเลอร์ แล้วใช้เวลาที่เหลือทั้งวันไปกับการเรียนรู้ว่าทำไมถึงทำสิ่งที่อยากทำไม่ได้
โดยปกติมักติดอยู่กับ C++14 และบางปัญหาก็ถูกแก้ในเวอร์ชันหลัง ๆ แล้ว แต่ก็ยังเป็นแบบนั้นอยู่ดี
ผมอยากชอบ C++ มากจริง ๆ เพราะในทางทฤษฎีมันให้ C ที่ทรงพลังกว่าและควรช่วยเพิ่ม productivity ได้ แต่สุดท้ายภาระทางความคิดมันเยอะเกินไป จนปกติก็ลงเอยด้วยการเขียน “C ที่มีคลาส” แล้วผ่าน ๆ ไป
ในปี 2003 ผมใช้ C++ แบบ real-time เยอะมากและเกลียดมัน แต่ปีที่แล้วผมเขียนโค้ดส่วนใหญ่ด้วย C++ แล้วในที่สุดก็เริ่มชอบมัน
lambda และ
autoคือจุดเปลี่ยนที่ทำให้ผมเลิกเกลียด C++ผมก็ใช้ template นิดหน่อย แต่หลัก ๆ เพื่อไม่ต้องเขียน branch เยอะ ๆ สำหรับแต่ละ variation ของฟังก์ชันเดียวกัน
Lambda ทำให้ผมเขียนโค้ดได้ตามวิธีที่เคยเรียนครั้งแรกจากครูสาย Lisp บรรยากาศแบบ SICP
พอใช้
unique_ptrแล้ว การ allocation ก็ไม่ได้รู้สึกแย่อย่าทำแบบนั้น ควรคิดก่อนว่าจะใช้โค้ดอย่างไร แล้วถ้ามีฟีเจอร์ไหนแก้ปัญหาได้ค่อยใช้
ต้องเป็น ปัญหา → ทางแก้ ไม่ใช่กลับกัน
เช่น template ของ C++ โดยรวมแล้วค่อนข้างเลวร้าย แต่ duck typing ตอน compile-time หรือการเติม padding อัตโนมัติตาม
sizeof()ก็มีประโยชน์มากในบางครั้งตอนแรกผมเป็นโปรแกรมเมอร์ C# ที่กำลังเรียน C เพราะโปรเจกต์ embedded และลำดับเหตุการณ์ก็เหมือนกันเลย
C++ มีฟีเจอร์เจ๋ง ๆ มากมายที่ดูทรงพลังถ้ามันเข้ากับแอปพลิเคชันพอดี
แต่ทุกครั้งที่ลองฟีเจอร์ใหม่ สิ่งที่ผมพยายามทำมักเป็น กรณีขอบเขต ที่ใช้ไม่ได้ในสถานการณ์นั้นเสมอ และหลังจากพยายามเป็นชั่วโมงหรือเป็นวันก็ยอมแพ้ แล้วกลับไปเขียน C เฉย ๆ
แน่นอนว่าก็มีภาษาบางอย่างอย่าง Python หรือ Ruby ที่ไม่ค่อยเป็นไปตามแนวโน้มนี้
ปกติผมจะคัดลอกข้อความ error ไปให้มันช่วยถอดความ
C++ สนุกจริง ๆ และผมคิดว่าความไม่พอใจของผู้คนขึ้นอยู่กับบริบทมาก
นักพัฒนา C++ จำนวนมากเกลียดภาษา แต่จริง ๆ แล้วบางครั้งทิศทางของความเกลียดนั้นผิด
หลายกรณีจริง ๆ คือกำลังรับมือกับ ผลิตภัณฑ์ legacy ที่สร้างโดยคนที่ไม่ได้ใช้ซอฟต์แวร์เก่งนัก
ผมก็เคยเจอคล้าย ๆ กันกับ Rust ตอนถูกดึงเข้าไปทำโปรเจกต์ Rust เดิมของบริษัท ซึ่งใน codebase เก่ามี convention ที่ขัดแย้งกันเองเยอะมาก
มี error handling type ที่ประกอบกันได้ไม่ดี abstraction ของคลาสที่แย่ และ block
unsafeที่ไม่จำเป็น เป็นหนึ่งในโปรเจกต์ที่ทรมานที่สุดที่เคยทำมาโทษ Rust ได้ง่าย แต่จริง ๆ แล้วมันก็แค่การพัฒนาซอฟต์แวร์ที่แย่
C++ มีข้อบกพร่องจริง แต่ความเจ็บปวดจำนวนมากที่ผู้คนเจอเกิดจากการต้องรับมือกับ โค้ดแย่ ๆ ที่ไม่ว่าจะเขียนด้วยภาษาใดก็เละอยู่ดี
v[x]=yทุกครั้งไม่ได้เท่ากับเชิญชวนให้หน่วยความจำเสียหายแบบสุ่มstd::optionalของ C++ ถ้าเรียก*vตอนที่vว่าง จะกลายเป็น พฤติกรรมที่ไม่ได้นิยามไว้จุดประสงค์ของ optional คือเก็บค่าที่อาจว่างได้ แต่ยากจะเข้าใจว่าทำไมตอน optional ว่าง การดำเนินการที่พบบ่อยที่สุดถึงถูกทำให้เป็นพฤติกรรมที่ไม่ได้นิยามไว้
ในฐานะคนที่ใช้ C++ มาเยอะ ปัญหาคือโปรแกรมเมอร์ทุกคนในโปรเจกต์ต้องสมบูรณ์แบบ 100% ตลอดเวลา 100%
คุณอาจรัน memory checker และ STL debug mode ได้ แต่ถ้าไม่ได้รันสิ่งเหล่านั้นใน release ก็ต้องหวังว่า test suite จะไปแตะทุกเรื่องแปลก ๆ ที่ผู้ใช้โง่หรือผู้ใช้ประสงค์ร้ายอาจทำได้
ในยุคที่ซอฟต์แวร์สำคัญขนาดนี้ และ Rust ดูเหมือนจะมี performance ใกล้เคียง C++ ผมสงสัยว่ามันยังคุ้มไหมที่จะใช้ภาษาที่ฟีเจอร์พื้นฐานจำนวนมากใช้อย่างปลอดภัยได้ยากมาก
แถมยังแย่ลงเรื่อย ๆ ด้วย การเรียก
std::functionที่ว่างเคยโยน assert แต่std::copyable_functionใหม่ทำให้สิ่งนี้เป็นพฤติกรรมที่ไม่ได้นิยามไว้type system น่ารำคาญ และถึงอย่างนั้นก็ไม่ได้ memory safety ที่แท้จริง
most vexing parse น่ารำคาญจริง ๆ และความประหลาดที่รับมาจาก C อย่าง pointer decay ก็ยังอยู่ครบ
แล้วก็เอาแนวทางใหม่อย่าง
std::arrayมาโปะทับโดยที่ไม่สามารถกำจัดวิธีเก่าได้การยังพึ่ง preprocessor เพื่อเลียนแบบระบบ import module จริง ๆ ก็เป็นปัญหา และเพราะอย่างนั้นจึงต้องมีทางอ้อมอย่างการจัดโค้ดคลาสหรือ idiom แบบ pimpl ตามมา
โดยเนื้อแท้แล้วข้อบกพร่องมันใหญ่และเยอะเกินไป จนยากจะมองหาความงามในนั้นได้อีก
ในทางกลับกัน โปรเจกต์ภาษา blub ที่เรียบง่ายมักถอดความได้ค่อนข้างง่าย ไม่ว่า codebase จะอยู่ในสภาพไหน
เป็นเรื่องดีที่มีคนรู้สึกสนุกกับ C++ แต่โดยส่วนตัว หลังจากเจอมานาน กว่า 20 ปี ตอนนี้ผมคงต้องจบกับ C++ แล้ว
มันเละเทะไปหมด
ถ้าต้องการการควบคุมระดับต่ำจริง ๆ ก็ใช้ C แม้จะมีข้อบกพร่อง หรือไม่ก็ Rust, Python ฯลฯ ทำให้ผมมีความสุขกว่าเยอะ
แต่ C++ ก็จะยังคงอยู่ต่อไป
มีโค้ดที่เขียนด้วยภาษานี้มากเกินไป และแน่นอนว่าถ้าเรียนรู้ไว้ก็เป็นทักษะที่ดี แถมยังมีงานที่ได้เงินดีมากด้วย
สำหรับผม ภาษานี้ขวางทางเกินไป และรู้สึกซับซ้อนเกินจำเป็น
ผมรู้วาทกรรมที่ว่า “C++ สมัยใหม่” นั้นยอดเยี่ยม ไม่จำเป็นต้องเรียนเวอร์ชันเก่า และทุกเวอร์ชันใหม่ทำให้เรียบง่ายขึ้น
ปัญหาคือ codebase ที่ได้ทำจริง ๆ ไม่ใช่ C++ สมัยใหม่
มันใช้ฟีเจอร์ทุกอย่างที่เคยมีมา และยาก แถมเต็มไปด้วยกับดัก
คนที่ทำ C++ เฉพาะในโปรเจกต์ของตัวเองมาหลายปีอาจพัฒนาความเชี่ยวชาญจนคุ้นชินกับความซับซ้อนได้ในระดับหนึ่ง แต่มันก็ไม่ใช่ภาษาที่ดีจริง ๆ
เช่น การเปลี่ยนชนิดข้อมูลหลัก ไลบรารีมาตรฐาน ฯลฯ
โดยเฉพาะตั้งแต่ C++20 เป็นต้นมา รากฐานสำหรับการแทนที่เหล่านี้ให้ความรู้สึกค่อนข้างเนทีฟและสื่อความได้ดี
โปรเจกต์ C++ ใหม่ ๆ จำนวนไม่น้อยที่ผมเห็นเลือกแนวทางนี้อย่างชัดเจน
การที่สามารถสร้างภาษาเฉพาะโดเมนระดับระบบสำหรับแอปพลิเคชันได้ง่าย คือจุดแข็งของ C++
น่าเสียดายที่ทำไม่เสร็จ แต่ที่จำได้ก็มี class,
std::function,std::unordered_map,std::string,std::unique_ptrประมาณนี้ถ้าไม่ใช่สไตล์คล้าย ๆ กัน ก็นึกภาพไม่ออกเลยว่าจะอ่านโค้ดคนอื่นได้อย่างไร
เพราะไม่ได้ทำงานกับโปรแกรมขนาดใหญ่เป็นอาชีพ สิ่งที่ยากที่สุดคือการก้าวข้าม รูปแบบการเขียนโปรแกรม อย่าง Visitor pattern
ผมหวังว่า C++ จะหยุดอยู่ที่ C++11
ตอนนี้คณะกรรมการดูเหมือนอยากใส่ทุกอย่างลงไปในภาษา และ C++ ก็ดูเหมือนภาษาไซซ์มหึมาที่รองรับสไตล์การเขียนโปรแกรมเฉพาะทางทุกซอกทุกมุม
แต่มันเป็น ความเละเทะที่สนุก และผมชอบเขียนด้วย C++
บางครั้งเรื่องนั้นก็สำคัญ
ความสัมพันธ์กับ Rust นั้นเย็นชากว่ามาก
ผมเคารพ Rust และโดยเฉพาะในบริบทที่ยากจะปกป้องการใช้ C++ เช่นงานจริง ถ้าคิดว่า Rust เหมาะ ผมก็ใช้ และมองว่าสิ่งที่ Rust ทำอยู่นั้นสำคัญ
แต่ถึงตอนนี้จะทำโปรเจกต์ Rust มาพอสมควรแล้ว ก็ยังรู้สึกว่าน่าเบื่อเวลาเขียน
ในแง่สำคัญ ๆ มันดีกว่า แต่สำหรับผมอย่างน้อย มันสนุกน้อยกว่า
ถ้าปลดผนึก
unsafeก็สามารถ cast จำนวนเต็มเป็น pointer แบบชัดเจนได้ และเช่น ใช้ memory-mapped I/O เพื่อควบคุมฮาร์ดแวร์ได้ไม่ใช่หรือ?บทความนี้เป็นการพูดยืดยาวที่ครอบคลุมกว้าง และแค่คำว่า “C++” ก็อาจกระตุ้นคนจนทำให้หลายส่วนถูกมองข้ามได้
ผมเองก็เป็นแบบนั้นบ้างเหมือนกัน
ถ้าอยากดูข้อร้องเรียน ให้ข้ามไปส่วน “It's Not All Puppies and Butterflies” ได้
ผู้เขียนประทับใจ C++11 มาก และหลังจากจงใจเมิน C++ มาเกือบ 20 ปี ผมก็รู้สึกคล้ายกัน
ดีที่บทความแนะนำแพ็กเกจและไลบรารีให้ลองเล่น แต่การเอาไลบรารีอื่นเข้ามาในโปรเจกต์ของผมก็ยังมักเป็นเรื่องเจ็บปวดอยู่ดี
นึกถึง header ไฟล์เดียวขึ้นมาเลย
FTXUI น่าสนใจ
และ cppreference.com ก็ยอดเยี่ยมจริง ๆ
เอกสารของ Python ก็ค่อนข้างดี แต่ผมไม่เคยเห็นเอกสารไหนที่ดีเท่า cppreference.com
เอกสาร Python กระจัดกระจายอยู่หลายที่ หลายส่วนไม่สมบูรณ์ และยังขาดสไตล์การแก้ไขถ้อยคำที่สม่ำเสมอ
แต่ถ้าวัดตามกรอบ Diataxis มันก็ครอบคลุมเอกสารหลายประเภทได้ค่อนข้างดี ไม่ใช่แค่เอกสารอ้างอิง
คนที่เขียนเอกสารเหล่านั้นคำนึงถึงกรอบนี้อย่างชัดเจนและมองหาทางปรับปรุง
ถึงอย่างนั้นก็ยังเป็นงานโอเพนซอร์สที่พึ่งพาอาสาสมัคร ซึ่งเดินไปในแบบใกล้เคียงกับการพัฒนาโค้ดมาก
ผมอยาก “เข้าใกล้ระบบมากขึ้น” มาสักพักแล้ว และการเรียน Rust ควบคู่ไปด้วยก็ไม่ง่าย
อ่านบทความนี้แล้วเริ่มมีความหวังว่าถ้ากลับมาเรียน C++ อีกครั้งอาจเป็นไปได้
สวัสดี CMake… ไม่สิ บางทีควรพูดว่า Meson มากกว่า
ถ้าทีมที่มีความสามารถรู้วิธีใช้ C++ สมัยใหม่ ได้ดีและเริ่มโปรเจกต์ใหม่ ผมเห็นด้วยว่า C++ นั้นยอดเยี่ยม
เป็นภาษาที่สนุกและทรงพลัง ประสิทธิภาพดี และแม้จะซับซ้อน แต่การดีบักกับการปรับให้เหมาะสมก็ค่อนข้างตรงไปตรงมา
ผมเคยมีโอกาสทำงานกับ codebase ที่มีอายุราว 5 ปี ซึ่งเขียนตามมาตรฐานหลัง C++11 และด้วยเหตุผลหลายอย่างที่บทความพูดถึง มันสนุกมาก
ในทางกลับกัน ถ้าเป็น codebase เก่าที่วิวัฒนาการมา 20–30 ปี หรือ codebase ที่ไม่ได้ดูแลโดยคนมีฝีมือ ประสบการณ์จะต่างออกไปอย่างสิ้นเชิง
ตอนอายุ 21 บริษัทเสนอจ่ายค่าเล่าเรียนให้ ผมจึงกลับไปเรียนปริญญาสาขาวิศวกรรมคอมพิวเตอร์ และภายหลังเปลี่ยนเป็นวิทยาการคอมพิวเตอร์
วันแรกของวิชา “บทนำสู่การเขียนโปรแกรม” ทันทีที่ได้จับ C++ ผมก็ตกหลุมรัก
เมื่อเทียบกับ PHP 7 ที่ใช้ตอนนั้น ระบบชนิดข้อมูล, การดีบัก, ecosystem ยอดเยี่ยมมาก
หลังได้รับอนุญาตจากผู้จัดการ ผมสร้าง API ที่ใช้ C++ สำหรับบางส่วนของแอปอินทราเน็ตเดิม ให้ PHP เรียกผ่าน WebSocket และสามารถใช้ประโยชน์จากระบบชนิดข้อมูลกับประสิทธิภาพได้
ระบบเหล่านั้นยังถูกใช้ทั่วบริษัททุกวัน และการบำรุงรักษาก็ไม่เป็นปัญหา
ทั้งที่มันรันอยู่บนสภาพแวดล้อมค่อนข้างพิเศษอย่าง IBM Pase for i ด้วยซ้ำ
ตอนนี้หลังจากได้ลอง Rust กับ Axum แล้ว เวลาจะสร้าง API แบบนั้น ผมชอบ ecosystem ของ Rust มากกว่าเยอะ แต่ C++ ก็สมควรได้รับการยอมรับ
โดยเฉพาะถ้าย้ายมาจากภาษาเว็บอย่าง JavaScript ที่ไม่ใช่ TypeScript หรือ PHP มันเป็นภาษาที่ยอดเยี่ยมจริง ๆ
จริง ๆ แล้วจากความเป็นไปได้หลายอย่างที่นึกออก เช่น C, Java, Fortran ผมน่าจะชอบ C++ มากกว่า
ข้อยกเว้นอาจเป็น C# แต่ไม่แน่ใจว่ามันเก่าพอจะเข้ากับเงื่อนไขนั้นหรือยัง
แม้จะมีคนบอกว่า C++ มี regex ในตัวแล้วและค่อนข้างดี แต่
std::regexก็พูดได้ยากว่าดีประสิทธิภาพแย่และการรองรับ Unicode ก็ยังไม่พอ โดยทั่วไปจึงควรหลีกเลี่ยง
std::regexเคยเรียน C++ และก็สนุกกับมัน แต่ไม่ได้ลงลึกมาก
ชอบ C มากกว่าเสมอ และโดยพื้นฐานแล้วก็มี โค้ดเบสระดับยอดเยี่ยม มากมายให้อ่านเพื่อเรียน C ให้เก่งขึ้น เช่นเอนจินเกม Dune หรือยูทิลิตีของ Unix
ช่วงหลังลองแตะ Rust นิดหน่อย ก็ไม่ค่อยเห็นเหตุผลหนักแน่นที่จะใช้ C++
การผสานระบบชนิดข้อมูลที่ทรงพลังซึ่งได้แรงบันดาลใจจาก functional programming เข้ากับประสิทธิภาพ ดูเหมือนจะเอาชนะได้ยาก และแทบจะเป็นภาษาที่สมบูรณ์แบบ
ถึงอย่างนั้น เหตุผลด้านเลกาซีที่ต้องใช้ C++ ก็คงมีอยู่แน่นอน
อาจเป็นอย่างเอนจินเกม, การเขียนโปรแกรม embedded, หรือการผูกติดกับเลกาซีในรูปแบบอื่น ๆ
ถ้าเป็นโค้ดเบส C++ ใหม่ ก็ทำให้ค่อนข้างสะอาดได้
แต่ ณ จุดนี้ก็ยังไม่ค่อยเข้าใจว่าทำไมต้องสร้างซอฟต์แวร์ใหม่ด้วย C++
สิ่งน่ารำคาญของ C++ มีเยอะ
การจัดการไลบรารี/แพ็กเกจไม่ได้มาตรฐาน, header คือการซ้ำซ้อนของโค้ด, และ standard library ก็แตกต่างกันตาม implementation แถมแทบอ่านไม่รู้เรื่อง
มาตรฐานมีพฤติกรรมแปลก ๆ, ผู้คนพึ่งพา undefined behavior โดยไม่รู้ตัว, มีปัญหาใช้ก่อนจัดสรร, และเกิด memory leak แบบแนบเนียนจากปัญหา ownership กับ reference count ที่ผิดพลาด
ต้องทำทุกอย่างให้เป็น
constแทนที่จะเป็นค่าเริ่มต้น, หากจะรับประกันnoexceptก็ต้องตรวจ exception ของทุกอย่างที่เรียกใช้, และ error ระหว่างทำงานกับ standard library ก็อ่านยากโค้ดที่เน้น OOP หนัก ๆ โดยแท้จริงแล้วเป็นหนี้ทางเทคนิค
LSP ของ C++ ไม่ได้ใช้วิธีเชิงโครงสร้างแบบ Rust ที่ตรวจ abstract syntax tree เพื่อหานิยาม ทำให้การนำทางและทำความเข้าใจโค้ดเบสช้า
Rust รองรับ
nostdอย่างชัดเจนในฐานะฟีเจอร์ชั้นหนึ่ง แต่ใน C++ ถ้าจะปิด standard library ต้องใช้ flag เฉพาะคอมไพเลอร์ และตรวจได้ยากว่าทำถูกต้องหรือไม่ดังนั้นเหตุผลที่ว่าใช้ C++ เพราะ embedded จึงไม่น่าเชื่อถือสำหรับฉันนัก
Rust ก็มีเอนจินเกมอย่าง bevy แต่ยังใหม่อยู่ และถ้าต้องการก็สามารถผูก Rust เข้ากับการสคริปต์ของ Godot ได้
งานเสียงระดับต่ำก็ง่ายพอ ๆ กันใน Rust และจัดการข้ามแพลตฟอร์มได้ด้วย crate เดียว
โดยรวมแล้วคิดว่าแก่นหลักคือ โค้ดเลกาซี และความลังเลต่อการเปลี่ยนแปลง
รวมถึงจำนวนผู้ใช้, ความรู้และแหล่งข้อมูลที่เผยแพร่และเข้าถึงได้, หนังสือ, คอร์ส, บล็อก, บทความ, วิดีโอ, ไลบรารีซอฟต์แวร์, รวมถึงความเข้ากันได้สูงกับ C ซึ่งเป็นอีกภาษาขนาดใหญ่มหาศาล
สำหรับคนที่อยู่ในวงการนี้มาหลายปีขึ้นไป นี่แทบจะเป็นสามัญสำนึกทั่วไปของอุตสาหกรรมซอฟต์แวร์
ฉันไม่เคยใช้ C++ มากนัก จึงคงเรียกว่าเป็นมือใหม่ที่แท้จริงก็ยังยาก แต่เคยซื้อและอ่านหนังสือ C++ คลาสสิกของผู้สร้างภาษาอย่าง Bjarne Stroustrup, Scott Meyers และคนอื่น ๆ และเข้าใจในระดับหนึ่ง
อย่างไรก็ตาม เคยใช้ C ในโปรดักชันมาหลายปี รวมถึงผลิตภัณฑ์เชิงพาณิชย์ที่ประสบความสำเร็จ
https://www.stroustrup.com/applications.html
https://www.stroustrup.com
https://en.m.wikipedia.org/wiki/Bjarne_Stroustrup
https://en.m.wikipedia.org/wiki/Scott_Meyers
ดังนั้นจึงคิดว่าการพัฒนาเกมจะเป็นพื้นที่ที่อยู่กับ C++ นานที่สุด
ต่อให้เกมล่มด้วย segmentation fault สำหรับผู้ใช้ 0.001% แล้วไงล่ะ ก็ประมาณนั้น