new 失敗**必須拋出** std::bad_alloc;new (std::nothrow) 返回 NULL;operator new,分別在 newop.cpp (拋出版) 和 newop2.cpp (nothrow 版);new BigClass **不拋出異常**,直接返回 NULL (行為如 nothrow)。libcp*.lib),再解析 C 庫 (libc*.lib);use_ansi.h 透過 #pragma comment(lib, ...) 自動引入對應版本 C++ 庫;dumpbin /SYMBOLS libcp.lib 顯示 newop.obj **無任何符號定義** (空殼);newop.cpp 原始碼:#if !defined(_MSC_EXTENSIONS) ... operator new 實作 ... #endif;_MSC_EXTENSIONS 宏:/Ze (預設,啟用 MS 擴展) 定義它,**導致實作被編譯器剔除**;/Ze,故 newop.obj 空無一物;new.cpp** (非標準、不拋異常、返回 NULL) —— **錯誤符號勝出**。#include
#include
class BigClass { char buf[0x7FFFFFFF]; };
int main() {
try { BigClass* p = new BigClass; }
catch (std::bad_alloc&) { std::cout << "bad_alloc thrown\n"; }
BigClass* q = new (std::nothrow) BigClass;
if (!q) std::cout << "nothrow returned NULL\n";
}
**VC6 預設建置輸出**:
nothrow returned NULL (第一個 new 也返回 NULL,無異常)。
VC98\CRT\SRC\newop.cpp、dbgint.h 到專案目錄;newop.cpp:#include "dbgint.h" (本地路徑);cl /c /Za /D_CRTBLD newop.cpp/Za:禁用 MS 擴展 → _MSC_EXTENSIONS 未定義 → 實作生效;/D_CRTBLD:繞過 dbgint.h 內部頭文件保護;cl /c /GX test.cpp (/GX 啟用異常處理);link test.obj newop.obj (新 obj 覆蓋庫中空殼)。bad_alloc thrown
nothrow returned NULL
bad_alloc thrown
#if !defined(_MSC_EXTENSIONS) 守衛;newop.cpp/newaop.cpp (array new) 實作完整保留;newopnt.cpp/newaopnt.cpp。newop.cpp (以 /Za 編譯) 或全域關閉優化 (/Od) 並啟用 /GX;new 使用處,**統一改用 new (std::nothrow) + NULL 檢查**,避免假象。set_new_handler 模擬異常行為,但不標準。)作者 2001 年遇此問題,CSDN 發帖無解,擱置 4 年。後因研究 LNK2005 符號重複錯誤,洞悉鏈接器解析規則,重拾舊謎順藤摸瓜,終破案。**原始碼之前,了無秘密。**