為啥不能#define private public了?

  • 2019 年 11 月 6 日
  • 筆記

今天在寫一個單元測試的時候出現了如下編譯錯誤:

以前用gtest為了測試業務程式碼里的private函數和變數,一直是在單元測試程式碼通過#define private public這樣的trick達到測試業務程式碼的private變數的目的.怎麼現在就不行了呢?
現在用的gcc版本是8.3 以前用的gcc4.8肯定是沒問題的.

剛看到這個編譯告警我是很懵逼的,我沒有使用sstream這個頭文件啊,而且這個redclared是什麼鬼,我沒有定義過這個struct __xfer_bufptrs啊,怎麼會有重定義的問題呢.

根據編譯錯誤告警sstream:redclared with diffrent access,我們打開標準庫的sstream看一下.

在第67行,聲明了__xfer_bufptrs,但是並沒有顯式的聲明訪問許可權,那默認的就是private.


302行,在具體的定義處,確又顯式地聲明了訪問許可權為private.

原來是我的測試程式碼引用了一個第三方的頭文件,第三方的頭文件里用到了標準庫的sstream. 當我們單元測試程式碼里去#define private public時,對sstream第67行是無效的,這裡__xfer_bufptrs被認為是private,而到了第302行,private被替換為public,_xfer_bufptrs被認為是public. 這就造成了編譯的錯誤:訪問許可權的重定義衝突了.

這個事情告訴我們,自己寫的業務程式碼變數許可權也最好要顯式地聲明清楚.不然你就沒法在單元測試里用#define private public這種trick啦.

沒辦法,為了測試業務程式碼里的private變數,只好修改待測試的業務程式碼

#ifdef UNIT_TEST  #define MYPRIVATE public  #else  #define MYPRIVATE private  #endif    class yourclassname  {  //private:  MYPRIVATE:      int a;  }

然後在單元測試程式碼里#define UNIT_TEST.

或者你覺得這種方式看起來很ugly的話,只能添加public介面去獲取private變數了,但是當你要測試的private變數很多時,也是個很麻煩的事情.