次スレを立てる時は本文の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
レス数が900を超えています。1000を超えると表示できなくなるよ。
1デフォルトの名無しさん 転載ダメ (ワッチョイ faeb-wbjw)
2017/10/10(火) 00:11:34.01ID:nc/5PI4P0829デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 16:10:52.86ID:SsMAbqSz0 >>827
つか、完全に暴走してるなこれは。
これならmemcpyと同じだし、
わざわざ別に作らずともmemcpyを正式に認めてCと同じ並びにしたほうがいい。
それ以前に reinterpret_cast が使われている関数内は自動的に -fno-strict-aliasing すればいいだけなんだが。
(関数単位でこの最適化を切る。ほぼ全てこれでいけるはず)
ただまあ、これが真面目に議論されているのなら、仕様書の文面や俺の感想はともかく、
君の言う通り、今のC++の仕様では対処する方法がない、ということなのだろうね。
つか、完全に暴走してるなこれは。
これならmemcpyと同じだし、
わざわざ別に作らずともmemcpyを正式に認めてCと同じ並びにしたほうがいい。
それ以前に reinterpret_cast が使われている関数内は自動的に -fno-strict-aliasing すればいいだけなんだが。
(関数単位でこの最適化を切る。ほぼ全てこれでいけるはず)
ただまあ、これが真面目に議論されているのなら、仕様書の文面や俺の感想はともかく、
君の言う通り、今のC++の仕様では対処する方法がない、ということなのだろうね。
830デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 16:11:41.87ID:xhmNfS4m0 >>828
"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"
これが lvalue (それ自体は未定義ではない)を通した「アクセス」を未定義とするルールとして読めないのだとしたら、もうどう説明しても無理だろう。
用語を知らないといいながら共通の定義を求めるのではなく開き直って勝手な解釈に基づく話を進められるようではまともな会話にもならない。
説明は諦める。
規格や先人の解説を読みなおすなりして誤りに気づいてもらえれば幸いだ。
https://www.google.com/search?q=aliasing+rule
"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"
これが lvalue (それ自体は未定義ではない)を通した「アクセス」を未定義とするルールとして読めないのだとしたら、もうどう説明しても無理だろう。
用語を知らないといいながら共通の定義を求めるのではなく開き直って勝手な解釈に基づく話を進められるようではまともな会話にもならない。
説明は諦める。
規格や先人の解説を読みなおすなりして誤りに気づいてもらえれば幸いだ。
https://www.google.com/search?q=aliasing+rule
831デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 16:30:16.51ID:SsMAbqSz0 >>830
ちげーよ。
俺は、reinterpret_castの結果が正当なlvalueなら、それはド頭の
the dynamic type of the object
に該当するから、
*(long long*)&f = i
はありだろ、と読んでるんだよ。そこは君も同じだろ。
> ポインタの reinterpret_cast で型違いの結果を得ることは未定義動作にならないし (>>819)
つまり (long long*)&f で long long* 型になるのはおk ←君の見解ね、俺も同意だが。
> それに * を適用して lvalue を得ることも未定義動作にはならない。
得られた lvalue を通したアクセスが aliasing rule に基づいて未定義動 (>>819)
つまり、*(long long*)&f もおk ←これも君の見解ね、俺も同意で。
> 得られた lvalue を通したアクセスが aliasing rule に基づいて未定義動作となる可能性がある
ここが違う。
3.10.10には alias が云々って何も書いてないだろ。
しかも *(long long*)&f = i; は両方とも long long なんだから、「型違い」のaliasではないんだよ。
だからGCC等の -fstrict-aliasing には該当しない。
というのが文面からとれる意味だ。あくまで「文面」な。
ただまあ、実際にはそうじゃないんだろ。
ちげーよ。
俺は、reinterpret_castの結果が正当なlvalueなら、それはド頭の
the dynamic type of the object
に該当するから、
*(long long*)&f = i
はありだろ、と読んでるんだよ。そこは君も同じだろ。
> ポインタの reinterpret_cast で型違いの結果を得ることは未定義動作にならないし (>>819)
つまり (long long*)&f で long long* 型になるのはおk ←君の見解ね、俺も同意だが。
> それに * を適用して lvalue を得ることも未定義動作にはならない。
得られた lvalue を通したアクセスが aliasing rule に基づいて未定義動 (>>819)
つまり、*(long long*)&f もおk ←これも君の見解ね、俺も同意で。
> 得られた lvalue を通したアクセスが aliasing rule に基づいて未定義動作となる可能性がある
ここが違う。
3.10.10には alias が云々って何も書いてないだろ。
しかも *(long long*)&f = i; は両方とも long long なんだから、「型違い」のaliasではないんだよ。
だからGCC等の -fstrict-aliasing には該当しない。
というのが文面からとれる意味だ。あくまで「文面」な。
ただまあ、実際にはそうじゃないんだろ。
832デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 16:33:08.86ID:SsMAbqSz0 ああすまん、ちょっと慌ててて余分なコピペされてるわ。
上記1回目の「得られた lvalue を通したアクセスが…」は余分で。
上記1回目の「得られた lvalue を通したアクセスが…」は余分で。
833デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 16:34:35.29ID:xhmNfS4m0 >>830
> 俺は、reinterpret_castの結果が正当なlvalueなら、それはド頭の
> the dynamic type of the object
> に該当するから、
> *(long long*)&f = i
> はありだろ、と読んでるんだよ。そこは君も同じだろ。
違うねぇ。
オブジェクトの型 dynamic type は式の型とは違うし、式の型の影響を受けるものじゃないんだよ。
何度も区別しろと言ったつもりだったんだけど。
> 俺は、reinterpret_castの結果が正当なlvalueなら、それはド頭の
> the dynamic type of the object
> に該当するから、
> *(long long*)&f = i
> はありだろ、と読んでるんだよ。そこは君も同じだろ。
違うねぇ。
オブジェクトの型 dynamic type は式の型とは違うし、式の型の影響を受けるものじゃないんだよ。
何度も区別しろと言ったつもりだったんだけど。
834デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 16:35:57.16ID:xhmNfS4m0 ごめん、アンカーミスった。 >833 は >831 宛てね。
835デフォルトの名無しさん (ワッチョイ 82ae-Eq1o)
2017/11/19(日) 16:43:31.03ID:7jEiMXMd0836デフォルトの名無しさん (オッペケ Srd1-0Zlk)
2017/11/19(日) 16:46:31.93ID:Q6cWJ/Rgr > *(long long*)&f で long long* 型になるのはおk
んなこたーない
doubleオブジェクトの領域にlong longでアクセスすることが未定義動作
んなこたーない
doubleオブジェクトの領域にlong longでアクセスすることが未定義動作
837デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 17:22:20.65ID:XAwzlQ9S0 double f = 0;
と変数fを構築した時点で、「値0.0のdoubleオブジェクト」が作られてメモリに置かれるんだよ(規格で言うstored valueな)
それはスタック回収やdeleteで破壊されるまでずーーっとdoubleのままで、変わることはないの
外側でポインタや参照をどれだけいじくり回したって決して変わらないの
家の横に「←ここは馬小屋です」って看板を立てたって、その家は家のままだし、勝手に馬を入れて飼うのは未定義動作なんだよ
そろそろ理解したらどうなの
と変数fを構築した時点で、「値0.0のdoubleオブジェクト」が作られてメモリに置かれるんだよ(規格で言うstored valueな)
それはスタック回収やdeleteで破壊されるまでずーーっとdoubleのままで、変わることはないの
外側でポインタや参照をどれだけいじくり回したって決して変わらないの
家の横に「←ここは馬小屋です」って看板を立てたって、その家は家のままだし、勝手に馬を入れて飼うのは未定義動作なんだよ
そろそろ理解したらどうなの
838デフォルトの名無しさん (ワッチョイ c58a-iF25)
2017/11/19(日) 17:56:59.79ID:BMNBgd4s0 >>835
内容ある発言と言われても別にこんなのは規格をひっくり返して議論するようなことでないし
たぶん俺なら(little endianだとして)
union Double {
double v;
struct {
uint64_t f:52; // fraction
uint64_t e:11; // exponent
uint64_t s:1; // sign
};
};
とかにするかな、それで何の問題も起こらない
内容ある発言と言われても別にこんなのは規格をひっくり返して議論するようなことでないし
たぶん俺なら(little endianだとして)
union Double {
double v;
struct {
uint64_t f:52; // fraction
uint64_t e:11; // exponent
uint64_t s:1; // sign
};
};
とかにするかな、それで何の問題も起こらない
839デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 18:00:09.08ID:SsMAbqSz0 >>837
多分それが違うぞ。それはどこに書いてある?
少なくとも多くのCプログラマはそう思って無い。だから平気でキャストする。
そして830内ULRも読んだが、これも明示的なエイリアスがあるケースだ。
お前らが過度にびびって拡大解釈してるだけだろ。
多分それが違うぞ。それはどこに書いてある?
少なくとも多くのCプログラマはそう思って無い。だから平気でキャストする。
そして830内ULRも読んだが、これも明示的なエイリアスがあるケースだ。
お前らが過度にびびって拡大解釈してるだけだろ。
840デフォルトの名無しさん (ワッチョイ 82ae-Eq1o)
2017/11/19(日) 18:11:47.43ID:7jEiMXMd0 あー、こいつcast-as-lvalueに完全に洗脳されている手合いかw
841デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 18:14:47.74ID:xhmNfS4m0 >>839
https://timsong-cpp.github.io/cppwp/n4659/intro.object#1
> ... The properties of an object are determined when the object is created. ... An object has a type. ...
今度からは少なくとも自分でどこをどう探したかぐらい示そうな。
https://timsong-cpp.github.io/cppwp/n4659/intro.object#1
> ... The properties of an object are determined when the object is created. ... An object has a type. ...
今度からは少なくとも自分でどこをどう探したかぐらい示そうな。
842デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 18:31:26.29ID:SsMAbqSz0 >>841
嘘つけ。キャストした場合についてはどこにも書いてない。
型が普遍なんてのは、君が勝手に思い込んでいるだけだ。
というか、いわゆる「強い型」ってのはそうらしいが、C++はそうじゃないだろ。
ちなみに俺も反論を用意してたところだ。
https://godbolt.org/g/viYhGj
中身は795の場所で、ついでだから f = *(double*)&i; を試した。
予想通りこちらはfmov(movsd)が出た。(最適化は切ってある)
つまり、俺が768で言ったように、
*(long long*)&f = i; // mov命令でコピー
または
f = *(double*)&i; // fmov命令でコピー
になるんだよ。少なくともgccはキャストされればその型だと認識している。
君はこれを矛盾無く説明出来ないだろ。
嘘つけ。キャストした場合についてはどこにも書いてない。
型が普遍なんてのは、君が勝手に思い込んでいるだけだ。
というか、いわゆる「強い型」ってのはそうらしいが、C++はそうじゃないだろ。
ちなみに俺も反論を用意してたところだ。
https://godbolt.org/g/viYhGj
中身は795の場所で、ついでだから f = *(double*)&i; を試した。
予想通りこちらはfmov(movsd)が出た。(最適化は切ってある)
つまり、俺が768で言ったように、
*(long long*)&f = i; // mov命令でコピー
または
f = *(double*)&i; // fmov命令でコピー
になるんだよ。少なくともgccはキャストされればその型だと認識している。
君はこれを矛盾無く説明出来ないだろ。
843デフォルトの名無しさん (オッペケ Srd1-0Zlk)
2017/11/19(日) 18:51:00.89ID:Q6cWJ/Rgr >キャストした場合についてはどこにも書いてない
はて、N4700の6.10/p8ほぼそのままの文面が少し上に貼り付けてあったような…
>>821
N4700 3.9, 4.5/p1, 6.8全般, 6.10/p8, 12.3/p1, 12.3/p(5.3), その他「launder」が登場する記述全般
はて、N4700の6.10/p8ほぼそのままの文面が少し上に貼り付けてあったような…
>>821
N4700 3.9, 4.5/p1, 6.8全般, 6.10/p8, 12.3/p1, 12.3/p(5.3), その他「launder」が登場する記述全般
844デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/19(日) 18:52:07.63ID:p3uF8GIb0 正しいそうなコードが吐かれたことは未定義動作でないという証拠には全くならない
なぜなら未定義動作というのは
コンパイル時のエラー、実行時のエラー(または例外)、一見正常っぽく気体通り動く、その他、
というあらゆる事象を包含し得るので、、、
もちろんコンパイラの変更で(ことによったらコンパイル条件の変更だけでも)
ある日突然狂ったコードが吐かれる危険性があるが
そうなっても未定義動作をプログラムした人の責任
よって現時点で正しいげなコードが吐かれることをいかに力説しても無駄で、
規格の矛盾の指摘にはつながらない
なぜなら未定義動作というのは
コンパイル時のエラー、実行時のエラー(または例外)、一見正常っぽく気体通り動く、その他、
というあらゆる事象を包含し得るので、、、
もちろんコンパイラの変更で(ことによったらコンパイル条件の変更だけでも)
ある日突然狂ったコードが吐かれる危険性があるが
そうなっても未定義動作をプログラムした人の責任
よって現時点で正しいげなコードが吐かれることをいかに力説しても無駄で、
規格の矛盾の指摘にはつながらない
845デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 18:53:33.74ID:xhmNfS4m0 >>842
オブジェクトの型に関与しない操作についていちいち記述があるわけないだろ。
まさか「〜によりオブジェクトの方は変わらない」とかの記述が全演算子&標準関数その他諸々について必要だ
なんて言うわけじゃないよね?
未定義動作の結果はなんでもアリだと言っただろう。
その結果(想定の命令コードが生成されたこと)が未定義動作の結果のひとつだとして、何の矛盾も無い。
オブジェクトの型に関与しない操作についていちいち記述があるわけないだろ。
まさか「〜によりオブジェクトの方は変わらない」とかの記述が全演算子&標準関数その他諸々について必要だ
なんて言うわけじゃないよね?
未定義動作の結果はなんでもアリだと言っただろう。
その結果(想定の命令コードが生成されたこと)が未定義動作の結果のひとつだとして、何の矛盾も無い。
846片山博文MZ ◆T6xkBnTXz7B0 (ワッチョイ f9b3-HT85)
2017/11/19(日) 19:03:59.08ID:R56+Z6E80 inline const self_type *const_this()
{
return this;
}
template <typename T_TYPE>
inline T_TYPE *drop_const(const T_TYPE *obj)
{
return const_cast<T_TYPE *>(obj);
}
{
return this;
}
template <typename T_TYPE>
inline T_TYPE *drop_const(const T_TYPE *obj)
{
return const_cast<T_TYPE *>(obj);
}
847デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/19(日) 19:04:38.54ID:RgqRbH7C0 ソースが仕様、ソース読めってやつか。
848デフォルトの名無しさん (ワッチョイ 82ae-Eq1o)
2017/11/19(日) 19:25:00.73ID:7jEiMXMd0 そう言って居直るやつは問題だが
ソースを読まない言い訳にするやつもダメ
腐敗は両岸から起きうることだ
ソースを読まない言い訳にするやつもダメ
腐敗は両岸から起きうることだ
849デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 19:53:33.03ID:SsMAbqSz0 >>844-845
うむ。それは一理ある。
>>845
では逆から行こう。reiniterpret_castのど頭、
> 5.2.10 Reinterpret cast
> 1. The result of the expression reinterpret_cast<T>(v) is the result of converting the expression v to type T.
vをTに型変換したのが結果だとそのまま書いてある。
これはどう解釈すれば、「型はどうやっても変更できない」と取れるのだ?
さすがに無理だろ。
> 7. An object pointer can be explicitly converted to an object pointer of a different type.
これも型を変更できると読めるが。そして再び1に戻ると、
> 1. ---- If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue;
つまり当然有効なlvalueであり、デリファレンスも可能だ。
だからキャストを反映してmovなりfmovが出るのだ。
違うか?
君が言うようにメモリ上の型が普遍なら、どうやっても i には fmov が出ては駄目だろ。
(と思ったが、君は837ではないのか、、、)
うむ。それは一理ある。
>>845
では逆から行こう。reiniterpret_castのど頭、
> 5.2.10 Reinterpret cast
> 1. The result of the expression reinterpret_cast<T>(v) is the result of converting the expression v to type T.
vをTに型変換したのが結果だとそのまま書いてある。
これはどう解釈すれば、「型はどうやっても変更できない」と取れるのだ?
さすがに無理だろ。
> 7. An object pointer can be explicitly converted to an object pointer of a different type.
これも型を変更できると読めるが。そして再び1に戻ると、
> 1. ---- If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue;
つまり当然有効なlvalueであり、デリファレンスも可能だ。
だからキャストを反映してmovなりfmovが出るのだ。
違うか?
君が言うようにメモリ上の型が普遍なら、どうやっても i には fmov が出ては駄目だろ。
(と思ったが、君は837ではないのか、、、)
850デフォルトの名無しさん (ワッチョイ 82ae-Eq1o)
2017/11/19(日) 20:02:38.24ID:7jEiMXMd0851デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 20:09:33.36ID:xhmNfS4m0 >>849
> これはどう解釈すれば、「型はどうやっても変更できない」と取れるのだ?
式の型 (static type) は変わるが、オブジェクトの型 (dynamic type) は変わらない。
> 君が言うようにメモリ上の型が普遍なら、どうやっても i には fmov が出ては駄目だろ。
未定義動作ならなんでもアリだと言った。
> これはどう解釈すれば、「型はどうやっても変更できない」と取れるのだ?
式の型 (static type) は変わるが、オブジェクトの型 (dynamic type) は変わらない。
> 君が言うようにメモリ上の型が普遍なら、どうやっても i には fmov が出ては駄目だろ。
未定義動作ならなんでもアリだと言った。
852デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 20:15:36.23ID:SsMAbqSz0 >>851
それで突っぱねるのなら平行線だね。
俺は仕様書に詳しいわけでは無いから動作から説明するしかない。
君は仕様書には詳しいようだが、キャストした場合にも型が変更されないという記述を出して来れない。
ま、デッドロックだ。
とはいえ状況は色々分かったよ。ありがとう。
それで突っぱねるのなら平行線だね。
俺は仕様書に詳しいわけでは無いから動作から説明するしかない。
君は仕様書には詳しいようだが、キャストした場合にも型が変更されないという記述を出して来れない。
ま、デッドロックだ。
とはいえ状況は色々分かったよ。ありがとう。
853デフォルトの名無しさん (オッペケ Srd1-0Zlk)
2017/11/19(日) 20:42:27.06ID:Q6cWJ/Rgr >つまり当然有効なlvalueであり、デリファレンスも可能だ。
仕様を引用して説明されてもこのとんちんかんな発言を繰り返すあたり、
知らないから間違えているのではなくオツムが悪いので必然的に無知になったと言うことに>>851は気付くべき
仕様を引用して説明されてもこのとんちんかんな発言を繰り返すあたり、
知らないから間違えているのではなくオツムが悪いので必然的に無知になったと言うことに>>851は気付くべき
854デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 20:47:51.98ID:xhmNfS4m0 >>852
> 俺は仕様書に詳しいわけでは無いから動作から説明するしかない。
なら↓お前の理解に基づいてこの動作を説明できるか試してみるといいかもしれない。
https://wandbox.org/permlink/2aKzO4VN3KRDB6Gu
> 君は仕様書には詳しいようだが、キャストした場合にも型が変更されないという記述を出して来れない。
式の型 (static type) とオブジェクトの型 (dynamic type) は別物だという客観的な
前提 [intro.defs] を素直に読みさえすれば何度も見えてるはずなんだけどな。
> 俺は仕様書に詳しいわけでは無いから動作から説明するしかない。
なら↓お前の理解に基づいてこの動作を説明できるか試してみるといいかもしれない。
https://wandbox.org/permlink/2aKzO4VN3KRDB6Gu
> 君は仕様書には詳しいようだが、キャストした場合にも型が変更されないという記述を出して来れない。
式の型 (static type) とオブジェクトの型 (dynamic type) は別物だという客観的な
前提 [intro.defs] を素直に読みさえすれば何度も見えてるはずなんだけどな。
855デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 20:54:00.37ID:XAwzlQ9S0 こいつわかってて引っ掻き回してるだけのような気がするわ
そうじゃなかったら馬鹿すぎる
そうじゃなかったら馬鹿すぎる
856デフォルトの名無しさん (ワッチョイ 02e7-GXP8)
2017/11/19(日) 21:10:07.51ID:JvH46D6m0 ある型の変数を入力として、別の型にキャストされた値を返すのはそりゃできるだろう
元の変数の型を変えることはそりゃ無理だろう
元の変数の型を変えることはそりゃ無理だろう
857デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 21:20:19.91ID:SsMAbqSz0858デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/19(日) 21:40:24.30ID:xhmNfS4m0 >>857
お前の中でどういう理解になっているかは把握できていない。
その答えからすると、
"*(long long*)&f = i;" なら未定義動作にならないけど "auto p = (long long*)&f; *p = i;" なら未定義動作になる、
という理解なのかな。まぁそんなことは無いんだけどさ。
お前の中でどういう理解になっているかは把握できていない。
その答えからすると、
"*(long long*)&f = i;" なら未定義動作にならないけど "auto p = (long long*)&f; *p = i;" なら未定義動作になる、
という理解なのかな。まぁそんなことは無いんだけどさ。
859デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/19(日) 22:14:48.53ID:RgqRbH7C0 いやまあ無いんだけどな。
いつまで言い張る気なんだろうか。
いつまで言い張る気なんだろうか。
860デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/19(日) 22:16:28.57ID:RgqRbH7C0 あると言えばあるんだけどな。
そろそろごめんなさいしてはどうか。
そろそろごめんなさいしてはどうか。
861デフォルトの名無しさん (ワッチョイ 6e81-LokX)
2017/11/19(日) 22:24:05.56ID:kv2+5Ve80 本の虫での解説記事が待たれる
862デフォルトの名無しさん (ワッチョイ a980-61Vg)
2017/11/19(日) 23:33:53.04ID:qbUCqX2r0 strict aliasing ruleについてはここで解りやすく解説されてる。自分で怪しいと思う奴は読め。
http://d.hatena.ne.jp/yohhoy/touch/20120220/p1
http://d.hatena.ne.jp/yohhoy/touch/20120220/p1
863デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/19(日) 23:37:47.80ID:SsMAbqSz0 >>858
ああそうだぞ。それは>>815で既に言ったし、実際に発現事例は今のところ全てaliasされてる。
顕在化させるには、「別型」で「alias」しないといけないんだよ。
オプションの名前も全くそうだろ。
多分君は理屈が分かってないんだ。
あれはtypeグループごとにメモリフェンスしていて、
別typeグループに入っていると結果的にout-of-orderになるだけなんだよ。
それは常時動いている。
ただし different type で alias して無いと顕現しない(ユーザ側には見えない)というだけ。
だからその可能性がある部分にwarningが出る。
しかしwarningというのは「普通やらないけど大丈夫か?」であって「絶対駄目」ではない。
結局君は different type alias について正確に理解出来てないんだよ。
上記を覆したければ、alias無しで different type alias の最適化がかかっている例を持って来い。
君の言う、
> まぁそんなことは無いんだけどさ。
の例だね。多分無いから。
既に言ったがLLVMだからインデックスレジスタは完全に残るんだよ。(多分)
キャストを知らないのだから理解出来ないようだが、(long long*) 部分は命令にならない。
(これはC++仕様書にも明記してあるが、C界では常識)
だから *&f だけが残り、結果、
*(long long*)&f と *&f (=f) は同じLLVM命令になる。(はず)
だからそこは問題視されてないんだよ。最適化器からも同じに見えるから。
逆に考えてみろ。同じtypeグループ内、例えば int と int が out-of-order になったら話にならんだろ。
だから同typeグループ内は alias があっても in-orderになってる。
そして別グループ double と int は常にout-of-orderになってるが、当然、関数でつながれているときにはフェンスされる。
例えば int a = max_idx(double*) みたいな感じで、doubleの配列から最大値の添字を取るときとかね。
だから different type で alias して無いとそれが見えないようになってるんだよ。
というのが俺の理解だ。覆す例があればよろしく。
ああそうだぞ。それは>>815で既に言ったし、実際に発現事例は今のところ全てaliasされてる。
顕在化させるには、「別型」で「alias」しないといけないんだよ。
オプションの名前も全くそうだろ。
多分君は理屈が分かってないんだ。
あれはtypeグループごとにメモリフェンスしていて、
別typeグループに入っていると結果的にout-of-orderになるだけなんだよ。
それは常時動いている。
ただし different type で alias して無いと顕現しない(ユーザ側には見えない)というだけ。
だからその可能性がある部分にwarningが出る。
しかしwarningというのは「普通やらないけど大丈夫か?」であって「絶対駄目」ではない。
結局君は different type alias について正確に理解出来てないんだよ。
上記を覆したければ、alias無しで different type alias の最適化がかかっている例を持って来い。
君の言う、
> まぁそんなことは無いんだけどさ。
の例だね。多分無いから。
既に言ったがLLVMだからインデックスレジスタは完全に残るんだよ。(多分)
キャストを知らないのだから理解出来ないようだが、(long long*) 部分は命令にならない。
(これはC++仕様書にも明記してあるが、C界では常識)
だから *&f だけが残り、結果、
*(long long*)&f と *&f (=f) は同じLLVM命令になる。(はず)
だからそこは問題視されてないんだよ。最適化器からも同じに見えるから。
逆に考えてみろ。同じtypeグループ内、例えば int と int が out-of-order になったら話にならんだろ。
だから同typeグループ内は alias があっても in-orderになってる。
そして別グループ double と int は常にout-of-orderになってるが、当然、関数でつながれているときにはフェンスされる。
例えば int a = max_idx(double*) みたいな感じで、doubleの配列から最大値の添字を取るときとかね。
だから different type で alias して無いとそれが見えないようになってるんだよ。
というのが俺の理解だ。覆す例があればよろしく。
864デフォルトの名無しさん (ワッチョイ c6e7-RjUU)
2017/11/19(日) 23:50:16.66ID:XAwzlQ9S0 ダメだこりゃ
865デフォルトの名無しさん (ワッチョイ 8d8a-Dzd0)
2017/11/20(月) 00:03:11.09ID:y/6cZRj30 そろそろ専用スレを建てて欲しいな
866デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/20(月) 00:06:21.48ID:Veq8ZMOx0 最初に質問した奴が謝罪すれば治まるのでは。
867デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/20(月) 00:12:55.32ID:gqHMI2DN0 最適化は人類には早すぎた
早すぎたテクノロジー
早すぎたテクノロジー
いきなりレベルの低い話で割り込んで恐縮です。
よろしくお願いいたします。
久々にJava から C++ に移行して、簡単なイテレータパターンを実装しました。
Java で書いた
https://ideone.com/DJ9pI5
を元に C++ で書いてみたのがこれです。
https://ideone.com/FwNlc4
ここで、コンテナにあたる Aggregateクラス(具象クラスは BookShelf) の中に
イテレータ(Iterator:具象クラスは BookShelfIterator) を作成して返すメンバ関数 iterator() を定義していますが、
C++ だからデストラクタも定義しないとね、と考えて
当初、Aggregate クラスに仮想メンバ関数 delete_iterator() を書いて
Aggregate::iterator() と Aggregate::delete_iterator() を対にするように作っておりました。
しかし教科書をみると
Aggregate::delete_iterator() みたいなデストラクタはそもそも定義しないようで、
普通に
Iterator *it = BookShelf(具象クラス)->iterator();
delete it;
でなんの問題もないようです。
なぜ、これで問題がないのかトンと見当がつきません。
イテレータを作った具象クラスの中でデストラクタを定義する、というのならば分かりやすいのですが、
抽象クラスのポインタをキャストもせずに直接 delete できるのは、どういうからくりになっているのでしょうか?
よろしくお願いいたします。
よろしくお願いいたします。
久々にJava から C++ に移行して、簡単なイテレータパターンを実装しました。
Java で書いた
https://ideone.com/DJ9pI5
を元に C++ で書いてみたのがこれです。
https://ideone.com/FwNlc4
ここで、コンテナにあたる Aggregateクラス(具象クラスは BookShelf) の中に
イテレータ(Iterator:具象クラスは BookShelfIterator) を作成して返すメンバ関数 iterator() を定義していますが、
C++ だからデストラクタも定義しないとね、と考えて
当初、Aggregate クラスに仮想メンバ関数 delete_iterator() を書いて
Aggregate::iterator() と Aggregate::delete_iterator() を対にするように作っておりました。
しかし教科書をみると
Aggregate::delete_iterator() みたいなデストラクタはそもそも定義しないようで、
普通に
Iterator *it = BookShelf(具象クラス)->iterator();
delete it;
でなんの問題もないようです。
なぜ、これで問題がないのかトンと見当がつきません。
イテレータを作った具象クラスの中でデストラクタを定義する、というのならば分かりやすいのですが、
抽象クラスのポインタをキャストもせずに直接 delete できるのは、どういうからくりになっているのでしょうか?
よろしくお願いいたします。
869デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/20(月) 00:34:03.39ID:uuALJ8Da0 >>863
> 上記を覆したければ、alias無しで different type alias の最適化がかかっている例を持って来い。
これでいいかな。
https://wandbox.org/permlink/RNDO0CIl9UpsaRwQ
> 上記を覆したければ、alias無しで different type alias の最適化がかかっている例を持って来い。
これでいいかな。
https://wandbox.org/permlink/RNDO0CIl9UpsaRwQ
870デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/20(月) 00:41:55.57ID:uuALJ8Da0871デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/20(月) 00:53:02.54ID:H8zFncfx0 >>869
せこいわw
gcc7.2.0(そこの最新版)で%eにしたら見えるがな。
まあ努力はご苦労様。
とはいえ、gcc4.4.7ならこのコードでも顕在化するし、「aliasが要る」という要件が怪しいのは認める。
この最適化はまだ発展途上のようだね。
せこいわw
gcc7.2.0(そこの最新版)で%eにしたら見えるがな。
まあ努力はご苦労様。
とはいえ、gcc4.4.7ならこのコードでも顕在化するし、「aliasが要る」という要件が怪しいのは認める。
この最適化はまだ発展途上のようだね。
872デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/20(月) 01:07:57.23ID:H8zFncfx0 >>870
おっとすまん、輻輳してしまったが、869で問題なく分かったぞ。
そして両方とも、gcc7.2.0にするか、globalにすると直る。
したがって、 different type alias で問題が発生するのには 「aliasが要る」という俺の見解は間違いだ。
ただ、過度の最適化による不具合を防ぐ努力は行われており、
gcc4..4.7→gcc7.2.0でこのコードに関しては修正されてる。
とはいえgcc7.2.0でもどこまで動くか分かった物ではないね。
おっとすまん、輻輳してしまったが、869で問題なく分かったぞ。
そして両方とも、gcc7.2.0にするか、globalにすると直る。
したがって、 different type alias で問題が発生するのには 「aliasが要る」という俺の見解は間違いだ。
ただ、過度の最適化による不具合を防ぐ努力は行われており、
gcc4..4.7→gcc7.2.0でこのコードに関しては修正されてる。
とはいえgcc7.2.0でもどこまで動くか分かった物ではないね。
873デフォルトの名無しさん (ワッチョイ 0233-dUYE)
2017/11/20(月) 01:11:14.23ID:uuALJ8Da0 >>872 さぁ、お前の罪を数えろ。
874デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/20(月) 01:32:56.30ID:Veq8ZMOx0 何で素直に謝罪できないんだろうね。
875はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 01:42:11.88ID:mEO8F9pQ0 >>868
それが virtual の効果だとしか。
基底で virtual 宣言したメンバ関数群はそのポインタをまとめたテーブルが作られ、オブジェクトはそのテーブルを指すポインタを持つ。
派生のオブジェクトは派生側の関数群を指すポインタテーブルへのポインタを持つ。
だから virtual を使うと「変数の型ではなくオブジェクトが呼出すべきメンバ関数を知っている」という状況を作れるんだよ。
ただ、基底のデストラクタを virtual に指定しないときでも見かけ上は型システムをパスしてしまいコンパイルエラーにならない場合がある。
これは未定義だからやっちゃダメだよ。
それが virtual の効果だとしか。
基底で virtual 宣言したメンバ関数群はそのポインタをまとめたテーブルが作られ、オブジェクトはそのテーブルを指すポインタを持つ。
派生のオブジェクトは派生側の関数群を指すポインタテーブルへのポインタを持つ。
だから virtual を使うと「変数の型ではなくオブジェクトが呼出すべきメンバ関数を知っている」という状況を作れるんだよ。
ただ、基底のデストラクタを virtual に指定しないときでも見かけ上は型システムをパスしてしまいコンパイルエラーにならない場合がある。
これは未定義だからやっちゃダメだよ。
876はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 01:59:59.63ID:mEO8F9pQ0 >>868,875
Wikipedia にも解説があるやないけ
https://ja.wikipedia.org/wiki/%E4%BB%AE%E6%83%B3%E9%96%A2%E6%95%B0%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB
Wikipedia にも解説があるやないけ
https://ja.wikipedia.org/wiki/%E4%BB%AE%E6%83%B3%E9%96%A2%E6%95%B0%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB
>>875-876
うーん、普通のポリモフィズムの話が同様に適用できるんですね…
Base<-Derived1
Base<-Derived2
の基底・派生関係のとき
Base *p = new Derived1() ならば、delete p; は delete (Derived1 *)p;
Base *p = new Derived2() ならば、delete p; は delete (Derived2 *)p;
となる、と考えていいでしょうか。
Base *p = new Derived1() ならば、p->method(); は p->method_Dirived1();
Base *p = new Derived2() ならば、p->method(); は p->method_Dirived2();
という話と同じなんですね。
んーなせ Aggregate::delete_iterator() を作らなくちゃ、と考えたのか逆にわからなくなってしまいました…
ありがとうございました。
うーん、普通のポリモフィズムの話が同様に適用できるんですね…
Base<-Derived1
Base<-Derived2
の基底・派生関係のとき
Base *p = new Derived1() ならば、delete p; は delete (Derived1 *)p;
Base *p = new Derived2() ならば、delete p; は delete (Derived2 *)p;
となる、と考えていいでしょうか。
Base *p = new Derived1() ならば、p->method(); は p->method_Dirived1();
Base *p = new Derived2() ならば、p->method(); は p->method_Dirived2();
という話と同じなんですね。
んーなせ Aggregate::delete_iterator() を作らなくちゃ、と考えたのか逆にわからなくなってしまいました…
ありがとうございました。
次に >>868 のテンプレート版を書いてみました。
https://ideone.com/LO68r5
void * (Java の Object)をキャストするのを嫌ったという理由になります。
>>868
>class Iterator
>virtual void *next() = 0;
>class BookShelfIterator : public Iterator { };
>void *BookShelfIterator::next()
>Book *book = (Book *)it->next();
https://ideone.com/LO68r5
そこで不思議に思ったことなんですが、
コンストラクタは
template <typename T> class Derived : Base { public: Derived(){}; };
とテンプレート引数 T をコンストラクタ名をつけなくていい(public: Derived<T>(){}; としない)のに、
デストラクタは
template <typename T> class Derived : Base { public: ~Derived<T>(){}; }; (クラスのメンバ関数宣言)
template <typename T> Derived<T>::~Derived<T>() { } (クラスのメンバ関数定義)
とテンプレート引数 T をデストラクタ名につけないといけないのでしょうか?何か分かりやすい理由はありますでしょうか?
https://ideone.com/LO68r5
void * (Java の Object)をキャストするのを嫌ったという理由になります。
>>868
>class Iterator
>virtual void *next() = 0;
>class BookShelfIterator : public Iterator { };
>void *BookShelfIterator::next()
>Book *book = (Book *)it->next();
https://ideone.com/LO68r5
そこで不思議に思ったことなんですが、
コンストラクタは
template <typename T> class Derived : Base { public: Derived(){}; };
とテンプレート引数 T をコンストラクタ名をつけなくていい(public: Derived<T>(){}; としない)のに、
デストラクタは
template <typename T> class Derived : Base { public: ~Derived<T>(){}; }; (クラスのメンバ関数宣言)
template <typename T> Derived<T>::~Derived<T>() { } (クラスのメンバ関数定義)
とテンプレート引数 T をデストラクタ名につけないといけないのでしょうか?何か分かりやすい理由はありますでしょうか?
879はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 03:03:42.40ID:mEO8F9pQ0 >>877
キャストとは意味が違うんだよ。
上でさんざん議論してる static type と dynamic type の話とも関係あるのかなぁ?
入り組んでてよくわからん。
型はあくまでも Base* で、仮想関数テーブルを辿って必要な関数を呼び出すってだけだ。
繰返すけど、 Base のデストラクタに virtual がついてないときに Base のポインタに対して delete すると
Base のデストラクタが呼び出されるだけになってまうので気をつけてな。
派生クラスのデストラクタが空っぽのときでもデストラクタが呼び出される必要はあるらしいぞ。
キャストとは意味が違うんだよ。
上でさんざん議論してる static type と dynamic type の話とも関係あるのかなぁ?
入り組んでてよくわからん。
型はあくまでも Base* で、仮想関数テーブルを辿って必要な関数を呼び出すってだけだ。
繰返すけど、 Base のデストラクタに virtual がついてないときに Base のポインタに対して delete すると
Base のデストラクタが呼び出されるだけになってまうので気をつけてな。
派生クラスのデストラクタが空っぽのときでもデストラクタが呼び出される必要はあるらしいぞ。
>>878 の続きです。
同じく、テンプレート版
https://ideone.com/LO68r5
にて一点不満におもったことがあります。
>>878 では基底クラスの記述について、
template <typename T>
class Iterator {
public:
virtual T *next() = 0;
};
派生クラスは
template <typename T>
class XXXIterator : Iterato<T> {
public:
T *next();
};
template <typename T> T *XXXIterator::next() { ... }
と書きました。
しかし本当は、基底クラスを純粋に一個にしたいと希望しているのです。
つまり基底クラスにテンプレート引数Tを書きたくない。
class Iterator {
public:
virtual ○○○ *next() = 0;
};
と基底クラスを一つだけにしぼりつつ、
派生クラスにテンプレート引数を使用して記述することは可能でしょうか?○○○に書けるなにかいい記述はないでしょうか?
テンプレート引数を使用した具象クラスに対応する、テンプレート引数を使用しない抽象クラスを書くことは可能でしょうか?
同じく、テンプレート版
https://ideone.com/LO68r5
にて一点不満におもったことがあります。
>>878 では基底クラスの記述について、
template <typename T>
class Iterator {
public:
virtual T *next() = 0;
};
派生クラスは
template <typename T>
class XXXIterator : Iterato<T> {
public:
T *next();
};
template <typename T> T *XXXIterator::next() { ... }
と書きました。
しかし本当は、基底クラスを純粋に一個にしたいと希望しているのです。
つまり基底クラスにテンプレート引数Tを書きたくない。
class Iterator {
public:
virtual ○○○ *next() = 0;
};
と基底クラスを一つだけにしぼりつつ、
派生クラスにテンプレート引数を使用して記述することは可能でしょうか?○○○に書けるなにかいい記述はないでしょうか?
テンプレート引数を使用した具象クラスに対応する、テンプレート引数を使用しない抽象クラスを書くことは可能でしょうか?
881はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 03:15:21.39ID:mEO8F9pQ0 >>878
付けなくてもいいし、付けても通るってのは私は今初めて知った。
付けなくてもいいし、付けても通るってのは私は今初めて知った。
882はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 03:23:45.23ID:mEO8F9pQ0 >>879
ありがとうございます。
meyers の effective C++ 第7章を読み返しています
C++ には Java の fainal がないので、うっかり、std::string や std::vector を派生させてしまうところでした、危ないなあ…
ありがとうございます。
meyers の effective C++ 第7章を読み返しています
C++ には Java の fainal がないので、うっかり、std::string や std::vector を派生させてしまうところでした、危ないなあ…
884デフォルトの名無しさん (ワッチョイ 869f-GXP8)
2017/11/20(月) 03:30:13.52ID:iECo0Ul80 >>868
混乱するならシンプルに設計したら?例えばこんな感じ?登録して表示するだけなら簡単でしょ?
#include <stdio.h>
#include <string>
#include <vector>
class Book{
public:
std::string name;
Book(std::string _name) : name(_name){}
void show(){printf("%s\n",name.c_str());}
};
class Books{
public:
std::vector<Book *>m_list;
Books(){}
~Books(){for (auto p : m_list) if (p) delete p;}
void addBook(Book *p){m_list.push_back(p);}
};
int main(){
Books books;
books.addBook(new Book("aa"));books.addBook(new Book("bb"));
books.addBook(new Book("cc"));books.addBook(new Book("dd"));
for (auto p : books.m_list) p->show();
// iterator使いたいなら
//for (auto it = books.m_list.begin(); it != books.m_list.end; it++) (*it)->show();
return 0;
}
混乱するならシンプルに設計したら?例えばこんな感じ?登録して表示するだけなら簡単でしょ?
#include <stdio.h>
#include <string>
#include <vector>
class Book{
public:
std::string name;
Book(std::string _name) : name(_name){}
void show(){printf("%s\n",name.c_str());}
};
class Books{
public:
std::vector<Book *>m_list;
Books(){}
~Books(){for (auto p : m_list) if (p) delete p;}
void addBook(Book *p){m_list.push_back(p);}
};
int main(){
Books books;
books.addBook(new Book("aa"));books.addBook(new Book("bb"));
books.addBook(new Book("cc"));books.addBook(new Book("dd"));
for (auto p : books.m_list) p->show();
// iterator使いたいなら
//for (auto it = books.m_list.begin(); it != books.m_list.end; it++) (*it)->show();
return 0;
}
885はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 03:34:54.09ID:mEO8F9pQ0 >>880
Java のことはあまり知らんので元ネタにした Java 版の方をよく見てなったけど、
interface のかわりに抽象クラスを使おうとしてたのか。
似たような機能に見えちゃうかもしれないけど、インターフェイスを強制する方法としては抽象クラスはあまり良くない。
C++ 的にはコンパイル時にディスパッチする多相と実行時の多相があって、
抽象クラスは実行時にディスパッチする仕組みなのでコンパイル時に確定するはずのことを実行時にするのはクソザコという風潮。
だけど「コンセプト」の機能が C++ に導入されるのが延び延びになってていまだ入ってないので、
traits とか SFINAE とかを使ったまわりくどいメタプログラミングで代用してるのが実情なんだ。
Java のことはあまり知らんので元ネタにした Java 版の方をよく見てなったけど、
interface のかわりに抽象クラスを使おうとしてたのか。
似たような機能に見えちゃうかもしれないけど、インターフェイスを強制する方法としては抽象クラスはあまり良くない。
C++ 的にはコンパイル時にディスパッチする多相と実行時の多相があって、
抽象クラスは実行時にディスパッチする仕組みなのでコンパイル時に確定するはずのことを実行時にするのはクソザコという風潮。
だけど「コンセプト」の機能が C++ に導入されるのが延び延びになってていまだ入ってないので、
traits とか SFINAE とかを使ったまわりくどいメタプログラミングで代用してるのが実情なんだ。
>>881
>付けなくてもいいし
うーん、デストラクタの場合はテンプレート引数をつけないとおこられちゃいます…
×https://ideone.com/x5FrwU 69行目
○https://ideone.com/FUJ3OO 69行目
よくわらからないな…
>付けなくてもいいし
うーん、デストラクタの場合はテンプレート引数をつけないとおこられちゃいます…
×https://ideone.com/x5FrwU 69行目
○https://ideone.com/FUJ3OO 69行目
よくわらからないな…
887はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 03:53:09.38ID:mEO8F9pQ0 >>886
いや、型名の方には付ける必要あるよ
×:
template <typename T> TShelf::~TShelf() { delete [] (this->t_s); }
〇:
template <typename T> TShelf<T>::~TShelf() { delete [] (this->t_s); }
△: 知らんかった
template <typename T> TShelf<T>::~TShelf<T>() { delete [] (this->t_s); }
いや、型名の方には付ける必要あるよ
×:
template <typename T> TShelf::~TShelf() { delete [] (this->t_s); }
〇:
template <typename T> TShelf<T>::~TShelf() { delete [] (this->t_s); }
△: 知らんかった
template <typename T> TShelf<T>::~TShelf<T>() { delete [] (this->t_s); }
>>884
はい、すごくよくわかります!!
std::vector とか、std::list とかstd::deque とかは、たぶんいけると思います。
http://mevius.2ch.net/test/read.cgi/tech/1434079972/14
http://mevius.2ch.net/test/read.cgi/tech/1434079972/19
なんとなくデザパタ本を読み返していて、車輪の再発明に没頭してしまいましたが、C# のデザパタ本、というのも聞かないし、もうデザパタは古いのかな…
はい、すごくよくわかります!!
std::vector とか、std::list とかstd::deque とかは、たぶんいけると思います。
http://mevius.2ch.net/test/read.cgi/tech/1434079972/14
http://mevius.2ch.net/test/read.cgi/tech/1434079972/19
なんとなくデザパタ本を読み返していて、車輪の再発明に没頭してしまいましたが、C# のデザパタ本、というのも聞かないし、もうデザパタは古いのかな…
889デフォルトの名無しさん (ワッチョイ 42b3-VAF2)
2017/11/20(月) 03:58:54.21ID:O993TKuI0 マジか
役に立つ日が来るかどうかはシランケド
役に立つ日が来るかどうかはシランケド
>>887
ありがとうございます。確認いたしました。
ありがとうございます。確認いたしました。
891デフォルトの名無しさん (ワッチョイ 42b3-VAF2)
2017/11/20(月) 03:59:26.41ID:O993TKuI0 ↑ >>887
>>885
夜遅くにコメントいただきありがとうございます。
>C++ 的にはコンパイル時にディスパッチする多相と実行時の多相があって、
理解できます。コンパイル時に確定できるのなら最大限それに努める思想はたとえば constexpr にも現れていると思いました。
>抽象クラスは実行時にディスパッチする仕組みなのでコンパイル時に確定するはずのことを実行時にするのはクソザコという風潮。
うーん、たぶん私が周回遅れなだけだと思いますが、じゃあ、ひところ、あれほどまでにもてはやされたデザインパターンは、どこにいってしまったのでしょう…もう誰もやらないのかな…
夜遅くにコメントいただきありがとうございます。
>C++ 的にはコンパイル時にディスパッチする多相と実行時の多相があって、
理解できます。コンパイル時に確定できるのなら最大限それに努める思想はたとえば constexpr にも現れていると思いました。
>抽象クラスは実行時にディスパッチする仕組みなのでコンパイル時に確定するはずのことを実行時にするのはクソザコという風潮。
うーん、たぶん私が周回遅れなだけだと思いますが、じゃあ、ひところ、あれほどまでにもてはやされたデザインパターンは、どこにいってしまったのでしょう…もう誰もやらないのかな…
893はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 04:13:43.35ID:mEO8F9pQ0 >>887
なんでこうなってるかっていうのは割と感覚的にやっちゃってるからうまいこと説明できひんのやけど。
クラステンプレートの中に関数テンプレートも書けたりするので
template<class T>
class foo {
public:
template<class U> void bar(void);
};
実装書くときはどれがどれに掛かってるかわかるようにせんといかん
template<class T> template<class U>
void foo<T>::bar(void) {
}
みたいな話なんじゃないかとコンパイラの気持ちになる仁奈ちゃんの気持ちになってた。
なんでこうなってるかっていうのは割と感覚的にやっちゃってるからうまいこと説明できひんのやけど。
クラステンプレートの中に関数テンプレートも書けたりするので
template<class T>
class foo {
public:
template<class U> void bar(void);
};
実装書くときはどれがどれに掛かってるかわかるようにせんといかん
template<class T> template<class U>
void foo<T>::bar(void) {
}
みたいな話なんじゃないかとコンパイラの気持ちになる仁奈ちゃんの気持ちになってた。
894はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 04:30:34.82ID:mEO8F9pQ0 >>892
抽象クラスを使うパターンなんてのがあるわけ? GoF 本とか読んだことないから知らんけど。
それはインターフェイスをまとめた何かを作れって話とかじゃないの?
C++ の抽象クラスを使えって話とは違ったりしそうだけど。
デザインパターンはあくまでデザインの話なんだから言語の具体的な機能はその時代に有るものでやるしかないし、
よりよい機能が提供されるようになったら使うだろ、そりゃ。
抽象クラスを使うやり方しかできないなら「デザイン」を学び取れてないってこった。
まあ今は C++ への理解も十分でないからってのもあるだろうけどさ。
ところで QZ って C++ スレの常連みたいに思ってたけど、
その割にアレなのでひょっとして共通トリップだったりするの?
抽象クラスを使うパターンなんてのがあるわけ? GoF 本とか読んだことないから知らんけど。
それはインターフェイスをまとめた何かを作れって話とかじゃないの?
C++ の抽象クラスを使えって話とは違ったりしそうだけど。
デザインパターンはあくまでデザインの話なんだから言語の具体的な機能はその時代に有るものでやるしかないし、
よりよい機能が提供されるようになったら使うだろ、そりゃ。
抽象クラスを使うやり方しかできないなら「デザイン」を学び取れてないってこった。
まあ今は C++ への理解も十分でないからってのもあるだろうけどさ。
ところで QZ って C++ スレの常連みたいに思ってたけど、
その割にアレなのでひょっとして共通トリップだったりするの?
>>894
>その割にアレなのでひょっとして共通トリップだったりするの?
単に、あれよあれよと、また、次から次へと忘れていくので、ぜんぜん進歩しないだけなのでした。
こんな感じ… https://www.youtube.com/watch?v=Hflpt1-kAl4
>その割にアレなのでひょっとして共通トリップだったりするの?
単に、あれよあれよと、また、次から次へと忘れていくので、ぜんぜん進歩しないだけなのでした。
こんな感じ… https://www.youtube.com/watch?v=Hflpt1-kAl4
896デフォルトの名無しさん (ワッチョイ 228d-zvir)
2017/11/20(月) 07:05:19.03ID:8Dez9ldp0 手元に古いGoF日本語訳(1999年初版)があったので覗いてみたら、
Iteratorのサンプル(C++)が>>880みたいに抽象クラスで実装されていてびっくりした。
抽象クラスを使わなくても、処理の共通化を考えないなら問題ないし、
共通化したい場合でも、そこだけテンプレート化すればよいような気がする。
https://ideone.com/sFzBq4
Iteratorのサンプル(C++)が>>880みたいに抽象クラスで実装されていてびっくりした。
抽象クラスを使わなくても、処理の共通化を考えないなら問題ないし、
共通化したい場合でも、そこだけテンプレート化すればよいような気がする。
https://ideone.com/sFzBq4
897デフォルトの名無しさん (ワッチョイ 4178-kX9V)
2017/11/20(月) 08:00:57.16ID:GfOPAtNP0 VC++とか今でこそまともだけど昔はテンプレート周りがうんこすぎて風呂釜洗剤教の人のやり方に頼らざるを得なかったらしいね
898デフォルトの名無しさん (ワッチョイ 826e-Eq1o)
2017/11/20(月) 09:24:05.14ID:9q5rB25R0 そういう「まとも」を求めてVCを選ぶのは情弱のすることだ
意味の違う「まとも」で定評のあるコンパイラであって
意味の違う「まとも」で定評のあるコンパイラであって
899デフォルトの名無しさん (ワッチョイ f9b3-AWKa)
2017/11/20(月) 09:46:04.69ID:Veq8ZMOx0 Vistaまではgccでコンパイルしてたらしいからな。
900デフォルトの名無しさん (アウーイモ MM05-0x9U)
2017/11/20(月) 10:17:12.94ID:5dn4op1oM 初心者なんですがusing使い方を教えて下せえ
901デフォルトの名無しさん (ワッチョイ 0234-1gB9)
2017/11/20(月) 10:36:08.17ID:Fx3rJ6pW0 usingは時代によって使える機能が異なる
昔はnamespaceから使える宣言を取り出す役割
最近は=を用いてtypedefの簡略化っぽい書き方が出来る
昔はnamespaceから使える宣言を取り出す役割
最近は=を用いてtypedefの簡略化っぽい書き方が出来る
902デフォルトの名無しさん (ワッチョイ 0234-1gB9)
2017/11/20(月) 10:42:51.51ID:Fx3rJ6pW0 将来的にはusingがプロパティの役割まで担ってくれると余計な予約後増やさなくて済む希ガス
903デフォルトの名無しさん (ワンミングク MM52-Dzd0)
2017/11/20(月) 12:17:25.71ID:OatlO4rKM904デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
2017/11/20(月) 14:57:25.95ID:ZHV8ZCmh0 ratioのバグとかinitializer_listとかね
しっかりしているようで時おり大ボケで笑いを取る謎な会社だ
しっかりしているようで時おり大ボケで笑いを取る謎な会社だ
905デフォルトの名無しさん (ササクッテロラ Spd1-CMbJ)
2017/11/20(月) 16:59:42.71ID:CB3KD7K4p906デフォルトの名無しさん (ワッチョイ ae6e-Eq1o)
2017/11/20(月) 17:06:25.94ID:ZHV8ZCmh0 重箱の隅じゃあんめえ
仮想デストラクタがないことと継承禁止は近いが違う
仮想デストラクタがないことと継承禁止は近いが違う
907はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 17:20:13.60ID:mEO8F9pQ0 std::vector とかを public 継承してもスライシングが起こらないように使う分には全然問題ないわけだしな。
でも人間はアホだからスライシングするし、スライシングしたときにコンパイルエラーにしてくれないから避けようっていう「習慣」なだけで、
言語機能としてはデストラクタが仮想になってないからといって継承が禁止されているってわけではないんだ。
そこらへんは確かに意味づけが違う。
でも人間はアホだからスライシングするし、スライシングしたときにコンパイルエラーにしてくれないから避けようっていう「習慣」なだけで、
言語機能としてはデストラクタが仮想になってないからといって継承が禁止されているってわけではないんだ。
そこらへんは確かに意味づけが違う。
908デフォルトの名無しさん (ワッチョイ 02cf-Gm5t)
2017/11/20(月) 17:54:47.05ID:4sV97R+K0 デザパタは基本的にGC言語向きだしな
C++とは相性が良くない
C++とは相性が良くない
909デフォルトの名無しさん (スプッッ Sd41-LOf1)
2017/11/20(月) 19:05:49.28ID:RcaXyFV8d C++の基本的なコーディングを学ぶのにオススメな書籍あるかな?
テクニック集とかもあると読んでみたいと思っている
テクニック集とかもあると読んでみたいと思っている
910デフォルトの名無しさん (ワッチョイ a17f-8CrJ)
2017/11/20(月) 19:11:23.76ID:q0WTO8Pn0 EffectiveC++シリーズ
Exceptional C++
C++ Coding Standards
あたりの定番中の定番でいいだろ
Exceptional C++
C++ Coding Standards
あたりの定番中の定番でいいだろ
911デフォルトの名無しさん (ワッチョイ 41eb-RjUU)
2017/11/20(月) 20:12:37.95ID:rJCmscgl0 ここって本職でやってる人らばっかりなんかね
日曜プログラマが気安く書き込んでもいいのだろうか
日曜プログラマが気安く書き込んでもいいのだろうか
912はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/20(月) 20:21:38.03ID:mEO8F9pQ0 >>911
いいよ。 俺も趣味プログラマだけど偉そうに書き込んでるし。
いいよ。 俺も趣味プログラマだけど偉そうに書き込んでるし。
913デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/20(月) 21:53:59.25ID:gqHMI2DN0 GoF本のうち
Stateパターンは抽象クラス必須
Abstractなんちゃら系も抽象クラス必須
な印象
Stateパターンは抽象クラス必須
Abstractなんちゃら系も抽象クラス必須
な印象
914デフォルトの名無しさん (ワッチョイ 02e7-GXP8)
2017/11/20(月) 22:05:37.00ID:vFwnmuVP0 >>911
プロがここでうんちく垂れてたら引くわな
プロがここでうんちく垂れてたら引くわな
915デフォルトの名無しさん (ワッチョイ a19f-RjUU)
2017/11/20(月) 22:07:59.95ID:H8zFncfx0 >>873
最新版で該当ケースを探せず、
わざわざ5年前の版を持ち出してきてまで俺ツエーしたいヘタレを相手にしてしまい、すいませんでしたー
gcc4.4.7(2012/3/13)の時点で対応できて無いという情報はものすごく役に立ちますー(棒)
つかマジで、賢いつもりなら最新版で該当ケース探してgccに報告しろよ。
問題に遭遇したらとりあえず最新版、というのは基本だ。
ここを問題視する奴がgcc4.4.7なんて今使ってるわけないだろ。お前は馬鹿なのか?
お前のその努力は誰の為にも役に立ってないだろ。
これは多分に政治的問題で、コンパイラ屋がごねているだけだ。
既に言ったとおり、
reinterpret_cast相当のことがなされている場合、その関数単位で -fno-strict-aliasing すればいいだけで、
これに関して技術/仕様的問題は何もない。
ただ、「ソースさえ正しければこんな問題は発生しない」とか言って、コンパイラ屋がごねてるんだよ。
だから、力関係が逆転すればいきなり全部直ってもおかしくない。
gcc7.2.0がどっちのアプローチ、
つまり、上記の通りばっさり最適化を切ってしまい、最適化ケースを積み上げる方向にしたのか、
或いは従来どおり、過度の最適化を検出し、最適化を防ぐケースを積み上げることにしたのかは、俺は知らない。
ただ、どちらのケースであっても、最新版で上手く行かないケースがあれば、それはgccにとっては有用な情報なんだよ。
それをわざわざ旧版で、しかも隠してしれっととか、意味無いしせこいわw
最新版で出現しないから焦ったか?小物感ありあり。
> まぁそんなことは無いんだけどさ。
とか言うから、お?釣りか?ならここは全力で釣られてやるさ、該当事例持って来いよ!って流れなのに、
事前に該当事例用意しておかずに釣りとかアホかテメーは。
君が最新版で完全にアウトなケースを用意してれば、ああこれは完全に俺の負けですサーセン、とお後がよろしかったのに、
gcc4.4.7であることにも触れず俺ツエーするとか、小物過ぎて泣ける。
お前もうちょっとスレの流れを考えろよ。
最新版で該当ケースを探せず、
わざわざ5年前の版を持ち出してきてまで俺ツエーしたいヘタレを相手にしてしまい、すいませんでしたー
gcc4.4.7(2012/3/13)の時点で対応できて無いという情報はものすごく役に立ちますー(棒)
つかマジで、賢いつもりなら最新版で該当ケース探してgccに報告しろよ。
問題に遭遇したらとりあえず最新版、というのは基本だ。
ここを問題視する奴がgcc4.4.7なんて今使ってるわけないだろ。お前は馬鹿なのか?
お前のその努力は誰の為にも役に立ってないだろ。
これは多分に政治的問題で、コンパイラ屋がごねているだけだ。
既に言ったとおり、
reinterpret_cast相当のことがなされている場合、その関数単位で -fno-strict-aliasing すればいいだけで、
これに関して技術/仕様的問題は何もない。
ただ、「ソースさえ正しければこんな問題は発生しない」とか言って、コンパイラ屋がごねてるんだよ。
だから、力関係が逆転すればいきなり全部直ってもおかしくない。
gcc7.2.0がどっちのアプローチ、
つまり、上記の通りばっさり最適化を切ってしまい、最適化ケースを積み上げる方向にしたのか、
或いは従来どおり、過度の最適化を検出し、最適化を防ぐケースを積み上げることにしたのかは、俺は知らない。
ただ、どちらのケースであっても、最新版で上手く行かないケースがあれば、それはgccにとっては有用な情報なんだよ。
それをわざわざ旧版で、しかも隠してしれっととか、意味無いしせこいわw
最新版で出現しないから焦ったか?小物感ありあり。
> まぁそんなことは無いんだけどさ。
とか言うから、お?釣りか?ならここは全力で釣られてやるさ、該当事例持って来いよ!って流れなのに、
事前に該当事例用意しておかずに釣りとかアホかテメーは。
君が最新版で完全にアウトなケースを用意してれば、ああこれは完全に俺の負けですサーセン、とお後がよろしかったのに、
gcc4.4.7であることにも触れず俺ツエーするとか、小物過ぎて泣ける。
お前もうちょっとスレの流れを考えろよ。
916デフォルトの名無しさん (ブーイモ MMcd-pLBf)
2017/11/20(月) 22:13:38.04ID:cvRta7BJM >>908
GoF本はc++とsmalltalkだったろ
GoF本はc++とsmalltalkだったろ
917デフォルトの名無しさん (ワッチョイ 02bd-VFQ0)
2017/11/20(月) 22:48:11.84ID:gqHMI2DN0 テンキー風のボタンの並びでモードによって意味が変わる(Num Lock ON/OFFのもっと複雑化したようなやつ
というユザーインターフェースの実装はStateパターンのどくだんば
そこまでレトロなのでなくてもGUIでお絵かきツールを集めたツールボックスなUIとか作ると
Abstructなんちゃらパターンのどれかを再発明しているケースが多いと思う
というユザーインターフェースの実装はStateパターンのどくだんば
そこまでレトロなのでなくてもGUIでお絵かきツールを集めたツールボックスなUIとか作ると
Abstructなんちゃらパターンのどれかを再発明しているケースが多いと思う
918デフォルトの名無しさん (ワッチョイ 02e7-GXP8)
2017/11/20(月) 23:04:17.12ID:vFwnmuVP0 ←なぜか変換できない
919デフォルトの名無しさん (ワッチョイ 466f-MUuo)
2017/11/20(月) 23:35:39.24ID:mEO8F9pQ0 独擅場 ← どくせんじょう
920はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 466f-RuWE)
2017/11/21(火) 00:48:45.97ID:KkY90WH60 >>913
昨日 >>885 でまわりくどいメタプログラミングと言ってたのがそれだ。
State パターンのように特定のメンバ関数を持っていることを強制したいときには
それを判定するトレイツを作って対応する。
たとえば >>886 にあるコードを対象に考えて、
「あるクラスがそのクラス自身のポインタを返す next という名前のメンバ関数を持っているか」
を判定するトレイツはこうなる。
template<class T>
class has_next {
template<class U, class V = T>
struct helper : std::false_type {};
template<class U>
struct helper<U, typename std::enable_if<std::is_same<decltype(std::declval<U>().next()), U*>::value, T>::type> : std::true_type {};
public:
static const bool value = helper<T>::value;
};
C++ 標準の type_traits を真似してるので使い方もだいたい同じ。
static_assert(!has_next<TShelfIterator<Book>>::value, "TShelfIterator must has next() method.");
みたいに書いておけば TShelfIterator<Book> がメンバ関数 next を持っていることが保証される。
持っていなければコンパイル時にエラーになるから。
ここではひとつのメンバ関数を判定するだけのものを作ったけど、 Boost にはもっと汎用的にいい感じにかけるやつが有った気がする。
知らんけど。
昨日 >>885 でまわりくどいメタプログラミングと言ってたのがそれだ。
State パターンのように特定のメンバ関数を持っていることを強制したいときには
それを判定するトレイツを作って対応する。
たとえば >>886 にあるコードを対象に考えて、
「あるクラスがそのクラス自身のポインタを返す next という名前のメンバ関数を持っているか」
を判定するトレイツはこうなる。
template<class T>
class has_next {
template<class U, class V = T>
struct helper : std::false_type {};
template<class U>
struct helper<U, typename std::enable_if<std::is_same<decltype(std::declval<U>().next()), U*>::value, T>::type> : std::true_type {};
public:
static const bool value = helper<T>::value;
};
C++ 標準の type_traits を真似してるので使い方もだいたい同じ。
static_assert(!has_next<TShelfIterator<Book>>::value, "TShelfIterator must has next() method.");
みたいに書いておけば TShelfIterator<Book> がメンバ関数 next を持っていることが保証される。
持っていなければコンパイル時にエラーになるから。
ここではひとつのメンバ関数を判定するだけのものを作ったけど、 Boost にはもっと汎用的にいい感じにかけるやつが有った気がする。
知らんけど。
921デフォルトの名無しさん (ワッチョイ 6e81-LokX)
2017/11/21(火) 01:13:43.73ID:H+r6aFWv0 そんなくそレガシーなtraits
久々に見た…
久々に見た…
922デフォルトの名無しさん (スップ Sd82-LOf1)
2017/11/21(火) 17:31:41.16ID:6BA+Ife8d あるファイルに下のような文字が書き込まれていて
xxxx=3
これの3を取得する完璧無欠なロジックなにかないかな
xxxx=3
これの3を取得する完璧無欠なロジックなにかないかな
923デフォルトの名無しさん (ワッチョイ 4178-kX9V)
2017/11/21(火) 17:32:59.03ID:uRVBPn0b0 完璧無欠とは?
924デフォルトの名無しさん (スップ Sd82-LOf1)
2017/11/21(火) 17:36:16.46ID:6BA+Ife8d925デフォルトの名無しさん (アウアウカー Sa49-vUM9)
2017/11/21(火) 18:10:16.89ID:B2ib4/wIa 正規表現でよくない?
926デフォルトの名無しさん (ワッチョイ a104-0wpo)
2017/11/21(火) 19:05:58.85ID:DIhAB+/L0 リバースイテレータをfindしてイコールでセパレート。
って、数行から見つけるのか。
構文解析とかか?
って、数行から見つけるのか。
構文解析とかか?
927デフォルトの名無しさん (スップ Sd82-LOf1)
2017/11/21(火) 19:38:49.19ID:6BA+Ife8d928デフォルトの名無しさん (ワッチョイ a168-+5lI)
2017/11/21(火) 19:53:50.67ID:GhiisSyt0 (?<=^xxx=)\d+$
レス数が900を超えています。1000を超えると表示できなくなるよ。
ニュース
- 国民 居住目的でない住宅所有者に「空室税」課せる法案を提出 [少考さん★]
- 国民 居住目的でない住宅所有者に「空室税」課せる法案を提出 ★2 [少考さん★]
- 「働いて働いて」の流行語大賞に懸念 「言葉が独り歩き」 過労自殺遺族 [尺アジ★]
- アメリカ、入国時に「日本人を含む外国人観光客の最大5年分のSNS履歴の提出」義務化へ 過去10年間に使用のメールアドレスや電話番号等も★3 [Hitzeschleier★]
- 【画像】消えた美人女優 上原多香子さん(42)、沖縄で目撃される [牛丼★]
- 「暖房が使えない」「食費が高くて子どもの栄養が…」 物価高に苦しむ子育て世帯、政府に期待する支援は ★2 [蚤の市★]
- 【高市悲報】JA、発狂www「臨時に経費率を下げるので、どうかお米券を使ってください」 [246620176]
- 【実況】博衣こよりのえちえちダンガンロンパ2🧪★1
- 高市早苗、森元総理の愛人だった [347751896]
- 【悲報】 世界最大級のポルノサイトPornHubの日本人ユーザーの年齢層、ヤバ過ぎる [303493227]
- 【高市朗報】中国、歴史上日本に一度も侵攻したことがない親日国だった [931948549]
- 新たなる弱男判定法見つかるwwwwwwwwwwwwwwwwww
