簡體   English   中英

內聯這個函數,有意義嗎?

[英]inline this function, does make sense?

我有下一個成員函數:

template <typename T>
inline T Foo::Read(const DWORD addr) const                          // Passing by value.
{
    T buffer;
    ReadProcessMemory(m_processHandle, (LPVOID)addr, &buffer, sizeof(T), NULL);
    return buffer;
}

如果我沒記錯的話,編譯器內聯函數時,會避免調用該函數,而是將被調用函數的代碼放入調用函數中。

所以在調用者函數中(假設一個整數返回類型)我想要這樣的東西:

ReadProcessMemory(m_processHandle, (LPVOID)addr, &bufferOfTheCaller, sizeof(int), NULL);

關於這個我有三個問題:

1)我們從函數返回的變量會發生什么? 變量緩沖區的聲明不是在運行時執行的嗎?

2)在這種情況下ReadProcessMemory是一個來自 WinAPI 的巨大函數,編譯器是否仍然能夠內聯這個函數?

3)將成員函數定義在類定義內部與在類定義外部使用關鍵字inline聲明有什么區別? 如果我想使用 inline 關鍵字,我必須將內聯函數放在同一個文件 .h 中還是?

重要的是要注意inline關鍵字與對函數的內聯調用無關。 它所做的只是允許在多個翻譯單元中定義函數,只要所有定義都相同。

inline關鍵字的作用是讓您在頭文件中定義一個函數,該函數將包含在多個翻譯單元中。 這可能會給編譯器更好的機會來內聯調用該函數,因為它在多個翻譯單元中具有完整的定義,但它不是命令,甚至不是您希望編譯器這樣做的提示。 編譯器將自行決定是否應該內聯對任何給定函數的調用。 如果您確實想強制對函數的調用進行內聯,則可以使用特定於編譯器的擴展,但這不是inline關鍵字的作用。


順便說一下,我要補充一點,編譯器內聯函數調用根本不會改變 C++ 的規則。 它不是文本替換,就像預處理器宏一樣。 編譯器會弄清楚如何將被調用函數的邏輯插入到調用者中。 那時,像 C++ 變量這樣的東西並不真正存在。 如果您的電話看起來像這樣:

int someValue = myFoo.Read(someAddress);

那么編譯器可以很容易地將它轉換成這樣的:

int someValue;
ReadProcessMemory(myFoo.m_processHandle, (LPVOID)someAddress, &someValue, sizeof(int), NULL);

由於 as-if 規則。 這兩個片段都導致相同的可觀察行為,因此編譯器可以在它們之間自由轉換。

我們從函數返回的變量會發生什么?

它將被銷毀,因為函數調用表達式丟棄了返回值。

變量緩沖區的聲明不是在運行時執行的嗎?

聲明發生在編譯時。

在這種情況下 ReadProcessMemory 是一個來自 WinAPI 的巨大函數,編譯器是否仍然能夠內聯這個函數?

如果編譯器知道函數的定義,那么它可以內聯擴展它。 是否應該,或者是否會這樣做取決於許多因素。 函數的大小是一種啟發式方法,可能會影響編譯器所做的選擇。

將成員函數定義在類定義內部並在類定義外部使用關鍵字 inline 聲明它有什么區別?

在一種情況下,定義在類內部,而在另一種情況下,定義在類外部。 沒有其他區別。

如果我想使用 inline 關鍵字,我必須將內聯函數放在同一個文件 .h 中還是?

  • 如果您想內聯定義成員函數,但想在類定義之外定義它,那么您必須在類定義中聲明該函數內聯——除了函數模板,它是隱式內聯的。
  • 如果你想在類定義中定義成員函數,那么你不需要顯式聲明它內聯; 它會如此含蓄。
  • 如果不想內聯定義函數,那么必須在類定義之外定義函數,並且不得使用 inline 關鍵字。

如果我沒記錯的話,編譯器內聯函數時,會避免調用該函數,而是將被調用函數的代碼放入調用函數中。

是的,但inline與此無關。

1)我們從函數返回的變量會發生什么? 變量緩沖區的聲明不是在運行時執行的嗎?

編譯器,無論是否內聯,都必須為buffer保留一些空間,通常在堆棧上。

換句話說,沒有bufferOfTheCaller 如果您的函數是內聯的,則buffer將位於調用者的堆棧幀中; 否則,它將被放入被調用者的堆棧幀中。

2) 在這種情況下 ReadProcessMemory 是來自 WinAPI 的一個巨大函數,編譯器是否仍然能夠內聯這個函數?

ReadProcessMemory的實現有多大並不重要,您的代碼只是對其執行一個函數調用,這是很小的。 優化編譯器可能會內聯您的函數。

3) 將成員函數定義在類定義內部與在類定義外部使用關鍵字 inline 聲明有什么區別?

沒有不同。

如果我想使用 inline 關鍵字,我必須將內聯函數放在同一個文件 .h 中還是?

inline關鍵字與內聯無關。 如果要將函數的定義放在頭文件中,則可能需要inline以防止重新定義錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM