一段通信協議的代碼,早年在GCC 4.4。VS2013下編譯都挺好的,移植到GCC 4.8 ,為C++ 11做准備,在編譯的時候發現問題
源代碼省略後的版本如下:
class Zerg_App_Frame
{
public:
//重載New函數
static void *operator new (size_t , size_t lenframe = LEN_OF_APPFRAME_HEAD);
//不重載delte與情理不通,但是其實沒有什麼問題,
static void operator delete(void *ptrframe,size_t);
public:
//整個通訊包長度,留足空間,包括幀頭的長度.
uint32_t frame_length_;
//frame_appdata_ 是一個變長度的字符串序列標示,
#ifdef ZCE_OS_WINDOWS
#pragma warning ( disable : 4200)
#endif
char frame_appdata_[];
#ifdef ZCE_OS_WINDOWS
#pragma warning ( default : 4200)
#endif
};
GCC(G++) 4.8編譯提示的錯誤如下,
soar_zerg_frame.h:260:17: error: non-placement deallocation function ‘static void Zerg_App_Frame::operator delete(void*, size_t)’ [-fpermissive]
static void operator delete(void *ptrframe,size_t);
^
In file included from soar_svrd_app_fsm_notify.cpp:3:0:
soar_zerg_frame_malloc.h:323:86: error: selected for placement delete [-fpermissive]
Zerg_App_Frame *proc_frame = new(size_appframe_[list_no] + 1) Zerg_App_Frame();
google了一下錯誤信息發現了一個比較清晰的解釋。
http://stackoverflow.com/questions/5367674/what-does-the-error-non-placement-deallocation-function
可以翻譯為GCC支持0x標准後,任務placement new有2個參數,對應的delete應該是2個參數,(第二個為size),非placement的new,對應的delete不能是2個參數。
而我的代碼裡面的new是new一個變長的數據,(這是一個協議頭)所以不是placement的new,所以也就能有std::size_t參數。把代碼改為:
//重載New函數
static void *operator new (size_t , size_t lenframe = LEN_OF_APPFRAME_HEAD);
//不重載delte與情理不通,但是其實沒有什麼問題,
static void operator delete(void *ptrframe);
G++編譯通過,OK,但回到VC++ 2013上編譯,結果發現了如下告警:
2>soar_zerg_frame.cpp(395): warning C4291: 'void *Zerg_App_Frame::operator new(size_t,size_t)' : no matching operator delete found; memory will not be freed if initialization throws an exception
2> e:\courage\zcelib\zcelib.git\src\commlib\soarlib\soar_zerg_frame.h(339) : see declaration of 'Zerg_App_Frame::operator new'
看來VC++還沒有跟上腳步。
又只有用ifdef寫晦澀的兼容代碼。
Linux升級GCC 4.8.1清晰簡明教程(Ubuntu 12.04 64位版為例) http://www.linuxidc.com/Linux/2014-04/99583.htm
在CentOS 6.4中編譯安裝GCC 4.8.1 + GDB 7.6.1 + Eclipse 在CentOS 6.4中編譯安裝GCC 4.8.1 + GDB 7.6.1 + Eclipse
Ubuntu下Vim+GCC+GDB安裝及使用 http://www.linuxidc.com/Linux/2013-01/78159.htm
Ubuntu下兩個GCC版本切換 http://www.linuxidc.com/Linux/2012-10/72284.htm
CentOS6.5升級手動安裝GCC4.8.2 http://www.linuxidc.com/Linux/2015-01/112595.htm
GCC 的詳細介紹:請點這裡
GCC 的下載地址:請點這裡