Tôi đang sử dụng từ khóa MS cụ thể để buộc một hàm toàn cục được gạch chân, nhưng tôi nhận thấy rằng hàm không tự nội tuyến nếu nó sử dụng một đối tượng có trình phá hủy tầm thường rõ ràng.Tìm hiểu hàm C++ Inlining
Trích dẫn từ MSDN
Ngay cả với
__forceinline
, trình biên dịch không thể inline mã trong tất cả hoàn cảnh. Trình biên dịch không thể nội tuyến một hàm nếu:
Hàm hoặc người gọi của nó được biên dịch với
/Ob0
(tùy chọn mặc định để gỡ lỗi).Chức năng và người gọi sử dụng các loại xử lý ngoại lệ khác nhau (xử lý ngoại lệ C++ trong một, xử lý ngoại lệ có cấu trúc trong trường còn lại).
Hàm có danh sách đối số biến.
Hàm sử dụng lắp ráp nội tuyến, trừ khi được biên dịch với
/Og
,/Ox
,/O1
hoặc/O2
.Hàm này đệ quy và không kèm theo
#pragma inline_recursion(on)
. Với pragma, các hàm đệ quy được đưa vào chiều sâu mặc định của 16 cuộc gọi. Để giảm độ sâu nội tuyến, hãy sử dụnginline_depth
pragma.Chức năng này là ảo và được gọi là hầu như. Các cuộc gọi trực tiếp đến các chức năng ảo có thể được nội tuyến.
Chương trình lấy địa chỉ của hàm và cuộc gọi được thực hiện qua con trỏ tới hàm. Các cuộc gọi trực tiếp đến các chức năng có địa chỉ được thực hiện có thể được inlined.
Chức năng này cũng được đánh dấu bằng công cụ sửa đổi
__declspec
trần truồng.
tôi đang cố gắng khép kín chương trình sau đây để kiểm tra hành vi
#include <iostream>
#define INLINE __forceinline
template <class T>
struct rvalue
{
T& r_;
explicit INLINE rvalue(T& r) : r_(r) {}
};
template <class T>
INLINE
T movz(T& t)
{
return T(rvalue<T>(t));
}
template <class T>
class Spam
{
public:
INLINE operator rvalue<Spam>() { return rvalue<Spam>(*this); }
INLINE Spam() : m_value(0) {}
INLINE Spam(rvalue<Spam> p) : m_value(p.r_.m_value) {}
INLINE Spam& operator= (rvalue<Spam> p)
{
m_value = p.r_.m_value;
return *this;
}
INLINE explicit Spam(T value) : m_value(value) { }
INLINE operator T() { return m_value; };
template <class U, class E> INLINE Spam& operator= (Spam<U> u) { return *this; }
INLINE ~Spam() {}
private:
Spam(Spam<T>&); // not defined
Spam& operator= (Spam&); // not defined
private:
T m_value;
};
INLINE int foo()
{
Spam<int> p1(int(5)), p2;
p2 = movz(p1);
return p2;
}
int main()
{
std::cout << foo() << std::endl;
}
Với destructor tầm thường INLINE ~Spam() {}
tại chỗ, chúng tôi đã sau tháo
int main()
{
000000013F4B1010 sub rsp,28h
std::cout << foo() << std::endl;
000000013F4B1014 lea rdx,[rsp+30h]
000000013F4B1019 lea rcx,[rsp+38h]
000000013F4B101E mov dword ptr [rsp+30h],5
000000013F4B1026 call movz<Spam<int> > (013F4B1000h)
000000013F4B102B mov rcx,qword ptr [__imp_std::cout (013F4B2050h)]
000000013F4B1032 mov edx,dword ptr [rax]
000000013F4B1034 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013F4B2040h)]
000000013F4B103A mov rdx,qword ptr [__imp_std::endl (013F4B2048h)]
000000013F4B1041 mov rcx,rax
000000013F4B1044 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013F4B2058h)]
}
nơi như mà không có destructor INLINE ~Spam() {}
chúng tôi có sau tháo gỡ
int main()
{
000000013FF01000 sub rsp,28h
std::cout << foo() << std::endl;
000000013FF01004 mov rcx,qword ptr [__imp_std::cout (013FF02050h)]
000000013FF0100B mov edx,5
000000013FF01010 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013FF02040h)]
000000013FF01016 mov rdx,qword ptr [__imp_std::endl (013FF02048h)]
000000013FF0101D mov rcx,rax
000000013FF01020 call qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (013FF02058h)]
}
000000013FF01026 xor eax,eax
}
Tôi không hiểu, tại sao trong sự hiện diện của các destructor, trình biên dịch không nội tuyến chức năng T movz(T& t)
- Note Các hành vi phù hợp 2008-2013
- Note Tôi đã kiểm tra với Cygwin-gcc nhưng trình biên dịch không inline mã.Tôi không thể xác minh trình biên dịch khác tại thời điểm này, nhưng sẽ cập nhật trong 12 giờ tới nếu được yêu cầu
Hỏi những người đã viết trình biên dịch và có thể gửi báo cáo lỗi. –
@ n.m .: Tôi muốn, nhưng trước đó tôi muốn hỏi cộng đồng, nếu họ biết vấn đề này, hoặc nếu tôi thiếu điều gì đó hiển nhiên :-) – Abhijit
Có thiếu '# define' nào không? 'INLINE __forceinline' – dyp