2011-01-24 33 views
7

Tôi đang cố gắng viết một chương trình theo phong cách chức năng với C càng nhiều càng tốt. Tôi biết trình biên dịch tốt như GCC/Clang làm tối ưu hóa cuộc gọi đuôi âm thầm, nhưng nó không được bảo đảm. Có tùy chọn nào để buộc tối ưu hóa cuộc gọi đuôi trên các trình biên dịch không? (Tất nhiên khi chỉ có nó được gọi là ở cuối của chính nó)Có thể bắt buộc tối ưu hóa cuộc gọi đuôi trên GCC/Clang không?

+4

Trình biên dịch có lẽ khá thông minh về vấn đề này, chỉ cần tin tưởng nó. Không cần hack * không di động *. –

+1

Bạn muốn điều gì xảy ra trong trường hợp bạn cho rằng tối ưu hóa đuôi nên xảy ra nhưng trình biên dịch không có khả năng thực hiện nó (vì bất kỳ lý do gì)? –

+4

@Michael Tôi mong đợi một lỗi thời gian biên dịch nếu tối ưu hóa cuộc gọi đuôi buộc là không thể được thực hiện. – Eonil

Trả lời

4

Clang không thực hiện bất kỳ sự tối ưu nào. Có một thẻ LLVM pass tailcallelim có thể làm những gì bạn muốn (nhưng nó không được bảo đảm). Bạn có thể chạy riêng nó với opt.

+0

Lựa chọn là gì? Tôi có thể có bất kỳ liên kết cho nó? – Eonil

+0

opt là một công cụ dòng lệnh vận chuyển với llvm, http://llvm.org/cmds/opt.html –

+3

Hoặc bạn có thể tinh chỉnh trình điều khiển clang để đảm bảo rằng nó chạy vượt qua một cách rõ ràng. –

0

Trong thực tế rất nhiều trình biên dịch cho C đã xử lý này cho bạn. Như eq đã đề cập bạn cũng có thể cho phép trình biên dịch xử lý hầu hết những thứ này thay vì cố tạo các tối ưu hóa sẽ không hoạt động ở nơi khác. Thông thường, bạn sẽ tìm thấy ngay cả khi bạn đặt cờ tối ưu hóa mà thực sự không có sự khác biệt về hiệu suất.

1

Một câu trả lời meta:

Có một số bài học đó là hữu ích để tiếp nhận vào C từ các ngôn ngữ chức năng: sử dụng chức năng, chức năng sử dụng nhỏ mà không đột biến hoặc globals hoặc đối số đầu vào, đừng sợ con trỏ hàm. Nhưng có giới hạn đối với những gì bạn có thể làm ở đây một cách hợp lý và dựa vào việc loại bỏ cuộc gọi đuôi ('đuôi gọi tối ưu hóa' không thực sự là thuật ngữ đúng) có lẽ ngoài những gì hữu ích. Bạn không thể buộc trình biên dịch sử dụng chiến lược này, và thậm chí nếu bạn có thể, kết quả C sẽ cực kỳ không đơn điệu, và khó đọc cho người khác, bao gồm cả bản thân tương lai của bạn.

Sử dụng ngôn ngữ cho điểm mạnh của chúng. C tốt cho một số thứ, vì vậy hãy sử dụng nó cho những thứ đó, theo kiểu C tốt. Nếu bạn muốn những điểm mạnh khác nhau, hoặc nếu bạn muốn sử dụng một phong cách chức năng (quyết định tuyệt vời!), Hãy sử dụng một ngôn ngữ chức năng.

0

Nếu nó thực sự là một cuộc gọi đuôi sau đó một vòng lặp while hoặc một goto wont nhìn mà nhiều khác nhau từ một cuộc gọi đệ quy. Chỉ cần cập nhật tất cả các biến thay vì chuyển chúng thành các tham số. AFAIK đây là cách đa nền tảng duy nhất trong C để kiểm soát việc sử dụng ngăn xếp ở tất cả các mức tối ưu hóa. Nó thực sự có thể dễ đọc hơn vì bạn có một hàm khởi tạo theo sau bởi vòng lặp, nó khá là thành ngữ. Phiên bản đệ quy đuôi yêu cầu hai hàm, một cho khởi tạo và một cho phần đệ quy.

Các vấn đề liên quan