さほど実用的でもないポインタと配列の違い

経験から、ポインタと配列を混同している例をみたことがあるので、それを提示。
あまりマニアックな動作だと役に立たないかもとか。

例えば、自分は下記のようなデータ構造をよく使う。
可変長のデータ構造で、
先頭に個数が入っており、その個数分のデータが続くという場合。
ここではvalueはintだが、多くの場合は構造体。

struct Hoge1 {
    int count;
    int value[0];
};

struct Hoge2 {
    int count;
    int* value;
};

で、ポインタが配列だと思っている人、即ち
value[i]と書いた場合、
同じ動作をすると思っている人は
上の動作を意図して(データがそこに続いているんだよということを意図して
下のようにint* valueと書いてしまうことがある。
で、あれれ、ってなっちゃう。(なっちゃってた。
配列とポインタは同じじゃなかったの? そんなわきゃーない。

ちょっと例外的だが、キャストして値をあててみるとわかりやすい。

int main()
{
    int dummy[100] = {5,2,3,4,5,6};
    
    Hoge1* hoge1 = reinterpret_cast<Hoge1*>(dummy);
    printf("Hoge1 sizeof:%d\n", sizeof(Hoge1));
    for (int i=0; i < hoge1->count; ++i) {
        int value = hoge1->value[i];
        printf("%d\n", value);
    }
    
    Hoge2* hoge2 = reinterpret_cast<Hoge2*>(dummy);
    printf("Hoge2 sizeof:%d\n", sizeof(Hoge2));
    for (int i=0; i < hoge2->count; ++i) {
        int value = hoge2->value[i];
        printf("%d\n", value);
    }
    return 0;
}

dummyに対してマップしてみた結果。
hoge1もhoge2も同じような表記ができるが、していることは全く異なる。
value[0]とかvalue[]とか書けない処理系でこういうことをしたいなら
value[1]とでも書いておくべきか。