gets()をゲッツ、puts()をプッツと読んでたな
最大のミスは、文字列そのものをデータ型としては持たずに、
文字列はヌルで終端された不定長の文字の配列であるとしたことにある。
C言語の関数名ってまだリンカがシンボルの先頭から6文字までしか認識しなかった頃の名残だしな
変な短縮形が多い
strcpy()とか意図しようがしまいが簡単にメモリをぶっ壊せる
よくよく考えるとキチガイ過ぎる
>>15
根本的な所を勘違いしてる。
C言語で安全性が求められないからと言って、
C言語で作ったアプリには安全性は求められるだろ?
例えば、getsは安全に使うことが不可能なんだよ。 >>18
> 例えば、getsは安全に使うことが不可能なんだよ。
ならgetsを使わずにgetcでやればいいだけ 組み込みでC言語は使うけど、10個以上の標準関数って使わないな...。
memcpy / memset / memcmp
strlen / str(n)cpy / str(n)cmp / str(n)cat
これで10個
組み込みで文字列扱わないことも多いね。
どんな製品でもほぼ使うのはmemset、memcpy、memcmpぐらいじゃない?
>>25
>>1のリンク先より
未チェックの時代遅れの関数
以下の関数を、未チェックの時代遅れの関数と定義する。
memcpy, strcpy, strncpy, strcat, strncat (一部抜粋)
半分あてはまってるなw
>>26
memcpyは危険なので使うのはやめましょう memcpyが危険とか言うなら
C言語使うなってことになる
>>28
標準じゃない関数だと...
失敗談みたいなのを期待してた? >>1
セキュリティ考慮していない元関数より、代替関数の設計ミスが酷いな
strtodとかなにこれw
エラーの返し方がアホすぎる >>32
> strtodとかなにこれw
> エラーの返し方がアホすぎる
そう言うのは改善案を提案しないと単なるアホの独り言にしかならんぞw 一体どういう考えで昔の人は、getsの仕様はあれでOKだと思ったんだろう?
どう考えてもバッファオーバーフローするやん?
しない方法なんて存在するの?
バッファオーバーフローしないデータを食わせれば良い
わざわざ変なデータを入力するヤツが悪い
って考えの時代の関数だ
gets は、もう、標準ライブラリにも入っていないので許せ
>>36
1行80文字とかって決め打ちできる環境なんでしょ
自分しか使わないようなツールとかならこれで十分
って考え 8ビットの整数型を char などというものにしたのも、アメリカ人は
自分たちの英語しか知らない田舎者であることを如実に表している。
>>41
実に田舎者の考え方で笑える
逆だよ、都会の人間は都会のことしか知らないし知る必要がない
なぜか田舎の人間は都会のことも知ろうとするw > 逆だよ、都会の人間は都会のことしか知らないし知る必要がない
だから世界が狭くて無知になりやすい
> なぜか田舎の人間は都会のことも知ろうとするw
だから世界が広い
C言語が出来た時の時代を考えれば十分
「変数名に日本語が使えない言語は糞」
って時代もそのうち来るよ
>>44
残念ながらそうはなってないんだなw
狭く深くっていう世界だから
要するに田舎でな何をするにもオーバーヘッドが大きいってことな
今はネットでだいぶマシになったけどネット以前の情報収集考えたらアホでもわかる話 アホなデータ食わせるアホなやつのために堅牢な仕組みにする必要はない
>>46
メモリが640kバイトしか使えなかった頃からのものだしな 大昔って端末やエディタなんかでも1行256とか1024バイト程度しか扱えなかったばず
昔は1行の長さを先に決めてファイルをクリエイトしました
途中で変更はできません
関数そのものじゃないが
breakにラベル指定出来なかったのは設計ミスやろ
gotoはラベルのスコープが広いから使いにくい。ループごとに別のラベル名を
付けないといけないし、ラベル名を別のループ用のものと書き間違えると
意図しない所へ飛んで行ってしまう。スパゲッティでバグの元。
ループにラベルを付ければ、スコープがそのループ内に限定され、そのループの
外にある別のループに同じラベル名を付けることができるから、書きやすく
読みやすい。例えば、こんな感じ。
for @outer (i = 1; i <= 3; i++) {
for (j = 1; j <= 3; j++) {
printf("%d, %d\n", i, j);
if (i * j > 3) break @outer;
}
}
for @outer (i = 1; i <= 5; i++) {
for (j = 1; j <= 5; j++) {
printf("%d, %d\n", i, j);
if (i * j > 5) break @outer;
}
}
1000行のコードでbreak 7;とかされても、
どこに抜けるかわからんよな!
ネストの数がわからないような巨大な構造は
それだけで最低だ
そんなんだと名前付きループにした所で
@outerなんて名前が使い回されて
同じ名前のループがネストされて
それこそ難読コードになる
それならユニークなラベルによるgotoの方が良い
>>57くらいのループなら
break 2;
は名前を考える手間が無くて楽だし
見にくくもない とは書いたけど
どっちも有るならどっちも欲しい
どっちかだけげならbreak 2;の方が欲しい
って感じ
>>61
> そんなんだと名前付きループにした所で
> @outerなんて名前が使い回されて
> 同じ名前のループがネストされて
> それこそ難読コードになる
無能の妄想w ループの先頭、ループの終わり、break部分
3箇所見ないとダメってだけでダメな仕様
>>64
なぜか自分の前提は
> >>57くらいのループなら
なのにラベルにした途端にループの頭とbreakとループの終わりが一瞥でわからないとかアホすぎ 名前を付ける手間を許容するならgotoという解決法が既にある
>>60
ネスト変わるような変更あるたびにbreakの引数勝手に書き換えてくれるエディタとかマクロが流行る >>67
ifとgotoあるからforもwhileもdoも要らんという主張か
本物のプログラマーだなw 歪んだ教育のせいで
gotoに拒絶反応を示す人が多いんだよな
2重ループを抜けるなら素直にgotoを使えって
アセンブラの
jmp 1f
とかを C でやりたいという話なのか?
やってみりゃいいじゃん。プリプロセッサの出力を処理すればいい。
1 パスで出来ると思うよ。
ひょっとしてもう誰かがやってるかも。
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:;
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:;
わざわざ言語拡張しなくても
>>57以上の事が実現出来る ラベルのスコープを狭くしたいという話のようだから
マクロの中で使ってこそ真価を発揮するんじゃないかな。
フル仕様のパースが必要というわけではなく、かなり手抜きできそうではある。
あれば便利というのは否定しないが、C でそこまで必要かというと…
{
goto hoge;
hoge:;
}
{
goto hoge;
hoge:;
}
これで二重になってたら困るしある意味なってなくても困るな
マクロで二重以上のループってのもなかなか考えづらいなあ
一応、ラベル名をパラメータとする手もある
使う側のコストを考えるとgotoの為にパラメータを増やさないよな
gotoを使わない主義者がよくやってるように
余分な変数を使って実装するんだろうね
アセンブラだとマクロローカルラベルってのがあったりする
ラベルを頻繁に使うので
あと
@@/@b/@fのように、
直近のラベルを指定する仕組みもある
>>72 >>73 みたいなのって
gotoの使いどころだと思うんだけだ
gotoを使わない人はどう書いてるの?
特に >>57 の答えを聞いてみたい 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");
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");
"短い処理"をいちいち関数にしなくて済むから、break 2とかはあってもいいが、
長い処理は関数にしてないとろくにテストできないんだからgotoなんていらない