一段通訊協議的代碼,早年在GCC 4.4。VS2013下編譯都挺好的,移植到GCC 4.8 ,爲C++ 11作準備,在編譯的時候發現問題git
源代碼省略後的版本以下:app
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();
ui
google了一下錯誤信息發現了一個比較清晰的解釋。google
http://stackoverflow.com/questions/5367674/what-does-the-error-non-placement-deallocation-functionspa
能夠翻譯爲GCC支持0x標準後,任務placement new有2個參數,對應的delete應該是2個參數,(第二個爲size),非placement的new,對應的delete不能是2個參數。翻譯
而個人代碼裏面的new是new一個變長的數據,(這是一個協議頭)因此不是placement的new,因此也就能有std::size_t參數。把代碼改成:code
//重載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上編譯,結果發現了以下告警:blog
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寫晦澀的兼容代碼。TNNNNNNND。
====================================
原來寫了ifdef 熬過去了。
2018年更新一下VS,升級到了VS2017,發現一個更加好玩的事情。編譯
new errors : C2956 : sized deallocation function。
static void *operator new (size_t , size_t lenframe = LEN_OF_APPFRAME_HEAD); static void operator delete(void *ptrframe,size_t);
問題的緣由 在這個地方 https://msdn.microsoft.com/en-us/library/mt723604.aspx 有說明。
發現VC++爲了適應C++14,又不容許你的 delete 出現
delete(void *ptrframe,size_t); 這種方式了。即便在類裏面。但你改爲static void operator delete(void *ptrframe);卻仍然有 C4291的告警。看了一下推薦的修改方式,其實也是擾的方式。心中默默的豎起了一箇中指。