宣言された順序でアドレスが増加するように表示されることが保証されています。これは一般に、アクセス指定子を介在させないデータ メンバーに当てはまります。したがって、クラスに他のデータ メンバーが存在する場合、それらが介入できる唯一の方法は、そこにアクセス指定子がある場合です。
パディング バイトを変更しても安全であるとは限りません。実装がデータメンバーの間に「何か重要なもの」を入れないことが保証されているとは思いませんが、実装がそこに入れたいと思うものはすぐには思いつきません。奇妙に設計された正確なマーキング GC の型情報は? バッファ オーバーランをテストするための認識可能な値は?
all-bits-zero が null 関数ポインターを表すことは保証されていません。
次のようなものを使用して、すべてのビットがゼロの表現の問題に対処できます。
std::fill(&func1, &func4 + 1, (void(*)(void))0);
しかし、それでもパディングの問題は残ります。配列にはパディングがないことが保証されていますが、(標準では) クラスにはパディングされていません。実装で使用される ABI は、上記のクラスが 4 つの関数ポインターの配列と同じようにレイアウトされるようにするために必要な程度まで構造体レイアウトを指定する場合があります。
別の方法として、次のことを行います。
struct function_pointers {
void (*func1)();
void (*func2)();
void (*func3)();
void (*func4)();
};
class C : private function_pointers
{
public:
C() : function_pointers() {}
};
イニシャライザは、それ自体のインスタンスがデフォルトで初期化されている場合でもfunction_pointers()
、(ユーザーが宣言したコンストラクタがないため) のメンバーfunction_pointers
がゼロで初期化されることを指示します。アクセスするためにもう少し入力したい場合などは、基本クラスではなくデータメンバーにすることができます。C
function_pointers
func1
C
C++03 では、現在非 POD であることに注意してください。C++11 ではC
、この変更後も標準レイアウトのままですがC
、 で定義されたデータ メンバーが存在する場合は標準レイアウトではなく、自明なクラスではありません。したがって、POD/標準/自明性に依存している場合は、これを行わないでください。代わりに の定義をC
そのままにして、集約初期化 ( C c = {0};
) を使用して C のインスタンスをゼロで初期化します。