2012-02-25 72 views
8

Làm thế nào (trong GCC/"GNU C") bạn có khai báo một con trỏ hàm trỏ đến hàm __attribute__((const)) không? Ý tưởng được rằng tôi muốn trình biên dịch để tránh tạo ra nhiều cuộc gọi đến các chức năng được gọi là thông qua con trỏ hàm khi nó có thể cache giá trị trả về từ một cuộc gọi trước đó.Hàm con trỏ tới hàm __attribute __ ((const))?

+0

Chưa bao giờ đã làm được điều đó và gần như chìm vào giấc ngủ để nghiên cứu, nhưng cố gắng gói một cuộc gọi theo địa chỉ của một hàm như vậy có chức năng khai báo rõ ràng rằng có thuộc tính const và chấp nhận con trỏ đó như một tham số. Nếu gcc có thể xác định rằng địa chỉ con trỏ chính nó & đối số không thay đổi - nó sẽ loại bỏ các cuộc gọi không cần thiết. –

+1

@Vlad: Tôi cũng nghĩ về điều đó, nhưng sau đó gcc từ chối nội tuyến chức năng trong trường hợp tôi muốn nó. Ban đầu tôi đã có một hàm bao bọc như thế, nhưng tôi đã loại bỏ nó để khắc phục hành vi nội tuyến. Trong trường hợp nó thú vị, hàm trong câu hỏi là '((pthread_t (*) (void)) 0xffff0fe0)' (hàm get-thread-pointer-Linux-ARM). –

+0

Câu hỏi thú vị. Câu trả lời của Justin có kết quả mong muốn không? – Praxeolitic

Trả lời

3
typedef void (*t_const_function)(void) __attribute__((const)); 

static __attribute__((const)) void A(void) { 
} 

static void B(void) { 
} 

int main(int argc, const char* argv[]) { 
    t_const_function a = A; 

    // warning: initialization makes qualified 
    // function pointer from unqualified: 
    t_const_function b = B; 

    return 0; 
} 

Hoặc chỉ:

__attribute__((const)) void(*a)(void) = A; 
+0

Bleh, 'typedef' luôn là giải pháp khi bạn có kiểu con trỏ hàm khó chịu. Đã chấp nhận. Nhưng bất kỳ ý tưởng nếu có một cách để viết các diễn viên trong bình luận của tôi về câu hỏi chính mà không có một 'typedef'? –

+0

@R. Thật không may, tôi * không * biết làm thế nào để gió tất cả vào một tuyên bố mà không có một 'typedef' - nó dường như không thể trên GCC 4.2. '((__attribute __ ((const)) pthread_t (*) (void)) 0xffff0fe0)' là cách tôi nghĩ nó sẽ được thực hiện, nhưng nó được diễn giải khác với những gì bạn muốn (nó xuất hiện GCC áp dụng thuộc tính cho kiểu trả về, chứ không phải chức năng). – justin

0

Mặc dù đây không phải là khá câu trả lời cho câu hỏi của bạn, có thể bạn muốn biết điều này:

Bạn không thể trong trường hợp chung mong đợi trình biên dịch để thực hiện việc tối ưu hóa mà bạn mong đợi ở đây. Trình biên dịch không thể trong trường hợp chung làm phân tích bí danh cần thiết để biết rằng việc sử dụng nhiều con trỏ hàm tương ứng với cùng một hàm.

Một cuộc gọi hàm giữa hai lần gọi hàm thông qua con trỏ có thể, trong trường hợp chung, thay đổi nội dung con trỏ, do đó làm cho hàm được gọi khác nhau trong lần gọi thứ hai.

Do tính chất của C, việc phân tích bí danh thích hợp thường khó có thể xảy ra và loại tối ưu hóa này không có khả năng xảy ra.

+2

Đó là những gì __attribute __ ((const)) làm - nó cho trình biên dịch biết rằng bạn biết rõ hơn và đưa ra một ánh sáng màu xanh lá cây cho một số tối ưu hóa. –

+0

Trong trường hợp của tôi nó có thể biết, mặc dù, bởi vì con trỏ là một chữ địa chỉ (một số nguyên đúc một con trỏ hàm). Xem nhận xét. –

+2

@Vlad: Tôi nghĩ điểm của Perry là ngay cả khi chức năng chỉ định là 'const', trình biên dịch cũng sẽ phải chắc chắn rằng con trỏ * không thay đổi giữa các lời gọi. Nhưng đó không phải là quá khó để xác định, và trong trường hợp của tôi nó không thể vì nó là một địa chỉ tuyệt đối theo nghĩa đen. –

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