Tại sao mã này mất quá nhiều thời gian để biên dịch với g ++?


12

Hãy xem xét các mã sau đây:

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

Khi điểm chuẩn biên dịch của nó bằng g ++ bằng lệnh Bash sau (với 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

Tôi nhận được đầu ra sau đây:

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

Vì vậy, thời gian biên dịch là theo cấp số nhân LEVEL. Nhưng nếu tôi thay đổi B x, y;thành B x[2];, thì quá trình biên dịch diễn ra trong thời gian không đổi (~ 30 ms).

Tại sao nó xảy ra? Tôi nghĩ rằng, vì trình biên dịch biết rằng đó Blà một và cùng loại cho cả hai xy, nó sẽ mất cùng thời gian với việc biên dịch x[2]. Nhưng vì một số lý do, nó xuất hiện khác nhau. Tôi bằng cách nào đó có thể buộc Bphải được nhận ra (trái ngược với bí danh đơn giản) để g ++ có thể tạo cả hai biến dễ dàng như khi tạo mảng không?


1
Một câu trả lời đúng về mặt kỹ thuật nhưng vô dụng (cho bạn): vá trình biên dịch.
Botje

5
Tại sao bạn sẽ đăng nó ở đây? Gcc có một bugzilla để báo cáo sự cố ... Mặc dù vậy, hãy chắc chắn rằng bạn đã thử nghiệm với phiên bản mới nhất trước tiên.
Marc Glisse

@MarcGlisse Tôi hy vọng có thể có một lời giải thích tốt hoặc một cách giải quyết. Không chắc chắn liệu nó có bị coi là một lỗi đáng để sửa hay không nếu tôi báo cáo như vậy.
Ruslan

3
Họ thậm chí còn có một từ khóa "compile-time-hog" cho các trường hợp trình biên dịch mất quá nhiều thời gian để biên dịch, vì vậy họ cho rằng nó đáng để sửa (điều đó không có nghĩa là họ sẽ làm điều đó ngay lập tức). Vì vậy, đặc biệt nếu bạn có thể thấy một trình biên dịch khác không có hành vi theo cấp số nhân (vì vậy bạn biết đó là điều có thể tránh được), vui lòng báo cáo nó. Cũng có thể kiểm tra xem bạn có thấy bất cứ điều gì tương tự trong cơ sở dữ liệu không, nhưng sẽ ổn nếu bạn bỏ lỡ một bản sao không rõ ràng.
Marc Glisse

5
@MarcGlisse đã báo cáo: gcc.gnu.org/ormszilla/show_orms.cgi?id=91990
Ruslan

Câu trả lời:


1

Bởi vì có một lỗi trong ví dụ g ++ của bạn. Không nên và như @Marc Glisse đã nhận xét, bạn nên báo cáo nó (điều mà bạn đã làm vào thời điểm viết bài)

Bạn có thể muốn xóa câu hỏi của bạn sau đó (lựa chọn khôn ngoan hơn). Hoặc chấp nhận câu trả lời này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.