- C++相談室 part138
808 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 00:08:53.58 ID:x6gTDhtk0 - 糞使えなかった do-while 文だが、最近使えそうなところに遭遇した。
が、結局スコープの問題で使えなかった。コード構成は以下と同じ。 do { Type value(GetCurrentValue()); Process(value); } while (condition(value)); // https://stackoverflow.com/questions/13297243/why-is-whiles-condition-outside-the-do-while-scope ここで上記の筆者も言っているが、do-whileのスコープって使えないよな?(設計としてよくない) そこで他言語でこのスコープが直っている物を知らないか? 最有力としてはC#だが、試したが駄目だった。 (スコープはCと同様、そしてdo-while自体がレア https://ufcpp.net/blog/2016/12/tipsdowhile/ ) Rustは do-while ループを廃止したらしい。Goはwhile文自体を廃止している。 言語設計としての一貫性は重要として、 for文がスコープを拡張しているのに、do-whileがスコープを拡張してないのは間違いのように思う。 というか、do-whileが使えないのってこのスコープ設計が間違っているからであり、 正しくスコープが拡張されていれば有効性はあったように思うが、どうか? while (true) { if ... break;} より1行短く書けるメリットもあるが、 それ自体ではなくく、その形式のループを全部do-whileにすることにより可読性が上がる。 違う言い方をすれば、 while ループでの頻出形式を for に纏めたのと同じく、 必ず一度は実行し最後に break する形式の while ループを全て do-while にすることにより識別しやすくなる。 もっとも、JaveScriptに慣れた状況だと、最早ブロックスコープイラネとも思えてきたが。 ブロックスコープだとどうしてもこういう状況等で宣言型(変数の宣言と同時に常に初期値を代入し、必要なければ再代入をしない)で書けない。 関数スコープの問題は関数を小さくすることによりほぼ回避出来るので。 (JavaScriptは全ての関数がクロージャを持つので、C言語でのループは常に関数内関数としてそのまま切り出せる)
|
- C++相談室 part138
816 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 08:14:01.65 ID:x6gTDhtk0 - >>821
見やすさなら従来通りの do-while がいい。問題はスコープなだけで。 do { bool flag = ... } while (flag); 頭でflagを確定させられる場合は、これはいわゆる従来記法 while ((line = sr->Readline())!=nullptr) { ... } とほぼ等価になる。が、(本来の)今風なのは上側の do-while だと思う。 なおfor文で do-while はGoがやっていて、 for (bool flag=true; flag; flag = update_flag()) { } の構成らしい。ただこれは見る限り駄目だろ。 ただし確かに実行コードとしては、頭の条件判定が抜けるだけでしかない。 以下を見れば一瞬で「絶対に一度は入る」とは分かるから、 コンパイラが最適化してくれるのなら、行数が1行増えること以外には問題はない。 が、俺はこの1行にもこだわりたいんだが。 while (1) { ... if (condition) break; }
|
- C++相談室 part138
818 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 08:46:39.98 ID:x6gTDhtk0 - >>817
現実的には俺もそうしている。 ただ、最近は、「こう書ければな」と考えながら書くのが重要なのだと思うようになった。 少なくとも、DI(Dependency Injection)とかの問題は自然と回避出来る。 そこでコードを見てて、ふと思ったわけだ。 この if 文、do-whileのスコープが正しければ削除出来るよなと。 ただ、他言語も特に対応していない状況であれば、今現在は コンパイラに任せて、ユーザーはど定番の記述を書け、ということなのだろう。
|
- C++相談室 part138
823 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 11:14:39.14 ID:x6gTDhtk0 - >>819
結局お前の意見は何なんだ? 俺の意見は、「do-whileはforと同様にスコープを{}の外まで拡張すべきだった」というものだ。 つまり、再記するが以下の書き方が出来るのが『正しい言語』と考える。 do { bool flag = ... } while (flag); 現行のC言語では、for文以外はスコープを {} 内に物理的に配置したものに限定しており、 for文だけ例外的に ()までスコープを拡張している。 C++17でif文とswitch文も拡張された。 https://cpprefjp.github.io/lang/cpp17/selection_statements_with_initializer.html なら何故 do-while もそうしなかったのか?という話だ。 俺はC++23に期待するが。
|
- C++相談室 part138
830 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 12:40:35.62 ID:x6gTDhtk0 - >>824,825
なるほど、提案しろと言うのはごもっともだ。 しかし俺は仕様を提案するほどには仕様に詳しくないからパスだな。 そして確かに同様の人が多いというのは認める。 >>829 それは俺も以前考えた。 Cのマクロはそこでしかパース出来ないので、前に出す事が出来ず、限界がある。 (例えばdo-whileブロック内のflag宣言をwhileよりも前に出すことができない) そしてそれでも無理矢理やるならいっそのことPython等での自前パーサを先に通すほうがまし、という結論に達した。 そして一部それを既にやっている。 (俺は使ってないが)何だかんだでmakefileが融通が利くのはこういう点でもある。 そして自前パーサで全く別のように見える記述になってきたら、新言語の完成、というわけだ。 C++も同様だったと聞いているし。
|
- C++相談室 part138
836 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 16:21:38.04 ID:x6gTDhtk0 - >>831
すまんがそのコードの意味はよく分からない。 >>834 それはマクロにすることが目的で、見やすいコードを書こうとしていないので、 FAQでなくても止めろと言われて当然だ。 マクロも当然ながら見てすぐ分からないといけない。 この意味ではlinuxのコードが参考になるだろう。 小文字マクロが大量に使われていて、それでも何とかなってる。 逆に言えば、小文字マクロ=関数だと勘違いしても問題ない範囲で使え、ということだ。 どう変換されるかぱっと分からないマクロは逆に読みづらくなる。 ただまあ、ifとswitchの取り扱いからすると、 C: for文が例外で、他は{}がスコープ C++: do-while文が例外で、スコープを開始出来るキーワード(for/switch/if)ではキーワード部分までスコープに含める という状況なので、do-whileのスコープも拡張されるのは時間の問題だとも思うが。
|
- C++相談室 part138
838 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 19:17:52.66 ID:x6gTDhtk0 - >>837
ゆとり死ね > みんなわかってることを長々書く人 何度も言っているが、お前らゆとりが駄目なのはそういうところだ。 ここで話すのに「俺の人格」なんて全く関係ないし、実際今のところ気にしてた奴なんていないだろ。 お前以外は全員、技術面にフォーカス出来ている。 ゆとりが駄目なのは、結局、こうやって場を一々ぶち壊していくことだ。 結果、ゆとりゴキブリが一匹でも入り込める場は全部ぶち壊されていく。 その結果、ゆとり自身の居場所が無くなっているというのが、現在のお前らを取り巻く状況だ。 お前らゆとりはネット上では何を言ってもいい、何をやってもいいと勘違いしている。 そうじゃない。 自由に意見は言っていいが、コミュニティに対する破壊活動は許容されない。 そしてお前らは何がそれに該当するのかさっぱり理解出来ていない。 しかしお前らはネット慣れしていると勘違いしているからかそれを認めることすら出来ない。 お前らは本当に救いようがない。 おそらくはネットが出現することによって、リアルが希薄になり、 結果、リアルでのコミュニティ(人間関係)を構築することが不得手になっている。 しかしそれは当然ネット上にも適用/応用出来るものであり、結果、ゆとりはコミュ障となっている。 ところがゆとりは誰かがネット上で形成したコミュニティにただ乗りして来れているから、その問題にも気づけない。 それが「コミュ力」とか言われた問題の本質だよ。 それ以前の世代では否応なしに必要とされた最低限の「コミュ力」がゆとりにはない。 (ただしこの意味ではコミュ障害でも生きていける社会に改善された、と考えることも出来るが) お前の発言によって、コミュニティがどう動くか、少しは考えてから物を言え。 そうじゃないからお前らゆとりはお前ら自身で形成したコミュニティを持てないんだよ。 それにすら気づけないのだろうけど。
|
- C++相談室 part138
841 :デフォルトの名無しさん (ワッチョイ ff7b-x173)[sage]:2019/12/14(土) 20:47:22.30 ID:x6gTDhtk0 - >>840
StackOverflowの質問の筆者もそうだが、技術的にはやれば出来る程度の問題のはず。 あとは言語としての一貫性(={}をスコープとする)をどこまで厳密に適用するかだ。 ただ俺はこれがおかしな仕様のまま残されていることが奇妙だと思っている。 Cはほぼ変化する気がないからともかくとして、 Cの駄目なところを改善している他の新しい言語(C#等)でもそのままなのに驚いた。 ただ、ifやswitchまで拡張されたのなら、whileもそうだな。 現行 String^ line; while ((line = sr->Readline())!=nullptr) { ... } 次?(もしかして今ももう出来る?) while ((String^ line = sr->Readline())!=nullptr) { ... } 駄目だ駄目だと言われている条件式内での代入も、カンマ演算子も、上手く使えば美しく書けることに気づいた。 そして駄目だと言われているのは「白黒端末」前提であり、実は 「条件式内で代入演算子を用いた場合、太字にする」とかIDEのサポートがあれば問題ない気がしてきている。 つまりは、見た目気づきにくいから駄目なだけであって、見りゃ分かる、なら問題ないからだ。 だからコーディングルールもカラー端末大画面前提でのルールに変えていくべきなんだよな、とも。
|