กลับไปหน้าบทความ

อ่าน 4 นาที

รหัสที่ไม่สามารถเข้าถึงได้

ใน การเขียน โปรแกรมคอมพิวเตอร์โค้ดที่ไม่สามารถเข้าถึงได้คือส่วนหนึ่งของซอร์สโค้ดของโปรแกรมซึ่งไม่สามารถเรียกใช้งานได้เลย เนื่องจากไม่มี เส้นทาง...

รหัสที่ไม่สามารถเข้าถึงได้

ใน การเขียน โปรแกรมคอมพิวเตอร์โค้ดที่ไม่สามารถเข้าถึงได้คือส่วนหนึ่งของซอร์สโค้ดของโปรแกรมซึ่งไม่สามารถเรียกใช้งานได้เลย เนื่องจากไม่มี เส้นทาง ควบคุมการไหลไปยังโค้ดจากส่วนที่เหลือของโปรแกรม[ 1 ]

บางครั้งโค้ดที่ไม่สามารถเข้าถึงได้ก็เรียกว่าโค้ดที่ตายแล้ว [ 2 ] [ 3 ]แม้ว่าโค้ดที่ตายแล้วอาจหมายถึงโค้ดที่ถูกเรียกใช้งานแต่ไม่มีผลต่อผลลัพธ์ของโปรแกรมก็ตาม[ 4 ]

โดยทั่วไปแล้ว การเข้าถึงโค้ดไม่ได้ถือเป็นสิ่งที่ไม่พึงประสงค์ด้วยเหตุผลหลายประการ:

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

สาเหตุ

โค้ดที่ไม่สามารถเข้าถึงได้อาจเกิดขึ้นได้จากหลายสาเหตุ เช่น:

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

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

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

ตัวอย่าง

ในส่วนของโค้ดภาษาซีนี้:

int foo ( int x , int y ) { return x + y ; int z = x + y ; }

นิยามนี้จะไม่ถูกเรียกใช้เลย เนื่องจากฟังก์ชันจะส่งค่ากลับก่อนเสมอ ดังนั้น ตัวแปรจึงไม่จำเป็นต้องได้รับการจัดสรรพื้นที่จัดเก็บหรือกำหนดค่าเริ่มต้น intz=x+y;z

goto ล้มเหลว บั๊ก

SSL/TLSของ Apple จากเดือนกุมภาพันธ์ 2014 มีช่องโหว่ด้านความปลอดภัยที่สำคัญซึ่งรู้จักกันอย่างเป็นทางการในชื่อCVE - 2014-1266และเรียกกันอย่างไม่เป็นทางการว่า "goto fail bug" [ 5 ] [ 6 ] ส่วนของโค้ดที่เกี่ยวข้อง[ 7 ] คือ:

static OSStatus SSLVerifySignedServerKeyExchange ( SSLContext * ctx , bool isRsa , SSLBuffer signedParams , uint8_t * signature , uint16_t signatureLen ) { OSStatus err ; // ... if (( err = SSLHashSHA1 . update ( & hashCtx , & serverRandom )) != 0 ) goto fail ; if (( err = SSLHashSHA1 . update ( & hashCtx , & signedParams )) != 0 ) goto fail ; goto fail ; if (( err = SSLHashSHA1 . final ( & hashCtx , & hashOut )) != 0 ) goto fail ;// ... ล้มเหลว: SSLFreeBuffer ( & signedHashes ); SSLFreeBuffer ( & hashCtx ); ส่งคืนerr ; }

ในที่นี้มีgoto failคำสั่งสองคำสั่งที่ต่อเนื่องกัน ในไวยากรณ์ของภาษา Cคำสั่งแรกหลังจากifคำสั่งที่ไม่มีวงเล็บปีกกาเท่านั้นที่จะเป็นเงื่อนไข ดังนั้นคำสั่งที่สองgoto failจึงไม่มีเงื่อนไข และด้วยเหตุนี้จึงข้ามการเรียกใช้เสมอSSLHashSHA1.finalผลที่ตามมาคือerrจะเก็บสถานะของ การดำเนินการอัปเดต SHA1และตราบใดที่การเรียกใช้ ทั้งสองครั้งSSLHashSHA1.updateสำเร็จ การตรวจสอบลายเซ็นจะไม่ล้มเหลว[ 5 ]

ในที่นี้ โค้ดที่ไม่สามารถเข้าถึงได้คือการเรียกใช้finalฟังก์ชัน[ 6 ]การใช้ คอมไพเลอร์ Clangพร้อมตัวเลือก-Weverythingจะรวมการวิเคราะห์โค้ดที่ไม่สามารถเข้าถึงได้ ซึ่งจะทำให้เกิดสัญญาณเตือนสำหรับโค้ดนี้[ 6 ]

ซี++

ในC++โครงสร้างบางอย่างถูกกำหนดให้มีพฤติกรรมที่ไม่แน่นอนคอมไพเลอร์มีอิสระที่จะใช้งานพฤติกรรมใดๆ หรือไม่มีเลย และโดยทั่วไปคอมไพเลอร์ที่ปรับแต่งประสิทธิภาพจะถือว่าโค้ดนั้นไม่สามารถเข้าถึงได้[ 8 ]

การวิเคราะห์

การตรวจจับโค้ดที่ไม่สามารถเข้าถึงได้เป็นรูปแบบหนึ่งของการวิเคราะห์การไหลของควบคุมเพื่อค้นหาโค้ดที่ไม่สามารถเข้าถึงได้ในสถานะโปรแกรมที่เป็นไปได้ใดๆ ในบางภาษา (เช่นJava [ 9 ] ) โค้ดที่ไม่สามารถเข้าถึงได้บางรูปแบบจะถูกห้ามโดยชัดแจ้ง การเพิ่มประสิทธิภาพที่ลบโค้ดที่ไม่สามารถเข้าถึงได้เรียกว่าการกำจัดโค้ดที่ตายแล้ว

โค้ดอาจไม่สามารถเข้าถึงได้อันเป็นผลมาจากการแปลงที่ดำเนินการโดยคอมไพเลอร์ที่ปรับแต่งประสิทธิภาพ (เช่นการกำจัดนิพจน์ย่อยที่เหมือนกัน )

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

int n = 2 + 1 ;ถ้า( n == 4 ) { // เข้าถึงไม่ได้}

อย่างไรก็ตาม จำเป็นต้องใช้ความซับซ้อนมากกว่านี้มากจึงจะสามารถระบุได้ว่าบล็อกที่เกี่ยวข้องนั้นไม่สามารถเข้าถึงได้ในโค้ดต่อไปนี้:

#include <math.h>double x = sqrt ( 2 );ถ้า( x > 5 ) { // เข้าถึงไม่ได้}

เทคนิคการกำจัดโค้ดที่ไม่สามารถเข้าถึงได้นั้น จัดอยู่ในกลุ่มการเพิ่มประสิทธิภาพเดียวกับการกำจัดโค้ดที่ไม่ได้ใช้งานและการกำจัด โค้ดที่ซ้ำซ้อน

บางภาษาอนุญาตให้ระบุโค้ดที่ไม่สามารถเข้าถึงได้โดยชัดเจน:

  • C : ผ่านมาโคร (ใน) [ 10 ]unreachable()<stddef.h>
  • C++ : ผ่านฟังก์ชัน (ใน) ซึ่งคือ[ 11 ]std::unreachable()<utility>[[noreturn]]
  • C# : สามารถระบุได้โดยใช้คลาส โดยใช้เมธอด[ 12 ]System.Diagnostics.DebugDebug.Fail()
  • Java : โดยปกติจะทำเครื่องหมายโดยการโยนข้อยกเว้น[ 13 ]java.lang.AssertionError
  • Rust : ผ่านทางมาโคร[ 14 ]unreachable!()
  • Swift : ผ่านหรือฟังก์ชันที่ส่งคืน[ 15 ]fatalError()Never
  • Zig : ผ่านunreachableคำหลัก[ 16 ]

การเข้าถึงไม่ได้เทียบกับการสร้างโปรไฟล์

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

ดูเพิ่มเติม

ดึงข้อมูลมาจาก " https://en.wikipedia.org/w/index.php?title=Unreachable_code&oldid=1352109556 "

สรุปเนื้อหา

ข้อมูลสำคัญจากบทความ

ข้อมูลสำคัญเกี่ยวกับ รหัสที่ไม่สามารถเข้าถึงได้

ใน การเขียน โปรแกรมคอมพิวเตอร์โค้ดที่ไม่สามารถเข้าถึงได้คือส่วนหนึ่งของซอร์สโค้ดของโปรแกรมซึ่งไม่สามารถเรียกใช้งานได้เลย เนื่องจากไม่มี เส้นทาง...

สาเหตุ

โค้ดที่ไม่สามารถเข้าถึงได้อาจเกิดขึ้นได้จากหลายสาเหตุ เช่น:

goto ล้มเหลว บั๊ก

SSL/TLS ของ Apple จากเดือนกุมภาพันธ์ 2014 มีช่องโหว่ด้านความปลอดภัยที่สำคัญซึ่งรู้จักกันอย่างเป็นทางการในชื่อ CVE - 2014-1266และเรียกกันอย่างไม่เป็นทางการว่า "goto fail bug" [ 5 ] [ 6 ] ส่วนของโค้ดที่เกี่ยวข้อง [ 7 ] คือ:

ซี++

ใน C++ โครงสร้างบางอย่างถูกกำหนดให้มี พฤติกรรมที่ไม่แน่นอน คอมไพเลอร์มีอิสระที่จะใช้งานพฤติกรรมใดๆ หรือไม่มีเลย และโดยทั่วไปคอมไพเลอร์ที่ปรับแต่งประสิทธิภาพจะถือว่าโค้ดนั้นไม่สามารถเข้าถึงได้ [ 8 ]