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))?
Trả lời
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;
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'? –
@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
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.
Đó 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. –
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. –
@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. –
- 1. con trỏ tới hàm thành viên const typedef
- 2. Hàm con trỏ tới hàm thành viên
- 3. Gọi một hàm có con trỏ không const sẽ chuyển thành hàm mẫu trên một hàm lấy con trỏ tới const
- 4. Con trỏ tới Const Char
- 5. Gán con trỏ cho một hàm địa chỉ của con trỏ tới đối tượng hàm
- 6. Chuyển hàm con trỏ thành thành viên làm con trỏ tới hàm
- 7. không thể chuyển con trỏ tới hàm giữa các lớp
- 8. C++ Con trỏ tới các hàm thành viên Thừa kế
- 9. Chuyển một con trỏ tới hàm putchar đến một hàm nhận int (*) (int)
- 10. Con trỏ hàm thành viên
- 11. Cú pháp cho một con trỏ tới một hàm trả về một con trỏ hàm trong C
- 12. Hàm con trỏ tới hàm thành viên của lớp mẫu? (C++)
- 13. Con trỏ hàm trong C#
- 14. Đối số chấp nhận con trỏ hàm
- 15. hàm mẫu quá tải: const * vs const &
- 16. chuyển functor làm con trỏ hàm
- 17. con trỏ đến hàm thành viên
- 18. Vượt qua một mảng tới một hàm bọc như kích thước con trỏ + hoặc phạm vi
- 19. Cách lấy tên hàm từ con trỏ hàm trong C#?
- 20. Khai báo cú pháp con trỏ trong một hàm
- 21. thành ngữ hàm tạo ảo với con trỏ thông minh
- 22. lấy con trỏ hàm 'ldftn' trong C#
- 23. Con trỏ hàm C++ làm tham số
- 24. Con trỏ hàm được đúc trong C++
- 25. Toán tử làm con trỏ hàm
- 26. Con trỏ "này" trong hàm lồng nhau
- 27. con trỏ hàm không có typedef
- 28. Mảng con trỏ hàm trong C
- 29. Trả về con trỏ từ hàm C
- 30. Gọi C++ con trỏ hàm từ C#
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. –
@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). –
Câu hỏi thú vị. Câu trả lời của Justin có kết quả mong muốn không? – Praxeolitic