ทำไมรหัสนี้ใช้เวลานานในการคอมไพล์ด้วย g ++


12

พิจารณารหัสต่อไปนี้:

template<int i> class A
{
    typedef A<i-1> B;
    B x, y;
};
template<> class A<0> { char m; };
int main()
{
    A<LEVEL> a;
}

เมื่อทำการเปรียบเทียบการคอมไพล์ด้วย g ++ โดยคำสั่ง Bash ต่อไปนี้ (ด้วย g ++ 8.3.0)

for ((level=1; level<30; ++level)); do
    echo -n ${level},
    /usr/bin/time -f %U g++ -DLEVEL=$level test.cpp -o /dev/null
done

ฉันได้รับผลลัพธ์ต่อไปนี้:

1,0.03
2,0.03
3,0.04
4,0.04
5,0.04
6,0.04
7,0.04
8,0.04
9,0.03
10,0.04
11,0.02
12,0.04
13,0.02
14,0.03
15,0.04
16,0.05
17,0.05
18,0.08
19,0.11
20,0.20
21,0.35
22,0.67
23,1.30
24,2.52
25,5.02
26,10.23
27,19.96
28,40.30
29,80.99

LEVELดังนั้นเวลาที่สะสมอยู่ในการชี้แจง แต่ถ้าฉันเปลี่ยนB x, y;ไปการB x[2];รวบรวมจะเกิดขึ้นในเวลาคงที่ (~ 30 ms)

ทำไมมันเกิดขึ้น ผมคิดว่าตั้งแต่คอมไพเลอร์รู้ว่าBเป็นหนึ่งในประเภทเดียวกันและสำหรับทั้งสองxและก็จะใช้เวลาเดียวกับที่รวบรวมy x[2]แต่ด้วยเหตุผลบางอย่างมันดูแตกต่าง ฉันสามารถบังคับBให้รับรู้ได้อย่างไร (เทียบกับนามแฝงเพียงนามแฝง) เพื่อให้ g ++ สามารถสร้างตัวแปรทั้งสองได้อย่างง่ายดายเช่นเดียวกับที่สร้างอาร์เรย์


1
คำตอบที่ถูกต้อง แต่ไม่มีประโยชน์ (สำหรับคุณ) ทางเทคนิค: แก้ไขคอมไพเลอร์
Botje

5
ทำไมคุณถึงโพสต์ที่นี่? Gcc มีข้อผิดพลาดในการรายงานปัญหา ... ตรวจสอบให้แน่ใจว่าคุณทดสอบด้วยเวอร์ชันล่าสุดก่อน
Marc Glisse

@ MarcGlisse ฉันหวังว่าอาจจะมีคำอธิบายที่ดีหรือวิธีแก้ปัญหา ไม่แน่ใจว่ามันจะได้รับการพิจารณาว่าเป็นข้อผิดพลาดที่ควรลองแก้ไขหากฉันรายงานเช่นนั้น
Ruslan

3
พวกเขายังมีคีย์เวิร์ด "compile-time-hog" สำหรับกรณีที่คอมไพเลอร์ใช้เวลาในการคอมไพล์นานเกินไปดังนั้นใช่พวกเขาคิดว่ามันคุ้มค่าในการแก้ไข (ซึ่งไม่ได้หมายความว่าพวกเขาจะทำทันที) ดังนั้นโดยเฉพาะอย่างยิ่งหากคุณเห็นคอมไพเลอร์อื่นที่ไม่มีพฤติกรรมแบบเอ็กซ์โปเนนเชียล (เพื่อให้คุณรู้ว่าสามารถหลีกเลี่ยงได้) โปรดรายงาน อาจตรวจสอบว่าคุณเห็นอะไรที่คล้ายกันมากในฐานข้อมูล แต่ก็โอเคถ้าคุณพลาดสำเนาที่ไม่ชัดเจน
Marc Glisse

5
@MarcGlisse รายงาน: gcc.gnu.org/bugzilla/show_bug.cgi?id=91990
Ruslan

คำตอบ:


1

เนื่องจากมีข้อผิดพลาดในอินสแตนซ์ g ++ ของคุณ ไม่ควรและตามที่ @Marc Glisse แสดงความคิดเห็นคุณควรรายงาน (ซึ่งคุณได้ทำในขณะที่เขียน)

คุณอาจต้องการลบคำถามของคุณ (ตัวเลือกที่ฉลาด) หรือยอมรับคำตอบนี้

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