次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part131
http://mevius.2ch.net/test/read.cgi/tech/1501295308/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.101【環境依存OK】
http://mevius.2ch.net/test/read.cgi/tech/1500329247/
■長いソースを貼るときはここへ。■
http://codepad.org/
https://ideone.com/
[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
探検
C++相談室 part132
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん 転載ダメ (ワッチョイ faeb-wbjw)
2017/10/10(火) 00:11:34.01ID:nc/5PI4P0712デフォルトの名無しさん (ブーイモ MMa3-GOXm)
2017/11/15(水) 20:48:51.98ID:5RHQ4qAcM713デフォルトの名無しさん (ワントンキン MMdf-ZLBY)
2017/11/15(水) 20:52:44.99ID:r8JgjB1aM714デフォルトの名無しさん (ワッチョイ ff75-ckd2)
2017/11/15(水) 22:24:21.73ID:KiQc4/2v0 自分なりにやってみた。
https://ideone.com/ugURi1
>>711
vector::insertで領域の再確保が起こると既存のイテレータが破壊されるんで
24-25行あたりの処理はヤバイ。
https://ideone.com/ugURi1
>>711
vector::insertで領域の再確保が起こると既存のイテレータが破壊されるんで
24-25行あたりの処理はヤバイ。
715デフォルトの名無しさん (ワッチョイ 7fa8-ydEu)
2017/11/15(水) 22:45:07.35ID:sivdqd190716デフォルトの名無しさん (ワッチョイ 41eb-RjUU)
2017/11/16(木) 19:03:07.86ID:qgvG7lfo0 すれちがいだけど、
C++が出る前のC言語で、STLが必要な処理はどうしてたの?
C++が出る前のC言語で、STLが必要な処理はどうしてたの?
717片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd22-EXIO)
2017/11/16(木) 19:10:17.36ID:1Qzf60whd >>716
固定バッファとか、ヒープとか、自己参照構造体などで管理してたはず。
固定バッファとか、ヒープとか、自己参照構造体などで管理してたはず。
718デフォルトの名無しさん (ワッチョイ cd83-RjUU)
2017/11/16(木) 20:50:27.90ID:WXeeSnzL0 >>612 ←こういう馬鹿がいるから
719デフォルトの名無しさん (ワッチョイ b9a8-8CrJ)
2017/11/16(木) 21:22:02.83ID:xIkq77qW0 一応つっこみ。
型の一般化がテンプレートと思うが
マクロじゃなくてテンプレート使えって書いてた本もあったような
気がする。
型の一般化がテンプレートと思うが
マクロじゃなくてテンプレート使えって書いてた本もあったような
気がする。
720デフォルトの名無しさん (スップ Sd82-lBnI)
2017/11/16(木) 21:27:58.68ID:w4cxkmV2d >>718
新たな馬鹿の登場かな?
新たな馬鹿の登場かな?
721デフォルトの名無しさん (ブーイモ MMf6-6+Yk)
2017/11/16(木) 21:39:47.71ID:Pxu9bZObM >>716
いや自分で書けばよくね?
いや自分で書けばよくね?
722デフォルトの名無しさん (ワッチョイ dd23-3Z+5)
2017/11/17(金) 08:37:40.63ID:smNhjLrp0 >>716
STL 等はあれば便利なだけで「それが必要な処理」などない。
STL 等はあれば便利なだけで「それが必要な処理」などない。
723デフォルトの名無しさん (ワッチョイ 4178-kX9V)
2017/11/17(金) 09:38:50.05ID:S87VOpst0 >>716
STLで使われているアルゴリズムはC++前からあったものばっかだよ
STLで使われているアルゴリズムはC++前からあったものばっかだよ
724デフォルトの名無しさん (ワントンキン MM52-LokX)
2017/11/17(金) 09:46:53.51ID:4EHSQg4KM 汎用アルゴリズムのコードを業界で共通化することもなく、みんなが各々で実装してたんですか?というアンチテーゼだろ
725デフォルトの名無しさん (ワッチョイ dd23-3Z+5)
2017/11/17(金) 09:59:16.63ID:smNhjLrp0 違うと思うけど?
726デフォルトの名無しさん (ワッチョイ a104-0wpo)
2017/11/17(金) 10:03:14.26ID:NwY4XtJI0 まぁ、ライブラリとして偏在はしてたんだろうけど、あの会社はあのライブラリこの会社はこのライブラリってややこしいことになってたと思う。
727デフォルトの名無しさん (アウアウカー Sa49-6di6)
2017/11/17(金) 16:57:04.66ID:vGXyPrNqa リンクリストと平衡二分木ぐらいなら雑に書いても500行ぐらいでできる
みんな大学の復習と思って書いてたんじゃないかな?
みんな大学の復習と思って書いてたんじゃないかな?
728デフォルトの名無しさん (スップ Sd82-fw3n)
2017/11/17(金) 18:49:47.16ID:a6b9gyRQd 自力で書いてる人の方が多かった
STLがあっても用途によっては独自になるよな
ディスク上に作るとか、JPEGのハフマン符号みたいに表現が決まってる物とか
STLがあっても用途によっては独自になるよな
ディスク上に作るとか、JPEGのハフマン符号みたいに表現が決まってる物とか
729デフォルトの名無しさん (スップ Sd82-fw3n)
2017/11/17(金) 18:52:08.38ID:a6b9gyRQd STLはあくまでお手軽用途
表現縛りがなかったとしても、
ガチガチに最適化する用途では使えない
表現縛りがなかったとしても、
ガチガチに最適化する用途では使えない
730デフォルトの名無しさん (ワッチョイ 8203-Eq1o)
2017/11/17(金) 20:50:18.49ID:HNipYc2I0 最適化できない? なんで??
テンプレートだろ
テンプレートだろ
731デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/17(金) 21:51:52.32ID:Eetf/DNi0 テンプレート万能説爆誕。
732デフォルトの名無しさん (ワッチョイ 02e7-GXP8)
2017/11/17(金) 22:21:21.86ID:EgKbzTW+0 if ( オーバーヘッドがない != 最適化される )
733デフォルトの名無しさん (オッペケ Srd1-jTIY)
2017/11/17(金) 22:36:52.56ID:stAFfC8Ar ガチガチに最適化する状況が最近はほとんどない
734デフォルトの名無しさん (ブーイモ MM22-6+Yk)
2017/11/17(金) 23:08:51.45ID:grVEZAi9M ガチガチに最適化すべき場合ってどんな時だろうか
735デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/17(金) 23:17:53.86ID:Eetf/DNi0 ガチガチの最適化が仕様に盛り込まれたとき。
736デフォルトの名無しさん (ブーイモ MM22-6+Yk)
2017/11/17(金) 23:46:01.61ID:grVEZAi9M そんな恒真命題は期待してないゾ
証券取引所とかか
証券取引所とかか
737デフォルトの名無しさん (ワッチョイ 2de3-8CrJ)
2017/11/17(金) 23:47:03.87ID:Xj6+FFKd0 プログラミング工数の最適化
738デフォルトの名無しさん (ワッチョイ a980-61Vg)
2017/11/17(金) 23:50:29.19ID:sEHgCDk10 最近は凝ったアルゴリズムより単純な配列(vector)の方が速かったりするうえに、余程古いかクソな標準ライブラリを使用してない限りstd::vectorを最適化する余地なんてほぼ無いわな。
739デフォルトの名無しさん (ワッチョイ 6ee8-jTIY)
2017/11/18(土) 00:03:07.23ID:r8nC/FGp0 最適化はコンパイラに任せてソースは読み易さ重視
std使っとけばデバッガでも追いやすいし
std使っとけばデバッガでも追いやすいし
740デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/18(土) 00:08:41.90ID:CUoz+hOS0 拡張ライブラリが有ったとしたら、名前空間はstxになるのかね。
741デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/18(土) 00:11:29.34ID:CUoz+hOS0 Qtでウェブサイト作ったら何の問題もなくずっと動き続けてびっくりですよ。
Javaスレの人たちがC++は稼働し続けるとメモリーの分断化で落ちるとか言ってたから、
早く書き直さなきゃって思ってたんだけど。
クライアント用のQtがサーバーで頑健だったのは意外だった。
Javaスレの人たちがC++は稼働し続けるとメモリーの分断化で落ちるとか言ってたから、
早く書き直さなきゃって思ってたんだけど。
クライアント用のQtがサーバーで頑健だったのは意外だった。
742デフォルトの名無しさん (ワッチョイ 4178-kX9V)
2017/11/18(土) 00:14:32.63ID:asu2qdyg0 まぁ意識高い系が言うことなんかその程度ってこった
743デフォルトの名無しさん (ワッチョイ 8d2d-+5lI)
2017/11/18(土) 00:21:40.93ID:GO3RY34O0 >>741
TreeFrogの人?
TreeFrogの人?
744デフォルトの名無しさん (ワッチョイ a980-61Vg)
2017/11/18(土) 01:10:27.30ID:PnwIkFzo0 >>741
クソJavaプログラマーがC++を書くとほぼ間違いなくやるただのメモリリークを俺のせいじゃないということにしたかっただけというのに1票
クソJavaプログラマーがC++を書くとほぼ間違いなくやるただのメモリリークを俺のせいじゃないということにしたかっただけというのに1票
745デフォルトの名無しさん (ワッチョイ 25d6-Eq1o)
2017/11/18(土) 06:06:05.59ID:mIICZMYh0 自分のコードでさえ後で読むと読みやすく書いたつもりが裏目に出ていたりする
746デフォルトの名無しさん (ワッチョイ 0234-1gB9)
2017/11/18(土) 08:23:02.49ID:cx1PUhyJ0 奴らはnewしても決してdeleteしないからな
747デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/18(土) 11:32:01.12ID:azZ7ClyG0 俺も最近unique_ptrに任せっきりでdeleteってほとんど書かねえわ
コピコンの=deleteとかは書くけど
コピコンの=deleteとかは書くけど
748デフォルトの名無しさん (ワッチョイ e18a-RuWE)
2017/11/18(土) 12:02:10.83ID:Erlsd62p0 >>739
古いコンパイラ(つっても10年くらい)だと、クラス内の配列をイジるとクラスオブジェクト自体がイジられたことになるので最適化放棄とかしてたしなー
そういうのだとvectorなんて最適化放棄しまくり。
古いコンパイラ(つっても10年くらい)だと、クラス内の配列をイジるとクラスオブジェクト自体がイジられたことになるので最適化放棄とかしてたしなー
そういうのだとvectorなんて最適化放棄しまくり。
749デフォルトの名無しさん (ワッチョイ bd9f-DRcV)
2017/11/18(土) 13:45:01.11ID:6KFO0fze0 バカは素直にスマポ使っとけばいいのにな
750デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/18(土) 14:09:50.22ID:fgAW9Gk/0 >>748
オブジェクトXに対するアクセスの最適化放棄はコンパイラの知りえない形での
Xへの副作用が有り得ると判断された場合に行われるがこれは現用コンパイラでも変わらん
改善したというのはコンパイラの能力向上というよりは、テンプレートによるインライン展開のご利益なのでは…
(つまりstd::vectorは元来最適化向きの進化である
オブジェクトXに対するアクセスの最適化放棄はコンパイラの知りえない形での
Xへの副作用が有り得ると判断された場合に行われるがこれは現用コンパイラでも変わらん
改善したというのはコンパイラの能力向上というよりは、テンプレートによるインライン展開のご利益なのでは…
(つまりstd::vectorは元来最適化向きの進化である
751デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/18(土) 14:13:16.03ID:fgAW9Gk/0 例:
次のコードの並びにおいて、
1と3の読み込み結果は同一とはみなされず、1〜3を通してのX.aのレジスタ割り当ては行われない
1. Xのメンバaを読む
2. 外部リンケージ(かつ素性の知れた組み込み関数以外)の関数foo()を呼ぶ
3. Xのメンバaを読む
特効薬はfoo()のインライン展開
次のコードの並びにおいて、
1と3の読み込み結果は同一とはみなされず、1〜3を通してのX.aのレジスタ割り当ては行われない
1. Xのメンバaを読む
2. 外部リンケージ(かつ素性の知れた組み込み関数以外)の関数foo()を呼ぶ
3. Xのメンバaを読む
特効薬はfoo()のインライン展開
752デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/18(土) 14:16:28.52ID:fgAW9Gk/0 なお手動を厭わないなら次の風にしても良い:
0. auto変数v = X.a
1. X.aを読む代りにvを読む
2. 外部リンケージ(かつ素性の知れた組み込み関数以外)の関数foo()を呼ぶ
3. X.aを読む代りにvを読む
これならいくら古いコンパイラでもvを1〜3を通してレジスタ割り当てすることが気体できる
0. auto変数v = X.a
1. X.aを読む代りにvを読む
2. 外部リンケージ(かつ素性の知れた組み込み関数以外)の関数foo()を呼ぶ
3. X.aを読む代りにvを読む
これならいくら古いコンパイラでもvを1〜3を通してレジスタ割り当てすることが気体できる
753デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
2017/11/18(土) 16:28:12.38ID:gZtBhbAH0 浮動小数点をすべて網羅するループが書きたいのですがどうすればいいでしょうか。
754デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/18(土) 16:29:45.36ID:CUoz+hOS0 ラスボス級が現れた。
755デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
2017/11/18(土) 16:46:32.60ID:gZtBhbAH0 http://takashiijiri.com/study/miscs/fastsqrt.html
やりたいことは、上のサイトにある高速根号計算の精度検証です。
サイト内では2の根号に対して精度検証していますが
すべての倍精度実数に対して検証をしたいと考えています。
64bitの整数のビット表現を、同じビット表現の倍精度実数に変換できれば
整数についてループを回すことで網羅できると考えています。
変換の方法をご存知の方がいれば教えて頂けないでしょうか。
やりたいことは、上のサイトにある高速根号計算の精度検証です。
サイト内では2の根号に対して精度検証していますが
すべての倍精度実数に対して検証をしたいと考えています。
64bitの整数のビット表現を、同じビット表現の倍精度実数に変換できれば
整数についてループを回すことで網羅できると考えています。
変換の方法をご存知の方がいれば教えて頂けないでしょうか。
756デフォルトの名無しさん (ワッチョイ a104-0wpo)
2017/11/18(土) 16:47:50.09ID:R4dFDjUs0 >>753
イプシロン足してくとか。
イプシロン足してくとか。
757デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 16:48:48.90ID:np1Yc2el0 >>755 memcpy
758デフォルトの名無しさん (ワッチョイ a104-0wpo)
2017/11/18(土) 16:49:32.41ID:R4dFDjUs0759デフォルトの名無しさん (ワッチョイ a104-0wpo)
2017/11/18(土) 16:50:13.11ID:R4dFDjUs0 >>757
reinterpret_castでいい予感。
reinterpret_castでいい予感。
760デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 16:51:55.15ID:np1Yc2el0 >>755
ところでその検証、何年ぐらい時間かけていい話なの?
ところでその検証、何年ぐらい時間かけていい話なの?
761デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 16:53:01.86ID:np1Yc2el0 >>759
未定義動作でも「いい」と言うなら、そう。
未定義動作でも「いい」と言うなら、そう。
762デフォルトの名無しさん (ワッチョイ a104-0wpo)
2017/11/18(土) 16:55:15.51ID:R4dFDjUs0 あー検証だからな。すまんかった。
763デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
2017/11/18(土) 17:20:21.34ID:gZtBhbAH0 みなさま、レスありがとうございます。
>>757
memcpyでできそうです。ありがとうございます。
int main() {
double f = 0;
for (unsigned long long i = 0; i <= -1; ++i) {
void* fp = static_cast<void*>(&f);
void* ip = static_cast<void*>(&i);
std::memcpy(fp, ip, sizeof(i));
std::cout << f << std::endl;
}
system("pause");
}
>>760
そんなに時間かかるんですかね。。。
1週間ぐらいは覚悟してたんですが。
とりあえず回してみます。
>>757
memcpyでできそうです。ありがとうございます。
int main() {
double f = 0;
for (unsigned long long i = 0; i <= -1; ++i) {
void* fp = static_cast<void*>(&f);
void* ip = static_cast<void*>(&i);
std::memcpy(fp, ip, sizeof(i));
std::cout << f << std::endl;
}
system("pause");
}
>>760
そんなに時間かかるんですかね。。。
1週間ぐらいは覚悟してたんですが。
とりあえず回してみます。
764デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 17:32:14.09ID:np1Yc2el0 >>763
https://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/
> ... you can test every float bit-pattern (all four billion!) in about ninety seconds. ...
32bit が 90 秒ほどで済ませられるそうな。 64bit だと単純計算で・・・ 735439.6... 年ぐらいかな。
1週間で済ませようと思ったら 38347922 並列ぐらいで走らせればよさそう。
検証する計算内容によっても変わるだろうけど、まぁがんばれ。
https://randomascii.wordpress.com/2014/01/27/theres-only-four-billion-floatsso-test-them-all/
> ... you can test every float bit-pattern (all four billion!) in about ninety seconds. ...
32bit が 90 秒ほどで済ませられるそうな。 64bit だと単純計算で・・・ 735439.6... 年ぐらいかな。
1週間で済ませようと思ったら 38347922 並列ぐらいで走らせればよさそう。
検証する計算内容によっても変わるだろうけど、まぁがんばれ。
765デフォルトの名無しさん (ワッチョイ a193-oo0Z)
2017/11/18(土) 17:35:34.11ID:hpuIg+Nf0 とりあえず範囲を絞って回してみて、
力任せの方法で受け入れられる処理時間なら単純なプログラムのまま、
時間かかりすぎるようなら先にプログラムを洗練させる、としないと。
力任せの方法で受け入れられる処理時間なら単純なプログラムのまま、
時間かかりすぎるようなら先にプログラムを洗練させる、としないと。
766デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
2017/11/18(土) 17:56:05.12ID:gZtBhbAH0767デフォルトの名無しさん (ワッチョイ 0234-1gB9)
2017/11/18(土) 19:06:18.60ID:cx1PUhyJ0 isnan()でnanチェック入れたほうが良さそう
768デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/18(土) 19:44:12.36ID:euoYf0NO0769デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 20:29:47.22ID:np1Yc2el0 >>768
type-based aliasing rule (strict aliasing rule) というものがあってな。
(詳しく調べると闇に落ちるから言語オタクでもなければ深堀りはおすすめしない。)
mempcy なら動作が定義されてるかというとそうでもないんで、
明示的に未定義といわれているかどうか(=最適化で問題を起こしやすいかどうか)の違いしかないんだけど。
type-based aliasing rule (strict aliasing rule) というものがあってな。
(詳しく調べると闇に落ちるから言語オタクでもなければ深堀りはおすすめしない。)
mempcy なら動作が定義されてるかというとそうでもないんで、
明示的に未定義といわれているかどうか(=最適化で問題を起こしやすいかどうか)の違いしかないんだけど。
770デフォルトの名無しさん (ワッチョイ 7efb-0Zlk)
2017/11/18(土) 20:40:55.67ID:b6ZSsfqz0 std::launder「そろそろ俺の出番だな」
771デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/18(土) 21:23:52.47ID:azZ7ClyG0 ここまでfrexpとldexpの話なし
772片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd22-EXIO)
2017/11/18(土) 21:57:24.41ID:QiNK1qRtd773片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd22-EXIO)
2017/11/18(土) 21:58:52.49ID:QiNK1qRtd 初回の例外というのがよくわからない。。。
774デフォルトの名無しさん (ワッチョイ 4178-kX9V)
2017/11/18(土) 22:06:57.57ID:asu2qdyg0 なんか古い書き方だから2000年ごろからの年季の入ったソースかと思ったら最近の奴なんだな
775片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd22-EXIO)
2017/11/18(土) 22:12:33.66ID:QiNK1qRtd776デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/18(土) 22:42:09.82ID:euoYf0NO0 >>769
調べたけどこれでいいのか?
https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
これならreinterpret_cast関係ないじゃん。static_castにしたところで変わらん。
ただそれ以前に該当しないだろ。
「同一のメモリを違う型としてaliasしたときにコンパイラがそれに気づけず最適化で削除してしまう」という問題であり、
今回はそうではない。
> mempcy なら動作が定義されてるかというとそうでもないんで
ほんとか?それじゃmemcpyマトモに使えないじゃん。
void*は++で1増えるって仕様に決まったはずで、、、と思ったがこれがgcc拡張だという話があり、このことを言っているのか?
ならグダグダ言わずにCキャストで書けよもう、としか思わないが。
或いはC++的には許せないのかもしれんが static_cast<double>にしてしまうとかか?
調べたけどこれでいいのか?
https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
これならreinterpret_cast関係ないじゃん。static_castにしたところで変わらん。
ただそれ以前に該当しないだろ。
「同一のメモリを違う型としてaliasしたときにコンパイラがそれに気づけず最適化で削除してしまう」という問題であり、
今回はそうではない。
> mempcy なら動作が定義されてるかというとそうでもないんで
ほんとか?それじゃmemcpyマトモに使えないじゃん。
void*は++で1増えるって仕様に決まったはずで、、、と思ったがこれがgcc拡張だという話があり、このことを言っているのか?
ならグダグダ言わずにCキャストで書けよもう、としか思わないが。
或いはC++的には許せないのかもしれんが static_cast<double>にしてしまうとかか?
777デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/18(土) 22:48:23.04ID:euoYf0NO0 すまんミスった
× static_cast<double>
○ static_cast<double*>
× static_cast<double>
○ static_cast<double*>
778デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 23:20:13.09ID:np1Yc2el0 >>776
static_cast じゃコンパイル通らない。
"*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
未定義動作になる。結果は「最適化で削除してしまう」に限らず、何でもアリだよ。
これが「「同一のメモリを違う型としてalias」に該当しないという理屈も無いでしょ。
memcpy の結果が定義されてるのは、同じ型のオブジェクト間でのコピーだけだったかと。
違う型の間で memcpy した結果の値が実は定義されてるということなら実に興味深いので
ぜひ規格の該当箇所を示して欲しい。
この場合の C スタイルキャストの動作は reinterpret_cast に丸投げされるだけなので話は変わらないよ。
static_cast じゃコンパイル通らない。
"*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
未定義動作になる。結果は「最適化で削除してしまう」に限らず、何でもアリだよ。
これが「「同一のメモリを違う型としてalias」に該当しないという理屈も無いでしょ。
memcpy の結果が定義されてるのは、同じ型のオブジェクト間でのコピーだけだったかと。
違う型の間で memcpy した結果の値が実は定義されてるということなら実に興味深いので
ぜひ規格の該当箇所を示して欲しい。
この場合の C スタイルキャストの動作は reinterpret_cast に丸投げされるだけなので話は変わらないよ。
779デフォルトの名無しさん (ワッチョイ 1d79-Kvax)
2017/11/18(土) 23:37:48.32ID:5VdCNKN70 ここまでnextafter/nexttowardが出てきていない
780デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/18(土) 23:38:32.35ID:euoYf0NO0 >>778
> "*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
してないぞ。
それは「fのアドレスを(long long*)にキャスト(この時点でlong long*型)したアドレスに対しiを書き込め」
であって、つまり long long に long long を書いている。だからmovが出る。
逆に f = *(double*)&i; は double に double を書くから fmov が出る。
その後の最適化で変更されるのはまた別の話。
> static_cast じゃコンパイル通らない。
だったら最初から>>759の言うとおり、reinterpret_castでいいだろ。
> 違う型の間で memcpy した結果の値が実は定義されてる
void* と void* なんだから同じ型だろ。何言ってんだ?
お前、基本的に理解がずれてね?
> "*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
してないぞ。
それは「fのアドレスを(long long*)にキャスト(この時点でlong long*型)したアドレスに対しiを書き込め」
であって、つまり long long に long long を書いている。だからmovが出る。
逆に f = *(double*)&i; は double に double を書くから fmov が出る。
その後の最適化で変更されるのはまた別の話。
> static_cast じゃコンパイル通らない。
だったら最初から>>759の言うとおり、reinterpret_castでいいだろ。
> 違う型の間で memcpy した結果の値が実は定義されてる
void* と void* なんだから同じ型だろ。何言ってんだ?
お前、基本的に理解がずれてね?
781デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/18(土) 23:47:06.34ID:np1Yc2el0 >>780
なるほど、オブジェクトの型と式の型との区別がついてないんだね。
そこの理解無しで aliasing rule に関する話は無理だから、
C++ の規格を読み直すなりして区別が付くようになってからの出直しをおすすめする。
なるほど、オブジェクトの型と式の型との区別がついてないんだね。
そこの理解無しで aliasing rule に関する話は無理だから、
C++ の規格を読み直すなりして区別が付くようになってからの出直しをおすすめする。
782デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/18(土) 23:50:31.47ID:euoYf0NO0783デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/19(日) 00:03:31.90ID:xhmNfS4m0 >>782
そうなると GCC も「全く理解出来てない」ことになるねぇ。
https://wandbox.org/permlink/WMFUTpXAgs2oZuos
> prog.cc:5:17: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
> *(long long*)&f = i;
> ^
> prog.cc:6:18: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
> f = *(double*)&i;
> ^
そうなると GCC も「全く理解出来てない」ことになるねぇ。
https://wandbox.org/permlink/WMFUTpXAgs2oZuos
> prog.cc:5:17: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
> *(long long*)&f = i;
> ^
> prog.cc:6:18: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
> f = *(double*)&i;
> ^
784デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 00:12:55.40ID:XAwzlQ9S0785デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 00:41:57.82ID:p3uF8GIb0 まあ未定義な動作がどこまで行っても未定義な動作であって(教条主義的には)悪なのは確かだが
>>784のリンク先のを読むと
>ストアによってPの値が変わる可能性を考慮しなくてはいけないからだ。
という理由で最適化できないケースがあるから考慮する代りに未定義動作ということにしますた!
というだけで、ストアによってPの値が変わらないなら特に問題を生じないように思える…
で、ストアによってPの値が変わるケースというのは
int main() {
P = (float*)&P; // このキャストによって zero_array の中で TBAA 違反となる
zero_array();
}
みたいな変態的なケースしかなさげ;
>>784のリンク先のを読むと
>ストアによってPの値が変わる可能性を考慮しなくてはいけないからだ。
という理由で最適化できないケースがあるから考慮する代りに未定義動作ということにしますた!
というだけで、ストアによってPの値が変わらないなら特に問題を生じないように思える…
で、ストアによってPの値が変わるケースというのは
int main() {
P = (float*)&P; // このキャストによって zero_array の中で TBAA 違反となる
zero_array();
}
みたいな変態的なケースしかなさげ;
786デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 00:54:18.30ID:SsMAbqSz0 >>784
答え書いてんじゃねーかよ。
> この種の未定義な振る舞いは、-fno-strict-aliasing フラグを指定することで無効にすることができ
つまり指定すれば万事解決だ。
ただその前にwarning出てても動作するとは思うが。
> この種の型の乱用はあまり一般的ではないので、標準委員会は、"妥当な" 型のキャストによる予期しない結果と引き換えに、大幅なパフォーマンス向上を選んだ。
これっていつから?LLVMに乗せた頃からっぽいが、、、日付や元URL見るかぎりC++11からか?
あとこれって、Cもか?
(Cでは俺が書いたようなキャストは常用されているから)
知っている人がいたらよろしく。
答え書いてんじゃねーかよ。
> この種の未定義な振る舞いは、-fno-strict-aliasing フラグを指定することで無効にすることができ
つまり指定すれば万事解決だ。
ただその前にwarning出てても動作するとは思うが。
> この種の型の乱用はあまり一般的ではないので、標準委員会は、"妥当な" 型のキャストによる予期しない結果と引き換えに、大幅なパフォーマンス向上を選んだ。
これっていつから?LLVMに乗せた頃からっぽいが、、、日付や元URL見るかぎりC++11からか?
あとこれって、Cもか?
(Cでは俺が書いたようなキャストは常用されているから)
知っている人がいたらよろしく。
787デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 01:21:45.70ID:p3uF8GIb0 つかmemset(buf, ch, nのbufって__restrictじゃなかったのか…
今知った……
今知った……
788デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 01:24:03.10ID:XAwzlQ9S0 C89からずーっとそうだよ
お前が書いてるコードが動いてるのは、コンパイラがそうしないという保証を独自に与えているか(-fno-strict-aliasingはその一例)
さもなくばたまたま動いてるだけ
お前が書いてるコードが動いてるのは、コンパイラがそうしないという保証を独自に与えているか(-fno-strict-aliasingはその一例)
さもなくばたまたま動いてるだけ
789デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/19(日) 01:33:36.82ID:xhmNfS4m0 >>786
広く知れ渡ったのは gcc 2.95 で実際にそのルールに基づく最適化が行われるようになってからかな。
https://www.gnu.org/software/gcc/gcc-2.95/features.html
> - Type based alias analysis is enabled by default. ...
そこから数えてももう 20 年近く経つわけだが。
知らずにそんなキャスト常用してるなら是非悔い改めてくれ。
広く知れ渡ったのは gcc 2.95 で実際にそのルールに基づく最適化が行われるようになってからかな。
https://www.gnu.org/software/gcc/gcc-2.95/features.html
> - Type based alias analysis is enabled by default. ...
そこから数えてももう 20 年近く経つわけだが。
知らずにそんなキャスト常用してるなら是非悔い改めてくれ。
790デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 01:35:13.22ID:p3uF8GIb0 (ま、__restrictな形でしかポインタしか使わない漏れには関係ないし…
791デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 01:37:52.26ID:XAwzlQ9S0 ちなみに-fno-strict-aliasing付けるとこんな基本的な最適化さえ出来なくなって
パフォーマンスが激悪化する可能性があるからな
それを完全に理解した上で万事解決だと言ってるならそれでもいいけどさ
int foo(double* pd){
int k = 42;
*pd = 666;
return k * 2;
}
-fno-strict-aliasingを付けた場合、戻り値を"84"に最適化することは出来ない
なぜならpdのアドレスが&kを指してるかもしれないから
(strict aliasing ruleが効いてればdouble*がintを指してたら未定義動作なのでケアする必要がなく最適化できる)
パフォーマンスが激悪化する可能性があるからな
それを完全に理解した上で万事解決だと言ってるならそれでもいいけどさ
int foo(double* pd){
int k = 42;
*pd = 666;
return k * 2;
}
-fno-strict-aliasingを付けた場合、戻り値を"84"に最適化することは出来ない
なぜならpdのアドレスが&kを指してるかもしれないから
(strict aliasing ruleが効いてればdouble*がintを指してたら未定義動作なのでケアする必要がなく最適化できる)
792デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/19(日) 01:42:54.83ID:xhmNfS4m0 >>791
引数で受け取った(有効な)ポインタが関数内のローカル変数を指すことは不可能だから、その例は最適化できるよ。
引数で受け取った(有効な)ポインタが関数内のローカル変数を指すことは不可能だから、その例は最適化できるよ。
793デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 02:15:02.16ID:XAwzlQ9S0 有効なポインタならね
デタラメなポインタがたまたま&kを指してるかもしれない
普通はそんなのは未定義動作だからケアしないんだけどそれをケアしろって言うのが-fno-strict-aliasing
デタラメなポインタがたまたま&kを指してるかもしれない
普通はそんなのは未定義動作だからケアしないんだけどそれをケアしろって言うのが-fno-strict-aliasing
794デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 02:22:43.60ID:SsMAbqSz0 >>789
> mempcy なら動作が定義されてるかというとそうでもないんで (>>769)
これは間違いだろ。784内見る限り、
> Cは、このような型変換をmemcpyを使って実現することを要求している。
なら、memcpy使えば正しい結果が得られるはずだし、そうじゃないとコンパイラのバグになる。
つまり、>>763のコードは正しく動くはず、と読めるが。
ちなみに>>783のページで色々試してみた。(もし編集が残っているようならすまん)
全てgcc 7.2.0 で、結果は以下。
・CはC11/C11(GNU)の両方でwarinigも何もでない。
・C++はこの中の一番古いC++03/C++03(GNU)の両方でwarinigは出る。
ということはかなり昔からC++ではそうだった、ということだね。全く知らんかったわ。
ここら辺がCの連中がC++を嫌っているところなのかもしれない。
>>788
おお、サンクス、C++89からか。
俺環はVC++2008だからね。MS側が吸収してくれてるわけか。
>>789
いや俺環では問題ないしな。
つかたぶんこれC++の話で、上記試した限りCなら問題ないんだよ。
ただ俺はbetterCの人だから、まあ微妙なわけだが、、、VC++2017とかに移行するときは気をつけるよ。
さてそのリンク先
https://www.gnu.org/software/gcc/news/alias.html
も読んでみたが、つまり s->x_m[i] は s->a_m と型が違うから上書きしないはず、
だからループ内で毎回 s->a_m を取らずに前回の値をそのまま使っていい、ということらしい。(s->b_mも同様)
ただこれなら
for (unsigned long long i = 0; i <= -1; ++i) *(long long*)&f = i;
は確実に動くけどな。ここで端折られるのはfのアドレス確認 &f 部分だけだから。
ただしstackoverflowの連中は言っていることが少し違うから、もうちょっと確認が必要だが。
> mempcy なら動作が定義されてるかというとそうでもないんで (>>769)
これは間違いだろ。784内見る限り、
> Cは、このような型変換をmemcpyを使って実現することを要求している。
なら、memcpy使えば正しい結果が得られるはずだし、そうじゃないとコンパイラのバグになる。
つまり、>>763のコードは正しく動くはず、と読めるが。
ちなみに>>783のページで色々試してみた。(もし編集が残っているようならすまん)
全てgcc 7.2.0 で、結果は以下。
・CはC11/C11(GNU)の両方でwarinigも何もでない。
・C++はこの中の一番古いC++03/C++03(GNU)の両方でwarinigは出る。
ということはかなり昔からC++ではそうだった、ということだね。全く知らんかったわ。
ここら辺がCの連中がC++を嫌っているところなのかもしれない。
>>788
おお、サンクス、C++89からか。
俺環はVC++2008だからね。MS側が吸収してくれてるわけか。
>>789
いや俺環では問題ないしな。
つかたぶんこれC++の話で、上記試した限りCなら問題ないんだよ。
ただ俺はbetterCの人だから、まあ微妙なわけだが、、、VC++2017とかに移行するときは気をつけるよ。
さてそのリンク先
https://www.gnu.org/software/gcc/news/alias.html
も読んでみたが、つまり s->x_m[i] は s->a_m と型が違うから上書きしないはず、
だからループ内で毎回 s->a_m を取らずに前回の値をそのまま使っていい、ということらしい。(s->b_mも同様)
ただこれなら
for (unsigned long long i = 0; i <= -1; ++i) *(long long*)&f = i;
は確実に動くけどな。ここで端折られるのはfのアドレス確認 &f 部分だけだから。
ただしstackoverflowの連中は言っていることが少し違うから、もうちょっと確認が必要だが。
795デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/19(日) 02:26:53.00ID:xhmNfS4m0796デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 02:37:45.46ID:SsMAbqSz0 >>791
周回遅れですまんが俺には794に書いたとおり、
・型違いは全てmemcpy使え。
と読める。だから763のコードはOKだと。
>>791-793の内容は理解した。
さて再度だが、やはり以下は動くだろ。
for (unsigned long long i = 0; i <= -1; ++i) *(long long*)&f = i;
ここで問題なのは、「fがiのアドレスをさしてたら未定義動作(&f==&i等)」であって、
i をコピーしてやらない、ではない。
791-793の言い分どおりなら、これはwarningが出てるだけで全く問題なく動くはず。
ただしstackoverflowの連中はちょっと違うことを言っているが。
周回遅れですまんが俺には794に書いたとおり、
・型違いは全てmemcpy使え。
と読める。だから763のコードはOKだと。
>>791-793の内容は理解した。
さて再度だが、やはり以下は動くだろ。
for (unsigned long long i = 0; i <= -1; ++i) *(long long*)&f = i;
ここで問題なのは、「fがiのアドレスをさしてたら未定義動作(&f==&i等)」であって、
i をコピーしてやらない、ではない。
791-793の言い分どおりなら、これはwarningが出てるだけで全く問題なく動くはず。
ただしstackoverflowの連中はちょっと違うことを言っているが。
797デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/19(日) 02:42:26.05ID:xhmNfS4m0 >>794
C の aliasing rule には memcpy, memmove によって宣言型を持たない(たとえば
malloc で確保した)オブジェクトの型 (effective type) を変更できるという規定がある。
引用された「memcpyを使って実現することを要求している」はこのことだろう。
でも、 C++ にはこれに相当する規定が無い。
C の aliasing rule には memcpy, memmove によって宣言型を持たない(たとえば
malloc で確保した)オブジェクトの型 (effective type) を変更できるという規定がある。
引用された「memcpyを使って実現することを要求している」はこのことだろう。
でも、 C++ にはこれに相当する規定が無い。
798デフォルトの名無しさん (ワッチョイ 0233-2Rtq)
2017/11/19(日) 02:53:12.72ID:xhmNfS4m0 >>796
残念、まだ理解できてないよ。
答えは >778 にある。
> "*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
> 未定義動作になる。結果は「最適化で削除してしまう」に限らず、何でもアリだよ。
これ以上は規格見てからしゃべってくれ。
残念、まだ理解できてないよ。
答えは >778 にある。
> "*(long long*)&f = i" は double 型のオブジェクトに long long 型の参照を通してアクセスしているので
> 未定義動作になる。結果は「最適化で削除してしまう」に限らず、何でもアリだよ。
これ以上は規格見てからしゃべってくれ。
799デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 03:03:03.03ID:SsMAbqSz0800デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 06:07:15.51ID:p3uF8GIb0 未定義動作マジコエー;;(>>784のリンク先の次のページ
ttp://blog-ja.intransient.info/2011/05/c-23.html
ttp://blog-ja.intransient.info/2011/05/c-23.html
801デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 06:25:20.22ID:p3uF8GIb0 プロセス屋さんががんばってCPUを3年ごとに倍早くしてくれるのだから
我々ソフト屋は口を開けて待っているだけにして
最適化なんてやめてしまえば良いのに
我々が忙しく働くということは、それだけバグを産むということなのだ…!
我々ソフト屋は口を開けて待っているだけにして
最適化なんてやめてしまえば良いのに
我々が忙しく働くということは、それだけバグを産むということなのだ…!
802デフォルトの名無しさん (オッペケ Srd1-0Zlk)
2017/11/19(日) 07:18:18.83ID:mXpVaiBzr803デフォルトの名無しさん (ワッチョイ 82a4-Eq1o)
2017/11/19(日) 07:18:20.90ID:Rb2sIcHm0 CPUだけ速くなってもDRAMの速度が昔のままだ
.7CRなんて法則を持ち出すまでもなく
現実にCPU速度が飽和したと感じたことなどないはずだが
.7CRなんて法則を持ち出すまでもなく
現実にCPU速度が飽和したと感じたことなどないはずだが
804デフォルトの名無しさん (オッペケ Srd1-0Zlk)
2017/11/19(日) 07:23:52.01ID:mXpVaiBzr805デフォルトの名無しさん (ワッチョイ f9b3-GXP8)
2017/11/19(日) 08:50:45.23ID:OzmZfN1I0 >>768
読んでも分からないときは?
読んでも分からないときは?
806デフォルトの名無しさん (ワッチョイ 82a4-Eq1o)
2017/11/19(日) 10:12:41.15ID:Rb2sIcHm0807デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 13:02:38.85ID:SsMAbqSz0 >>795改造は-fno-strict-aliasing有り無しによらず動くコードが出た。詳細は以下。
https://godbolt.org/g/QaSwTn
-O3 -fno-strict-aliasing -std=c++14 -pedantic -Wall -Wextra で mov QWORD PTR [rsp+8], rbx (27,29行目)が出る。
-fno-strict-aliasing を切っても同じ mov 命令が出る。
だからこれはwarningが出ているだけで動くコードが出る。
このときのコードは以下。
void test() {
double f = 0;
for (long long i = 0; i <= 10; ++i) {
*(long long*)&f = i; // (A)
std::cout << f << std::endl; // (B)
}
}
https://godbolt.org/g/QaSwTn
-O3 -fno-strict-aliasing -std=c++14 -pedantic -Wall -Wextra で mov QWORD PTR [rsp+8], rbx (27,29行目)が出る。
-fno-strict-aliasing を切っても同じ mov 命令が出る。
だからこれはwarningが出ているだけで動くコードが出る。
このときのコードは以下。
void test() {
double f = 0;
for (long long i = 0; i <= 10; ++i) {
*(long long*)&f = i; // (A)
std::cout << f << std::endl; // (B)
}
}
808デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 13:04:16.49ID:SsMAbqSz0 >>798
なお上記のGCC結果、或いは以下GCCのドキュメントは読んだ。
(ついでに後出の仕様書もチラ見したが、やはり今のところ君の理解がずれてるという見解だ。)
https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Optimize-Options.html#index-fstrict_002daliasing-750
ここでは以下コードがアウトだと言っている。
union a_union {
int i;
double d;
};
int f() {
double d = 3.0; // (C)
return ((union a_union *) &d)->i; // (D)
}
アウトな理由だが、上記と794内URLによると、「『型違いのaliasはない』と仮定して最適化」する為であり、
つまり(C)はd名でdoubleに書き(D)はi名でint読み出しだから(C)と(D)は関係ない、
よって(C)はデッドコードでいきなり(D)の読み出ししてよし、ということらしい。
ただこれだとやはり上記(A)(B)は動く。(A)も(B)もfの読み書きであり、aliasして無いからだ。
この規定は「型違いの『aliasは』ないものとみなす」であり、aliasしてなければ関係ない。
今のところ見る限り、他の例も必ずalias(別名でアクセス)している。
なお正しくはunionを使え、ということらしい。>>763
まあ確かにunionはこれ用ではあるが、単発ならCキャストする奴が多いとは思う。
そもそもunionは撲滅対象だと思っていたのだが、これは意外だ。
(或いは仕様上 char*, unsigned char* については許可《どう見ても妥協だが》しているので、void*ではなくchar*にすればいい)
なお上記のGCC結果、或いは以下GCCのドキュメントは読んだ。
(ついでに後出の仕様書もチラ見したが、やはり今のところ君の理解がずれてるという見解だ。)
https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Optimize-Options.html#index-fstrict_002daliasing-750
ここでは以下コードがアウトだと言っている。
union a_union {
int i;
double d;
};
int f() {
double d = 3.0; // (C)
return ((union a_union *) &d)->i; // (D)
}
アウトな理由だが、上記と794内URLによると、「『型違いのaliasはない』と仮定して最適化」する為であり、
つまり(C)はd名でdoubleに書き(D)はi名でint読み出しだから(C)と(D)は関係ない、
よって(C)はデッドコードでいきなり(D)の読み出ししてよし、ということらしい。
ただこれだとやはり上記(A)(B)は動く。(A)も(B)もfの読み書きであり、aliasして無いからだ。
この規定は「型違いの『aliasは』ないものとみなす」であり、aliasしてなければ関係ない。
今のところ見る限り、他の例も必ずalias(別名でアクセス)している。
なお正しくはunionを使え、ということらしい。>>763
まあ確かにunionはこれ用ではあるが、単発ならCキャストする奴が多いとは思う。
そもそもunionは撲滅対象だと思っていたのだが、これは意外だ。
(或いは仕様上 char*, unsigned char* については許可《どう見ても妥協だが》しているので、void*ではなくchar*にすればいい)
809デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 13:06:08.29ID:SsMAbqSz0 仕様書は以下でいいか?読み慣れてないからだいぶ推測が入るが、
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
俺の結論は以下かな。
・gccのは -fstrict-aliasing で、あくまで alias についてだが、仕様書内は alias なんて関係ない。
・fstrict-aliasing 出来る理由が3.10.10によるのなら、reinterpret_castの存在価値はなく、仕様書内に矛盾がある。
・おそらく reinterpret_cast 撲滅で union に書き換えろ、という方向か?
aliasってのは多分折衷案で、union 以外は全部アウトにしたいっぽい。
詳細は以下。
5.2.10 Reinterpret castでは特に妙なところはなし、型キャストは為される。
aliasについては3.10.10だが、reinterpret_castしてれば the dynamic type 扱いでアクセスに問題なし、と見る。
3.10.10.の注 54) The intent of this list is to specify those circumstances in which an object may or may not be aliased.
なんだから、やはりこれは alias されているかどうか?であって、アクセスできるかどうかではない。
ただしここを根拠に undefined behavior だから最適化してよし、としてるのはかなり強引で、
(というかここでalias云々がかなり唐突で、そもそもaliasの話をここではしていない)
(D)がreinterpret_cast扱いだというのなら仕様内に矛盾があることになる。
そしてこの解釈(=reinterpret_castされたものは the dynamic type ではなく undefied behaviorだからどうなってもよし)が通るのなら、
reinterpret_castの存在価値がなくなってしまうし、
aliasとかせこいことを言わず、reinterpret_cast相当のところは全部undefined扱いで削除していいことになる。
というか、多分コンパイラ側はこの主張で、これに対してユーザ側が反対し、
結果、 alias とかいう折衷案でごまかしているように読める。(既に書いたがaliasが唐突過ぎ)
確かに正しくはunionを使うべきであり、この流れだと将来的には reinterpret_cast は廃止で union しろってことになるのか?
しかし逆に言えば、C++89以来これで大して変わらないのなら、早々急に変わることもないか。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
俺の結論は以下かな。
・gccのは -fstrict-aliasing で、あくまで alias についてだが、仕様書内は alias なんて関係ない。
・fstrict-aliasing 出来る理由が3.10.10によるのなら、reinterpret_castの存在価値はなく、仕様書内に矛盾がある。
・おそらく reinterpret_cast 撲滅で union に書き換えろ、という方向か?
aliasってのは多分折衷案で、union 以外は全部アウトにしたいっぽい。
詳細は以下。
5.2.10 Reinterpret castでは特に妙なところはなし、型キャストは為される。
aliasについては3.10.10だが、reinterpret_castしてれば the dynamic type 扱いでアクセスに問題なし、と見る。
3.10.10.の注 54) The intent of this list is to specify those circumstances in which an object may or may not be aliased.
なんだから、やはりこれは alias されているかどうか?であって、アクセスできるかどうかではない。
ただしここを根拠に undefined behavior だから最適化してよし、としてるのはかなり強引で、
(というかここでalias云々がかなり唐突で、そもそもaliasの話をここではしていない)
(D)がreinterpret_cast扱いだというのなら仕様内に矛盾があることになる。
そしてこの解釈(=reinterpret_castされたものは the dynamic type ではなく undefied behaviorだからどうなってもよし)が通るのなら、
reinterpret_castの存在価値がなくなってしまうし、
aliasとかせこいことを言わず、reinterpret_cast相当のところは全部undefined扱いで削除していいことになる。
というか、多分コンパイラ側はこの主張で、これに対してユーザ側が反対し、
結果、 alias とかいう折衷案でごまかしているように読める。(既に書いたがaliasが唐突過ぎ)
確かに正しくはunionを使うべきであり、この流れだと将来的には reinterpret_cast は廃止で union しろってことになるのか?
しかし逆に言えば、C++89以来これで大して変わらないのなら、早々急に変わることもないか。
810デフォルトの名無しさん (ワッチョイ e1b3-GXP8)
2017/11/19(日) 14:06:40.01ID:PnhOPMpK0 >>787
ポインタの引数が1つしかないのに__restrictつける意味ないからでしょ
ポインタの引数が1つしかないのに__restrictつける意味ないからでしょ
811デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 14:19:11.46ID:p3uF8GIb0 コンパイラがうまくType-Based Alias Analysis出来るケースをいくら列挙したところで
Type-Based Alias Analysisできないケースが簡単に生じることは否定できない事実じゃんヤバイじゃん?
unionの使用が解決策というのも語弊があって、unionのメンバのアドレスを取ってから関数foo()に渡す手順だと
foo()のコンパイル時には渡ってきた2つのポインタが、型が違うけど(ループ変数などの条件次第で)同じ領域を指す(ことがある)
かどうか(ループを実際に実行してみねば)判断つかないじゃん?→コンパイラは怖くてループをmemcpy()やmemset()に置き換えられない
つまりunionこそ別の翻訳単位に属する関数に下手な渡り方をするとaliasingのすくつと化す気配が微レ存
元を断つにはやっぱID:xhmNfS4m0やGCC様がおっしゃるように、
そもそも型の混同要因(つまりポインタのキャスト)を絶つか、最適化が効いてほしい関数でプログラマが明示的に__restrictするしか、
※ 個人の感想です
Type-Based Alias Analysisできないケースが簡単に生じることは否定できない事実じゃんヤバイじゃん?
unionの使用が解決策というのも語弊があって、unionのメンバのアドレスを取ってから関数foo()に渡す手順だと
foo()のコンパイル時には渡ってきた2つのポインタが、型が違うけど(ループ変数などの条件次第で)同じ領域を指す(ことがある)
かどうか(ループを実際に実行してみねば)判断つかないじゃん?→コンパイラは怖くてループをmemcpy()やmemset()に置き換えられない
つまりunionこそ別の翻訳単位に属する関数に下手な渡り方をするとaliasingのすくつと化す気配が微レ存
元を断つにはやっぱID:xhmNfS4m0やGCC様がおっしゃるように、
そもそも型の混同要因(つまりポインタのキャスト)を絶つか、最適化が効いてほしい関数でプログラマが明示的に__restrictするしか、
※ 個人の感想です
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 日本語が話せない「外国籍」の子が急増中、授業がストップ、教室から脱走も…先生にも大きな負担「日本語支援」追いつかず★2 [七波羅探題★]
- 【芸能】デパートで見つけたランドセルが衝撃価格! つまみ枝豆「どこかで規制しないと」に共感の声殺到 「全て同感」「高すぎますね」 [冬月記者★]
- 「暖房が使えない」「食費が高くて子どもの栄養が…」 物価高に苦しむ子育て世帯、政府に期待する支援は [蚤の市★]
- 【速報】年収の壁の自民案判明、26年は168万円 [蚤の市★]
- 「ワールドトリガー」原作1話から完全新作アニメ化、よりパワーアップした1stシーズンとして [爆笑ゴリラ★]
- 自ら「パンセクシュアル」だと明かし、東由貴・東京都議(立憲民主)が「パートナーシップ」施策の充実求める:東京新聞 [少考さん★]
- お昼のまったり🍵😶‍🌫🤏すこすこハウス🏡
- ネトウヨ「中国ロシアとの戦争?日本にはアメリカがついてるので100%勝ちますよ」 [165981677]
- 【悲報】高市政権、中国軍機のレーダー照射について国際社会に発信へ [115996789]
- 「ミニトマトがボウルに入ってるから使ったら残りはラップして輪ゴムしといてー」👉アスペ系旦那、とんでもない行動に出てしまう [242521385]
- 外人激怒「日本のアニメのヒロインは"白人"はいるのに黒人はいない」 [793833473]
- 【超絶悲報】玉川徹、反日売国奴。「レーダー照射問題は高市さんの台湾有事答弁から始まった。中国をいたずらに刺激しても何も得はない」 [519511584]
