อะไรคือประโยชน์ของการยกเลิกถ้า…อื่นถ้าสร้างด้วยประโยคอื่น?


136

องค์กรของเรามีกฎการเข้ารหัสที่ต้องการ (ไม่มีคำอธิบายใด ๆ ) ที่:

ถ้า…อื่นถ้าการสร้างควรถูกยกเลิกด้วยประโยคอื่น

ตัวอย่างที่ 1:

if ( x < 0 )
{
   x = 0;
} /* else not needed */

ตัวอย่างที่ 2:

if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
}

เคสแบบขอบนี้ออกแบบมาเพื่อจัดการอย่างไร?

สิ่งที่เกี่ยวข้องกับฉันเกี่ยวกับเหตุผลก็คือตัวอย่างที่ 1ไม่จำเป็นelseแต่ตัวอย่างที่ 2ทำ หากเหตุผลคือการใช้งานใหม่และการขยายฉันคิดว่าelseควรจะใช้ในทั้งสองกรณี


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

32
ตัวอย่างที่ 2 เป็นตัวอย่างที่ดีสำหรับที่ที่assert(false, "should never go here")อาจทำให้รู้สึก
Thilo

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

4
if (x < 0) { x = 0; } else { if (y < 0) { x = 3; }}คุณก็สามารถเอาชนะถ้ามี หรือคุณเพียงแค่ทำตามกฎดังกล่าวซึ่งส่วนใหญ่เป็นเรื่องโง่ ๆ เพียงเพราะคุณจำเป็นต้องทำ
Jim Balter

3
@Thilo ฉันมาช้า แต่ก็ยังไม่มีใครทำผิด: ไม่มีข้อบ่งชี้ว่าคนอื่นไม่ควรจะเกิดขึ้นเพียงว่ามันจะไม่มีผลข้างเคียง (ซึ่งดูเหมือนว่าปกติเมื่อทำการ< 0ตรวจสอบ) เพื่อยืนยัน เพื่อผิดพลาดโปรแกรมในกรณีที่น่าจะเป็นกรณีที่พบบ่อยที่สุดที่ค่าอยู่ในขอบเขตที่คาดหวัง
Loduwijk

คำตอบ:


148

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

นั่นคือทุกif - else ifสิ้นต้องมีสระelseและทุกสิ้นต้องมีswitchdefault

มีสองเหตุผลสำหรับสิ่งนี้:

  • รหัสเอกสารด้วยตนเอง ถ้าคุณเขียนelseแต่ปล่อยให้มันว่างเปล่ามันหมายความว่า "ผมได้มีการพิจารณาแน่นอนสถานการณ์เมื่อค่าifมิได้else ifเป็นจริง"

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

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

    if (mybool == TRUE) 
    {
    } 
    else if (mybool == FALSE) 
    {
    }
    else
    {
      // handle error
    }

    รหัสนี้จะแปลกใหม่อย่างสิ้นเชิงกับโปรแกรมเมอร์ PC และนักวิทยาศาสตร์คอมพิวเตอร์ แต่มันก็สมเหตุสมผลดีในซอฟต์แวร์ที่มีความสำคัญต่อภารกิจเพราะมันจะจับกรณีที่ "mybool" เสียหายไปไม่ว่าจะด้วยเหตุผลใดก็ตาม

    ในอดีตคุณจะกลัวความเสียหายของหน่วยความจำ RAM เนื่องจาก EMI / เสียงรบกวน นี่ไม่ใช่ปัญหาของวันนี้ มีความเป็นไปได้สูงที่ความเสียหายของหน่วยความจำเกิดขึ้นเนื่องจากข้อผิดพลาดอื่น ๆ ในรหัส: ตัวชี้ไปยังตำแหน่งที่ไม่ถูกต้องข้อบกพร่องของอาร์เรย์ที่ไม่อยู่ในขอบเขต, สแต็กล้น, รหัสที่ไม่สามารถควบคุมได้เป็นต้น

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


แก้ไข

เกี่ยวกับสาเหตุที่elseไม่จำเป็นหลังจากทุก ๆif :

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

พลัสก็จะถ่วงขึ้นรหัสสมบูรณ์หากคุณเขียนที่ว่างเปล่าหลังจากที่แต่ละคนและทุกelseif

MISRA-C: 2012 15.7 ไม่ให้เหตุผลว่าทำไมelseไม่ต้องการมันเป็นเพียงแค่กล่าวว่า:

หมายเหตุ: elseคำสั่งสุดท้ายไม่จำเป็นสำหรับif คำสั่งง่ายๆ


6
หากหน่วยความจำเสียหายฉันคาดว่ามันจะทำลายมากกว่าแค่ mybool รวมถึงรหัสตรวจสอบด้วยตัวเอง ทำไมคุณไม่เพิ่มบล็อกอื่นที่ยืนยันว่าคุณได้if/else if/elseรวบรวมสิ่งที่คุณคาดหวังไว้ แล้วอีกหนึ่งการยืนยันตัวตรวจสอบก่อนหน้าเช่นกัน
Oleg V. Volkov

49
ถอนหายใจ ดูสิถ้าคุณไม่มีประสบการณ์อย่างอื่นนอกเหนือจากการเขียนโปรแกรมเดสก์ท็อปคุณไม่จำเป็นต้องแสดงความคิดเห็นเกี่ยวกับสิ่งที่คุณเห็นได้ชัดว่าไม่มีประสบการณ์ สิ่งนี้จะเกิดขึ้นเสมอเมื่อมีการพูดถึงการตั้งโปรแกรมการป้องกันและโปรแกรมเมอร์พีซีหยุดทำงาน ฉันเพิ่มความคิดเห็น "รหัสนี้จะเป็นคนต่างด้าวอย่างสมบูรณ์กับโปรแกรมเมอร์ PC" ด้วยเหตุผล คุณทำไม่ได้โปรแกรมซอฟต์แวร์ความปลอดภัยที่สำคัญเพื่อให้ทำงานบน RAM-based คอมพิวเตอร์เดสก์ทอป ระยะเวลา รหัสนั้นจะอยู่ใน flash ROM พร้อมกับ ECC และ / หรือ CRC checksums
Lundin

6
@Dupuplicator แน่นอน (ยกเว้นกรณีmyboolที่ไม่ใช่แบบบูลเช่นเดียวกับกรณีก่อนที่ C จะเป็นของตัวเองboolแล้วคอมไพเลอร์จะไม่ทำการตั้งสมมติฐานโดยไม่มีการวิเคราะห์แบบคงที่เพิ่มเติม) และในเรื่องของ 'ถ้าคุณเขียนสิ่งอื่น แต่ปล่อยให้ว่างมันหมายถึง: "ฉันได้พิจารณาสถานการณ์อย่างแน่นอนเมื่อไม่เช่นนั้นถ้าไม่จริง" ": ปฏิกิริยาแรกของฉันคือการสมมติว่าโปรแกรมเมอร์ลืมใส่รหัส บล็อกอื่นมิฉะนั้นเหตุใดบล็อกว่างเปล่าเพิ่งนั่งอยู่ตรงนั้น // unusedความคิดเห็นจะเหมาะสมไม่เพียงบล็อกที่ว่างเปล่า
JAB

5
@JAB ใช่elseบล็อกต้องมีข้อคิดเห็นบางอย่างหากไม่มีรหัส ปฏิบัติทั่วไปสำหรับที่ว่างเปล่าเป็นอัฒภาคเดียวบวกความคิดเห็น:else else { ; // doesn't matter }เนื่องจากไม่มีเหตุผลว่าทำไมทุกคนจะพิมพ์เพียงย่อหน้าเดียวที่มีเครื่องหมายย่อหน้า while(something) { ; // do nothing }การปฏิบัติที่คล้ายกันคือบางครั้งใช้ในลูปที่ว่างเปล่า (รหัสที่มีตัวแบ่งบรรทัดชัดเจนดังนั้นความคิดเห็นไม่อนุญาต)
Lundin

5
ฉันต้องการที่จะทราบว่าโค้ดตัวอย่างนี้ที่มี IFs สองตัวและอย่างอื่นสามารถไปที่อื่นแม้ในซอฟต์แวร์เดสก์ท็อปปกติในสภาพแวดล้อมแบบมัลติเธรดดังนั้นค่าของ mybool สามารถเปลี่ยนได้ระหว่าง
Iłya Bursov

61

บริษัท ของคุณทำตามคำแนะนำการเข้ารหัส MISRA มีแนวทางไม่กี่เวอร์ชันที่มีกฎนี้ แต่จากMISRA-C: 2004 :

กฎ 14.10 (จำเป็น): ทั้งหมดถ้า…อื่นหากโครงสร้างจะถูกยกเลิกด้วยประโยคอื่น

กฎนี้ใช้เมื่อใดก็ตามที่คำสั่ง if ถูกตามด้วยอย่างน้อยหนึ่งคำสั่งถ้า; สุดท้ายifจะตามมาด้วยelse คำสั่ง ในกรณีของifคำสั่งง่ายๆคำelse สั่งไม่จำเป็นต้องรวม ข้อกำหนดสำหรับelse คำสั่งสุดท้ายคือการตั้งโปรแกรมป้องกัน elseคำสั่งอย่างใดอย่างหนึ่งจะต้องดำเนินการที่เหมาะสมหรือมีความคิดเห็นที่เหมาะที่จะเป็นไปทำไมไม่มีการดำเนินการ นี้สอดคล้องกับข้อกำหนดที่จะมีdefaultประโยคสุดท้ายในswitchคำสั่ง ตัวอย่างเช่นรหัสนี้เป็นคำสั่งง่ายๆถ้า:

if ( x < 0 )
{
 log_error(3);
 x = 0;
} /* else not needed */

ในขณะที่รหัสต่อไปนี้แสดงให้เห็นถึงif, else ifสร้าง

if ( x < 0 )
{
 log_error(3);
 x = 0;
}
else if ( y < 0 )
{
 x = 3;
}
else /* this else clause is required, even if the */
{ /* programmer expects this will never be reached */
 /* no change in value of x */
}

ในMISRA-C 2012ซึ่งใช้แทนรุ่นปี 2004 และเป็นข้อเสนอแนะปัจจุบันสำหรับโครงการใหม่กฎเดียวกันมีอยู่ แต่จะมีหมายเลข 15.7

ตัวอย่างที่ 1: ในรายการเดียวถ้าโปรแกรมเมอร์คำสั่งอาจต้องตรวจสอบจำนวนเงื่อนไขและดำเนินการเดียว

if(condition_1 || condition_2 || ... condition_n)
{
   //operation_1
}

ในการใช้งานปกติที่มีประสิทธิภาพการดำเนินการไม่จำเป็นต้องใช้ตลอดเวลาเมื่อifมีการใช้

ตัวอย่างที่ 2: ผู้ เขียนโปรแกรมตรวจสอบจำนวน n เงื่อนไขและดำเนินการหลายอย่าง ในการใช้งานปกติif..else ifเป็นเหมือนswitchคุณอาจต้องดำเนินการเช่นเริ่มต้น ดังนั้นจึงelseจำเป็นต้องใช้งานตามมาตรฐานของ Misra

if(condition_1 || condition_2 || ... condition_n)
{
   //operation_1
}
else if(condition_1 || condition_2 || ... condition_n)
{
  //operation_2
}
....
else
{
   //default cause
}

ปัจจุบันและรุ่นที่ผ่านมาของสิ่งพิมพ์เหล่านี้พร้อมสำหรับการซื้อผ่านทางเว็บสโตร์ MISRA ( ผ่าน )


1
ขอบคุณคำตอบของคุณคือเนื้อหาทั้งหมดของกฎของ Misra แต่ฉันคาดหวังคำตอบสำหรับความสับสนในการแก้ไขบางส่วนของคำถาม
เทรเวอร์

2
คำตอบที่ดี. ไกด์เหล่านี้พูดอะไรเกี่ยวกับสิ่งที่ต้องทำหากคุณคาดหวังว่าelseประโยคจะไม่สามารถเข้าถึงได้ (ออกจากเงื่อนไขสุดท้ายแทนอาจเกิดข้อผิดพลาดหรือไม่?)
jpmc26

17
ฉันจะลงคะแนนให้กับการคัดลอกผลงานและลิงก์ที่ละเมิดลิขสิทธิ์ ฉันจะแก้ไขโพสต์เพื่อให้ชัดเจนว่าคำของคุณคืออะไรและคำของ MISRA คืออะไร ตอนแรกคำตอบนี้ไม่มีอะไรนอกจากคัดลอก / วางแบบดิบ
Lundin

8
@TrieuTheVan: คำถามจะต้องไม่ถูกย้ายเป้าหมาย ตรวจสอบให้แน่ใจว่าคำถามของคุณเสร็จสมบูรณ์ก่อนที่จะโพสต์
TJ Crowder

1
@ jpmc26 Nope แต่จุดประสงค์ของ MISRA ไม่ให้รหัสที่แน่นหนาแก่คุณมันคือการให้รหัสที่ปลอดภัยแก่คุณ คอมไพเลอร์ทุกวันนี้จะปรับปรุงโค้ดที่ไม่สามารถเข้าถึงได้ดังนั้นจึงไม่มีข้อเสีย
เกรแฮม

19

นี่เป็นสิ่งที่เทียบเท่ากับการกำหนดกรณีเริ่มต้นในทุกสวิตช์

สิ่งอื่นนี้จะลดความครอบคลุมรหัสของโปรแกรมของคุณ


จากประสบการณ์ของฉันกับการย้ายเคอร์เนล linux หรือรหัส android ไปยังแพลตฟอร์มที่แตกต่างกันหลายครั้งที่เราทำอะไรผิดพลาดและใน logcat เราเห็นข้อผิดพลาดบางอย่างเช่น

if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
        printk(" \n [function or module name]: this should never happen \n");

        /* It is always good to mention function/module name with the 
           logs. If you end up with "this should never happen" message
           and the same message is used in many places in the software
           it will be hard to track/debug.
        */
}

2
นี่คือที่__FILE__และ__LINE__มาโครเป็นประโยชน์สำหรับการทำให้ตำแหน่งต้นทางง่ายต่อการค้นหาหากมีการพิมพ์ข้อความ
Peter Cordes

9

เพียงคำอธิบายสั้น ๆ เนื่องจากฉันทำสิ่งนี้ทั้งหมดประมาณ 5 ปีที่ผ่านมา

ไม่มี (กับภาษาส่วนใหญ่) ไม่มีข้อกำหนดด้านไวยากรณ์เพื่อรวมelseคำสั่ง"null" (และไม่จำเป็น{..} ) และใน "โปรแกรมเล็ก ๆ น้อย ๆ อย่างง่าย" ไม่จำเป็นต้องใช้ แต่โปรแกรมเมอร์ที่แท้จริงอย่าเขียน "โปรแกรมเล็ก ๆ ง่ายๆ" และที่สำคัญคือพวกเขาไม่ได้เขียนโปรแกรมที่จะใช้เพียงครั้งเดียวแล้วละทิ้ง

เมื่อหนึ่งเขียน if / else:

if(something)
  doSomething;
else
  doSomethingElse;

{..}มันทั้งหมดดูเหมือนง่ายและเป็นหนึ่งแทบจะไม่เห็นแม้กระทั่งจุดเพิ่ม

แต่บางวันไม่กี่เดือนต่อจากนี้โปรแกรมเมอร์อื่น (คุณจะไม่ทำผิดพลาด!) จะต้อง "เพิ่ม" โปรแกรมและจะเพิ่มคำสั่ง

if(something)
  doSomething;
else
  doSomethingIForgot;
  doSomethingElse;

ทันใดนั้นdoSomethingElseลืมว่ามันควรจะอยู่ในelseขา

ดังนั้นคุณเป็นโปรแกรมเมอร์ที่ดีเล็ก ๆ น้อย ๆ {..}และคุณใช้งานอยู่เสมอ แต่คุณเขียนว่า:

if(something) {
  if(anotherThing) {
    doSomething;
  }
}

ทุกอย่างดีและดีจนกระทั่งเด็กใหม่ทำการปรับเปลี่ยนเที่ยงคืน:

if(something) {
  if(!notMyThing) {
  if(anotherThing) {
    doSomething;
  }
  else {
    dontDoAnything;  // Because it's not my thing.
  }}
}

ใช่มันมีรูปแบบไม่ถูกต้อง แต่เป็นครึ่งหนึ่งของรหัสในโครงการและ "ตัวจัดรูปแบบอัตโนมัติ" ได้รับการ bollixed โดย#ifdefคำสั่งทั้งหมด และแน่นอนรหัสจริงนั้นซับซ้อนกว่าตัวอย่างของเล่นนี้มาก

น่าเสียดาย (หรือไม่) ฉันออกจากสิ่งนี้มาสองสามปีแล้วดังนั้นฉันจึงไม่มีตัวอย่าง "ของจริง" ที่สดใหม่ในใจ - ข้างต้นคือ (เห็นได้ชัด) ที่วางแผนไว้และเป็นบิต


7

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

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


6

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

คำถามนั้นมีตัวนับที่ดีเช่นกันเงื่อนไขที่สองไม่เกี่ยวข้องกับ x เลย (ซึ่งเป็นเหตุผลว่าทำไมฉันมักชอบตัวแปรที่อิง if-based ที่ยืดหยุ่นมากกว่าสวิตช์ที่ใช้สวิตช์) จากตัวอย่างเป็นที่ชัดเจนว่าหากตรงตามเงื่อนไข A แล้ว x ควรถูกตั้งค่าเป็นค่าที่แน่นอน ไม่ควรทำตามเงื่อนไข A จากนั้นทดสอบเงื่อนไข B หากเป็นไปตามนั้น x ควรได้รับค่าอื่น หากไม่พบ A หรือ B ดังนั้น x จะไม่เปลี่ยนแปลง

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

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

if (A) {
    // do something
}
else {
    if (B) {
        // do something else (no pun intended)
    }
    else {
        // don't do anything here
    }
}

เมื่อ MISRA ขอให้ใส่เครื่องมือจัดฟันแบบโค้งงอทุกสาขามันจะขัดแย้งกับตัวเองโดยการพูดถึง "ถ้า ... ถ้าอย่างอื่นถ้าสร้าง"

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

if (A) {
    if (B) {
        // do something
    }
    // you could to something here
}
else {
    // or here
    if (B) { // or C?
        // do something else (no pun intended)
    }
    else {
        // don't do anything here, if you don't want to
    }
    // what if I wanted to do something here? I need brackets for that.
}

ดังนั้นฉันจึงมั่นใจว่าคนที่พัฒนาแนวทางของ MISRA นั้นมีความคิดคล้าย ๆ กันถ้าตั้งใจ

ในท้ายที่สุดมันลงมาเพื่อให้พวกเขากำหนดได้อย่างแม่นยำว่าอะไรคือความหมายของคำว่า "ถ้า ... ถ้าอื่นสร้าง"


5

เหตุผลพื้นฐานน่าจะเป็นความครอบคลุมของรหัสและโดยปริยายอื่น: รหัสจะทำงานอย่างไรถ้าเงื่อนไขไม่เป็นความจริง? สำหรับการทดสอบของแท้คุณต้องมีวิธีที่จะเห็นว่าคุณได้ทดสอบด้วยเงื่อนไขที่ผิดพลาด หากทุกกรณีการทดสอบคุณต้องผ่านประโยค if, รหัสของคุณอาจมีปัญหาในโลกแห่งความจริงเนื่องจากสภาพที่คุณไม่ได้ทดสอบ

อย่างไรก็ตามเงื่อนไขบางอย่างอาจเป็นไปตามตัวอย่างที่ 1 อย่างเช่นในการคืนภาษี: "หากผลลัพธ์น้อยกว่า 0 ให้ป้อน 0" คุณยังต้องมีการทดสอบว่าเงื่อนไขเป็นเท็จ


5

การทดสอบเชิงตรรกะหมายถึงสองสาขา คุณจะทำอย่างไรถ้ามันเป็นเรื่องจริงและคุณจะทำอะไรถ้ามันเป็นเท็จ

สำหรับกรณีที่สาขาใดไม่มีฟังก์ชั่นมันมีเหตุผลที่จะเพิ่มความคิดเห็นเกี่ยวกับสาเหตุที่ไม่จำเป็นต้องมีฟังก์ชั่น

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

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

ไมล์สะสมของคุณอาจแตกต่างกันไป


4

เวลาส่วนใหญ่ที่คุณเพิ่งมีifคำสั่งเดียวอาจเป็นหนึ่งในเหตุผลเช่น:

  • ฟังก์ชั่นการตรวจสอบยาม
  • ตัวเลือกการเริ่มต้น
  • สาขาการประมวลผลเพิ่มเติม

ตัวอย่าง

void print (char * text)
{
    if (text == null) return; // guard check

    printf(text);
}

แต่เมื่อคุณทำif .. else ifมันอาจเป็นหนึ่งในเหตุผลเช่น:

  • กรณีสวิตช์แบบไดนามิก
  • กำลังประมวลผลส้อม
  • การจัดการพารามิเตอร์การประมวลผล

และในกรณีที่คุณif .. else ifครอบคลุมความเป็นไปได้ทั้งหมดในกรณีนั้นคุณจะเป็นคนสุดท้ายif (...)นั้นไม่จำเป็นต้องคุณสามารถลบได้เพราะ ณ จุดนั้นค่าที่เป็นไปได้เท่านั้นคือค่าที่ครอบคลุมโดยเงื่อนไขนั้น

ตัวอย่าง

int absolute_value (int n)
{
    if (n == 0)
    {
        return 0;
    }
    else if (n > 0)
    {
        return n;
    }
    else /* if (n < 0) */ // redundant check
    {
        return (n * (-1));
    }
}

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

ตัวอย่าง

#DEFINE SQRT_TWO   1.41421356237309504880
#DEFINE SQRT_THREE 1.73205080756887729352
#DEFINE SQRT_FIVE  2.23606797749978969641

double square_root (int n)
{
         if (n  > 5)   return sqrt((double)n);
    else if (n == 5)   return SQRT_FIVE;
    else if (n == 4)   return 2.0;
    else if (n == 3)   return SQRT_THREE;
    else if (n == 2)   return SQRT_TWO;
    else if (n == 1)   return 1.0;
    else if (n == 0)   return 0.0;
    else               return sqrt(-1); // error handling
}

elseประโยคสุดท้ายนี้ค่อนข้างคล้ายกับสิ่งอื่น ๆ ในภาษาเช่นJavaและC++เช่น:

  • default กรณีในคำสั่งเปลี่ยน
  • catch(...) ที่มาหลังจากทั้งหมดที่เฉพาะเจาะจง catchบล็อก
  • finally ในประโยคลองจับ

2

ซอฟต์แวร์ของเราไม่ได้เป็นภารกิจที่สำคัญ แต่เราก็ตัดสินใจใช้กฎนี้เนื่องจากการตั้งโปรแกรมป้องกัน เราได้เพิ่มข้อผิดพลาดการโยนลงในโค้ดที่ไม่สามารถเข้าถึงได้ในทางทฤษฎี (สวิตช์ + if-else) และมันช่วยเราได้หลายครั้งเมื่อซอฟต์แวร์ไม่ทำงานอย่างรวดเร็วเช่นเมื่อมีการเพิ่มประเภทใหม่และเราลืมเปลี่ยนหนึ่งหรือสอง if-else หรือสวิตช์ ในฐานะโบนัสมันทำให้ง่ายต่อการค้นหาปัญหา


2

ตัวอย่างของฉันเกี่ยวข้องกับพฤติกรรมที่ไม่ได้กำหนด แต่บางครั้งบางคนพยายามแฟนซีและล้มเหลวอย่างหนักลองดู:

int a = 0;
bool b = true;
uint8_t* bPtr = (uint8_t*)&b;
*bPtr = 0xCC;
if(b == true)
{
    a += 3;
}
else if(b == false)
{
    a += 5;
}
else
{
    exit(3);
}

คุณอาจจะไม่เคยคาดว่าจะมีboolที่ไม่ได้trueมิได้falseแต่มันอาจจะเกิดขึ้น โดยส่วนตัวฉันเชื่อว่านี่เป็นปัญหาที่เกิดจากคนที่ตัดสินใจทำอะไรที่แฟนซี แต่elseคำแถลงเพิ่มเติมสามารถป้องกันปัญหาเพิ่มเติมได้


1

ฉันกำลังทำงานกับ PHP การสร้างแบบฟอร์มการลงทะเบียนและแบบฟอร์มการเข้าสู่ระบบ ฉันแค่ใช้ถ้าและอย่างอื่น ไม่มีอะไรอีกหรือสิ่งที่ไม่จำเป็น

หากผู้ใช้คลิกที่ปุ่มส่ง -> มันจะไปที่คำสั่งต่อไปถ้า ... หากชื่อผู้ใช้มีจำนวนอักขระน้อยกว่า 'X' ตัวอักษรจะแจ้งเตือน หากสำเร็จให้ตรวจสอบความยาวรหัสผ่านและอื่น ๆ

ไม่จำเป็นต้องใช้รหัสเพิ่มเติมเช่นอื่นหากสามารถยกเลิกความน่าเชื่อถือสำหรับเวลาในการโหลดเซิร์ฟเวอร์เพื่อตรวจสอบรหัสเพิ่มเติมทั้งหมด

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