厳密な別名規則(strict aliasing rules)で、構造体・共用体をもちいてエイリアシングを実現する方法とは
C言語を独学で勉強しているものです。今回初めて質問させていただきます。
ポインタについて調べていると、strict aliasing rulesというものを発見し、オブジェクトのエイリアス(別名)になるための規則があることを初めて知りました。
その規則は、以下のものであることを学びました。(C99)
オブジェクトに格納された値に対するアクセスは,次のうちのいずれか1つの型を持つ左辺値によらなければならない。
- オブジェクトの有効型と適合する型
- オブジェクトの有効型と適合する型の修飾版
- オブジェクトの有効型に対応する符号付き型または符号無し型
- オブジェクトの有効型の修飾版に対応する符号付き型または符号無し型
メンバの中に上に列挙した型の1つを含む集成体型または共用体型(再帰的に包含されている部分集成体または含まれる共用体のメンバを含む)
0. 文字型
発生している問題・エラーメッセージ
このうち、構造体・共用体の規則以外は理解できたのですが、4つ目の
"メンバの中に上に列挙した型の1つを含む集成体型または共用体型(再帰的に包含されている部分集成体または含まれる共用体のメンバを含む)"
がどのような意味を持つのか、そしてどのような形でそのケースのエイリアシングが実現されるのかが分からないです。
該当のソースコード
(ポインタのアライメントの未定義については今回は考慮せず、エイリアシングのみを焦点にしています。)
例えばコードが、
#include<stdio.h> #include<stdlib.h> typedef struct s { double a; float b; int c; short d; }st_alias; typedef union t { double e; float f; int g; short h; }uni_alias; int main(void){ st_alias * ali_s; uni_alias * ali_u; int test_1 = 10; short test_2 = 22; double test_3 = 123.4; float test_4 = 222.2f; system("pause"); return 0; }
のような状態であるとき、"ali_s"と"ali_u"のポインタは、変換におけるアラインメントが正しければ上記の規則によって、main関数内の4つのオブジェクトのエイリアスになることができ、ポインタを経由してアクセス(変更・読み取り)ができるということなのでしょうか?そして、それはメンバアクセス演算子(-> .)によって実現するのでしょうか?
ご教授して下さるととてもありがたいです。どうか宜しくお願いします。
試したこと
visual studio 2017 C++ でポインタにオブジェクトのアドレスを代入して、それを経由したアクセスをしたのですが、期待した結果ではありませんでした。(アラインメントによるアドレスの変化はなかったことは確認済みで、それが原因ではないと思っています。)
また、visual studio C++ が strict aliasing rules をサポートしているのかについて調査をしてみたのですが、そのようなものは見つかりませんでした。
もしかしたらそもそもサポートしていないのではないのかと思いました。
(inline関数の外部結合の定義形式も、C99のものではなくC++の形式をサポートしている状況もあったため、そのようなこともあるのではないのかと…)
補足情報(FW/ツールのバージョンなど)
visual studio C++ 2017を利用しています。(.cの形式で使用しています。)
また、strict aliasing rulesの日本語形式のものは、
https://www.jpcert.or.jp/sc-rules/c-exp39-c.htmlから引用させていただきました。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/28 16:35
2018/08/29 01:27
2018/08/29 02:23 編集
2018/08/29 13:40
2018/08/29 13:50
2018/08/29 13:55
2018/08/29 14:02
2018/08/30 03:37 編集
2018/08/30 09:01
2018/08/30 09:09
2018/08/30 09:14
2018/08/30 09:15
2018/08/30 09:47 編集
2018/08/30 15:45
2018/08/31 08:00