การใช้ค่าที่ไม่ได้กำหนดค่าเริ่มต้นในการต่อข้อมูล (.) หรือสตริงที่ ./Merge_gcov_generalised.pl บรรทัด 226, ‹FILE2› บรรทัด 284046 (#1)

ฉันได้เขียนสคริปต์ Perl เพื่อรวมไฟล์ gcov จากเครื่องต่างๆ ด้านล่างนี้เป็นรูทีนย่อยที่ฉันเขียนเพื่อรวมเข้าด้วยกัน

sub merge_gcov()
    {
        open(FILE1, "<$_[0]") or die "can not open file";
        open(FILE2, "<$_[1]") or die "can not open file";
        open(FILE3, ">$_[2]") or die "can not open file";
        my ($line1, $line2 , $flag );
        while ( 1 )
        {  
            $line1 = <FILE1>; # read them each
            $line2 = <FILE2>;
            last unless ( $line1 || $line2 ); # if both empty exit loop
            #
            # otherwise test for which one just finished
            #
            unless( $line1 )
            {
                $flag = 1;
            last;
            }
            unless( $line2 )
            {
                $flag = 2;
            last
            }   
            #
            # now do the voodo on the two lines
            #
            chomp($line2);
            chomp($line1);
            if($line1=~/^\s*-/ and  $line2 =~/^\s*-/)  
            {   
                print FILE3 "$line1\n";
            }
            elsif($line1=~/^\s*#####/ and  $line2 =~/^\s*#####/) 
            {      
                print FILE3 "$line1\n";
            }
            elsif($line1=~/^\s*#####:\s{0,}(\d{1,})/ and  $line2 =~/^\s{0,}(\d{1,})/) 
            {     
                print FILE3 "$line2\n"
            }
            elsif($line1=~/^\s{0,}(\d{1,})/ and  $line2 =~/^\s*#####:\s{0,}(\d{1,})/) 
            {  
                print FILE3 "$line1\n"
            }
            elsif($line1=~/^\s{0,}(\d{1,})/ and  $line2 =~/\s{0,}(\d{1,})/) 
            { 
                my @values1 =  split(/:/, "$line1");
                my @values2 =  split(/:/, "$line2");
                print FILE3 ("      ",$values1[0]+$values2[0]),":","$values1[1]:","$values1[2]\n";
            }
            else
            {  
                print FILE3 "$line1\n";
                print FILE3 "$line2\n";
             }

        }
    close(FILE3);
    }

การรวมเสร็จสิ้นอย่างถูกต้อง แต่หลังจากการรวมแล้ว ฉันได้รับข้อผิดพลาดด้านล่าง....

Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 284046 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 284414 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 302995 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 311633 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 311962 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 321536 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 323445 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 329553 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 336009 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 336330 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 338188 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 343170 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 349037 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 349610 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 633937 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 634509 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 634877 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 653458 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 662096 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 662425 (#1)
Use of uninitialized value in concatenation (.) or string at
        ./Merge_gcov_generalised.pl line 226, <FILE2> line 671999 (#1)
Use of uninitialized value in concatenation (.) or string at

ฉันรู้ว่าฉันไม่ได้รับคำเตือนเหล่านี้เมื่อฉันใช้ ไม่มีคำเตือน แต่มีวิธีอื่นใดในการลบคำเตือนเหล่านี้

บรรทัด 226 คือ :พิมพ์ FILE3 (" ",$values1[0]+$values2[0]),คีย์บอล:","$values1[1]:","$values1[2]\n";< /แข็งแกร่ง>


person Nethra    schedule 18.01.2013    source แหล่งที่มา
comment
รหัสของคุณดูเจ็บปวด มีข้อผิดพลาด 5 ข้อในสามบรรทัดแรกเพียงอย่างเดียว :-(   -  person melpomene    schedule 18.01.2013
comment
{0,} หรือ * และ {1,} หรือ + อะไรที่ทำให้สับสน?   -  person TLP    schedule 18.01.2013
comment
คำเตือนเหล่านี้หมายความว่าไม่ได้กำหนด $values1[1] หรือ $values1[2] ซึ่งหมายความว่าการแยกของคุณมีองค์ประกอบน้อยเกินไปที่จะเติมเต็มอาร์เรย์ได้ไกลขนาดนั้น ดังนั้นจึงเป็นสัญญาณว่าข้อมูลของคุณเสียหาย หรือคุณมีกรณี Edge ที่ทำให้โปรแกรมแยกวิเคราะห์ของคุณเสียหาย ตรวจสอบอินพุตสำหรับเส้นเหล่านั้นและดูวิธีจัดการกับเคสขอบเหล่านี้   -  person TLP    schedule 18.01.2013


คำตอบ (2)


หากสิ่งที่คุณต้องการทำคือกำจัด นั้น คำเตือนเฉพาะที่คุณคาดหวังไว้แล้วและ ได้คำนึงถึง สิ่งที่คุณต้องทำคือ:

{    no warnings 'uninitialized';
     # **Small** bit of code causing the problem.
     say "A string and $probably_undefined";
}

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

person Axeman    schedule 18.01.2013

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

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

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

  1. การทดสอบทั้งสองบรรทัดเป็นเท็จ (เช่น undef): นี่เป็นการใช้ undef ที่ดี
  2. การตั้งค่า $flag: การใช้งานที่ดี แต่ตรรกะไม่ดี เนื่องจากคุณไม่เคยใช้ $flag อีกเลย
  3. การจับคู่รูปแบบ: การใช้งานที่ดี เนื่องจากการจับคู่รูปแบบกับสิ่งใดที่ไม่ควร (และทำ) จะล้มเหลว และนี่เป็นสิ่งที่ถูกต้องสำหรับโค้ดของคุณ
  4. การพิมพ์บรรทัดที่อาจเป็น undef: การใช้งานที่ไม่ดี เนื่องจากจะสร้างคำเตือนและเอาต์พุตขึ้นบรรทัดใหม่ที่ว่างเปล่า

เนื่องจากการจับคู่รูปแบบทั้งหมดจะล้มเหลวเมื่อเทียบกับ undef คุณจึงสามารถข้ามโค้ดที่ตั้งค่า $flag ไว้ด้วยกัน และทำให้ else สุดท้ายมีลักษณะดังนี้:

...
else {
    # One or the other file has run out already. Note that
    # the $line variables being undef here is OK because that's
    # an expected possible value that we're actually testing for.
    # We could used "defined $lineX" but since undef itself is 
    # false, this is okay.
    print FILE3 "$line1" if $line1;
    print FILE3 "$line2" if $line2;
}

ตอนนี้สำหรับการปรัชญาบางอย่าง undef

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

  1. ฉันกำลังโทรหาบางสิ่งที่ส่งคืน undef หรือไม่ หากเป็นเช่นนั้น ฉันเรียกมันผิดหรือมีพารามิเตอร์ที่ไม่ดี ฉันสามารถทดแทนค่าเริ่มต้นโดยไม่มีข้อผิดพลาด เช่น 0 หรือ '' (โดยใช้ตัวดำเนินการที่กำหนดไว้หรือ //) ได้หรือไม่ หากการโทรของฉันถูกต้อง ฉันจำเป็นต้องมีตารางหรือตารางย่อยเพื่อให้ค่าเริ่มต้นแทนหรือไม่ ถ้าฉันไม่สามารถใช้ค่าเริ่มต้นได้ เกิดอะไรขึ้นกับตรรกะของฉัน
  2. หากไม่เป็นเช่นนั้น ฉันกำลังอ้างอิงถึงอาร์เรย์หรือรายการแฮชที่ไม่ได้เตรียมใช้งานหรือไม่ Perl จะ ทำให้มีชีวิตชีวาโดยอัตโนมัติ รายการเหล่านั้น และตั้งค่าเป็น undef ดัชนีหรือคีย์ของฉันไม่ดีหรือไม่? ถ้าไม่ ฉันควรตั้งค่ารายการเหล่านั้นเป็นค่าเริ่มต้นด้วยตัวเอง ตรวจสอบขอบเขตของอาร์เรย์สำหรับอาร์เรย์ หรือตรวจสอบว่าองค์ประกอบแฮช exists เป็นแฮชหรือไม่ มิฉะนั้นให้ใช้หลักเกณฑ์ข้อ 1.
  3. หากไม่เป็นเช่นนั้น ฉันมีตัวแปรสเกลาร์ที่ไม่ได้กำหนดค่าเริ่มต้น เหตุใดจึงไม่เริ่มต้น? ฉันควรเริ่มต้นมันเพื่ออะไร? ฉัน ลืมสร้าง สมมติฐานอะไร (โดยไม่เตรียมค่าสเกลาร์ให้เป็นค่าที่ทราบ)

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

person Joe McMahon    schedule 23.09.2014