C言語の設計ミスった危険な関数トップ10決めようぜ

2019/11/21(木) 12:23:44.93ID:T7Jjyyy1
gets関数とか

その他の例
https://www.jpcert.or.jp/sc-rules/c-msc24-c.html
2019/12/15(日) 06:50:28.91ID:6aWNd1w0
>>58
ネストの数を数えるとか最低だと思う
2019/12/15(日) 07:00:06.17ID:a0yEED8b
1000行のコードでbreak 7;とかされても、
どこに抜けるかわからんよな!
2019/12/15(日) 09:51:38.77ID:5sPbacoo
ネストの数がわからないような巨大な構造は
それだけで最低だ
そんなんだと名前付きループにした所で
@outerなんて名前が使い回されて
同じ名前のループがネストされて
それこそ難読コードになる
それならユニークなラベルによるgotoの方が良い

>>57くらいのループなら
break 2;
は名前を考える手間が無くて楽だし
見にくくもない
2019/12/15(日) 09:57:28.64ID:5sPbacoo
とは書いたけど
どっちも有るならどっちも欲しい

どっちかだけげならbreak 2;の方が欲しい
って感じ
2019/12/15(日) 10:52:04.89ID:6aWNd1w0
>>61
> そんなんだと名前付きループにした所で
> @outerなんて名前が使い回されて
> 同じ名前のループがネストされて
> それこそ難読コードになる
無能の妄想w
2019/12/15(日) 11:05:09.82ID:5sPbacoo
ループの先頭、ループの終わり、break部分
3箇所見ないとダメってだけでダメな仕様
2019/12/15(日) 12:32:17.60ID:bDjAMWVj
>>64
なぜか自分の前提は
> >>57くらいのループなら
なのにラベルにした途端にループの頭とbreakとループの終わりが一瞥でわからないとかアホすぎ
2019/12/15(日) 12:36:08.74ID:5sPbacoo
大きければgoto
小さければbreak n
2019/12/15(日) 12:38:50.49ID:5sPbacoo
名前を付ける手間を許容するならgotoという解決法が既にある
68デフォルトの名無しさん
垢版 |
2019/12/15(日) 13:48:44.02ID:o9m7qUoD
>>60
ネスト変わるような変更あるたびにbreakの引数勝手に書き換えてくれるエディタとかマクロが流行る
2019/12/15(日) 16:33:57.62ID:bDjAMWVj
>>67
ifとgotoあるからforもwhileもdoも要らんという主張か
本物のプログラマーだなw
2019/12/15(日) 16:52:03.21ID:u46gpj2V
歪んだ教育のせいで
gotoに拒絶反応を示す人が多いんだよな

2重ループを抜けるなら素直にgotoを使えって
2019/12/15(日) 16:53:29.68ID:pTp+dpJs
アセンブラの
jmp 1f
とかを C でやりたいという話なのか?
やってみりゃいいじゃん。プリプロセッサの出力を処理すればいい。
1 パスで出来ると思うよ。
ひょっとしてもう誰かがやってるかも。
2019/12/15(日) 18:05:59.04ID:5sPbacoo
for (i = 1; i <= 3; i++) {
  for (j = 1; j <= 3; j++) {
    printf("%d, %d\n", i, j);
    if (i * j > 3) goto outer;
  }
} outer:;
2019/12/15(日) 18:58:38.98ID:5sPbacoo
for (i = 1; i <= 3; i++) {
  for (j = 1; j <= 3; j++) {
    printf("%d, %d\n", i, j);
    if (i * j > 3) goto outer;
  }
}
printf("complete\n");
outer:;
2019/12/15(日) 19:01:19.97ID:5sPbacoo
わざわざ言語拡張しなくても
>>57以上の事が実現出来る
2019/12/16(月) 09:05:52.89ID:AI1GDY0I
ラベルのスコープを狭くしたいという話のようだから
マクロの中で使ってこそ真価を発揮するんじゃないかな。
フル仕様のパースが必要というわけではなく、かなり手抜きできそうではある。
あれば便利というのは否定しないが、C でそこまで必要かというと…
76デフォルトの名無しさん
垢版 |
2019/12/16(月) 12:33:03.93ID:0jmxiGrg
{
goto hoge;
hoge:;
}
{
goto hoge;
hoge:;
}
これで二重になってたら困るしある意味なってなくても困るな
2019/12/16(月) 13:21:05.83ID:ZZ8St2Js
マクロで二重以上のループってのもなかなか考えづらいなあ

一応、ラベル名をパラメータとする手もある

使う側のコストを考えるとgotoの為にパラメータを増やさないよな
gotoを使わない主義者がよくやってるように
余分な変数を使って実装するんだろうね
2019/12/16(月) 13:23:11.26ID:ZZ8St2Js
アセンブラだとマクロローカルラベルってのがあったりする
ラベルを頻繁に使うので

あと
@@/@b/@fのように、
直近のラベルを指定する仕組みもある
2019/12/16(月) 13:28:49.41ID:ZZ8St2Js
>>72 >>73 みたいなのって
gotoの使いどころだと思うんだけだ
gotoを使わない人はどう書いてるの?

特に >>57 の答えを聞いてみたい
2019/12/16(月) 15:17:28.75ID:arH1mwfY
void print_data(void) {
 for (i = 1; i <= 3; i++) {
   for (j = 1; j <= 3; j++) {
     printf("%d, %d\n", i, j);
     if (i * j > 3) return;
   }
 }
}
print_data();
printf("complete\n");
2019/12/16(月) 16:34:59.64ID:/0yHEQmX
outer より後に処理が続く場合は?
2019/12/16(月) 16:51:44.02ID:arH1mwfY
void print_data(void) {
 for (i = 1; i <= 3; i++) {
   for (j = 1; j <= 3; j++) {
     printf("%d, %d\n", i, j);
     if (i * j > 3) return;
   }
 }
}
print_data();
outer より後に処理が続く場合
printf("complete\n");
2019/12/16(月) 16:55:03.26ID:arH1mwfY
"短い処理"をいちいち関数にしなくて済むから、break 2とかはあってもいいが、
長い処理は関数にしてないとろくにテストできないんだからgotoなんていらない
2019/12/16(月) 19:03:13.17ID:4DgO9d+i
じゃあ>>57もいらないね
2019/12/16(月) 19:09:09.12ID:lsrBHsJG
gotoの基本的な使い方くらい知っておいた方が良いかと
ループを抜ける為だけに関数を分けないといけなくなるし
挙げ句の果てに言語の欠陥とか言い出す
2019/12/16(月) 20:06:51.00ID:3ha1TSe5
今のC言語ではネストしたループから抜けるのはフラグを使うかgotoしかないからたいていgoto使ってるけどgotoなんて野蛮なものはできたら使いたくないから他の言語で実装されてるラベル付きbreakなりレベル付きbreakが欲しいって話だろ
今更gotoの基本的な使い方ガーとか言ってる奴はどんだけ低レベルなんだよw
2019/12/16(月) 20:09:28.82ID:xr9KOlE0
あれ?
returnで抜ける為に関数に分けるんじゃなかったの?
2019/12/16(月) 20:21:09.65ID:xr9KOlE0
gotoは野蛮とかいう歪んだ教育のせいで
わざわざ変数を定義したりわざわざ関数を分けたりして
わざわざ見にくいコードにしちゃう

生でポインタを扱う野蛮なC言語なんか使わないで
上品な言語を使った方が良いよ
2019/12/16(月) 20:28:02.60ID:jL52ryYk
gotoじゃなくてgodowntoなら誰も文句言わなかった
2019/12/16(月) 20:47:58.36ID:LjjtFzBx
自分は小規模な字句解析みたいなのでもgoto使うことがある。
ラベルで状態を表してgotoで遷移する。
goto使わなかったら状態を変数に入れて、
ループの中でswitchで場合分けするようなコードになって辛い。
2019/12/16(月) 20:52:55.59ID:DbnQVwfE
ループの中のswitchでループを抜けるのに
gotoを使うんじゃ?
2019/12/16(月) 21:41:34.22ID:wRV+mRkt
次の状態を返す関数ポインタでループすればいんじゃないの?
2019/12/16(月) 21:45:33.24ID:jhycq5nX
そんな野蛮なことはしません
2019/12/16(月) 22:12:14.62ID:arH1mwfY
>>87
returnで抜けるためというか、

1. gotoで抜けたい
2. 関数にするか
3. あ、そもそもコードが複雑なんだな
4. 関数にして正解だった

こんな感じかな。

gotoで抜けたいと思う=コードが複雑になってるという警鐘だと思ってる。
2019/12/16(月) 22:22:18.57ID:xr9KOlE0
>>82みたいな意味不明な関数の分け方をすると
>>57は、より複雑な記述をしたいっていう主張だし

gotoに親を殺された人の言うことは支離滅裂
理由が後付けだからそうなる
2019/12/16(月) 22:27:34.28ID:arH1mwfY
> で>>82みたいな意味不明な関数の分け方をすると

なんで意味不明?
そもそもその処理に意味をもたせてから言おうよw
処理に意味をもたせると、関数にしたほうが良いと思うからさ
2019/12/16(月) 22:32:01.57ID:arH1mwfY
> 理由が後付けだからそうなる

質問の方が先なのに、理由を先に言えるわけがないw

Q. 多重ループから抜けるのに、gotoは必要ですか?
A. 必要ありません。多重ループが必要になるぐらい複雑なら関数にしますから


これが普通だから、後付にはならないよね。
2019/12/16(月) 22:37:09.13ID:xr9KOlE0
じゃ>>57も当然不要ですね
2019/12/16(月) 22:38:17.80ID:arH1mwfY
そんなにくり返し言わなくても、最初から不要だしw
2019/12/16(月) 22:39:57.37ID:xr9KOlE0
じゃあ>>57はどういうつもりで書いたんでしょうかね?
2019/12/16(月) 22:40:50.59ID:LjjtFzBx
gogoサイコーっす
2019/12/16(月) 22:41:03.68ID:LjjtFzBx
間違えたw goto
2019/12/16(月) 22:42:13.32ID:xr9KOlE0
話を戻して

・ループを抜けた後に関数の後処理が必要な場合
・ループを抜けた後にローカル変数を使った処理をする場合
・他、意味的に関数内で処理したい場合

はどうするの?
2019/12/16(月) 22:44:03.17ID:arH1mwfY
> ・ループを抜けた後に関数の後処理が必要な場合
前処理を関数の中でするな

> ・ループを抜けた後に関数の後処理が必要な場合
戻り値を返せ

>・他、意味的に関数内で処理したい場合
自分で具体例が思いつかないなら出すな
2019/12/16(月) 22:45:01.13ID:arH1mwfY
コピペミスったな

>・ループを抜けた後にローカル変数を使った処理をする場合
戻り値を返せ
2019/12/16(月) 22:48:10.00ID:xr9KOlE0
>>104
なぜ?
2019/12/16(月) 22:52:22.49ID:arH1mwfY
>>106
なにが?

ってか、もう少し具体例を書けよ。
それみれば設計がおかしいという結論になる

例えて言うなら、パーサーの処理の中でネットワークにアクセスしたい時困るから
ネットワークモジュールはグローバルにアクセスできるようにしておくべき
みたいなことを言ってるようなもんだよ。それは設計がおかしい。
2019/12/16(月) 22:54:10.44ID:xr9KOlE0
int func(int n){
ロック
ループ
アンロック
return 結果;
}
2019/12/16(月) 22:55:55.89ID:xr9KOlE0
int func(int n){
ループ
値を加工
return 値
}
2019/12/16(月) 22:58:13.41ID:arH1mwfY
>>108
「ループ」という言い方がおかしい。
ループで「実装」しているのであって
やっているのはなにかの「処理」だろう?


int func(int n){
ロック
処理
アンロック
return 結果;
}


「処理」という名前をつけたくなるならば、
そこは独立した関数にするべきだろう
2019/12/16(月) 23:02:27.04ID:xr9KOlE0
double sigma(const double *a){
ループで総和と2乗和と数を計算
標準偏差を計算
return 標準偏差
}
2019/12/16(月) 23:04:47.03ID:xr9KOlE0
int func(int n){
int a[10] = {0};
ループ
aから値を計算
return 値
}
2019/12/16(月) 23:06:46.75ID:xr9KOlE0
いくらでも思い浮かぶ
2019/12/16(月) 23:07:37.81ID:LjjtFzBx
全部関数に分けろって言われて終わりそう
2019/12/16(月) 23:09:19.22ID:xr9KOlE0
分ける理由がない
2019/12/16(月) 23:10:06.65ID:xr9KOlE0
>>112を分けてみて
2019/12/16(月) 23:17:03.74ID:xr9KOlE0
関数分けってのは意味、機能、汎用性、...で分けるべきであって
単にループを抜けるのにreturnを使いたいから分けるとかを考えるべきじゃない
2019/12/16(月) 23:23:11.90ID:xr9KOlE0
素直にgotoの使い方を覚えた方が良いよ
意地はってないで
2019/12/16(月) 23:42:01.03ID:arH1mwfY
>>118
だから意味とか汎用性とかで分けると
自然にループに抜けるときにreturnを使えば良くなるんだよ
2019/12/16(月) 23:45:51.39ID:jL52ryYk
gotoでもreturnでも読めれば良い
但し1関数50行以上は読めないんで宜しく
2019/12/16(月) 23:48:10.14ID:arH1mwfY
>>112
だから「ループ」と書くなっちゅうねんw
関数を設計するならこんな感じやろ?

int func(int n){
int a[10] = {0};
memset_random(a, sizeof(a)); // a配列をランダムな値で埋める
int chksum = chksum(a, sizeof(a)); // a配列のチェックサムを計算
return 値
}

関数の中でループしてようが何して用が関係ないわ
2019/12/16(月) 23:55:19.85ID:xr9KOlE0
sizeof(a) とか書くレベルの相手してたのか
アホらしい
2019/12/17(火) 00:04:36.92ID:JvBVW/sd
>>119
じゃあ普通のbreakもいらないね
まさか使ってないよね
2019/12/17(火) 06:41:54.53ID:YMIUnRyv
まあgotoあればbreakは要らんわなw
そんな言語は使いたくないけど
2019/12/17(火) 07:00:38.11ID:JvBVW/sd
gotoもbreakもいらないって
2019/12/17(火) 07:10:23.36ID:JvBVW/sd
gotoもbreakも無い
ループを抜けるときはreturn
switchを抜ける時もreturm
関数は単一の処理しか出来ない

こんな言語はイヤだね
2019/12/17(火) 07:23:38.89ID:JvBVW/sd
後に退けなくなったアホの作る言語
2019/12/17(火) 07:39:52.35ID:odSFZTU+
gotoの使い方

http://www7b.biglobe.ne.jp/~robe/cpphtml/html03/cpp03005.html
http://www9.plala.or.jp/sgwr-t/c/sec06-6.html
http://tomeapp.jp/archives/1029
http://opencv.jp/opencv-2svn/c/core_utility_and_system_functions_and_macros.html
2019/12/17(火) 08:49:57.51ID:QeraReD1
たとえ相手がアホであっても、しつこく絡むのもまたアホだと思うんだが…
2019/12/17(火) 12:33:06.04ID:vDeQfs2U
自分より下の人間を叩くしか能がないんだろ
ID:arH1mwfYなんてスルーでいいと思うんだがそれしか叩けないからいつまでたっても終わらないw
2019/12/17(火) 13:15:29.02ID:GBggCGQK
雑談スレだしネタも無いから良いんじゃね?
2019/12/17(火) 18:32:11.83ID:x9hYOthl
String型が無いって死ぬほど不便なんだが
2019/12/17(火) 19:06:56.22ID:p6v4J1KY
他の言語を使ってください
2019/12/17(火) 19:18:33.78ID:6LhBKKEf
>>132
自分で似たようなものを作ればいいだろ。汎用的なものがあっても使い勝手や性能で何かしら不満が出るのだから、自分の要求に合致するものを自分で作りな。
2019/12/17(火) 20:52:31.46ID:QeraReD1
特定の用途においてローカルラベルが役に立つことも無くはないかもしれないな。
自分でそれをやるかどうかは別にして。
いずれにせよ、gcc では式の中で変数を宣言できるのだから
ローカルラベルが可能になっても驚かないよ。
136132
垢版 |
2019/12/18(水) 23:56:34.28ID:9RDvo6To
typedefを使用
https://pastebin.com/iX2DDpRA
137デフォルトの名無しさん
垢版 |
2019/12/19(木) 00:12:48.48ID:vqVcyk4J
PHPはbreakにネスト数指定できるよな
2019/12/19(木) 09:03:44.36ID:vjQjJ4nK
C言語の開発者によるgoto文の使い方を対象とした実証研究の結果、「goto文は無害だと考えられる」
https://developers.srad.jp/story/15/02/14/2017207/
2019/12/19(木) 16:51:03.60ID:86m15ms9
longjmp についても調査してほしいな。
特に例は挙げないが、誰もが使っているようなプログラムでも結構使われてる。
140デフォルトの名無しさん
垢版 |
2019/12/19(木) 16:57:20.13ID:+cpLTGtZ
static
2019/12/25(水) 01:15:13.49ID:k3ZI/Zl3
>>139
それは代わりがない。
2020/07/09(木) 10:18:18.26ID:tNMImStE
>>7
大発明なんbだけどな、
リスクも大きい
143デフォルトの名無しさん
垢版 |
2020/07/09(木) 10:22:15.80ID:vrNDocOm
発明って言うか当時はそれが普通だったろ
2020/07/09(木) 10:51:31.74ID:I92CxMlL
longjmpは「設計上のミス」ではないんでは。
むしろそういう動作をする目的で設計・導入されたように思えるけど
(longjmpに関するRationaleを読んでないので当てずっぽうw)
2020/07/09(木) 16:31:13.77ID:KHuqFwsC
>>5
エスティーアールトゥーケー
2020/07/09(木) 21:58:30.04ID:Zo8nB2NL
例外は setjump、longjumpて実装されてるんじゃないのかな?
違うのかな?
2020/07/10(金) 22:03:48.37ID:AfLodKTd
>>143
普通じゃない
当時はPascalの文字数+文字列が普通
148デフォルトの名無しさん
垢版 |
2020/07/10(金) 22:26:03.98ID:U1HXCT7S
returnが1変数しか対応していないこと。

ポインター祭りになって可読性がウンコになる
2020/07/10(金) 23:11:39.81ID:7RoGj1wV
>>148
可読性がうんこなのはお前の能力が足りないから
150デフォルトの名無しさん
垢版 |
2020/07/11(土) 00:22:05.38ID:UdJEarb2
いろんな言語たらい回しにされるって不幸だよね。

こういうノーガキ垂れる奴がウチの職場にいなくて良かった〜ヽ(´▽`)/
151デフォルトの名無しさん
垢版 |
2020/07/11(土) 10:50:20.85ID:J0INoyBc
>>147
OSのAPIは文字数じゃなくて
文字列byte列+デリミタ'$'
みたいなのが多かったぞ
2020/07/11(土) 12:01:47.31ID:2M7rjl8q
>>151
それはCP/Mの文字列出力がそうなっていただけ
入力はC言語のfgets()なんかみたいにデリミタの '$' を付加したりしないよ
2020/07/11(土) 23:02:45.45ID:wT5X8b6q
MASM もそうだけど、$ は実際にメモリに配置されるのですか?
それとも、db(アセンブラ命令)で長さを省略するためのものですか?
2020/07/11(土) 23:04:50.81ID:wT5X8b6q
すみません、>>153 です
送信した瞬間に自分の発言の矛盾に気がつきました…
2020/07/13(月) 19:12:30.84ID:Xa4f7njE
>>146
longjumbと例外に関して
すばらしい文書があるからお読みなさって。
http://www.nurs.or.jp/~sug/a/super/longjmp.htm#sec36
156デフォルトの名無しさん
垢版 |
2020/07/13(月) 19:20:56.50ID:WBkWHxcT
そっちは Not Found ですよ
http://www.nurs.or.jp/~sug/soft/super/longjmp.htm
2020/07/13(月) 20:53:25.68ID:p7kPKe7n
>>156
ありがとうございます、昔に読んだのに URL を失ってしまって…ずっと探していたんです
2020/07/13(月) 21:24:21.32ID:jVM2RLmn
>>155
ありがとうございます >>146 です
拝見いたします
2020/07/14(火) 09:59:19.87ID:obK0XQNS
ありがとうございます。いや、longjmp をdisるような意図は無かったんだけど。
「シグナルとコールバック」も勉強になります。

http://www.nurs.or.jp/%7Esug/soft/super/signal.htm

この辺りは man を読んでも使い方が解りにくいので…
レスを投稿する

5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況