無效的指標算術
指標演算法的以下用法會導致未定義的行為:
-
如果結果不屬於與指標運算元相同的陣列物件,則新增或減去整數。 (這裡,結尾的元素被認為仍然屬於陣列。)
int a[10]; int* p1 = &a[5]; int* p2 = p1 + 4; // ok; p2 points to a[9] int* p3 = p1 + 5; // ok; p2 points to one past the end of a int* p4 = p1 + 6; // UB int* p5 = p1 - 5; // ok; p2 points to a[0] int* p6 = p1 - 6; // UB int* p7 = p3 - 5; // ok; p7 points to a[5]
-
如果它們不屬於同一個陣列物件,則減去兩個指標。 (同樣,超過結尾的元素被認為屬於陣列。)例外是可以減去兩個空指標,產生 0。
int a[10]; int b[10]; int *p1 = &a[8], *p2 = &a[3]; int d1 = p1 - p2; // yields 5 int *p3 = p1 + 2; // ok; p3 points to one past the end of a int d2 = p3 - p2; // yields 7 int *p4 = &b[0]; int d3 = p4 - p1; // UB
-
如果結果溢位
std::ptrdiff_t
,則減去兩個指標。 -
任何指標運算,其中運算元的指標型別與指向的物件的動態型別不匹配(忽略 cv-qualification)。根據標準,“[特別是,當陣列包含派生類型別的物件時,指向基類的指標不能用於指標算術。”
struct Base { int x; }; struct Derived : Base { int y; }; Derived a[10]; Base* p1 = &a[1]; // ok Base* p2 = p1 + 1; // UB; p1 points to Derived Base* p3 = p1 - 1; // likewise Base* p4 = &a[2]; // ok auto p5 = p4 - p1; // UB; p4 and p1 point to Derived const Derived* p6 = &a[1]; const Derived* p7 = p6 + 1; // ok; cv-qualifiers don't matter