14

次の C のコードには動作が定義されていますか?

int main() {
    const int i = 0;
    return *(int*)(&i);
}

6.5/7 では、有効なエイリアスとして「オブジェクトの有効な型と互換性のある修飾された型のバージョン」がリストされているため、質問します。しかし、オブジェクトの有効な型は であり、修飾されたバージョンではconst intないと思います(ただし、逆は真です)。どちらも互換性がありません(6.7.3/10)。intconst intintconst int

さらに、6.3.2.3/2 は、修飾子を追加することでポインター型を変換できること、および結果のポインターが等しいことを示しています。6.3.2.3/7 は、任意の 2 つのポインター型を変換できることを示しています (したがって、キャスト(int*)(&i)自体が許可されます)。しかし、結果のポインターが同じオブジェクトを参照しているとは言っていません。元の型 (この場合は ) に戻すことができるということだけconst int*です。つまり、エイリアスが合法であっても、ポインター変換が実際に を参照するポインターになることを標準が保証していることは明らかではありませんi

それで、標準は実際に私のコードの動作を定義していますか?もしそうなら、これはどこで定義されていますか?

コードが実際に機能することは承知しています。私は、それが機能しない架空の(そして奇妙な)実装を念頭に置いています。その実装が標準に準拠しているかどうか (および、準拠していない場合はどの部分に違反しているか) を尋ねることはできますが、私の想像上の実装が準拠していない他の点がある場合は、水を濁したくありません。誰かが質問に答えるのに役立つと思う場合は、実装について説明します。

4

1 に答える 1

8

§6.7.3 p5 により、少なくとも機能することが暗示されています。

const 修飾されていない型の左辺値を使用して、const 修飾された型で定義されたオブジェクトを変更しようとした場合、動作は未定義です。volatile 修飾されていない型の左辺値を使用して、volatile 修飾された型で定義されたオブジェクトを参照しようとした場合、動作は未定義です。

volatile 修飾された型の場合はrefer toと表示されますが、const 修飾された型の場合はmodifyとだけ表示されることに注意してください。これは、非変更アクセスが OK であることを意味します ( 「規則を証明する例外」)。

ただし、標準の欠陥を特定したように見えます。

于 2013-01-21T11:49:09.503 に答える