質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1909閲覧

strict alias rule違反となるのはキャストした時点か

yumetodo

総合スコア5850

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/11/24 15:49

編集2020/11/24 15:56

cpp

1class A {}; 2class B {}; 3 4A a; 5B* b = reinterpret_cast<B*>(&a);

上のようなコードがあるとき、変数bにたいしてなにか操作をしたらstrict alias rule違反となるのは明らかだと思われます。しかしながらB* b = reinterpret_cast<B*>(&a);の段階ですでに違反でUBなのかこの時点では大丈夫なのかわかりません。実際にアクセスが起こったときの型の問題と考えると大丈夫なような気もしてきます。

(コードの出処: https://rinatz.github.io/cpp-book/ch08-01-cpp-casts/#reinterpret_cast)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

実際にアクセスが起こったときの型の問題と考えると大丈夫なような気もしてきます。

いわゆる strict alias rule は「異なる型の左辺値(glvalue)を介して値(value)にアクセスする」時の規則ですから、質問中にある解釈で問題ないと思います。C++17 [basic.lval]/8

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • [...]

また、異なるオブジェクト型へのポインタ間の変換それ自体はwell-definedです。C++17 [expr.reinterpret.cast]/p7

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of object pointer type is converted to the object pointer type "pointer to cv T", the result is static_­cast<cv T*>(static_­cast<cv void*>(v)). [...]


本題からはそれますが、変換先のオブジェクト型Tのアライメント要件によっては「未規定(unspecified)のポインタ値」(≠ 未定義(undefined))となる可能性があります。C++17 [static.cast]/13

A prvalue of type "pointer to cv1 void" can be converted to a prvalue of type "pointer to cv2 T", where T is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If the original pointer value represents the address A of a byte in memory and A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified.

投稿2020/11/25 04:10

編集2020/11/25 06:00
yohhoy

総合スコア6191

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

仕様上の規則では「値にアクセスを試みること」について制限されているように読めます。 つまりポインタのキャストをした時点ではまだ未定義の挙動ではないと解釈すべきであると考えます。

投稿2020/11/25 00:13

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

厳密には規格書に当たるべき問題と思いますが、voidポインタとの代入を「未定義動作」とすると、C言語プログラムのかなりの部分が未定義動作になります。(更にvoid*だけでなく、int*float*間の代入でさえも未定義動作と規定するとC言語プログラムで未定義となる部分がちらほらと発生するだろうと思います。)
なので、原則としてポインタ同士の代入については「アドレスがコピーされる」的な定義がなされているのではないかと予想します。

投稿2020/11/24 16:08

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問