2015-02-17 13 views
13

Giả sử tôi đang sử dụng phiên bản hiện đại GCC để biên dịch chương trình C. Hơn nữa, hãy xem xét rằng chương trình của tôi chứa các nhánh cũ, nhưng tôi rất giống đoạn mã chết trong những nhánh cũ để được biên dịch và trình bày trong chương trình cuối cùng. Hãy xem xét các chương trình sau đây:GCC có thể được hướng dẫn không loại bỏ mã chết không?

int main(int argc, char** argv) { 
    int a = 0; 
    goto skip; 
     a = -1; 
    skip: ; 
    return a; 
} 

Rõ ràng, nếu tôi sử dụng GCC với các thiết lập tối ưu hóa mặc định, việc chuyển nhượng thứ hai sẽ không bao giờ làm cho nó vào chương trình chính thức, như trình biên dịch có thể dễ dàng nói rằng nó sẽ không bao giờ được thực thi. Giả sử tôi không muốn điều này xảy ra.

Trong GCC, có một số lá cờ mà vọc trong nước với mã chết (đáng chú ý nhất -fdce), và tôi có thể chọn để tắt một cách rõ ràng những khi gọi GCC cho phù hợp:

-fno-dce 
-fno-dse 
-fno-tree-dce 
-fno-tree-dse 

Theo như tôi có thể nói , điều này sẽ hướng dẫn GCC không gây rối với nhiệm vụ thứ hai. Tuy nhiên, các mã liên quan không bao giờ có vẻ làm cho nó vào chương trình của tôi.

Tại sao GCC nhấn mạnh việc xóa mã đã chết và có cách hướng dẫn GCC không để loại bỏ nhiệm vụ thứ hai không?

+0

Phiên bản gcc bạn đang sử dụng ? – anatolyg

+2

Tôi nhận thức được 'dễ bay hơi ', nhưng tôi tò mò muốn biết liệu điều này có thể thực hiện được với GCC hay không. Đối với GCC tôi đang sử dụng phiên bản 4.8.3, nhưng tôi muốn được quan tâm để biết nếu có một giải pháp bất kỳ phiên bản nhất định! – Caterpillar

+0

Bỏ qua nhận xét của tôi. Dễ bay hơi không ngăn GCC bỏ qua nhiệm vụ. –

Trả lời

8

Tùy chọn -fno-* không hoạt động đối với tôi với gcc-4.9.2. Điều đó nói rằng, tôi nghĩ rằng những điều sau đây nên được cầm tay cho tất cả gcc (4.5+) mục tiêu:

__asm__ goto (""::::no_skip); 
goto skip; 

no_skip: 
    a = -1; 

skip:; 

Từ hướng dẫn: "một tuyên bố asm goto luôn ngầm coi không ổn định"

Hơn nữa, với gcc-4.8 trở lên, bạn có thể xem xét thêm thuộc tính để cho trình biên dịch biết rằng đây là đường dẫn 'không chắc'. Điều này giúp ngăn ngừa hình phạt nhánh, vv, mà nếu không có thể xảy ra khi lấy con đường 'dự kiến':

no_skip: __attribute__ ((cold)); 

Nó đứng vào lý do đó bạn cũng có thể sử dụng:

skip: __attribute__ ((hot)); 
+0

Cảm ơn bạn. Điều này đặt ra câu hỏi về lý do tại sao ví dụ của tôi không được GCC xem là mã chết, hoặc ít nhất là tại sao các lá cờ đã cho không bao gồm nhiệm vụ thứ hai (có lẽ là nhánh cũ quá rõ ràng là không thể truy cập được mà nó bị loại bỏ ở giai đoạn trước không bị ảnh hưởng bởi các tùy chọn). – Caterpillar

+0

@Caterpillar - Tôi nghi ngờ bạn đúng, rằng mã không thể truy cập được loại bỏ tại điểm trước đó. Một khả năng khác là tài liệu không theo dõi chính xác sự phát triển. Tài liệu [internals] (https://gcc.gnu.org/onlinedocs/gccint/Edges.html#Edges) dường như có một số chi tiết thú vị. –

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