2012-04-06 36 views
13

Trong hầu hết các trường hợp nếu tôi muốn tạo ra một tính năng tùy chọn trong C, tôi chỉ cần tạo hai chức năng như thế này:Tại sao GCC giữ các chức năng trống?

#ifdef OPTIONAL_SOMETHING 
void do_something(int n, const char *s) 
{ 
    while (n--) { 
     printf("%s", s); 
    } 

    /* ...You might get the point, really do something... */ 
} 
#else 
void do_something(int n, const char *s) 
{ 
    /* Empty body */ 
} 
#endif 

Vì vậy, nếu các biểu tượng là undefined - khi tính năng bị vô hiệu hóa - một chức năng có sản phẩm nào được biên dịch vào thực thi.

Chuyển vào danh sách lắp ráp, có vẻ như GCC biên dịch và gọi chức năng trống khi tối ưu hóa bị tắt. Nếu tối ưu hóa được bật, cũng với -O2-O3, nó chỉ biên dịch mã xử lý ngăn xếp cần thiết, nhưng nó tối ưu hóa hướng dẫn cuộc gọi. Tất cả trong tất cả nó giữ chức năng.

Giới thiệu tương tự cũng áp dụng cho các phương pháp không trống, nhưng không được sử dụng.

Nó chỉ đơn giản là sẽ ném ra toàn bộ điều, nhưng nó không. Tại sao nó là hành vi mặc định? Và chỉ vì tò mò: Làm thế nào tôi có thể loại bỏ điều này?

+0

"Nếu tối ưu hóa được bật, cũng với -O2 và -O3 nó chỉ biên dịch mã xử lý ngăn xếp cần thiết, nhưng nó tối ưu hóa hướng dẫn cuộc gọi." Điều này có nghĩa là vẫn còn một số chi phí theo cách này? 'start_timer(); do_something(); stop_timer();' mất nhiều thời gian hơn 'start_timer(); stop_timer();'? –

Trả lời

24

Vì hàm có liên kết ngoài (không phải là static), trình biên dịch không thể loại bỏ nó vì một tệp đối tượng khác có thể tham chiếu đến nó. Nếu hàm là static, hàm sẽ bị loại bỏ hoàn toàn.

+4

Điều đó vẫn để lại câu hỏi về lý do tại sao GCC không trực tiếp nội dung chức năng (nghĩa là, bỏ qua cuộc gọi) khi cơ thể được biết là trống rỗng, mặc dù. – duskwuff

+1

@duskwuff: Tôi đã có các chức năng tĩnh được trình biên dịch biên dịch để tôi không thể đặt các điểm ngắt trên chúng, ngay cả khi tôi muốn. Nó có thể phụ thuộc vào phiên bản của GCC hoặc nền tảng mặc dù. Nếu không, tôi không biết; Tôi đã không tham gia vào sự phát triển của GCC và không chịu trách nhiệm đối với các quyết định được đưa ra về các vấn đề đó. –

+1

Bạn đã cho tôi tò mò vì vậy tôi chỉ cố gắng này bản thân mình: Tôi đang trên gcc 4.4.5 và với -O3 (chỉ) Tôi không thấy chức năng trống được gọi là (cho dù tĩnh hay không). – timday

1

Nếu bạn muốn trình biên dịch cuối cùng nội tuyến chức năng bạn đã nói cho anh ta. Khai báo hàm của bạn inline, điều này cho phép trình biên dịch không phải để phát ra hàm nếu nó phù hợp.

Bây giờ điều này có thể dẫn đến lỗi "biểu tượng không xác định" khi bạn biên dịch bằng -O0 hoặc hơn. Đặt "thuyết minh" như

void do_something(int n, const char *s); 

chỉ trong một đơn vị biên dịch (.c tệp).

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