【C/C++】Strict Aliasing Rule

全ての type-punned pointer を生まれる前に消し去りたい.全ての宇宙,過去と未来の全ての type-punned pointer を,この手で.
15
Akso de la Malbono @Cryolite

GCC の "warning: dereferencing type-punned pointer will break strict-aliasing rules" がうっとうしいので消し去りたいワン.

2011-08-16 18:34:43
SODA Noriyuki @n_soda

@Cryolite (char *)って書けば消えますヨン

2011-08-16 18:37:57
Akso de la Malbono @Cryolite

@n_soda 発生源が boost::function, boost::shared_ptr 周りなのでうにゃにゃにゃにゃ…….

2011-08-16 18:40:50
オスツ🍣 @alohakun

@Cryolite @n_soda -fno-strict-aliasing とかで消えそう。(勘)

2011-08-16 18:41:42
SODA Noriyuki @n_soda

@Cryolite ええっ、C++のそういうあたりで?

2011-08-16 18:43:44
Akso de la Malbono @Cryolite

@n_soda Boost の内部実装で割と type-punned なことしてるので……. C++03 の範疇だと規格上厳密な意味で安全にユーザ定義型を type-punned するのが不可能だったような?

2011-08-16 18:48:40
Akso de la Malbono @Cryolite

@alohakun あ,それで消えました.ありがとうございます.

2011-08-16 18:48:57
SODA Noriyuki @n_soda

@alohakun @Cryolite 消えますけど、gcc以外で意図しない最適化が起きる危険があるので、(char *)へのキャストの方が安全なことが多いかと。まあ原因をちゃんとみないと正確なことは言えないんですが...

2011-08-16 18:49:10
SODA Noriyuki @n_soda

@n_soda @alohakun @Cryolite まあgccの場合は、 -fno-strict-aliasing すれば、最適化を抑制してくれると思うので、大丈夫でしょうけど... でもつけないで放置しておくと最適化の結果ヤバいことが起きそうなんだけど、いいんかな。

2011-08-16 18:53:38
オスツ🍣 @alohakun

@n_soda @Cryolite ヘッダライブラリで警告が出る場合はしかたない気がしますね。(テストスイートが付いてるのはそのためですし。)個人的には C++ で C スタイルキャストを使うほうがはるかに気持ち悪いです。ちなみに QEMU も GCC とこのオプション必須です。

2011-08-16 19:09:14
SODA Noriyuki @n_soda

@alohakun @Cryolite 同じ最適化ルール使ってるなら、reinterpret_castでも警告は消えそう(最適化が抑制されそう)な気がするんですが、駄目なんでしょうか?

2011-08-16 19:18:57
Akso de la Malbono @Cryolite

@n_soda @alohakun 私はあくまで C++ の規格の範疇での話しかできないんですが, reinterpret_cast を使った場合でも GCC が危険な最適化をかけるのは C++ の規格的には合法だと思います.(そういうキャストの使い方をするほうが悪い)

2011-08-16 19:30:35
SODA Noriyuki @n_soda

@Cryolite @alohakun がびーん。unionしか選択肢はないっつうことですか。いやreinterpret_castじゃなくても、ad hocにunionを定義する以外の手が必要では?

2011-08-16 19:33:27
オスツ🍣 @alohakun

@n_soda @Cryolite union使っても、同じアドレスに異なる型でread/writeしてしまった時点で、コンパイラにリオーダーされてメチャクチャな結果になっても文句言えなかったと思います。(GCC限定ならunionによるアクセスまでは最適化しなかったはずですが。)

2011-08-16 19:44:26
chunjp @chunjp

unionでキャストするのは規格的には正しくないんですけど…… おれ、この仕事が終わったらstrict aliasing ruleの解説も書くんだ……。

2011-08-16 19:55:59
SODA Noriyuki @n_soda

@alohakun @Cryolite え、コンパイラに、「この2つの変数は実体同じ可能性があるから最適化するな」って伝える術がないんですか?その場合、unionもreinterpret_castも禁止するか、最適化を諦めるかしかないような。廃止は無理なので、後者?

2011-08-16 19:57:55
オスツ🍣 @alohakun

@n_soda @Cryolite なんか話がすれ違ってるような…前提として(1) Boost のヘッダの話なので、ユーザが書き換えることはしない(方向で)。(2)どのみちコンパイラ依存の方法しか無いので、GCC なら -fnostrict-aliasing (最適化を諦める。)

2011-08-16 20:06:24
SODA Noriyuki @n_soda

unionの実際のメンバーならOKだけど、キャストでフリさせるだけじゃ駄目ってことでしょうか。解説すごく期待 RT @chunjp: unionでキャストするのは規格的には正しくないんですけど… おれ、この仕事が終わったらstrict aliasing ruleの解説も書くんだ…

2011-08-16 20:18:01
SODA Noriyuki @n_soda

@alohakun @Cryolite いや、これらがC言語だと、portableに最適化を抑制する方法が、規格で定められてるんですよ。で、C++にもそういう手があれば、Boostはそうすべきなんじゃないかって話です。

2011-08-16 20:19:43
オスツ🍣 @alohakun

@n_soda @Cryolite まずは C でポータブルに strict-aliasing rules を攻略する方法を…!(適当に検索したら (char *) と union は OK という感じもしてきました…。以前 union も駄目とどこかで見たような。勘違いかな?)

2011-08-16 21:42:22
SODA Noriyuki @n_soda

@alohakun @Cryolite Cの方はJIS X3010「6.5 式」の注(73)のついた部分にあります。n1256.pdfだと同じく6.5で注76)のとこかな。CならunionはOKだと思いますが、正確な解釈は @chunjp さんに期待(ぉ

2011-08-16 21:54:08
Akso de la Malbono @Cryolite

C++03 (14882:2003) の場合, strict aliasing rule に対応するのは 3.10/15 のはずで, (1)char (2)unsigned char (3)union の場合データメンバの型のどれか の左辺値経由で触って良いとは書いているけれど,

2011-08-17 00:01:46
Akso de la Malbono @Cryolite

char/unsigned char 経由で触る場合の well-defined で許されている操作は 3.9 で記述されている操作で,要するに POD に対してしかまともに定義されていないし, union の場合は union のメンバになれる型の制限が厳しいしで,

2011-08-17 00:05:04