C++相談室 part148

■ このスレッドは過去ログ倉庫に格納されています
2020/01/31(金) 20:54:06.26ID:Nt0XFA2s
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part147
https://mevius.5ch.net/test/read.cgi/tech/1576659413/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
2020/02/01(土) 18:08:11.40ID:6nnXKMBq
>>55
C++ ではオブジェクトの寿命の管理と辻褄を合わせなきゃならないんだから full continuation は無理だぞ。
2020/02/01(土) 18:09:32.76ID:YFAnTUnh
継続とは?
2020/02/01(土) 18:12:05.70ID:YFAnTUnh
setjmp のことか
59デフォルトの名無しさん
垢版 |
2020/02/01(土) 18:12:34.25ID:Bc9LjLbW
ループに名前を付け、その名前で離脱や継続を行う。

ループA {
60デフォルトの名無しさん
垢版 |
2020/02/01(土) 18:16:20.88ID:Bc9LjLbW
途中で送信してしまった。面倒だから書き直さないが、
breakやcontinueはキーワードが紛らわしいのでPerlのlastとnextを拝借する。
last ループA; とか next ループA; みたいな感じ。
2020/02/01(土) 18:16:45.14ID:YFAnTUnh
わざわざ名前を付けるならgotoで良いんでは?
2020/02/01(土) 18:18:49.32ID:vKrtBnhX
gcc5ぐらいから一気にgcc10にしたらエラー表示とかデフォルトの警告とか色々変わっててわろた
63デフォルトの名無しさん
垢版 |
2020/02/01(土) 18:19:46.95ID:Bc9LjLbW
>>61
まあね。だけどgotoはフリーダムすぎて良くないでしょ。
2020/02/01(土) 18:34:11.57ID:YFAnTUnh
いや全然そう思わない
gotoで何か不都合がある?
2020/02/01(土) 18:52:41.69ID:pUJoLXPw
>>52
コンパイラ毎の最適化における癖とか、例外の実装についての差異なんかも語ってもいいんだぞ。
2020/02/01(土) 18:56:33.52ID:6nnXKMBq
>>63
goto は自由すぎるけども、ループを何段階も一気に抜けたいとかいう状況がすでにだいぶん自由だと思うぞ。
そういう状況が生まれたらもう駄目なんだよ。
ごちゃごちゃとした使い分けを考えるよりおとなしく goto した方が「そこが悪い」ってのが目立って良い。
2020/02/01(土) 19:01:47.00ID:YFAnTUnh
一番使いたいのは2段break
行列や画像など2次元構造では当たり前のように2重ループになる

2重ループを抜けたい状況は設計が悪い
と思う感覚が全く理解できない
2020/02/01(土) 19:01:49.68ID:TULylXcw
構造化を壊さないことを保証した仕組みで脱出したいってことでしょ
2020/02/01(土) 19:04:12.92ID:YFAnTUnh
2次元構造の2個のループを抜ける為に
非常に関連のある2個のループを別関数に分ける

この方が設計が悪い
というのがおれの感覚
2020/02/01(土) 19:07:14.52ID:JWECbGc7
>>67
gotoは悪、多重ループは悪、みたいなどこかで聞いたルールを杓子定規に常に遵守すべき絶対ルールのように考える人が少なからずいるんだろうね。声が大きいだけかもしれないけど。
2020/02/01(土) 19:09:12.42ID:PjJtYhAX
gotoの利用にコンパイラの補佐があればよかったのに
2020/02/01(土) 19:10:50.63ID:PjJtYhAX
中カッコ、変数の有効範囲含め
スコープ内に飛び込むジャンプを一切禁止、前方のみと決めれば
なかなか直観的でわかりやすいキーワード
だとおもうのに
2020/02/01(土) 19:19:24.65ID:YFAnTUnh
一切禁止とか言うから
それが絶対だと初心者が思って思考停止する
この典型がgoto

使った方が良い時は使う
再帰も生ポもグローバル変数も多重継承も多重ループも
2020/02/01(土) 19:25:00.72ID:6nnXKMBq
>>67
ここでワイが「悪い」って言ってるのは使うなとか別の方法がとれるとかいうほどの強い意味じゃなくてさ、
気を付けなきゃならないポイントとして目立ってもらわなきゃ困るって程度の意味。

だけど、日常的にそこら中でそういうポイントがあるのならやっぱり悪いとは思うけど……。
2020/02/01(土) 19:26:16.45ID:j/qpVk5O
二重ループの脱出は
[&]{
for(){
 for(){
  return;
 }
}}();
で結論出たはずだが
2020/02/01(土) 19:29:49.61ID:YFAnTUnh
これはひどい
2020/02/01(土) 19:44:49.47ID:PjJtYhAX
それオーバーヘッドかからんの?
2020/02/01(土) 19:47:58.86ID:j/qpVk5O
関数オブジェクトはまともなコンパイラならインライン展開される
2020/02/01(土) 19:48:45.53ID:7G0Z2VlM
贅沢言いすぎだね
素のPascalなんてreturnすら無いからね
もはやどうやってプログラムを書いたらいいか分からないレベル
2020/02/01(土) 19:53:54.21ID:7G0Z2VlM
Pascalは完璧な構造化言語を目指したから
入口と出口を常に一つずつにするというポリシーがあって
それゆえreturnが無いんだよね
returnがあると出口があちこちに散らばるので
構造化じゃない、汚い、という考え

なお、breakは有るもよう
2020/02/01(土) 19:58:58.33ID:+WgC03YT
[&]{
try{
for(){
 for(){
  throw 0;
 }
}catch(...){}
}}();
2020/02/01(土) 20:02:08.79ID:6nnXKMBq
抽象的なレベルで考えたら break は
「残りの文が if 式で囲まれていると見なして暗黙のフラグを設定する (そのフラグは暗黙にループの終了条件でもある)」
とも考えられるから、構文糖だといえば構造化は壊れていない。

だけどなぁ、プログラムは人が書くものだし、人にとってどう見えるかも大事なんだよな。
そこらへんは見方によってどうとでも理屈を付けられてしまう。
2020/02/01(土) 20:04:46.46ID:+WgC03YT
[&]{
try{
for(){
 for(){
  throw 2;
 }
}
}catch(int d)
{printf("%d段階ジャンプしたお¥n",d);}
}();
2020/02/01(土) 20:10:07.66ID:tav2AwxI
>>82
break 2 も gotoでループを抜けるのも同じ
2020/02/01(土) 20:24:42.41ID:iBA7Xa3w
>>83
それは最悪
throw 3; って書いてもチェックされないし
2020/02/01(土) 20:47:35.89ID:BhmlSyWc
>>67
3重ループは? 4重ループは? なんで2だけなの?
2020/02/01(土) 20:52:34.51ID:TULylXcw
たまに国語力が心配になるやつがいるよな
2020/02/01(土) 20:53:59.21ID:+WgC03YT
[&]{
try{
for(){
 for(){
  throw "リレミト";
 }
}
}catch(const char*s)
{printf("%sの呪文を唱えた¥n",s);}
}();
2020/02/01(土) 20:56:56.11ID:BhmlSyWc
>>87
答えられないならレスしないで下さい
ウザいだけです
2020/02/01(土) 21:07:19.54ID:vKrtBnhX
for () {
for () {
goto done;
}
}
done:

どう考えてもこちらのほうが綺麗
2020/02/01(土) 21:09:23.19ID:BhmlSyWc
>>90
だな
必要になったことを変に偽装する悪癖を治すべき病人多すぎ
2020/02/01(土) 21:14:53.51ID:6nnXKMBq
ほんまになぁ。
そんな簡単なことをラベル付き break だのなんだのって面倒なだけとしか思えぬ。
もう構造化は破綻してるんだからおとなしく goto しとけよな!
2020/02/01(土) 21:19:44.00ID:dP/tym/A
>>89
日本語が不得意みたいなので英語で説明しますね
Double loop frequently appears to treat a two dimension structure such as matrix or image data,
so "break from double loop"is used by programmers related mathematical or visual product.
>>67 states that is good reason and s not always bad design.
2020/02/01(土) 21:22:30.66ID:BhmlSyWc
>>93
意味わかんね
なんでそんなことするの?
アホだから? それともバカだから?
2020/02/01(土) 21:25:42.92ID:dP/tym/A
>>94
It's purely kindness for non-Japanese speaker. Did you not like it?
2020/02/01(土) 21:26:06.76ID:tav2AwxI
>>92
構造化的には
breakも途中でreturnもgotoでループを抜けるのも同じだよ
2020/02/01(土) 21:26:27.45ID:BhmlSyWc
Пожалуйста, говорите по-японски.
2020/02/01(土) 21:29:34.25ID:dP/tym/A
なんだロシア人か
Я не понимаю >>67, потому что я не понимаю японский?
2020/02/01(土) 21:32:56.91ID:tav2AwxI
2020/02/01(土) 21:34:56.10ID:6nnXKMBq
>>96
同じだからそれ以上に新しい文法を持ち込んでもそれほど綺麗にならんって! ということを言いたい。
2020/02/01(土) 21:36:54.68ID:BhmlSyWc
>>98
Mimi ni Kijapani.
2020/02/01(土) 21:38:38.94ID:TULylXcw
>>96
gotoは正しく使えばという但し書きがつくでしょ
そこをなんとかしたいという話だと思ってる
それが論点だとするとgoto使えというのは解にならない
2020/02/01(土) 21:40:19.97ID:BhmlSyWc
>>96
ほんこれ
2020/02/01(土) 21:42:54.84ID:tav2AwxI
>>102
正しく使う前提なのは当たり前
なんでgotoだと正しく使わない前提になるのか不思議
2020/02/01(土) 21:43:54.40ID:BhmlSyWc
>>104
ほんこれ
2020/02/01(土) 21:48:36.93ID:7G0Z2VlM
危ない操作はできないようにしようってのが言語の進化だからな
それ無視して、安全に使うのが前提とか、正しく使うのが前提とか、それ言っちゃね
なんかおかしな方向へ行くよね
2020/02/01(土) 21:48:59.21ID:TULylXcw
>>104
構造化プログラミングの概念は知ってるんだよね?
2020/02/01(土) 21:50:07.81ID:7G0Z2VlM
gotoを正しくしか使えないように改良したのがreturn、break、continue
ってことも忘れずに
2020/02/01(土) 21:54:44.41ID:BhmlSyWc
>>104
構造化プログラミングでは使わない制御構造を
使うべきでない理由が構造化プログラミングって論法に
抜け出せない枠があるとは思わないの?

>>108
continueだけ、それで正解なんだが
他はみんな間違ってるよ
2020/02/01(土) 21:57:47.27ID:7G0Z2VlM
見てください皆さん、ID:BhmlSyWc ← ひどいですよ
まず何言ってるか分からない
このレベルはきついな
2020/02/01(土) 22:02:32.59ID:tav2AwxI
>>106
どの辺からgotoが危ない操作だと思うの?
2020/02/01(土) 22:06:43.33ID:vKrtBnhX
まあ1万行ある関数の中で、5千行目ぐらいにgotoがあって、ラベルが関数の先頭付近にあるとか、それに近いのは見たことあるが、あれはどう考えてもgotoの悪い例だからな
包丁で味噌汁食ってるようなもん
2020/02/01(土) 22:06:57.37ID:BhmlSyWc
>>110
きつくて気の毒だな
不勉強なやつは自業自得なので同情はしない
2020/02/01(土) 22:08:59.52ID:BhmlSyWc
>>112
1万行か・・・これ↓より重症だなw
http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.10.4.html
2020/02/01(土) 22:11:31.06ID:tav2AwxI
不定値や無限ループの危険はgotoに限ったことじゃないし
ループを抜けるgotoには関係ない話

goto特有の危険な場面
何を心配してるんだろう
酸っぱいブドウ?
2020/02/01(土) 22:16:09.36ID:TULylXcw
だめだこりゃ
2020/02/01(土) 22:19:01.58ID:7G0Z2VlM
gotoはどこへ飛ぶか分からないから読みにくいんだよ
前に飛ぶのか、後ろに飛ぶのか、それすら分からない
飛び先を分かりやすく改良したのがreturn、break、continue
それぞれ飛び先が決まっているから追うのが楽
その英知が分からんっていうならreturn、break、continueを使わずに
全部gotoでやれば?って話
2020/02/01(土) 22:22:45.11ID:tav2AwxI
関数なんてもっとどこに飛ぶかわからんぞ
2020/02/01(土) 22:25:22.98ID:tav2AwxI
どこに飛ぶかわかる名前にするってのが普通の発想
意味でも構造でも文章でも好きな名前を付けられる

関数も変数も名前空間も全てそう
2020/02/01(土) 22:25:32.73ID:TULylXcw
gotoは中にも飛べるの知らないんじゃないこの人
2020/02/01(土) 22:25:55.92ID:BhmlSyWc
>>117
飛び先じゃなく飛ぶこと自体の問題なんだがw
2020/02/01(土) 22:26:20.90ID:7G0Z2VlM
つまりはそういう話で、追いやすいように飛び先を制限したいよねーってのが根底に有って
(当然そういうのが念頭にあってreturn,break,continueは生まれたわけで、前例に倣いたい所)
それでブロックに名前を付けるだのbreak 2だのって書き込んでいる人がいるわけで
gotoでいいんじゃね?っていうなら、return,break,continueもgotoでいいんじゃね?
むしろforやwhileもgotoでいいんじゃね?gotoを正しく使えばいいんだろ?ってなる
2020/02/01(土) 22:26:36.74ID:TULylXcw
構造化プログラミング知らずにgotoいきって使うのはさすがにやばい
2020/02/01(土) 22:28:23.87ID:BhmlSyWc
>>122
どうなっていれば「追いやすい」のかを
まず明らかにしようぜ

俺ルールでもいいし
広く認知されているルールでもいいし
2020/02/01(土) 22:31:09.71ID:7G0Z2VlM
巻数はどこに飛ぶか分からないが、必ず元に戻ってくる(のが基本)
行きっぱなしというか、ただのジャンプのgotoやらbreakやらとは違うのだよ
関数のコールは入口と出口が一つになってて非常に構造化されてる好例
こういうところ分からないってのはセンスないよ
2020/02/01(土) 22:32:56.84ID:7G0Z2VlM
巻数→関数
2020/02/01(土) 22:35:10.84ID:tav2AwxI
使い所でgotoが使えないのはセンス無い
使い所でgptoを使わないのはコードが見にくい
使い所でgotoを使わないのは危険なコード

goto否定派にレベルを合わせた主張をするとこんな感じ
2020/02/01(土) 22:42:27.15ID:TULylXcw
やっぱりこいつダメだな
知性がない
2020/02/01(土) 22:44:49.19ID:tav2AwxI
使い所でgotoを使わないのは知性が無い
2020/02/01(土) 22:45:34.37ID:7G0Z2VlM
本心では誰もgotoは否定していないんじゃないかな
今は多段breakの機能が無いんだからgotoを使えばいいだろう
しかし、もしgotoを使わないで済む多段breakの新機能があったのなら
それを使ったほうがいいだろうし
じゃーその新機能はどんなものが考えられるか?って遊びだろ?
ブロックに名前付けるだとかbreak nだとかは
2020/02/01(土) 22:50:41.91ID:wBNP08tW
多段breakは考えた奴は脳味噌が糞すぐる…
ループの深さを変えたとたんにバグるじゃん?
ループの深さは金輪際変えないとか
ループの深さを変えるとき必ずループ全体を机上確認するとかだったら
gotoでも逝けるじゃん??
2020/02/01(土) 22:53:08.37ID:vKrtBnhX
ああ、そうだな
break 2だとfor文が3重になったときにバグるな
個人的には面白いと思ったが
2020/02/01(土) 22:53:40.31ID:tav2AwxI
使い所は2次元構造の2重ループとかだよ
2020/02/01(土) 22:55:40.65ID:rsRLlL5x
画像処理とかで2重ループ良く書くけど、最近2段階breakしたくなった記憶がないな

実は要らないんじゃね
2020/02/01(土) 22:56:47.94ID:tav2AwxI
じゃあbreakもいらないんじゃない?
2020/02/01(土) 22:59:11.96ID:7G0Z2VlM
まーC++がプリプロセッサを殺すために進化しているのと同様
Cはgotoを殺すために進化したともいえるわけで
たとえば、関数、for、return、などなど、制御構造にかかわるほとんどの物が
gotoを殺すために有るといってもよい
だから、もっとgotoを殺すにはどうすればよいか、考えるのは自然な発想かと

C++でもテンプレートなどで出来ないことはプリプロセッサでしなければならないし
ただ、同じことがテンプレートとかで出来るならそのほうが良いだろうし
もっとプリプロセッサを殺すためにはどういう機能を追加すればよいか考えるのは自然な事だろう

同じ同じ
2020/02/01(土) 23:01:32.69ID:EspH/Y2K
goto とか break とか continue とか、他の言語(javaとか)でもいろいろ小手先的に弄られているけれども、それに何の意味があるのかいつも不思議におもいますね
C/C++ の goto とかはどう頑張っても関数の中でだけしか跳べないのだから、BASIC の GOTO ほどにはスパゲッティ状態を招けないのではと考えます
無論、その関数が異様にデカければ別ですが、そんなデカい関数を書くほうが問題であって goto が問題なのではないかと
2020/02/01(土) 23:11:38.33ID:tav2AwxI
ループを抜ける為にだけ使われる変数を使ったループ抜け
世の中にはたくさんこういうコードがある
たくさんのコードを見る機会がある人なら
たくさん見たことがあるはず

gotoネガティブキャンペーンのせいだよ
2020/02/01(土) 23:11:46.92ID:JWECbGc7
>>136
gotoが使わないで済むように進化してくのは期待している。
ただ現状として、多重ループを抜ける場合みたいにgotoを使うのがシンプルで分かりやすいならば、毛嫌いしたり盲目的に原則振りかざすよりgoto使えばいいだけのことだと思うよ。
2020/02/01(土) 23:32:29.85ID:TULylXcw
>>138
お前ほんとに病気だな
多重ループ脱出でgotoが簡潔なのはみなわかってる
でもgotoは自由度が高すぎて構造を壊す可能性があるわけ
だから改善するとしたら何があるかという話をしてるだけであって
別にgoto禁止とかの話はしてない
好きなだけ使ってろよ
あと構造化プログラミングぐらい知っとけ
2020/02/01(土) 23:45:45.20ID:tav2AwxI
>>140
色々と違う
2020/02/01(土) 23:46:54.20ID:vKrtBnhX
for () {
break label;
} label;

for () {
for () {
break label1
} label2;
} label1;

こういう風にfor文のお尻にラベルを付けられるようにすれば局所化したgoto風のbreakが使えるのでは
2020/02/01(土) 23:48:30.11ID:tav2AwxI
for () {
goto label;
} label:;

for () {
for () {
goto label1;
} label2:;
} label1:;
2020/02/01(土) 23:49:00.26ID:tav2AwxI
今でも出来る
2020/02/01(土) 23:49:30.89ID:wBNP08tW
Pythonはループにラベルをつける手が使えた
と思った(幻覚でなければ
2020/02/01(土) 23:52:18.24ID:pUJoLXPw
またgotoの話になってんのかよ。。
だからいっそ禁止にと思ったが、それよりもさらにクソな構文の提案が出てたり。。
想定を超えた馬鹿どもばっかりじゃねーか。
2020/02/01(土) 23:54:48.66ID:tav2AwxI
無理に会話に入って来なくて良いよ
2020/02/01(土) 23:59:22.03ID:7G0Z2VlM
ただ、凝りに凝った複雑怪奇なテンプレートより
シンプルに作ったマクロの方が読みやすいって事例も当然あるだろうよ
てか、わりと、最近、残念ながらその傾向が・・・で、C++が嫌われる理由にも・・・
だからgotoを殺すのも上手くやらないとむしろ酷くなる
そこが腕の振るいどころで面白い部分でもあるし、言語作ってる連中もそんなことで頭いっぱい
変なゲーム性が有って、逆にそれがまたダメな部分でもあって
あと、妹大好き
2020/02/02(日) 00:17:33.29ID:rWwvB4I9
多段breakの使用頻度がそれほど多くないことを加味すれば
break n;方式が妥当だろうね
これだと2重ループを3重ループに書き換えたときにバグる、とか
意味不明なことを言ってる奴もいるが
それは1重ループをbreakで抜けてたのを2重ループに書き換えたらバグった
と言ってるのと同じであって、当たり前の話だし、今でも同じことだ
break n;が一番シンプルで妥当だと思うね
2020/02/02(日) 00:32:21.06ID:7b/FZYuN
breakの後にマジックナンバーを書くのが気に入らない
定数には意味のわかる名前を付けたい
2020/02/02(日) 00:33:00.49ID:rWwvB4I9
ただし、break n;のnの部分が変数でもOKとかなってたらかなりウザいが
そこはnは定数と定めたいね、でもC++の場合は定数と言っても・・・
複雑にしようと思えばいくらでも複雑にできるわなー
普通に使う分には問題ないかと
明日からbreak n;が入っても、たぶん誰も困らないし、混乱も起きないだろう
割のいい賭けだし、俺はアリだと思うね
2020/02/02(日) 00:33:32.69ID:7b/FZYuN
breakとbreak nが同じとか意味不明な主張をなさる御仁がいらっしゃるが
じゃあcontinueがcontinue nになったらどんな地獄が発生するか
考えてみたら良い
2020/02/02(日) 00:48:04.23ID:rWwvB4I9
別にcontinue n;
全然ありでしょ
これと同等の事を、何か別の方法でやるよりスマート

for(;;){
 bool do_continue = false;
 for(;;){
  if(...){ do_continue = true; break;}
 }
 if( do_continue ){ continue; }
}



for(;;){
 for(;;){
  if(...){ continue 2; }
 }
}
2020/02/02(日) 01:00:22.64ID:7b/FZYuN
do {
 do {
  ...
  if (cond) {
   continue 2;
  }
 } while (副作用の有る式1);
} while (副作用の有る式2);
とから?
2020/02/02(日) 01:03:23.27ID:0Gqmr542
break nなんてやるくらいならbreak label で抜けるループを明示的に指定したいな

ループにラベルをつけるとして、先頭では見づらくて邪魔だな

ループの末尾にラベルを付ければ見やすいけど、それだとlabelついたループを抜けると言うよりlabelの指す位置へのジャンプだな

なんだgotoでいいじゃん

個人的には breakto label という記法でループ出口に書いたラベルに飛べるとするのが分かりやすいと思うけど、こんなことに新しい予約語を導入するくらいならgotoで十分だと思う。
■ このスレッドは過去ログ倉庫に格納されています