キャスト後のポインタの値

Home > 2005-10 / 実装技術 > This Entry [com : 0][Tb : 1]

2005-10-02

 Cでは、ある型へのポインタから別の型へのポインタにキャストした場合でも、ポインタの値(アドレス)が変わることはありませんでした。Cプログラマにとって、特にアドレスを意識することが多い組み込みプログラマにとっては、これはある意味で大原則のひとつかもしれません。

しかし、C++では、Cのそうした大原則・常識も簡単に覆ってしまいます。C++では、キャスト前の型とキャスト後の型の間に継承関係があれば、ポインタの値(アドレス)が維持されるとは限らないのです。

例えば、あるクラスAから派生したクラスBがあるとします。下の例を見てください。

class A
{
public:
    void foo();
private:
    int x;
};

class B : public A
{
public:
    void bar();
private:
    int y;
};



このとき、クラスBのオブジェクトは、クラスA相当の部分オブジェクトを内在することになります。ところが、そのクラスA相当分は、クラスBのデータメンバであるB::yより前に配置されるか、後に配置されるかは処理系に依存します。

もし、クラスA相当の部分オブジェクトよりB::yの方が先(アドレスが下位)に配置されたとすれば、クラスBからクラスAにキャストする場合には、sizeof(B::y)の分(および場合によってはパディングの分)だけ、アドレスをずらさなければなりません。クラスAからクラスBにキャストする場合も同様です。

現実には、クラスAの部分オブジェクトの方がB::yより先に配置されることが多いようですが、これを期待した実装はすべきではありません。

また、キャストによって確実にポインタの値がずれる場合もあります。それは多重継承の場合です。多重継承では基底クラスが複数あるわけですから、どの基底クラスに相当するの部分オブジェクトが先に配置されたところで、それ以外の基底クラスへのポインタにキャストされれば、必ずポインタの値がずれることになります。





Comment

Post a Comment









管理者にだけ表示を許可

Trackback

http://cppemb.blog17.fc2.com/tb.php/32-3440be9e

C/C++バグ予防: 安易にゼロを付けないようにしよう!

プログラムを組む上で、ソース中に数値を直書きするケースは多々ある。 (あまりよろしくないことだが・・・。) その際、安易に「0」を付けた事により、想定外の動作になるケースを紹介する。 たとえば次のようなケースでは、VALUE_010の値が「10」ではなく「8」になって. ...

健康なエンジニアのブログ : 2005-10-03 00:33

C++と組み込み環境 | Page Top▲

New >>
前置形式と後置形式の増減演算子
<< old
デストラクタからの例外送出
ブログ内検索
RSSフィード