Tôi muốn hiểu chính xác lý do macro hiển thị libC++ cho hàm nội tuyến sử dụng __forceinline
hoặc __attribute__((__always_inline__))
như một phần của thuộc tính mà nó liên kết với các hàm nội dòng.Tại sao libcxx áp dụng __forceinline hoặc GCC tương đương với các hàm nội tuyến đã ẩn của nó?
Đối với nền xem:
Nếu các chức năng nội tuyến sẽ được đánh dấu là __visibility__("hidden")
dù sao, tại sao nó cần thiết để bổ sung buộc các trình biên dịch để inline họ ?
Tôi đã suy nghĩ về nó một chút, và tôi có một vài giả thuyết, nhưng không ai có vẻ hoàn toàn thỏa đáng với tôi:
- Nó là để đảm bảo rằng các biểu tượng không vô tình trở thành một phần của ABI. Nếu, trong khi xây dựng thư viện, trình biên dịch đã chọn không inline chức năng, nó có khả năng có thể trở thành một biểu tượng bên ngoài, và do đó một phần của ABI. Nhưng không phải thuộc tính
hidden
là đủ? Tương tự như vậy, nó sẽ không chỉ cần thiết để buộc nội tuyến chức năng khi xây dựng thư viện? Người tiêu dùng không nên quan tâm. - Để đảm bảo rằng hàm không bao giờ có định nghĩa, để tránh các vấn đề ODR, nơi trình biên dịch không muốn nội tuyến hàm trong chính thư viện và không cho phép nội tuyến trong hàm trong mã do khách hàng tạo thư viện, dẫn đến hai định nghĩa khác nhau. Nhưng đó không phải là kết quả mong đợi (và được chấp nhận) của việc sử dụng
visibility("hidden")
? - Nó là một cái gì đó cụ thể cho việc thiết kế libC++ như một thực hiện của thư viện chuẩn.
Tôi hỏi điều này vì tôi đang xây dựng thư viện C++ mà tôi hy vọng một ngày nào đó sẽ tiêu chuẩn hóa ABI và tôi đang sử dụng libC++ làm hướng dẫn. Cho đến nay, nó đã làm việc tốt, nhưng vấn đề này đã gây ra một số đầu gãi.
Cụ thể, chúng tôi đã có báo cáo về người dùng phàn nàn rằng MSVC đã từ chối tôn trọng thuộc tính __forceinline
, dẫn đến cảnh báo. Giải pháp được đề xuất của chúng tôi là mở rộng tương tự của chúng tôi thành INLINE_VISIBILITY chỉ bao gồm __forceinline
(hoặc tương đương GCC) khi xây dựng thư viện, giả sử giải thích đầu tiên ở trên.
Tuy nhiên, vì chúng tôi không hoàn toàn tin tưởng rằng chúng tôi hiểu lý do đằng sau buộc các chức năng nội tuyến là __forceinline
hoặc __attribute__((__always_inline__))
ngay từ đầu, chúng tôi hơi lưỡng lự khi áp dụng giải pháp này.
Bất cứ ai có thể cung cấp câu trả lời dứt khoát cho lý do tại sao libC++ cảm thấy cần phải ép nội tuyến các hàm nội tuyến của nó, mặc dù chúng đã được trang trí là có khả năng hiển thị ẩn?
Tôi thích câu trả lời đó và cảm ơn bạn đã dành thời gian trả lời. Có vẻ như chúng ta có thể tiến lên và đánh giá lại liệu việc nuôi cấy __forceinline của chúng ta là không cần thiết và cần được loại bỏ. Nghe có vẻ như nó có thể là tốt. Ngoài ra, nếu bạn quan tâm đến việc thấy cách tiếp cận mà chúng tôi đang thực hiện hoặc cung cấp bất kỳ phản hồi nào, thư viện được đề cập là libmongocxx: https://github.com/mongodb/mongo-cxx-driver/tree/master – acm