มีกรณีที่เกิดขึ้นจริงสำหรับ C ++ โดยไม่มีข้อยกเว้นหรือไม่? [ปิด]


40

ในเมื่อใดจึงจะใช้ C เหนือ C ++ และ C ++ เหนือ C? มีคำสั่ง wrt ถึงข้อยกเว้นขนาดโค้ด / C ++:

คำตอบของเจอรี่ (ท่ามกลางประเด็นอื่น ๆ ):

(... ) มันมีแนวโน้มที่จะยากที่จะผลิตไฟล์เอ็กซีคิวต์เล็ก ๆ อย่างแท้จริงด้วย C ++ สำหรับระบบขนาดเล็กจริงๆคุณไม่ค่อยเขียนโค้ดจำนวนมากและส่วนเพิ่มเติม (... )

ที่ฉันถามว่าทำไมที่จะเป็นไปได้ซึ่ง Jerry ตอบ:

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

ซึ่งฉันไม่สงสัยจริงๆในระดับโลกทางเทคนิคจริง


ดังนั้นฉันสนใจ (หมดจดจากความอยากรู้อยากเห็น) ที่จะได้ยินจากตัวอย่างในโลกแห่งความจริงที่โครงการเลือก C ++ เป็นภาษาแล้วเลือกปิดการใช้งานข้อยกเว้น (ไม่ใช่เพียงแค่ "ไม่ใช้" ข้อยกเว้นในรหัสผู้ใช้ แต่ปิดการใช้งานในคอมไพเลอร์เพื่อที่คุณจะไม่สามารถโยนหรือตรวจจับข้อยกเว้น) ทำไมโครงการจึงเลือกที่จะทำเช่นนั้น (ยังคงใช้ C ++ และไม่ใช่ C แต่ไม่ใช่ ข้อยกเว้น) - อะไรคือ / เหตุผล (ทางเทคนิค) คืออะไร?


ภาคผนวก: สำหรับผู้ที่ต้องการอธิบายรายละเอียดเกี่ยวกับคำตอบของพวกเขาจะเป็นการดีที่จะให้รายละเอียดเกี่ยวกับการจัดการกับข้อยกเว้นที่ไม่มีข้อยกเว้น:

  • คอลเลกชัน STL ( vector, ... ) ทำงานไม่ถูกต้อง (ไม่สามารถรายงานความล้มเหลวในการจัดสรร)
  • new ไม่สามารถโยนได้
  • ก่อสร้างไม่สามารถล้มเหลว

1
JSF C ++ เจ็ตส์และข้อยกเว้นไม่รวมกัน
Coder

1
ข้อมูลบางอย่างที่กระจ่างแจ้งเกี่ยวกับปัญหาที่มีข้อยกเว้น (และ C ++ โดยทั่วไป) 250bpm.com/blog:4
Ambroz Bizjak

1
@AmbrozBizjak - ฉันจะอ้างอิง DeadMG จากความคิดเห็นไปยังโพสต์ที่คุณลิงค์ไปที่: อ้างว่า: "ดูเหมือนว่าฉันจะไม่เข้าใจข้อยกเว้น" ฉันเห็นด้วย. ผู้เขียนทำเลอะจัดการอย่างชัดเจนโดยดูตัวอย่างที่เขาให้ไว้ในโพสต์นั้น
Martin Ba

คำตอบ:


35

เกือบทุกเกมคอนโซลมีอยู่ใน C ++ ยกเว้นการยกเลิกแม้กระทั่งทุกวันนี้ ในตอนแรกเป็นการตั้งค่าเริ่มต้นสำหรับคอมไพเลอร์ C ++ ที่กำหนดเป้าหมายไปที่คอนโซลเหล่านั้น บางครั้งคุณสมบัติ C ++ บางอย่างไม่รับประกันว่าจะทำงานอย่างถูกต้องกับคอมไพเลอร์เหล่านั้นเช่นการสืบทอดหลาย ๆ ครั้ง (ฉันกำลังคิดถึงคอมไพเลอร์คอนโซลที่รู้จักกันดีเช่น)


นอกจากนี้อีกตัวอย่างหนึ่งคือฮาร์ดแวร์ Arduino SDK usnig GCC โดยไม่มีข้อยกเว้นการเปิดใช้งานใน C ++ และสิ่งอื่น ๆ เช่น STL ไม่มีที่จัดไว้ให้


มีเหตุผลทางเทคนิคไม่ว่าดีหรือไม่ดีไม่ได้เป็นคำแนะนำของฉัน แต่เป็นเหตุผลที่ฉันได้ยิน:

  1. คอนโซลส่วนใหญ่เป็นระบบฝังตัวจริงๆที่มีหน่วยความจำ จำกัด และเวลาในการประมวลผล บางทีมันอาจจะไม่เป็นความจริงในอนาคตคอนโซล แต่คนปัจจุบันยังคงมีข้อ จำกัด ก่อนเมื่อเทียบกับพีซี คอนโซลแบบพกพาบางตัวสามารถตั้งโปรแกรมได้ยากกว่าสมาร์ทโฟนทุกเครื่องเช่น NDS คุณสมบัติข้อยกเว้นเพิ่มหน่วยความจำและค่าใช้จ่ายเล็กน้อยแม้ว่าคุณจะไม่ได้ใช้ก็ตาม คุณสามารถตรวจสอบด้วยตัวคุณเองมันเป็นเรื่องจริงแม้บนพีซี
  2. วิดีโอเกมบนคอนโซลไม่สามารถผิดพลาดได้ พวกเขาจะต้องได้รับการทดสอบในวิธีที่หลีกเลี่ยงความผิดพลาดใด ๆ หรือความตายใด ๆ showstoper ใด ๆ นั่นเป็นเหตุผลที่ผู้ผลิตคอนโซลขอให้เกมตรวจสอบอย่างหนักก่อนที่จะเผยแพร่ นั่นก็หมายความว่าการจัดการข้อยกเว้นเพิ่มค่าใช้จ่ายที่ไม่ได้มีประโยชน์จริงๆในกรณีของเกมคอนโซล จะดีกว่าในสมาร์ทโฟนเช่นอาจมีวิธีกู้คืนหรือเพิ่มรหัสเพื่อส่งอีเมลถึงปัญหา แพลตฟอร์มที่ปิดเช่นคอนโซลส่วนใหญ่ไม่อนุญาตสิ่งนี้ ดังนั้นระบบการยกเว้นจึงไม่จำเป็นจริงๆ คุณ "แค่ต้องทำให้มันทำงานอย่างถูกต้อง" ;)
  3. การจัดการข้อยกเว้นเมื่อคุณไม่อนุญาตให้มีข้อผิดพลาดและล้มเหลวหมายความว่าคุณต้องใช้กลยุทธ์การจัดการข้อผิดพลาด ระบบดังกล่าวอาจซับซ้อนพอที่จะทำให้ใครคนหนึ่งทำงานได้มากเพื่อให้มีประโยชน์ นักพัฒนาเกมไม่มีความหรูหราในการทำงานกับคุณสมบัติที่คิดว่ามีประโยชน์ในการล่ม ...
  4. คอมไพเลอร์ไม่อนุญาต (ยัง) ใช่มันเกิดขึ้น

ฉันคิดว่าข้อยกเว้นมีประโยชน์แม้ในเกม แต่นั่นเป็นของจริงในเกมคอนโซลมันไม่มีประโยชน์จริงๆ


ปรับปรุง:

ฉันกำลังเพิ่มอีกตัวอย่างที่น่าแปลกใจที่นี่: LLVM / CLang ไม่ได้ใช้ข้อยกเว้นหรือ RTTI ด้วยเหตุผลดังต่อไปนี้ :

ในความพยายามที่จะลดรหัสและขนาดที่สามารถใช้งานได้ LLVM จะไม่ใช้ RTTI (เช่น dynamic_cast <>) หรือข้อยกเว้น คุณสมบัติสองภาษาเหล่านี้ละเมิดหลักการทั่วไปของ C ++ ของ "คุณจ่ายเฉพาะสิ่งที่คุณใช้" ทำให้เกิดการขยายตัวที่สามารถดำเนินการได้แม้ว่าจะไม่มีข้อยกเว้นในฐานรหัสหรือ RTTI ไม่เคยใช้สำหรับชั้นเรียน ด้วยเหตุนี้เราจึงปิดรหัสทั่วโลกในรหัส

ที่กล่าวว่า LLVM มีการใช้ RTTI ในรูปแบบรีดด้วยมือที่ใช้เทมเพลตเช่น isa <>, cast <> และ dyn_cast <> RTTI รูปแบบนี้เป็นการเลือกใช้และสามารถเพิ่มในชั้นเรียนใดก็ได้ นอกจากนี้ยังมีประสิทธิภาพมากขึ้นกว่า dynamic_cast <>

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


9
(3): คุณต้องการกลยุทธ์การจัดการข้อผิดพลาดไม่ว่าจะเกิดอะไรขึ้นถ้าคุณจะไปพร้อมกับ (2) ปัญหาจะเกิดขึ้นและซอฟต์แวร์คอนโซลของคุณต้องล้มเหลวอย่างนุ่มนวลและสง่างาม ฉันไม่ชัดเจนว่าการหลีกเลี่ยงข้อยกเว้นทำให้ง่ายขึ้นทั้งหมด
David Thornley

6
ตัวอย่างที่ดีทั้งหมดของสภาพแวดล้อมรันไทม์ที่ควบคุมอย่างแน่นหนาซึ่งจัดการข้อผิดพลาดอย่างเหมาะสมและไม่มีเหตุการณ์ "พิเศษ"
Patrick Hughes

1
@DavidThornley เพราะคุณคิดว่าระบบคอนโซลจะจัดการข้อผิดพลาดบางอย่างได้ แต่จะไม่ อาจจะเป็นบน PS3 หรือ XBox แต่จะไม่ได้รับอนุญาตให้ผ่านการทดสอบของผู้สร้างคอนโซล อย่างไรก็ตามเฟิร์มแวร์ของคอนโซลขั้นสูงส่วนใหญ่นั้นไม่ยืดหยุ่นเท่าที่คุณคิด เกมคอนโซลจำเป็นต้องเข้าถึงฮาร์ดแวร์ของคอนโซลเกือบทั้งหมดดังนั้นคุณจึงสามารถนึกถึงเกมที่ทำงานบนคอนโซลได้ราวกับว่ามันเป็น "OS" ของคอนโซล ... ยิ่งเรามีคอนโซลที่ทรงพลังมาก น้อยมันเป็นความจริง ดังนั้นฉันเห็นด้วยกับคุณว่ามันดูแปลกสำหรับบางกรณี
Klaim

2
นี่เป็นคำตอบที่ดีฉันอยากจะเพิ่มว่าแม้ว่าจะมีข้อผิดพลาดเกิดขึ้นและแสดงข้อผิดพลาดให้กับผู้ใช้เขาหรือเธอควรทำอย่างไรกับ D-pad ทางออกที่แท้จริงเพียงอย่างเดียวสำหรับผู้ใช้คือการรีสตาร์ท
anon

2
ฉันลบตัวอย่างความเขลาเพราะใครบางคนในทีมของพวกเขากล่าวว่าการเพิ่มการยกเว้นไม่ได้หมายความว่า "ไม่ต้องใช้ข้อยกเว้น" แต่ "ไม่มีข้อยกเว้นกฎ" ดูpermalink.gmane.org/gmane.comp.lib.boost.devel/231377
Klaim

9

เจอร์รี่กล่าวว่า: ... ผลที่ได้คือไม่ได้ค่อนข้าง c ++ อีกต่อไปในขณะที่คำอุปมาของฉันก็คือว่ามันเป็นอย่างชัดเจน c ++ เพียงแตกต่างกันเล็กน้อยภาษาเพราะโปรแกรมใช้รูปแบบอื่น ๆ การประชุมและรูปแบบการเขียน

นี่คือเหตุผลหลักของฉันสำหรับการปิดการใช้งาน:

ความเข้ากันได้ไบนารี

การข้ามภาษาและขอบเขตการแปลไม่ได้กำหนดไว้อย่างดีในระดับสากลหรือไม่ได้กำหนด หากคุณต้องการรับประกันว่าโปรแกรมของคุณทำงานภายในโดเมนของพฤติกรรมที่กำหนดคุณจะต้องกักกันข้อยกเว้นที่จุดออกจากโมดูล

ขนาดที่ทำงานได้

นี่คือขนาดไบนารีของโปรแกรมฟรีที่เป็นข้อยกเว้นที่ฉันเขียนสร้างโดยไม่มีและเปิดใช้งานข้อยกเว้น:

โดยไม่มีข้อยกเว้น:

  • executable + dependencies: 330
  • ไฟล์สั่งการแบบถอดได้สุดท้าย (build build): 37

ด้วยข้อยกเว้น:

  • executable + dependencies: 380
  • ไฟล์สั่งการที่ถูกปล้นขั้นสุดท้าย (build build): 44

คำเตือน: นั่นคือคอลเล็กชันของไลบรารีและโปรแกรมที่มีการส่ง / จับเป็นศูนย์ ธงคอมไพเลอร์จะช่วยให้ข้อยกเว้นในห้องสมุดมาตรฐาน C ++ ดังนั้นค่าใช้จ่ายในโลกแห่งความเป็นจริงจึงเห็นมากกว่า 19% ในตัวอย่างนี้

คอมไพเลอร์: apple gcc4.2 + llvm ขนาดเป็น MB

ความเร็ว

แม้จะมีคำว่า "การยกเว้นค่าใช้จ่ายที่เป็นศูนย์" แต่พวกเขายังคงเพิ่มค่าใช้จ่ายบางอย่างแม้ว่าจะไม่มีอะไรเกิดขึ้น ในกรณีข้างต้นมันเป็นโปรแกรมที่สำคัญเกี่ยวกับประสิทธิภาพ (การประมวลสัญญาณการสร้างการนำเสนอการแปลงด้วยชุดข้อมูล / สัญญาณขนาดใหญ่เป็นต้น) ข้อยกเว้นไม่ใช่คุณสมบัติที่จำเป็นในการออกแบบนี้ในขณะที่ประสิทธิภาพมีความสำคัญมาก

ความถูกต้องของโปรแกรม

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

ความง่าย

ข้อยกเว้นการใช้งานการจัดการไม่ได้รับการปรับปรุงให้ทันสมัยอยู่เสมอ พวกเขายังเพิ่มความซับซ้อนมากเพราะการใช้งานสามารถมีหลายทางออกมากมาย มันง่ายกว่าในการอ่านและบำรุงรักษาโปรแกรมที่ซับซ้อนสูงเมื่อใช้ชุดเล็ก ๆ ที่กำหนดไว้ดีพิมพ์ออกกลยุทธ์ที่ฟองสบู่และจัดการโดยลูกค้า ในกรณีอื่น ๆ การใช้งานอาจใช้เวลามากขึ้นหรือการอ้างอิงของพวกเขาอาจแนะนำพวกเขา ลูกค้าไม่สามารถป้องกันการออกจากสิ่งเหล่านี้ได้อย่างง่ายดายหรืออย่างง่ายดาย ฉันเขียนและอัปเดตห้องสมุดจำนวนมากมีวิวัฒนาการและการปรับปรุงบ่อยครั้ง การพยายามทำให้ทุกอย่างสอดคล้องกับลำดับการออกยกเว้น (ในฐานข้อมูลขนาดใหญ่) จะไม่ใช้เวลาและอาจเพิ่มเสียงรบกวนและ cruft เป็นจำนวนมาก เนื่องจากความถูกต้องของโปรแกรมที่เพิ่มขึ้นและการทดสอบเพิ่มเติม

ประวัติ / รหัสที่มีอยู่

ในบางกรณีพวกเขาไม่เคยได้รับการแนะนำด้วยเหตุผลทางประวัติศาสตร์ codebase ที่มีอยู่ไม่ได้ใช้งานการเปลี่ยนแปลงโปรแกรมอาจใช้เวลาหลายปีและทำให้มันน่าเกลียดจริงๆที่จะรักษาเพราะการทับซ้อนกันในการประชุมและการใช้งาน

ข้อเสีย

แน่นอนว่ามีข้อเสียที่ใหญ่ที่สุดคือ: ความไม่เข้ากัน (รวมเลขฐานสอง) กับห้องสมุดอื่น ๆ และความจริงที่ว่าคุณจะต้องใช้โปรแกรมจำนวนมากเพื่อให้เหมาะกับรุ่นนี้


+1 ข้อมูลที่ยอดเยี่ยม! (แม้ว่าฉันจะไม่เห็นด้วยกับวรรค Simplicity)
มาร์ตินบา

มันจะน่าสนใจถ้าคุณมีคอนสตรัคเตอร์ที่ไม่มีข้อผิดพลาดและวิธีจัดการการจัดสรร (- ความล้มเหลว)
Martin Ba

@ มาร์ติน 1) ไม่เห็นด้วยค่อนข้างดี ฉันเข้าใจว่า devs ส่วนใหญ่ไม่เห็นด้วยกับการปิดใช้งานข้อยกเว้นด้วยเหตุผลหลายประการ เพื่อความเรียบง่ายมันจะไปพร้อมกับความถูกต้องของโปรแกรม ปัญหา / รัฐที่ไม่ถูกต้องนั้นไม่ได้รับอนุญาตให้เดินทางไกล นั่นหมายความว่าพวกเขาตรวจสอบความล้มเหลวและออกอย่างสง่างาม โพสต์ของ jheriko สะท้อนสิ่งนี้
justin

1
@Martin 2b) การจัดสรรนั้นซับซ้อนกว่าเล็กน้อย ขั้นแรกจำนวนการจัดสรรฮีปจะลดลงในจำนวนและเพิ่มขนาด - มีการจัดสรรฮีปค่อนข้างน้อยเริ่มต้นด้วย ประการที่สองการจัดสรรผ่านตัวจัดสรรที่กำหนดเอง หากการจัดสรรไม่ได้ถูกจัดเตรียมไว้สำหรับตัวจัดสรร (เช่นmallocส่งคืน0) ในตอนแรกตัวจัดสรรจะเข้าสู่ตัวwhile (1)ที่มีการสลับบริบทแล้วตามด้วยความพยายามในการจัดสรรอีกครั้ง ใน codebase นี้มันเคยเป็นสิ่งใหม่ผ่านตัวจัดสรรสามารถส่งคืน 0 แต่การใช้งานที่ใหม่กว่านั้นทำงานได้ดี (ต่อ)
justin

2
ใช่มี wrapper ที่ใช้งานได้กับ stl บนอินเตอร์เฟสตัวจัดสรรที่กำหนดเอง ในทางเทคนิคโปรแกรมจะไม่ยกเลิกในรุ่น; มันจะแนะนำสวิตช์บริบท (เช่นอนุญาตให้เธรดอื่นทำงานซึ่งหวังว่าจะเพิ่มหน่วยความจำบางส่วน) ลองอีกครั้งและเข้าสู่ระบบหากล้มเหลว - ตลอดไป การทดสอบหน่วยสามารถทำงานได้หลายวันโดยไม่มีปัญหา ภัยคุกคามที่แท้จริงเพียงอย่างเดียวคือการจัดสรรจำนวนมากซึ่งส่วนใหญ่จะถูกดักจับก่อนที่จะร้องขอ อีกครั้งอัตราความล้มเหลวของระบบยังอยู่ในเรดาร์ ณ จุดนี้; ความเป็นไปได้มีอยู่ว่าพวกเขาจะล้มเหลวก่อนการดำเนินการหลักในสถานการณ์ดังกล่าว
justin

7

Google ไม่อนุมัติข้อยกเว้นในคู่มือสไตล์ C ++ซึ่งส่วนใหญ่เป็นเพราะเหตุผลทางประวัติศาสตร์:

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

ระบุว่ารหัสที่มีอยู่ของ Google ไม่ได้เป็นข้อยกเว้นค่าใช้จ่ายในการใช้ข้อยกเว้นจะค่อนข้างมากกว่าค่าใช้จ่ายในโครงการใหม่ กระบวนการแปลงจะช้าและผิดพลาดได้ง่าย เราไม่เชื่อว่าทางเลือกที่มีอยู่สำหรับข้อยกเว้นเช่นรหัสข้อผิดพลาดและการยืนยันจะแนะนำภาระที่สำคัญ

คำแนะนำของเราต่อการใช้ข้อยกเว้นไม่ได้บอกกล่าวล่วงหน้าในพื้นที่ทางปรัชญาหรือทางศีลธรรม แต่เป็นข้อปฏิบัติ เนื่องจากเราต้องการใช้โครงการโอเพ่นซอร์สของเราที่ Google และเป็นการยากที่จะทำเช่นนั้นหากโครงการเหล่านั้นใช้ข้อยกเว้นเราจึงจำเป็นต้องให้คำแนะนำกับข้อยกเว้นในโครงการโอเพ่นซอร์สของ Google ด้วย สิ่งที่อาจจะแตกต่างกันถ้าเราต้องทำมันทั้งหมดอีกครั้งตั้งแต่เริ่มต้น

มีข้อยกเว้นสำหรับกฎนี้ (ไม่มีการเล่นสำนวนเจตนา) สำหรับรหัส Windows

(ความสำคัญของบรรณาธิการ)


5

Qt แทบไม่เคยใช้ข้อยกเว้น ข้อผิดพลาดใน Qt มีความหมายด้วยรหัสข้อผิดพลาดและสัญญาณ เหตุผลที่ระบุไว้อย่างเป็นทางการคือ:

เมื่อ Qt เริ่มต้นข้อยกเว้นไม่พร้อมใช้งานสำหรับคอมไพเลอร์ทั้งหมดที่จำเป็นต้องได้รับการสนับสนุนโดย Qt วันนี้เราพยายามรักษา API ให้สอดคล้องกันดังนั้นโมดูลที่มีประวัติไม่ใช้ข้อยกเว้นจะไม่ได้รับรหัสใหม่โดยใช้ข้อยกเว้นที่เพิ่มเข้ามา

ทำไม QT ใช้ข้อยกเว้นน้อยมาก

ทุกวันนี้คำวิจารณ์ทั่วไปของ Qt ก็คือว่าข้อยกเว้นด้านความปลอดภัยยังไม่สมบูรณ์


1
ขอบคุณ ข้อมูลดี แต่ฉันสงสัยว่าส่วนใหญ่ QT รหัสฐานอาจจะมีข้อยกเว้นเปิดใช้งานในคอมไพเลอร์ ...
มาร์ตินบา

4

Symbian C ++ (ใช้กับโทรศัพท์มือถือ Nokia บางรุ่น) ไม่ได้ใช้ข้อยกเว้นอย่างน้อยก็ไม่โดยตรงเพราะคอมไพเลอร์ C ++ ไม่ได้ใช้งานได้อย่างเชื่อถือได้เมื่อ Symbian ได้รับการพัฒนาขึ้นเป็นครั้งแรก


1
สิ่งนี้ไม่ถือเป็น Symbian เวอร์ชันใหม่ Symbian TRAP และใบไม้ถูกนำมาใช้เป็นข้อยกเว้น C ++ จริงแต่ EPOC32 และ Symbian เวอร์ชันเก่านั้นใช้วิธีการอื่น (setjmp / longjmp ถ้าฉันจำได้ถูกต้อง)
otto

1
@OttoHarju: นั่นคือสิ่งที่ฉันหมายถึง "อย่างน้อยไม่ได้โดยตรง"
Keith Thompson

3

ฉัน / ไม่เคย / ใช้ข้อยกเว้น มีหลายสาเหตุด้วยกัน แต่เหตุผลหลัก ๆ สองข้อคือฉันไม่เคยต้องการให้พวกเขาสร้างรหัสที่มีประสิทธิภาพและลดประสิทธิภาพในการใช้งานจริง

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

ไม่มีอะไรผิดปกติอย่างร้ายแรงกับข้อยกเว้นตัวเอง / ถ้าคุณไม่สนใจเกี่ยวกับประสิทธิภาพ / และไม่มีเวลาที่จะทำอะไรอย่างถูกต้อง - เป็นคุณสมบัติภาษาสำหรับการจัดการข้อผิดพลาดและทดแทนที่ดีสำหรับกลไกการจัดการข้อผิดพลาดที่เหมาะสม อย่างไรก็ตามมีเกือบ / ดีกว่า / วิธีในการจัดการข้อผิดพลาด - เช่นเดียวกับตรรกะของคุณเอง (มันยากที่จะอธิบายรายละเอียดเกี่ยวกับเรื่องนี้ - มันเป็นเรื่องธรรมดาสามัญเกือบ) หากไม่ใช่ข้อผิดพลาดของคุณ แต่มาจากไลบรารี (เช่นไลบรารีมาตรฐาน) คุณต้องเคารพตัวเลือกของข้อยกเว้นหรือมีข้อผิดพลาดบางอย่าง แต่ฉันจะถามตัวเลือกนั้นเสมอ ฉันไม่เคยเห็นสถานการณ์ที่ข้อยกเว้นเป็นทางออกที่ดีที่สุด

การยืนยันสามารถ debuggable ได้มากขึ้นรหัสข้อผิดพลาดจะมีน้ำหนักน้อยกว่า ... ระหว่างสองหากใช้อย่างถูกต้องคุณจะสามารถอ่านแก้ไขและรักษารหัสได้เร็วขึ้น มันชนะทุกรอบ ...


1
Nope การใช้ข้อยกเว้นในทางที่ผิดได้ง่ายกว่า แต่ข้อยกเว้นอื่น ๆ นั้นทำงานได้ดี อย่างน้อยก็เป็นเรื่องง่ายที่จะให้เหตุผลหากฟังก์ชั่นทั้งหมดของคุณนั้นมีข้อยกเว้นที่ปลอดภัย การทำรหัสข้อผิดพลาดอย่างถูกต้องอาจเป็นเรื่องที่น่าเบื่อหน่ายอย่างมากและอาจส่งผลให้โปรแกรมของคุณฝังโค้ดผิดพลาด ในกรณีนั้นข้อยกเว้นจะดีกว่า โปรดจำไว้ว่าการทำสิ่งที่แตกต่างจากคุณไม่ใช่หลักฐานที่สรุปได้ว่าฉันไม่สนใจที่จะทำสิ่งที่ถูกต้อง
David Thornley

... สำหรับสาเหตุที่ RTTI ไม่ดีนั่นเป็นเรื่องราวอื่นทั้งหมด - RTTI ในตัวในคอมไพเลอร์ทุกตัวที่ฉันได้เห็นนั้นเอาชนะได้เล็กน้อย - ถ้าคุณต้องการ RTTI ด้วยซ้ำ มันเกี่ยวกับบริบททั้งหมด - สิ่งเหล่านี้เช่น RTTI และข้อยกเว้นนั้นยอดเยี่ยมสำหรับ RAD และแอพสำหรับองค์กร - พวกเขาไม่มีสถานที่ในโลกแห่งประสิทธิภาพสูง (เช่นเกม) การคำนวณ ฉันไม่เคยเห็น
เอ็นจิ้น

2
ขออภัย - RAII คือสิ่งที่ฉันหมายถึง หากคุณไม่ได้ใช้สิ่งนั้นไม่เพียง แต่ข้อยกเว้นเท่านั้นที่จะทำให้สับสน (อย่างไรก็ตามแบบไดนามิก casts ทำงานได้ดีมากในการทำงานของฉันและฉันจะต้องเกี่ยวข้องกับการแสดง)
David Thornley

หัวข้อที่น่าสนใจ: ฉันคิดว่าข้อยกเว้นอนุญาตให้มีข้อผิดพลาดที่กระชับยิ่งขึ้นในการจัดการโค้ด แต่รหัสข้อผิดพลาดจะมีประสิทธิภาพมากขึ้นเพราะพวกเขาอนุญาตให้จัดการข้อผิดพลาดภายในเครื่อง (คุณสามารถตรวจสอบรหัสส่งคืนได้ทันทีในผู้โทร และบางครั้งพวกเขาจะไม่ถูกจับส่งผลให้เกิดความผิดพลาดเว้นแต่คุณจะใช้ catch (... ))
Giorgio

3

ในมาตรฐานการเข้ารหัส Joint Strike Fighter C ++โดย Bjarne et al., ข้อยกเว้นถูกแบนเนื่องจากความต้องการแบบเรียลไทม์ของเครื่องบินรบแบบเรียลไทม์

JSF ++ เหมาะสำหรับการใช้งานแบบเรียลไทม์และปลอดภัยที่สำคัญ (ซอฟต์แวร์ควบคุมการบิน) หากการคำนวณใช้เวลานานเกินไปบางคนอาจเสียชีวิต ด้วยเหตุผลดังกล่าวเราจึงต้องรับประกันเวลาตอบสนองและเราไม่สามารถทำได้ - ด้วยการสนับสนุนเครื่องมือระดับปัจจุบัน - ทำเช่นนั้นเพื่อข้อยกเว้น ในบริบทนั้นการจัดสรรร้านค้าฟรีแม้ถูกแบน! ที่จริงแล้วคำแนะนำ JSF ++ สำหรับการจัดการข้อผิดพลาดจำลองการใช้ข้อยกเว้นในการรอคอยวันที่เรามีเครื่องมือในการทำสิ่งที่ถูกต้องเช่นการใช้ข้อยกเว้น

ยกมาจากBjarne ของ C ++ คำถามที่พบบ่อย

โปรดจำไว้ว่า C ++ อาจใช้งานซอฟต์แวร์ที่หลากหลายที่สุดในทุกภาษา ...


JSF ++ ยังห้ามการใช้ "ใหม่" (นอกเหนือจากตำแหน่งใหม่) และ "ลบ" ซึ่งเป็นหนึ่งในคำตอบที่ "ทำอย่างไรให้คุณจัดการกับความล้มเหลวใหม่โดยไม่ต้องมีข้อยกเว้น" บิตของคำถาม ...
armb

@armb: ใช่ โปรดดู "ในบริบทนั้นการจัดสรรร้านค้าฟรีแม้ถูกแบน! ข้างบน.
Macke

2

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

โดยส่วนตัวฉันเคยเห็นข้อยกเว้นถูกทารุณเมื่อทีมถูกสั่งให้ "โยนข้อยกเว้น" เมื่อใดก็ตามที่มีอะไรบางอย่างที่ไม่น่ากลัวเกิดขึ้น แน่นอนคุณเห็นข้อผิดพลาดที่นี่ - ข้อยกเว้นถูกโยนในรหัสก่อนที่จะมีใครคิดออกว่าจะทำอย่างไรกับมัน โครงการดังกล่าวมีปัญหาเกิดขึ้นเล็กน้อยเนื่องจากการขว้างปาลึกเหล่านี้ออกมาเป็นครั้งคราว


1

บางทีในเรื่องนี้ก็มูลค่าการกล่าวขวัญฝังตัว C สมองกลฝังตัว C ++ เป็นตัวแปรของการออกแบบ C ++ (ชัดเจนเพียงพอ) สำหรับระบบฝังตัว โดยพื้นฐานแล้วมันเป็นชุดย่อยที่เหมาะสมของ C ++ พร้อมด้วยแม่แบบ (เหนือสิ่งอื่นใด), เนมสเปซและการจัดการข้อยกเว้นถูกลบออก

ฉันควรเพิ่มว่าในขณะที่ EC ++ ทำสาดเล็กน้อยเมื่อมันใหม่พวกเขาดูเหมือนจะเงียบไปพอสมควร ฉันไม่แน่ใจว่าผู้คนหมดความสนใจหรือความพยายามครั้งแรกของพวกเขานั้นสมบูรณ์แบบมากจนไม่มีใครเห็นเหตุผลที่จะยุ่งกับมันมานานกว่าทศวรรษ<closed captioning for the humor impaired>Yeah, right!</closed captioning>


กำลังมองหาคำถาม & คำตอบ - caravan.net/ec2plus/question.html - ฉันว่ามันค่อนข้างตายแล้ว
Martin Ba

1

ตัวอย่างที่ดีคือการเขียนโปรแกรมในโหมดเคอร์เนล

คุณสามารถใช้ C ++ ที่นั่นเพื่อทำความสะอาดโค้ด แต่ไม่มีข้อยกเว้น ไม่มีไลบรารีรันไทม์สำหรับพวกเขาและการจัดการข้อยกเว้นใช้หน่วยความจำสแต็คมากเกินไปที่ จำกัด มากในเคอร์เนล (ฉันทดลองกับข้อยกเว้น C ++ ในเคอร์เนล Windows NT และการโยนข้อยกเว้นและคลี่คลายการกินสแต็กครึ่งหนึ่ง และพังทั้งระบบ)

โดยทั่วไปแล้วคุณกำหนดของคุณเองnewและdeleteผู้ประกอบการ นอกจากนี้ฉันยังพบว่ามีประโยชน์มากplacement newและ c + + 11 อ้างอิงค่า rvalue ไม่สามารถใช้ STL หรือไลบรารีโหมดผู้ใช้ C ++ อื่น ๆ ที่พึ่งพาข้อยกเว้นได้


0

เมื่อคุณพยายามที่จะให้หน่วยความจำปฏิบัติการลง โดยทั่วไปแล้วจะทำในระบบฝังตัว (หรือมือถือ) สำหรับแอปเดสก์ท็อปนั้นไม่จำเป็นต้องใช้ แต่บนเซิร์ฟเวอร์คุณอาจได้รับการพิจารณาหากคุณต้องการ ram มากที่สุดสำหรับเว็บเซิร์ฟเวอร์หรือสำหรับ sql

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.