[英]Can a valid pointer-to-member have the same value as a NULL pointer?
根據ABI的說法,
指向數據成員的指針是從包含該成員的類對象的基址開始的偏移量...空指針表示為-1
但是,根據c ++標准(我的修訂版為4296,在4.11 / 1中 ),
該類型的null成員指針值...可以與不是從null指針常量創建的指向成員的任何指針區分開
和-1可以是有效的偏移量。
考慮這種情況:
#include <iostream>
using namespace std;
struct A {
char a,b,c,d,e,f,g,h;
};
struct B {
int i;
};
struct C : A,B {};
int main() {
char C::*p=&C::h;
char B::*q = static_cast<char B::*>(p);
cout<< (q==nullptr) <<endl; //prints 1
}
在此代碼中,我的編譯器(x86_64-linux-gnu上的g ++ 4.9.2)將h
置於A
的最后一個字節,並將B
置於C
A
之后。 因此, C::A::h
與C::B
基址的偏移量為-1。
(該轉換是合法的,即使靜態類型為B,其結果也可以用於動態類型C的對象。該標准表示( 5.2.9 / 12 )“盡管類B不必包含原始成員,通過指向成員的指針執行間接訪問的對象的動態類型必須包含原始成員”)
我有什么誤會?
(我懷疑我的誤解是關於短語“包含原始成員的類”( 5.2.9 / 12 )-考慮到C::h
,該短語可能指向A
而不是C
,但是標准明確指出( 10 / 2 )“基類的成員也被視為派生類的成員”)
[expr.static.cast] / p12:
類型的“指針的構件A prvalue
D
類型CV1的T
”可以被轉換成類型的prvalue“指針的構件B
”型CV2的T
,其中B
是一個基類的(第10)D
,[。 ..]。 如果類B
包含原始成員,或者是包含原始成員的類的基類或派生類,則指向成員的結果指針將指向原始成員。 否則,行為是不確定的。
“包含原始成員的類”為A
B
不是基或派生類的A
,所以該行為是未定義。
您錯了,無法從基址偏移-1。 對象的基址是完整對象的地址,而不是該完整對象中子對象的地址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.