Vì nó hoàn toàn tùy thuộc vào trình biên dịch có hay không nó inline các chức năng của tôi, tôi có thể ngừng sử dụng từ khóa này hoàn toàn (giả sử nó sẽ nội tuyến mọi thứ nó có thể)?Tôi có thể ngừng sử dụng "nội tuyến" hoàn toàn không?
Trả lời
Bạn có thể ngừng sử dụng inline
làm kỹ thuật tối ưu hóa.
inline
về cơ bản chỉ hữu ích khi bạn muốn ODR (One Definition Rule) không áp dụng. Nói tóm lại, bạn có thể đánh dấu chức năng như inline
và cung cấp định nghĩa của họ trực tiếp trong một tập tin tiêu đề, sau đó được nhập khẩu bởi nhiều đơn vị dịch thuật, mà không có mối liên kết phàn nàn về điều này:
foo.hpp
inline int foo() { return 42; }
Foo.cpp
#include "foo.hpp" // <== THE LINKER WOULD COMPLAIN IF foo() WERE NOT inline,
// because its definition is imported also in main.cpp
void bar()
{
int x = foo();
}
main.cpp
#include "foo.hpp" // <== THE LINKER WOULD COMPLAIN IF foo() WERE NOT inline,
// because its definition is imported also in foo.cpp
int main()
{
std::cout << foo();
}
Sự hiện diện của từ khóa inline
(trong đó, một lần nữa, không đảm bảo rằng trình biên dịch sẽ thực hiện nội tuyến) đảm bảo rằng trình liên kết sẽ hợp nhất các định nghĩa đó.
Dĩ nhiên, để cho hoạt động hợp nhất này có ý nghĩa, tất cả các định nghĩa của một hàm đánh dấu là inline
mà kết thúc là một phần của các đơn vị dịch khác nhau phải giống hệt. Nếu đây không phải là trường hợp, chương trình của bạn có Hành vi không xác định và không cần chẩn đoán - điều đó có nghĩa là trình biên dịch/trình liên kết của bạn không bắt buộc phải phát hiện sự không nhất quán này và cho bạn biết có điều gì đó không ổn!
mỗi khoản 3.2/4 của Tiêu chuẩn C++ 11, trên thực tế:
Mỗi chương trình sẽ chứa chính xác một định nghĩa của tất cả các chức năng phi inline hoặc biến đó là ODR-sử dụng ở chỗ chương trình; không cần chẩn đoán. Định nghĩa có thể xuất hiện rõ ràng trong chương trình, có thể tìm thấy trong thư viện chuẩn hoặc thư viện do người dùng xác định, hoặc (khi thích hợp) được định nghĩa ngầm định (xem 12.1, 12.4 và 12.8). Một hàm nội tuyến sẽ được định nghĩa trong mọi đơn vị dịch mà nó không được sử dụng.
Chú ý, bạn có thể có chức năng tương tự được đánh dấu là inline
và theo nghĩa đen được xác định hai lần trong các đơn vị dịch khác nhau, và đó là tốt miễn là những định nghĩa là giống hệt nhau:
Foo.cpp
inline int foo() // Has the same body in main.cpp, no problem!
{
return 42;
}
chính.cpp
inline int foo() // Has the same body in foo.cpp, no problem!
{
return 42;
}
int main()
{
std::cout << foo();
}
Tuy nhiên, nếu hai định nghĩa khác nhau, bạn sẽ bơm UB trong mã của bạn, như trong ví dụ sau:
Foo.cpp
inline int foo()
{
return 42; // <== WATCH OUT! Different body in main.cpp
}
chính. cpp
inline int foo()
{
return -42; // <== WATCH OUT! Different body in foo.cpp
}
int main()
{
std::cout << foo();
}
Đây là lý do tại sao bạn thường đánh dấu các hàm là inline
khi bạn cung cấp định nghĩa của chúng trực tiếp trong tệp tiêu đề thường là #include
d.
Cũng lưu ý rằng, các hàm thành viên của lớp có định nghĩa được gạch chân trực tiếp trong định nghĩa lớp được tự động đánh dấu là inline
.
Phụ thuộc vào mục đích sử dụng inline
.
Phổ biến (mis) quan niệm:
inline
chỉ là một gợi ý mà một trình biên dịch có thể hoặc không thể tuân thủ để. Một trình biên dịch tốt sẽ anyways làm những gì cần phải được thực hiện.
Trong khi, sự thật:
inline
thường chỉ đến việc thực hiện mà thay inline của cơ quan chức năng tại thời điểm gọi là được ưa thích cơ chế chức năng cuộc gọi bình thường. Việc triển khai không bắt buộc để thực hiện thay thế nội tuyến này tại điểm gọi; tuy nhiên, ngay cả khi việc thay thế inline
này bị bỏ qua, các quy tắc khác (đặc biệt là w.r.t One Definition Rule) cho inline
được theo sau.
Vì vậy, nếu mục đích sử dụng của bạn là tối ưu hóa câu trả lời là:
YES, Bạn có thể ngừng sử dụng
inline
. Hầu hết các trình biên dịch hiện đại sẽ làm điều đó cho bạn khá độc đáo.
Nhưng nếu mục đích sử dụng của bạn của inline
là cho phép bạn để có được quá khứ một quy tắc định nghĩa và xác định một cơ quan chức năng trong một tập tin tiêu đề mà không vi phạm ODR sau đó trả lời là:
NO , Bạn cần đánh dấu rõ ràng các hàm là
inline
để có thể bỏ qua ODR.
Lưu ý: Các hàm thành viên được định nghĩa trong cơ thể lớp đang ngầm inline
, nhưng cùng không áp dụng cho các chức năng miễn phí.
- 1. Tôi có thể phát video youtube trong nội tuyến UIWebView (không phải toàn màn hình) không?
- 2. Tôi có thể sử dụng Phương thức mở rộng nội tuyến trong trang ASPX không?
- 3. Tôi có thể hoàn tác tác dụng của "sử dụng không gian tên" trong C++ không?
- 4. Lần khi không thể sử dụng chức năng nội tuyến
- 5. Tôi có thể viết nội tuyến nếu có nội dung HTML không?
- 6. Tôi có thể áp dụng CSS cho các phần tử trong khung nội tuyến không?
- 7. Khung nội tuyến không có src - Tôi có thể làm điều đó không?
- 8. Tôi có thể sử dụng màn hình hiển thị: nội tuyến có căn chỉnh văn bản không?
- 9. MySQL LIKE% string% không hoàn toàn tha thứ đủ. Bất cứ điều gì khác tôi có thể sử dụng?
- 10. Tôi có thể chuyển một biến URL tới một Khung nội tuyến bằng cách sử dụng PHP không?
- 11. Alloca có thể thay thế hoàn toàn không?
- 12. Redis có thể thay thế hoàn toàn mysql không?
- 13. Độ trễ/Javascript không thể nội tuyến không thể
- 14. Có thể tạo kiểu pseudo nội tuyến không?
- 15. Sử dụng Mẫu nội tuyến trong Góc
- 16. sử dụng HTTP PUT, nhưng không thay thế hoàn toàn các thực thể
- 17. Tải nội dung nội tuyến bằng cách sử dụng FancyBox
- 18. Tôi có thể bỏ qua người khác trong câu lệnh javascript nội tuyến không?
- 19. Có thể cấu hình ELMAH hoàn toàn bằng mã không?
- 20. Làm thế nào để hoàn toàn ngừng chạy mã và thoát khỏi ứng dụng?
- 21. Có thể nội tuyến một biểu thức lambda không?
- 22. Trong CSS, tôi có thể xếp hàng cao độ của các khối nội tuyến không?
- 23. Có thể xóa hoàn toàn tệp khỏi kho lưu trữ SVN của tôi không?
- 24. Tôi có thể sử dụng __init__.py để xác định các biến toàn cầu không?
- 25. Tôi có thể sử dụng đạo diễn làm bộ định tuyến trong expressjs
- 26. Tôi có thể nội tuyến các phương thức lớp tĩnh trong Objective-C không?
- 27. Không thể hoàn tác ứng dụng web hoàn toàn trong Tomcat 7
- 28. Làm thế nào để tôi đặt nội dung vị trí hoàn toàn trung tâm có chiều rộng không xác định?
- 29. Tôi có thể xóa an toàn tất cả nội dung trong/var/lib/php5 không?
- 30. q.js: tôi có thể ngừng chức năng thực hiện cho đến khi lời hứa được hoàn thành không?
Và, ngay cả khi bạn không bao giờ sử dụng 'inline', bạn vẫn có thể sử dụng nó một cách ngầm định:' struct Foo {int x; Foo(): x (0) {}}; 'trong một tệp .cpp và' struct Foo {double d; Foo(): d (0) {}}; 'trong một tệp .cpp khác, và bạn vừa tạo ra hai hàm tạo' inline' được gọi là 'Foo :: Foo' ... – Yakk
@Yakk: Sau đó, chương trình của bạn có hành vi không xác định, trừ khi cả hai 'Foo' được khai báo trong một không gian tên ẩn danh. –
@MatthieuM. Đúng, và tôi đã thấy điều đó xảy ra trong mã sản xuất. Về cơ bản, tôi nói rằng ngay cả khi bạn không sử dụng 'inline', bạn có thể bị cắn bởi nó, vì vậy bạn cần phải hiểu những gì' inline' thực sự là ngay cả khi bạn không sử dụng nó. – Yakk