2003:C++03 修正版——漫長等待中的小修#
事件#
2003 年,ISO 發佈 C++03(ISO/IEC 14882:2003)——這是一份缺陷修正報告(TC,Technical Corrigendum),不改變語言語義,只修補 C++98 的瑕疵。
關鍵內容#
- 值初始化(value-initialization) 語義明確化:
new T()保證初始化為零。 - 澄清
std::vector的記憶體連續性(讓&v[0]可當陣列用)。 - 修補樣板與
friend語法的模糊地帶。
為何重要#
- C++03 的意義在於「證明了一件壞事」:13 年不動標準(1998→2011),語言與硬體革命(多核心、64 位元)嚴重脫節——這個教訓直接催生了 C++11 之後「三年一版」的節奏。
- 值初始化的明確化,是後來 C++11
{}統一初始化語法的伏筆。
理論與實用原因#
- 理論原因:標準缺陷報告(DR)流程——標準文字有歧義時,以 TC 釐清而不改變設計。
- 實用原因:編譯器廠商需要明確規範才能實作正確;使用者需要確定語義才能寫出可攜程式碼。
彌補了什麼缺陷#
彌補了 C++98 文字歧義的缺陷;但也暴露了「標準更新太慢」的新缺陷——2011 年 C++11 才真正回應。
程式範例#
值初始化:new T vs new T()
#include <iostream>
int main() {
// C++98 舊寫法:new T 未初始化,內容是垃圾值
int* a = new int; // a 指向的值未定義,每次執行可能不同
// C++03 釐清:new T() 保證值初始化(零初始化)
int* b = new int(); // b 指向的值保證是 0
std::cout << *a << "\n"; // 可能是垃圾值(未定義行為風險)
std::cout << *b << "\n"; // 一定是 0
delete a;
delete b;
}
// 對自訂型別也一樣:C++03 之後 new T() 會先零初始化成員再呼叫建構子
struct Point { int x, y; };
Point* p1 = new Point; // C++98:x, y 是垃圾值
Point* p2 = new Point(); // C++03:x, y 保證是 0
std::vector 記憶體連續性:&v[0] 可當陣列指標
#include <vector>
// 呼叫需要裸陣列的 C API
void read_data(double* buf, int n); // 例如 C 函式庫介面
int main() {
std::vector<double> v(100);
// C++98 標準文字未明確保證 vector 連續,&v[0] 嚴格說不可攜;
// C++03 澄清了連續性保證,以下寫法正式合法:
read_data(&v[0], static_cast<int>(v.size()));
}