簡體   English   中英

可以在編譯單元之間區分內聯成員函數是否會破壞二進制兼容性?

[英]Can inline member functions differing across compilation units break binary compatibility?

我在一個大型項目中有很多代碼,它有兩種通用類型的代碼,其中一些代碼以一種漂亮的C ++風格完成,並且由C ++專家進行了代碼審查,有些則沒有,也沒有。 代碼中沒有很多for循環和未經檢查的數組(堆)訪問,包括讀取和寫入。 幸運的是,所有這些對堆的訪問都是通過類完成的。 為了論證,我們稱之為CArray

CArray完全在頭文件中定義,因為它是模板化的。 它大致定義如下(僅顯示相關部分):

template <typename elementType> class CArray
{
    /// Most of class details I'm leaving out

public:
    inline elementType & operator[](unsigned int i)
    {
#ifdef CARRAY_BOUNDARY_DEBUGGING
        if(i >= m_numElements)
        {
            throw SomeException("CArray::operator[] going out of bounds");
        }
#endif
        return m_pArray[i];
    }

    /// also have corresponding const version of this operator[]

private:
    elementType *m_pArray;
    int m_numElements;
}

(請假設構造函數,析構函數,復制構造函數,賦值運算符和相應的右值參考版本都是正確的。基本上假設類的用戶需要正確使用此類所需的一切。

現在的問題是,如果我有一些定義CARRAY_BOUNDARY_DEBUGGING編譯單元( .cpp文件),然后包含這個類(需要代碼改進/審查的那些),而其他那些沒有(那些堅如磐石的):

  1. 這是否保證是正常的並且不會引入問題,因為類經常通過C ++ 03通過復制,引用和右值引用(僅限C ++ 11)通過編譯單元邊界傳遞? C ++ 11?

  2. 有沒有更好的方法來嘗試這樣做?

編輯:澄清。 我知道非inline函數必須遵守C ++ 03標准第3.2節中所述的一個定義規則,但這是內聯的。 ODR是否仍然適用或在此處有效? 此外,C ++ 03標准規定“內聯函數應在每個使用它的翻譯單元中定義。”

不,這不好,這是UB。 整個程序中的內聯定義必須相同。 如果你想在某些地方使用額外的邏輯,但不是全部,只要讓它成為另一個成員(也寫CArray是愚蠢的):

struct silly_array {
    T& operator[](int x) { /* unchecked */ }
    T& at(int x) { /* check bounds */ return (*this)[x]; }
};

你忘了閱讀你所引用的句子的其余部分。 7.1.2(4)“內聯功能應在每個使用它的翻譯單元中定義, 並且在每種情況下都應具有完全相同的定義 (3.2)。”

暫無
暫無

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

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