[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 2chのread.cgiへ]
Update time : 05/09 12:13 / Filesize : 137 KB / Number-of Response : 558
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

sizeof(char)が必ず1でも、省略すべきではない



1 名前:デフォルトの名無しさん mailto:sage [2007/08/19(日) 20:06:26 ]
malloc(sizeof(char)*(strlen(s)+1))
ではなく
malloc(strlen(s)+1)
と書くような糞コードばかり見て育った、
悪しき慣習を引きずった人は引退すべし


331 名前:デフォルトの名無しさん mailto:sage [2007/08/31(金) 21:24:49 ]
>>329
ATL/MFC のコードなんだから C++。
なので char はクラスではない。

332 名前:デフォルトの名無しさん mailto:sage [2007/08/31(金) 23:56:30 ]
>>328
>>327みたいな奴の事だろう

333 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 01:06:20 ]
>>332
>>327みたいな奴は何がわかってないの?

334 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 02:00:21 ]
>>328
よく判ってないんで、>>321のソースを解説してはくれまいか?

335 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 11:25:14 ]
// 動的に確保した領域のポインタをpszSrcに代入
pszSrc= new char(12);
// newに成功した場合
if(pszSrc)
// 動的に確保した領域を無視して、文字列リテラルのポインタをpszSrcに保存
// 動的に確保した領域はリークする
pszSrc= "Hello world!";

C言語しか分からんけど、newをmallocに読み替えるとこんなところ。
C++だと文字列リテラルの代入は、なんかstrcpyみたいな動きすんのか?

336 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 11:36:12 ]
>// 動的に確保した領域のポインタをpszSrcに代入
>pszSrc= new char(12);
構文エラー。

>// newに成功した場合
>if(pszSrc)
newはNULLを返さない。

>// 動的に確保した領域を無視して、文字列リテラルのポインタをpszSrcに保存
>// 動的に確保した領域はリークする
>pszSrc= "Hello world!";
その通り。

>C言語しか分からんけど、newをmallocに読み替えるとこんなところ。
>C++だと文字列リテラルの代入は、なんかstrcpyみたいな動きすんのか?
しないしない。

>>324
寧ろ、こう。
・鍋を用意して一杯にお湯を沸かします(勿論、麺を入れたら溢れて大変ですね)。
・鍋は用意できましたか(当然である)?
・ではこちらに用意したカップラーメンをどうぞ(おいおい、鍋そのままw)。

337 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 12:01:38 ]
>>335
  pszSrc= new char(12);
は、C だと↓こんな感じ。
  (pszSrc = malloc(1)) = 12;

338 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 12:02:26 ]
あああ尻穴忘れた!
  *(pszSrc = malloc(1)) = 12;

339 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 12:15:23 ]
>>336
12はcharの初期化子として有効。エラーにはならない。



340 名前:デフォルトの名無しさん mailto:sage [2007/09/01(土) 15:08:20 ]
エレガントなメモリリークだなぁ

341 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 04:22:12 ]
mallocが失敗する可能性は考慮しないのか?
つーか、mallocってNULL以外が返ったとしても
実はメモリ確保に成功したかどうか不明だという
おそろしいバグがあるんだがLinuxって怖いよな

342 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 08:06:28 ]
mallocやnewが失敗する状況って、かなりヤバいよね。

それらに対処するコードで、mallocやnewを使うと、ミイラ取りがミイラになる恐れがあるし、
OSの仮想メモリを食い尽くしている状況では、他のプログラムも動作続行が厳しくなっていて、
終了処理も正常に行えるか怪しい。予想もつかないような事態が次々に発生しそう。

だから、mallocやnewに失敗した時点で、OSから再インストールするハメになるわけで、
成功したかどうかチェックし、失敗したことがわかったところで、ろくに対処できないなら、
開き直って、mallocやnewをラップして、失敗したらexitしてしまい、
ラップしたものを使う側は、失敗することはないものとしてコードを書いてしまうのもアリかと。


343 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 09:14:15 ]
>だから、mallocやnewに失敗した時点で、OSから再インストールするハメになるわけで、
おいおい、普通はrebootで充分だろ。

実際Gnomeなんか使っていると、malloc()に失敗する頃には事実上操作不能になっているから、
諦めてとっととexit()ってのはありだと思う。
私の仕事関係では、常駐型アプリケーションの起動は基本的にスクリプトから行ない、
アプリケーションが異常終了したときには可能ならそのアプリケーションを再起動するようにしている。

344 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 09:42:29 ]
>>343
rebootで十分という保証があれば、ね。

OSの上で走るすべてのプログラムが、
設定やデータをファイルに書く時、
一貫性を保てるように書いてくれればいいが、
そうでないと、
不正で壊れたファイルを読むことになり、
こまったことになってしまう。

345 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 13:09:01 ]
OSからとかねぇよw
書き込み中の電源断でさえジャーナルファイルシステムなら通常問題無いのに、
メモリ確保失敗くらいで整合性取れなくなるとかw

基幹システムなどなら、ソフトウェアとして既に品質に問題有りだし、
個人PCやグループサーバーレベルで再インストは潔癖過ぎだろ。

346 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 13:13:01 ]
1GiBのメモリ確保しようとして失敗したって状況なら、
メモリ確保失敗したとユーザに通知したり、
そのために数KiBのメモリを確保したりしようとしてもいいと思う。

347 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 13:32:25 ]
>>345
ファイルシステムのレベルで問題がなくても、ファイルの中身のレベルでは問題だよ。

ファイルの中身までトランザクションやジャーナルでやっていれば大丈夫だが、
そうでないプログラムの場合、ファイルの中身の一貫性が失われてしまう。

348 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 13:56:19 ]
>>347
>そうでないプログラムの場合、ファイルの中身の一貫性
345の下2行の通り。
重要なシステムなら論外、DBMSなどで一貫性の確保は必須だし、
それでも抜けた異常はバックアップからリカバリさせる。
OSからとかダウンタイム長すぎだろ。

それにメモリ不足でOS壊すってどんな状況?
viがLILOの設定ファイル書き換える最中に死んだって、
書き換え前にバックアップくらいしてるだろ。

ユーティリティか何かがhttpd.conf壊したって、
OSどころかapacheから入れなおす馬鹿は居ないだろ。

349 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 16:41:48 ]
>ユーティリティか何かがhttpd.conf壊したって、
>OSどころかapacheから入れなおす馬鹿は居ないだろ。
見たことあるな。
俺はこれをWindows病と名づけた。



350 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 18:53:50 ]
あーいるいる、「取り敢えず再インストールしてみました」って香具師。

351 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 20:36:44 ]
ネトゲのクライアントは、たまにWindowsの設定やらシステムファイルやらをぶち壊す奴が居る

352 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 20:37:39 ]
あ、補足。
多分mallocは関係ない。

353 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 21:53:13 ]
しばらく前、幻想三国志2っちゅーゲームでアホほど再起動かかってOSが不安定になった。
再起動の原因がメモリリークと気付くのが遅すぎた・・・。

HDDがガリガリ鳴り出したらセーブして再起動とか、
偽典女神転生を思い出して懐かしかった。

354 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 22:57:44 ]
突然だがスレを激しくrollbackしていいかな。

sizeof(char)は確かに仕様で1と決まっているけど、省略しない方が良い。
コメントやsizeof(char)==1の理解が無くても、
ソースを見るだけで文字数→バイト数として扱いたい意図が明確になる。
それにコンパイラの最適化でどうせコストは0だ。

ただ、そんな冗長なソースが散在しているのが嫌だというのも同意出来る。
しかしそれ以前に、文字列の操作なんて普通はラップしないか?

>malloc(sizeof(char)*(strlen(s)+1))
>malloc(strlen(s)+1)
両方とも、非常に短い関数以外でこんなん出てきたらどうかと思うんだが。

char*    strmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(char   ));}
wchar_t* wcsmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(wchar_t));}
void strfree(const char*    s){free(s);} // 確保/解放を対とするためfreeを単純にラップ
void wcefree(const wchar_t* s){free(s);} // 確保/解放を対とするためfreeを単純にラップ

char* s2 = strmalloc(strlen(s));
strfree(s2);

これくらいは抽象化するだろ?お前らどうやってる?

355 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 23:21:41 ]
>文字数→バイト数として扱いたい意図
ここは自明だろーがよ
というのが反対派の意見だと思う。

a++; // 1を足す
っていうコメントを読まされるような感じ というか

356 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 23:28:41 ]
>>354
一方俺はC++を使った。

357 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 23:49:03 ]
まぁ、俺も現実的にはC++使うな。
だけどC++使うからこそ観念的に省略しないんだけどな。

テンプレート関数とか作るとき
> ここは自明だろーがよ
> というのが反対派の意見だと思う。
そのはずの自明が、抽象化・総称化すればする程無くなっていく。
wchar_tの対応をしようとしただけで崩れる。
つまりその自明はあまり本質的でなかったということ。
むしろ、文字をchar型を扱うときに限り文字数とバイト数が同じになる、と考える。

文字列操作と言いながら型を強く意識するのは、やはりスマートとは思えないよ。

358 名前:デフォルトの名無しさん mailto:sage [2007/09/03(月) 23:52:00 ]
誤記は脳内保管で。

359 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:00:44 ]
>>357
ぶっちゃけ未対応ソフトの多バイト文字対応をするときは
charをwchar_tに機械変換♥ なんて絶対しないから
もうその辺はすごい勢いでどうでもいい話だと思う。



360 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:11:32 ]
そもそも文字型が独立しておらず、charやunsigned charが
整数型の1つである(JavaやC#でいうbyteにあたる型)という時点から
もう文字とバイトをごっちゃにするのは始まっている。

だから俺は文字 == バイトを甘んじて受け入れ、sizeof (char)を使わない。

361 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:15:20 ]
機械変換とかじゃなくて、テンプレート関数の話な。
allocator((Tr::getlen(s)+1) * Tr::char_size);
みたいな感じで実装して、型はコンパイル時に決まる。

ちょっとした関数を総称化すると、
自分が自明だとか本質的だと思っていたものが、
そうでもないと気付かされるって話。

362 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:18:56 ]
ぶっちゃげcharだけなんてXMLも扱えねぇよ最近。

363 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:28:46 ]
>>360
文字とバイトがごっちゃというのは整理出来ていないから。

文字は文字集合として独立していて、バイトも文字集合とは関係無い。
その2つを繋いで、バイト列の上で文字を表現するルールがエンコーディング。
概念が頭の中で分かれていれば、unsinedだとかSJIS, UTF-8やらがあってもごっちゃにはならないはず。

364 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:30:07 ]
型について、ちょい脱線するけど・・・。
時刻を保持する型を使ってて、8月中のデータを探すとき
(擬似コード。リテラルは変数に代入された値と思って)
if("2007/08/01" <= x && x <= "2007/08/31 23:59:59"){...}
のように書く奴が居る。

俺は
if("2007/08" <= x && x < "2007/09"){...}
と書く。月日は省略されると1、時間以下は0となる。(普通)

しかし、そう書く理由はソースが短くなるからじゃない。
if("2007/08/01 00:00:00" <= x && x < "2007/09/01 00:00:00"){...}
と書いても良い。
59:59だとか、9999だとかは、まずいサインだと思っている。
型を強く意識している場合は多いからだ、

上記の場合、この型がミリ秒まで保持することになったとき、
23:59:59は正確な最後ではなく、23:59:59.999と書く必要があり
僅かだが穴のあるプログラムとなる。

データ的にはピコ秒まで持てるようになったら?.999999...
精度の問題じゃない、結局は 「2007/09/01に限りなく近い値」となる
なら2007/09/01 00:00:00と比較すれば良い。

ソートで単に最後にしたいものに 9999 を入れるとか、
場合によってはハードコーディングとか、もう見てられない。

必要以上に型の精度に依存しないで欲しい。

365 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:33:50 ]
ミリ秒以前にうるう秒

366 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:36:45 ]
<= じゃなくて < を使えば済む話じゃないのか

367 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:48:33 ]
>>366
そう、そういう話。
でも使ってる精度が日まで(時以降が00:00)で、Webフォームから期間を入れられた場合、
開始日〜終了日という入力欄では終了日も含むので、
x < 終了日+1 とせず、単に x <= 終了日とする奴が中々多い。
右の方がシンプルだし、わからんでもないが。

それで登録日時(時分秒が有る)とかを検索する処理でも同じソース使って馬鹿がって結果になってた。

368 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 00:52:32 ]
>>363
文字とバイトがごっちゃというのは俺に言っているのか?
俺は、CとC++が文字とバイトをごっちゃに扱っていると言ったつもりだ。
だから俺にそんなこと言われても、お門違い。


369 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 01:04:36 ]
wchar.hなど有るし、文字とバイトをごっちゃに扱ってるようには思えないが・・・
それにchar==文字でなく、char*==nul終端文字ストリームというのがあったから
SJISなどをそれなりに扱えて来たわけだし。



370 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 01:20:30 ]
ちなみに、java,C#などは文字型が本当の意味で独立してるわけじゃなく、
単に内部のエンコードを割り切ってUTF-16に統一してるだけ。
昔、C言語がasciiで十分と考えたように。

その利便性はもちろん大きいけど、その代償としてUTF-8などを読み書きするとき
エンコード変換のオーバーヘッドを受け入れている。
※よほど巨大なファイルでない限り対したオーバーヘッドじゃないけど。

371 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 01:27:26 ]
UTF-16もサロゲートペアを考えるとchar==1文字とならない。
Unicode領域で固定バイトが出来るのはUTF-32だけ。
でもascii1文字に4byteも使うことと、
サロゲートペアの文字があまり重要でないことからUTF-32で扱っているシステムは少ない。

未来の言語のcharは32bitかもしれない。

372 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 02:46:39 ]
おれは>>355と同じように考える。
>>357,>>361で抽象化とか総称化とかって話がでてるけど、
そのようなケースになったときは、そう書けばいい。

しかし、このスレでは‘sizeof(char)’は抽象化されてない。
あくまで、>>1の記述に的を絞って考えたらやっぱり冗長かなーと。。。


373 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 02:49:51 ]
>>354
> char*    strmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(char   ));}

len=0のときにNULLにしてしまうのは、ちょっと馴染みがないんだが。


374 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 02:53:44 ]
え?

375 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 02:55:50 ]
>>354
その引数lenの型は、size_tにして、条件演算子は排除。


376 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 02:58:23 ]
>>373
len<0が0を含むっていうのは、ちょっと馴染みがないんだが。

377 名前:373 mailto:sage [2007/09/04(火) 03:40:49 ]
ごめん、寝ぼけてた。
真と偽を逆に見てた。

378 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 07:21:37 ]
>>375
あ、確かに、size_tだな。size_tってunsignedって保証あるんだったっけ?
\0を入れられない、len==-1(len+1が0に)でNULL以外が帰ると都合が悪いので負の数を弾いてた。

379 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 07:48:25 ]
>>369
例えばmemsetなどのmem〜関数がごっちゃにしている例。

wchar_tはいいが、後付なのでここでは省きたい。

Shift_JISなどはマルチバイト文字なのだから、
char1つで表せないのは当たり前のことだ。

>>370
charが単に16ビット符号無し整数型とは別に存在するだろ。
Javaにはそんな整数型は無いが、いずれにせよcharが
整数として演算可能な型ではないことを言いたかっただけ。

>>371
D言語はUTF-32も扱える



380 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 09:19:06 ]
>>379
「D言語は」って・・・Cだと扱えないのか?

381 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 11:33:12 ]
>>379
そりゃmem*でも文字列は扱えるけど、普通は str* wcs* を使うだろう。
文字列にmem*使う奴が悪いと思うが。

>wchar_tはいいが、後付なのでここでは省きたい。
Cの規格自体、かなり昔から何度も改訂されてるし、
今ではwchar_tも正式な仕様なのに、後付け扱いはあんまりかと・・・。
まぁCではtypedefなんで後付け感は確かにあるけど。

> charが単に16ビット符号無し整数型とは別に存在するだろ。
> Javaにはそんな整数型は無いが、
> 整数として演算可能な型ではないことを言いたかっただけ。
javaのcharは16ビット符号無し整数で、整数として演算可能だよ。

> D言語はUTF-32も
プログラミングで言えばlinuxのgccのwchar_tも32bitだっだはず。
俺が言いたかったのはUTF-32を内部コードとして使ってるOS,ライブラリ,ソフトウェアが少ないってこと。

>>380
UTF-32用の組み込み型があるって意味だと思う、
(Dはそもそも強いtypedefがあるから、組み込みでなくても問題ないけど)
「標準」っていうことが重要になる。

標準でないと、各々作ってしまう。
typedef unsigned longならまだいいけど、
構造体やクラス化されると他ライブラリとの互換性がね・・・。

382 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 16:19:11 ]
>>378
size_tは普通 signed な何かです。

383 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 16:37:46 ]
いいえ、unsigned intかunsigned longであることのほうが普通です。

384 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 17:09:44 ]
ssize_tと間違えていたよ

385 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 21:43:25 ]
>>371
D言語はUnicodeを知っていて、UTF-8,-16,-32の変換は勝手にやってくれるらしいぜ。

import std.stdio;
void main() {
string s = "AΑあ"; // UTF-8の配列
writefln(s.length); // 当然長さは、6
foreach(i, dchar c; s) // UTF-32で取り出す
writefln(i); // 0, 1, 3 ... 自動でUnicodeスカラ値単位に区切ってくれる!
}

386 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 21:51:22 ]
> // 当然長さは、6
当然?

素直に考えれば、長さは3だと思うけど。


387 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 21:54:37 ]
string は const(char)[] のaliasだから、ただのUTF-8シーケンスなのです。
だから、長さは6なのです。

388 名前:デフォルトの名無しさん mailto:sage [2007/09/04(火) 21:59:16 ]
Dはちょっと見ないあいだにますます変な機能が追加されてんだな

const(char)[] って何だよw

389 名前:デフォルトの名無しさん mailto:sage [2007/09/06(木) 07:48:16 ]
D言語って、そんなに悪くないと思うよ。
同じことをC++でベタベタとコードを書いたり、
可読性の酷くわるいマクロや、テンプレートを駆使しすぎるよりは。



390 名前:デフォルトの名無しさん mailto:sage [2007/09/06(木) 22:55:15 ]
385はうそっぱちなので真に受けないでください

391 名前:デフォルトの名無しさん [2007/09/06(木) 23:49:44 ]
デーげんごっていつのまにかたいへんなことになってんだな

392 名前:デフォルトの名無しさん [2007/09/14(金) 20:35:08 ]
さすがに、みんな飽きたな。
次のネタを検討しようか。

引数を1つしか取らないようなprintfを書くな。
そういうコード例の参考書は買ってはいけない。

ってのはどうよ。

Cの標準化の人達は、なんで、print を用意しなかったのかな。
putsとカブっているとはいえ、引数1つのprintfが氾濫するよりはマシだろうに。

393 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 21:13:54 ]
puts は最後に改行文字を出すぞ

394 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 21:18:32 ]
文盲?

395 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 21:24:10 ]
コンパイラが最適化するからどうでもいいんじゃないの?

396 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 21:37:40 ]
>>393
よくあるprintfの酷い使い方。

printf("==== ほげほげ version 1.0 ======\n") ;
printf("Programed by foobar\n") ;

一行ずつ別々にprintfを呼ぶなら、putsでもいいんじゃないか。


397 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 21:39:13 ]
>>395
そんな変な最適化をするコンパイラなんて捨ててしまえ。

そういうのに慣れていると、
printf("私のコードは100%safeです。\n") ;
なんていう恐ろしいことをやる馬鹿が出てくるんだよ。

398 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 21:42:51 ]
puts, gets, putchar, getchar, printf, scanfまるごとなくしてしまえ。
f版でいいよ。

gets, putsとfgets, fputsは微妙に挙動が違うのが癪だが。

399 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 22:09:27 ]
少なくともgccはフォーマット文の中身まで見て最適化するよ



400 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 22:35:27 ]
gccが最適化するからprintfを変な使い方をしてもいい、というのは間違いだと思う。
すでに書かれてしまった膨大なコードのために、変態な最適化をしてくれるのだと思う。


401 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 22:37:51 ]

void OutputMessage(char* s) {
printf(s) ;
}

こんな関数があったとしたら、
OutputMessage("100%safe") ;
なんて呼び出す輩が出てくる。

gccがprintfの引数を見て最適化してくれればバグが顕在化しないが、
最適化しない環境に持っていけばバグが顕在化してしまう。

402 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 22:38:28 ]
>>397
俺的には-Wallで警告出るから問題ない


403 名前:デフォルトの名無しさん mailto:sage [2007/09/14(金) 22:43:11 ]
>>402のようなのは警告でないっしょ?

404 名前:デフォルトの名無しさん mailto:sage [2007/09/15(土) 00:03:52 ]
でるよ。

405 名前:デフォルトの名無しさん mailto:sage [2007/09/15(土) 00:54:17 ]
>>401
俺は何でもかんでもprintf使う方だけど、コレは無いなぁ・・・。

void OutputMessage(char* s) {
printf("%s",s);
}


puts、fputsなんてここ5年ぐらい使ってない。
対話なCUI作るときは(滅多に作らないけど)cursesなことが多いし、
ログ出力は定型で吐くラッパ作ることが多いし、
出力部分をgrepするのに、いちいち正規表現やなんかで色々指定するのダルい。

406 名前:401 mailto:sage [2007/09/15(土) 01:53:37 ]
>>405
そのまさかをやる人間が少なくないのですよ。

printfに渡す文字列に対してサニタイジングを行うべし
なんて真顔で言う人間までいる。


407 名前:デフォルトの名無しさん mailto:sage [2007/09/15(土) 02:09:08 ]
あたしゃprintf("<>")なんてのはやるがね。

408 名前:デフォルトの名無しさん mailto:sage [2007/09/17(月) 16:14:37 ]
>>400
一般論だが、
想定外の変なデータにあわせてプログラムを書き換えるというのは
たいていあとでほころびが出たりしますよな。


409 名前:デフォルトの名無しさん mailto:sage [2007/09/18(火) 00:01:27 ]
ん? printf("\n") ;  がだめってことか?

何で悪いのか判らん・・・




410 名前:デフォルトの名無しさん mailto:sage [2007/09/18(火) 00:59:50 ]
別にいいと思うよ。

411 名前:デフォルトの名無しさん [2007/09/18(火) 01:10:15 ]
かつては、printfをどこかで使ってるなら出力は全部printfにしたほうが、
さらにもう一つputs関数がリンクされてしまうよりも
実行ファイルが小さくなるという効能があったのではないかと思う。


412 名前:デフォルトの名無しさん mailto:sage [2007/09/18(火) 01:37:58 ]
>>1
死ね

413 名前:デフォルトの名無しさん mailto:sage [2007/09/18(火) 01:42:07 ]
そもそもputsとfputsの挙動が違うのがな
今日の言語設計者は気持ち悪くて、そんなことできないと思う。

414 名前:デフォルトの名無しさん mailto:sage [2007/09/18(火) 03:22:46 ]
しょうがない。

もとはと言えば64KB程度のメモリで動いていたマシンのOSと、OSの上で動くプログラムを書くとき、
メモリを節約するために共通コードを関数としてライブラリ化したような代物だから。

415 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 23:17:00 ]
ところで、sizeof(char)=sizeof(short)=sizeof(int)=2っていう設定のトンデモコンパイラがあるらしい。
一応、C言語の規格上これは間違っていない。(型のサイズは決められてないからね。)

416 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 23:39:37 ]
kwsk

417 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 23:49:13 ]
sizeof(char)=2は規格上まずいだろ

418 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 00:00:53 ]
>>415
>>206

419 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 14:43:58 ]
もちろん、Cでもsizeof(char)は1だと明確に定められてるから。よろしく。



420 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 15:02:18 ]
>>415
「だから sizeof(char) は省略すべきではない」という主張?...でもなさそうだな。
このスレタイは「必ず1でも」って条件付きだから関係ないよね。


421 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 15:50:12 ]
無次元の1と1バイトって同一視して話していいんだっけ。


422 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 16:21:03 ]
数学で毎回全ての問題の全ての数字に (注意:これは10進数)
みたいな但し書きをかかれるようなものだろ。

423 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 17:20:15 ]
415はsizeof(char)が2になるトンデモコンパイラをはやく晒してくれ

424 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 00:01:05 ]
論理1バイトが物理2バイトだったらどうか。
自分でも書いててよくわからんが。

425 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 01:23:46 ]
>>424
charが、1バイトが、16ビットの可能性はあるかもしれない

それでも1バイトは1バイトだ

426 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 01:47:50 ]
>>419
それどこに書いてる?
ISOかJISの規格票のどちらかでいいから教えて

427 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 02:04:21 ]
>>426
ISO/IEC 9899とか。
ついでにググったらすぐ出てきた


6.5.3.4 The sizeof operator の抜粋な
2. The sizeof operator yields the size (in bytes) of its operand....
3 When applied to an operand that has type char, unsigned char, or signed char,
(or a qualified version thereof) the result is 1.

428 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 02:22:05 ]
なるほど
さんくす

429 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 20:00:42 ]
>>415
> ところで、sizeof(char)=sizeof(short)=sizeof(int)=2っていう設定のトンデモコンパイラがあるらしい。
> 一応、C言語の規格上これは間違っていない。(型のサイズは決められてないからね。)

それどこが出してる?
製品名と会社のweb siteのどちらかでいいから教えて




430 名前:デフォルトの名無しさん mailto:sage [2007/10/13(土) 21:04:48 ]
>>429
ひょっとしたら、sizeof(char*)=sizeof(short*)=sizeof(int*)と完治害してんじゃね?


431 名前:デフォルトの名無しさん [2008/01/21(月) 00:49:50 ]
未だにsizeof(char)を書いてる人っているの?

432 名前:デフォルトの名無しさん mailto:sage [2008/01/21(月) 01:54:36 ]
javaのcharは2バイトって聞いたぜ。
…どうでもいいか。

433 名前:デフォルトの名無しさん [2008/01/21(月) 19:55:24 ]
Cプログラマの為に、ポイントをまとめたドキュメントを販売しています。
プロのプログラマでもあまりにレベルが低い人が多すぎます。
そんな人に限って、自分のレベルの低さを自覚していない、、、

本人は構わないかもしれませんが、その下についた新人プログラマは
たまったものではありません。(私が経験しました。)

今になって分かりました。
彼らもまた、理解できていなかったのです。

プログラミング言語の一番の習得の近道はきちんと理解している人にアドバイスをもらうこと。です。
(何といったって、参考にしようとする市販の本さえ、 きちんと説明してくれていないのですから、
 その証拠にC言語の学習で悩む人がどんなに多いことか)

私のC言語に取り組んだ7年間をすべてぶつけたつもりでテキストを作りました。

私の会社の後輩からは、どんなテキストよりもわかりやすかった!や、
今まで教えてくれていた先輩や、テキストたちが、ちゃんと理解できていないことがわかりました。
と、嬉しいコメントをたくさんもらいました。

そしてなにより、彼らの社内での評価がとても高いということが、私の誇りです。

宣伝と言ってしまえば、そうなってしまうかもしれませんが、ひとりでも多くのプログラマを救いたい。

プログラムの世界そのものの実力を底あげに貢献し、
無意味なバグに、残業したり、悩んだりして欲しくないのです。

興味がある方はどうか、下のサイトをみてみてください。
mori.eco.to/

434 名前:デフォルトの名無しさん mailto:sage [2008/01/21(月) 20:09:56 ]
>コンピュータの専門学校に入学、在学中に情報系の国家試験である、基本情報処理技術者、ソフトウエア開発を取得。
専卒かよ。

435 名前:デフォルトの名無しさん mailto:sage [2008/01/22(火) 00:51:04 ]
>>433
ブラクラ注意

436 名前:デフォルトの名無しさん mailto:sage [2008/01/23(水) 02:12:26 ]
専門学校wwwwwwwwwwwwwwwwwwwwwwwwww

437 名前:デフォルトの名無しさん mailto:sage [2008/02/28(木) 13:45:03 ]
>>431
templateで間接的になら

438 名前:デフォルトの名無しさん mailto:sage [2008/03/04(火) 17:38:06 ]
sizeof (TCHAR)で間接的になら

439 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 00:22:32 ]
>>435
おいおい、ブラクラではなかったぞ。

>>434
学歴は関係ないと思う。

8,800円払って中身みたわけではないのだが、
大学の教授が書いているC言語入門書にも、
とんでもなく酷い本があるのだから、
もはや学歴や肩書きは関係ないと思うのよ。

BASIC時代のPRINTをそのまま引きずった、
printf("Hello, world\n");
なんてのが平然と書かれている本を見るたびに、
こんなので勉強したら無駄な時間を食うのは当然だなと思うし。



440 名前:デフォルトの名無しさん [2008/03/21(金) 02:42:30 ]
>>439
Hello,worldは基本中の初歩であって
これをバカにする理由が思い当たらないんだが


441 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 02:51:38 ]
puts("hello world");
ってやるべきってこと?

442 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 03:12:25 ]
そんなことを言い出したらフォーマット文字列の中に
足がすくんじゃって何も書けなくなってしまうわけだが

443 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 03:17:33 ]
正統派の基本を馬鹿にするのは新しいまがいものを売るときの基本
結局同じことの繰り返しになるわけだが

444 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 03:35:57 ]
30年間でほとんど進歩してないな。

マイクロソフトの新しいバージョンのVisual C++が出る度に、まっさきに、
Visual C++ バージョンほげほげ対応 という冠を付けた本が出るのだが、
いまだに本編は相変わらず昔のままで、付録的に
コンソールで cc hoge.c とやってコンパイルするのと同等のことをやる方法を
ちょろっと書いているだけで、Visual C++のデバッガの使い方を説明せず、
変数の値をprintfを埋め込んで標準出力に出して確認することを第一に教えている。

445 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 03:39:09 ]
>>442
それが正しい。

printfの第一引数が書式化文字列であるとういことを初手から叩き込むべき。
printf("%s\n", "hello, world!");
これくらい、わざとらしくやってもいいくらいだ。

そうでもしないと、↓みたいなことをやるマヌケが出てくるからな。
void print_message(const char *p)
{
printf(p);
}



446 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 16:48:42 ]
中身をみないで擁護できるのは本人だけ。

447 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 17:00:16 ]
入門書の何が問題かというと、「ポインタがわかりません」なんて人を今だに量産していること。
しかも、そこに書かれていることが、次の段階の本で否定されていたりする。

448 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 21:15:11 ]
>>439
どうやって文字列が表示されるのかを勉強している身としてはとてもバカにできない内容なんだが、
どういう内容を載せるべきだと言ってるのか教えて欲しいな。


449 名前:デフォルトの名無しさん mailto:sage [2008/03/21(金) 22:15:53 ]
printfは、C言語の仕様の一部ではあるものの、ライブラリの一関数に過ぎない。
printfやscanfの使い方は、ライブラリのマニュアルを読めばわかることであって、
入門書で解説すべきなのは、それらの使い方ではなく、
マニュアルを読めばわかるようになるための必要な前提知識である。

ってなことを頭の片隅に置いて聞いて欲しい。

hello, worldのサンプルなんだけど、なんかC言語っぽくないんだよね。
短くてエッセンスが凝縮されているサンプルが思いつかないんだけどさ。

>>448
> どうやって文字列が表示されるのかを勉強している

C言語とはあまり関係ないなぁ。
ライブラリがOSのシステムコールを呼んで、あとはOSが処理してる。



450 名前:デフォルトの名無しさん mailto:sage [2008/03/22(土) 05:04:58 ]
CもようやくOSを意識しないでプログラムを組める時代になったのか

451 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 03:19:41 ]
>>450
ないよ。




452 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 03:37:29 ]
>>445
という以前に、フォーマット文中に誤った引数が指定できて、しかも
その間違いがコンパイラでも内部処理でも検知できないっていう
printfの仕様上の欠陥があるわけで、そもそもprintfを使うことそれ自体が
NGだという話になるんじゃないの?

453 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 04:14:43 ]
それを言いはじめたら、標準ライブラリの多くの文字列がらみの関数がNGになるよ。
たとえばstrcpyがバッファオーバーランしうる、とか。

そもそも、
今さらC言語を使わないといけない、しかも、習得するプログラミング言語の最初がC言語でなければならない
っていう状況に閉じ込められた時点で、その人は終わっていると思う。


454 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 11:02:22 ]
除算も同じ意味でNGだな

455 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 12:01:53 ]
プログラム言語だけでプログラムが動くわけじゃないからな

456 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 14:37:08 ]
>>454
除算は「検知」はできるでしょ?

まあ、言いたいことはわかるけど。

457 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 17:53:21 ]
printfの引数不正も検知できますよ。
除算よりは面倒ですが。

458 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 18:20:34 ]
どうやって?

459 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:20:51 ]
printfの呼び出し元で実引数の型情報を渡すようにinstrumentする。



460 名前:デフォルトの名無しさん mailto:sage [2008/03/23(日) 19:33:19 ]
なるほど。

大変だな。

そこまでしてCを使うのは。

461 名前:デフォルトの名無しさん [2008/03/24(月) 21:13:13 ]
>>460
そうだよ。
だから、Cを使うということはそのあたりの危険性と利便性をトレードオフする
考え方をもたないと駄目です。
やたら安全性をどうこう言っててもprintf使うだけでもう台無しです。

462 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 21:18:20 ]
もう、かまってチャンは卒業しなよ

463 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 21:39:43 ]
やっぱり>>453だよな。

いまさらC言語入門なんて。

464 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 21:48:43 ]
だからバカはC言語使わないでください。おねがいします

465 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 22:04:12 ]
バカなのでC言語しか使えません。
他の言語は難しすぎて。

466 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 22:40:59 ]
Java だって + と - 間違えたら間違った計算結果が出てくるわけで・・・

467 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 22:59:48 ]
間違えることのでき、なおかつ、それを機械的に検出できない箇所の数が、道具によって変る

っていう話しなんだよ。

468 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 23:18:09 ]
たんによくあるセキュリティ的な話でそ。
Java で間違ったものを toString() しても機械が気付くわけでもなし。

469 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 23:46:10 ]
>>468
セキュリティに限らず、いかにバグの入り込む余地を減らすか、ってこと。
余地が少なければ、バグの有無を確認するための工数が減るわけよ。




470 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 23:55:12 ]
まあ、コンパイル時にチェックできるところはやるのは当然として、
実行時のチェックは性能とのトレードオフもあるから、Cは今ぐらい
で丁度いいと思う。

471 名前:デフォルトの名無しさん mailto:sage [2008/03/24(月) 23:59:58 ]
いろいろチェックしたらJavaと同じことをやることになって、Javaよりも遅くなったりしてね。

472 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 00:35:28 ]
Cは機械寄りだから技術者以外には使えないのは当然だと思う。

473 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 15:13:05 ]
>>469
まだわかってないな。

>バグの入り込む余地を減らすか
という観点では、printf が他の関数等よりもバグ発生契機が多いとは言えないだろう、
と言ってるわけ。もちろんセキュリティに関しては全く別だよ。

実際 gcc は printf("name=%s, qty=%d\n", qty, name) に warning だしてくれるけど、
Java は WriteLine( "name="+qty.toString()+"qty="+name) をスルーする。
printf でチェックが必要なら他のどの方法でもやはりチェックが必要。

漏れは LISP 使いだし出力は全て内部構造のままS式で出すよ、という人は別だけど。

474 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 15:27:34 ]
>>473
printfに限った話ではないし。

int height ;
int weight ;
中略
height = weight ;
こういうのを機械的に検出できるかどうかは、
微々たる事ではあるが、
ソフトウェアの規模が大きくなってくると重要よ。

475 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 15:49:47 ]
>>474
だからそれが printf とどう関係するんだよ、という話。
「限った話ではない」ではなく、全く関係のない独立した話ですよ。

>>469なんか、まるで printf の仕様がバグ発生契機を増やすかのように
さぞもっともらしいことを書いているが、ではどの処理系でどう書けば引数の
取り違えによるバグを避けられるかは一切提示していない。

>>474に至っては、printf の仕様の問題点については一切語らずに、
「に限った話ではない」との一言で、あたかもprintfに他の同等の処理よりも
多くの問題点があるかのようにほのめかしている。

printf に問題があるなら、プログラマなんだからもっとストレートフォワードに
この処理系のこういう書式化指定法ならバグが減る、と実例を出して批判して。

476 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 16:20:46 ]
yosoでやれ

477 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 16:46:28 ]
>>475
仮にprintfが他よりバグ発生契機が多いとは言えないとして、
それで一体お前は何を主張したいんだ?

printfフェチ?

478 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 17:26:31 ]
不当にCを貶めようとしてるヤツに怒ってるんじゃないの?

479 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 17:27:18 ]
そんな奴いたか?



480 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 18:27:14 ]
>>475
引数の順序などを取り違える
ことと、
書式化指定文字列での型指定を間違える
ことを分けて考えようぜ。


481 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 22:31:54 ]
>>474
どうでもいいけど、

> int height ;
> int weight ;
> 中略
> height = weight ;
> こういうのを機械的に検出できるかどうかは、

これは一体何が言いたいんだ?

482 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 22:35:59 ]
話を発散させるためなら内容なんてなんでもいいんだぜ?


483 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 22:37:15 ]
>>479

>>467
>>469
>>474

484 名前:デフォルトの名無しさん mailto:sage [2008/03/25(火) 22:52:23 ]
>>481
たぶん>>467だと思う。

485 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 08:04:24 ]
>>484
具体的に>>474のどこが間違いで、何が機械的に検出できないんだ?

486 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 09:10:16 ]
高さを表わすint型の値と重さを表わすint型の値は、
型は同じだけれども、値の意味が違う。

だから、
height = weight ;
のような代入は、
C言語の言語仕様的には間違っていないが、
プログラムの意味的には間違っている。

それを機械的に検出できないとは言ってない。
工夫して検出可能にすることもできる。

工夫して検出可能にするか、
あるいは、
小細工せず検出不可能のままにするかは、
自由だ。

ただ、ソフトウェアの規模が大きくなってくると、
「人間が注意してコーディングして、しっかりテストすればいいんだ」
なんて言ってられなくなるので、
機械的に検出できるものは検出しよう、ということになるわけ。

487 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 09:28:17 ]
>>486
そのプログラムの「意味」というのには、
 ソースが英語で書かれてる
というのが大前提としてあるよね。

仮に、heightが横幅でweightが縦幅を意味する言語があったら、
そのプログラムの「意味」は全く正しいということになる。

488 名前:474 mailto:sage [2008/03/26(水) 09:55:54 ]
>>487
このスレを読み書きしている人で、
heightとweightが英語だと理解しなかった人がいたら、
手をあげて欲しい。
そういう人がいたなら、次からは何か改善するよ。

489 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 10:02:53 ]
height = weightを機械的に検出しなきゃいけないってどんだけw
なんのための変数名だよ



490 名前:474 mailto:sage [2008/03/26(水) 10:25:44 ]
例がわかりやすいように、わざと豪快に間違ったコード片を書いた。

ここまで豪快なミスは少ないだろうが、このタイプのミスをしたことの
ある人はいるでしょう?

491 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 10:37:20 ]
その手の間違いでNASAの火星探査が失敗したってニュースがあったような

492 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 10:37:42 ]
>>488
問題は人間じゃなくて、機械がそれを英語かどうかを判断できないってこと

493 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 10:41:07 ]
>>488
例えば、heightをheiと省略したらその「意味」は通じなくなるし、
他にもhaightとミスタイプしたら通じなくなる。

494 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 10:43:10 ]
>>491
そりゃデバッグが足りなかっただけで、
それを言語仕様のせいにするのはちゃんちゃらおかしいだろw

495 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 11:27:35 ]
そこでアプリケーションハンガリアンですよ。
local.joelonsoftware.com/mediawiki/index.php/%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AF%E9%96%93%E9%81%95%E3%81%A3%E3%81%A6%E8%A6%8B%E3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B

496 名前:474 mailto:sage [2008/03/26(水) 11:34:13 ]
>>492
>>493
貴方達が人工知能的なアプローチしか頭にないのは、わかった。
俺らはtypedefを使ってコーディングして、それを機械的にチェックする。

497 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 11:47:31 ]
>>494
そういう考え方だと大きなプログラムのデバッグは大変だな。

498 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 13:11:47 ]
機械的ってのはコンパイラが検出という意味ではないのか。

TypedWidth redBoxWidth;
TypedHeight redBoxHeight;
  :
TypedWidth blueBoxWidth = redBoxHeight;
TypedWidth GreenBoxWidth = (redBoxWidth + redBoxHeight) / 2

とかコンパイルエラーになったら途方に暮れるもんな。

幅と高さは、型を分ける必要は感じないな。
熱量と体積とか、加速度と質量とかなら、型を分けて演算や代入に制限を加えるのは望ましいと思う。

499 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 14:48:04 ]
heightとweightの話をしてるのに気づかない人がいた



500 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 15:59:06 ]
>>496
>474に出てくる変数はすべてint型ですが?
少なくとも、今の話題にtypedefは関係ないよね。
それはまた別の話。

>>497
というかさ、コンパイラにプログラムの意味を解釈させるというのは、全く現実的な話じゃないわけさ。
プログラマの意図する「意味」とコンパイラの意図する「意味」の整合性を保つのがどれだけ大変かわかってるの?
テストを行う方が圧倒的に簡単だし、
そもそも俺には「コンパイラに意味を解釈させれば論理エラーが減る」
という考え方の方がよっぽどデバッグを大変にすると思うんだよね。

>>499
そこで質問なんだが、なぜ重さを高さに代入してはいけないの?
BMI指数なんかは、体重/身長^2 で計算するんだがこれは論理エラーなのか?
超体重理論の公式が、高さ=重さ*2.5 だった場合はどうなんだ?
他にも、例えば Tundere = Deredere はエラーになるのか?
Yandere = Tundere の場合はどうなのか?

501 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 17:07:34 ]
>>500
>BMI指数なんかは、体重/身長^2 で計算するんだがこれは論理エラーなのか?
BMI指数の次元が 重さ/長さ^2 であるってだけのことだなぁ。

>超体重理論の公式が、高さ=重さ*2.5 だった場合はどうなんだ?
それはきっと次元を持つ比例定数が省略されてるな。(超体重理論って何?)
PV=nRTのRみたいな。

502 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 17:19:08 ]
www.boost.org/libs/mpl/doc/tutorial/dimensional-analysis.html
C++なら次元解析なんかメタプログラミングで独自の型システム構築すればいいだけなのにね!

503 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 17:19:45 ]
>>501
例えば、PV=nRT で V=1, nR=1 なら簡略化して P=T と書けるよね。
つまり、pressure = temperature、圧力 = 気温 となるわけだ。
これは正しいんだよな?

そこで何度も同じ事を聞いて申し訳ないんだが・・・
なぜ height = weight が絶対に間違いだと言い切れるんだ?
どうして重さを高さに代入するのが「論理エラー」になるんだ?
比例定数1が隠されてる可能性は絶対にないと言い切れるのか?

504 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 17:27:12 ]
仮にheight = weightが正しい(意図してそうする)のであれば、
型でいうところのキャストみたいに、明示すればいいということだと思う。

505 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 17:57:12 ]
前提を隠されて「圧力 = 気温」と言われたら、間違ってるとしか言えない。
間違いと言われたくないなら前提を隠さないでくれ。

506 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 18:32:12 ]
>>504, 505

>>474
> int height ;
> int weight ;
> 中略
> height = weight ;

をエラーにするっていうのはこういう意味だよ。

507 名前:474 mailto:sage [2008/03/26(水) 18:55:09 ]
>>500
> 少なくとも、今の話題にtypedefは関係ないよね。

いや関係ある。

1. 引数の型が違う → 型をチェックすれば、検出できる間違いがある
2. 引数の型は同じだが、値に互換性がない → 値の互換性をチェックすれば、検出できる間違いがある
3. 引数の型が同じで、値にも互換性があるが、変数を取り違えている → お手上げ

こういう3段階があるものの、基本的には同一の問題だろう。

> コンパイラにプログラムの意味を解釈させるというのは、全く現実的な話じゃないわけさ。

その通り。俺に対して反論してる人が現実的ではない話を持ち出してるだけだぞ。
なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。

> BMI指数なんかは、体重/身長^2 で計算するんだがこれは論理エラーなのか?

そういう計算をする関数は数が限られているのだから、
それが意図したものであれば、慎重にチェックの対象から外せばいい。


508 名前:474 mailto:sage [2008/03/26(水) 19:05:52 ]
>>503
> 例えば、PV=nRT で V=1, nR=1 なら簡略化して P=T と書けるよね。

そこでスレタイ。1だからといって省略すべきではない。

そして、間違える余地を減らすためにも、
PをV、n、R、Tから求める関数を作って必ず使うようにすべき。
関数を使う以上、引数には1を渡すしかあるまい。

いまどきのコンパイラはinline展開してくれるからP=Tと同じ結果になろう。

> なぜ height = weight が絶対に間違いだと言い切れるんだ?

なぜなら、間違ってheight = weightと書いたという例だから。


>>506
色々とバグで痛い目を見ると、考え方が変ってくるかもよ。


509 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 19:45:35 ]
>>507
型が同じか違うかで、この問題の解答が全く変わってくる。
「基本的には同一の問題」というのはダウトだろう。
実際、>>507の1,2,3で間違い検出の可能性が全く違っているし。

> なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。
>
>>474 を見たら、「コンパイラによる意味解釈」ということしか思いつかないのだけど。。。
他に>>474の解釈があるなら是非教えて欲しい。
「型が同じでも違っても基本的には同一の問題だから、型チェックでどうにかする」
みたいな詭弁は無しの方向で頼む

> それが意図したものであれば、慎重にチェックの対象から外せばいい。
>
チェックの対象から外すというけど、そもそもそのチェックって一体どうやってやるんだい?
型チェックなら、古の言語Cでもすでにやってし、
なによりそれでで解決がつくなら、>>474でint型しか出さなかった理由がわからない。
確認するけど、型チェックは大前提としあって、
他にも意味論を持ち出せばさらにバグが減らせるという主張でいいんだよね?



510 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 19:47:23 ]
> そこでスレタイ。1だからといって省略すべきではない。
>
仮に sizeof(char) が省略すべきでないとしても、省略することは常に可能。
つまり、1は常に省略される可能性があるし、それは常に正しくあるべき。
というか、1をかけるかどうかで意味が変わってきたら、
「だから○○は使えねえんだよw」 (○○には好きな言語やライブラリ名をどうぞ)
とか言われそうなんだけど

> なぜなら、間違ってheight = weightと書いたという例だから。
>
たしかに>474はそれを間違いだと知ってるかもしれない。
でも、少なくとも俺にはそれが分からなかったし、もっと言えばコンパイラにはなんのことやらチンプンカンプンだろう。
なのでコンパイラにそれが間違いだと教える必要があるのだけど、それは一体どうやってやるの?

511 名前:デフォルトの名無しさん mailto:sage [2008/03/26(水) 19:59:24 ]
省略すべきでないのは型の使い分け・型変換の明示だろう。*1なんかいらない。
charとかstrlenとかをハードコーディングしちゃうのではね。

512 名前:498 mailto:sage [2008/03/27(木) 14:19:26 ]
素で間違えてた。眼鏡買ってくる。

>474とそのフォロワーが何人かいるのだとおもうが、

>509
多分フォロワーは、(現実的に可能なら)型を分けるべきという議論をしていると思う。
>474は、>496でtypedefでも機械的にチェックできると言ってるが、フォロワーは同意しないかもしれない。

圧力と気温を別の型として扱う型システムが手に届くところにあったら >509 も使うでしょ?
今は自前で定義するもの大変だし定番ライブラリも無いしね。

513 名前:デフォルトの名無しさん [2008/03/27(木) 16:10:03 ]
関数をハードコーディング?

514 名前:474 mailto:sage [2008/03/27(木) 22:48:04 ]
>>509
変数の取り間違い、という同一の問題です。
段階0として、人間が目を皿にして探す、ってのを入れてもいいよ。

> >>474 を見たら、「コンパイラによる意味解釈」ということしか思いつかないのだけど。。。
> そもそもそのチェックって一体どうやってやるんだい?

LINTの類いを使っていないと、それしか思いつかないのかもしれないね。

> >>474でint型しか出さなかった理由がわからない。

C言語のtypedefはtypedefしてたってintはintだよ。

> 確認するけど、型チェックは大前提としあって、
> 他にも意味論を持ち出せばさらにバグが減らせるという主張でいいんだよね?

「意味論」なんて持ち出してないぞ。


515 名前:デフォルトの名無しさん mailto:sage [2008/03/27(木) 22:57:35 ]
>>510
> つまり、1は常に省略される可能性があるし、それは常に正しくあるべき。

省略したらバグるべきだとは主張してませんが?

してもしなくても動作は変らないけど、
プログラムを読んだ人間に意図がわかるようにするために省略すべきではないのよ。

> 少なくとも俺にはそれが分からなかった

例や文章が不適切でゴメンね。
でも、今までの話で分かったでしょ?

> なのでコンパイラにそれが間違いだと教える必要があるのだけど、それは一体どうやってやるの?

機械的に検出するためには、機械的に検出できるようにコーディングするのよ。
コンパイル時にエラーになるだけが、検出ではないよ。

>>513
charやwchar_tを直に書かず、マクロやテンプレートによって切り換え可能にすることに対して、
それらを直に書くことをハードコーディングというのだろう。

516 名前:474 mailto:sage [2008/03/27(木) 22:57:56 ]
おう、515は名前欄かきわすれた。

517 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 00:02:37 ]
>プログラムを読んだ人間に意図がわかるようにするために省略すべきではないのよ。
それは常識が共有できている時しか成り立たない。
変なコードが書いてあったら書いた奴に意図を聞きたくなる。

そしてスレタイ。*sizeof(char) を書くべき派といらない派は、この点において常識を共有できていない。

518 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 00:39:49 ]
問題はいらない派がわかってて省略しているのかどうか

519 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 14:45:44 ]
>>514
LINT の類でお勧めは何だ?



520 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 15:18:57 ]
splint

521 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 19:25:44 ]
>>514
> LINTの類いを使っていないと、それしか思いつかないのかもしれないね。
>
LINTでどうやって間違いを検出するのかというと・・・
C言語ならforとかwhileとかを「キーワード」という特別な扱いにして
その周辺の文法や、他にもよくありがちな構文上の間違いが無いか検証するわけね。
話を戻すとつまり、weightとかheightや他の英単語をキーワードとして扱うということ?

> C言語のtypedefはtypedefしてたってintはintだよ。
>
>>474で重要なのは、weightとheightが「同じ型である」ということなわけ。
同一の型の代入を、「変数名が間違っている」という理由でどうやってエラーにするの?
と何度も聞いているのだけど。

> でも、今までの話で分かったでしょ?
>
ぜんぜん分からないのだけど。。。
>>474は一体何が問題なのか? というところから分からない

522 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 19:41:51 ]
>>515
> 機械的に検出するためには、機械的に検出できるようにコーディングするのよ。
> コンパイル時にエラーになるだけが、検出ではないよ。
>
間違いを検出するのは、コンパイル時ではないということ???
あなたの主張が全く見えないので、以下で確認させて欲しい。

問1) >>474は具体的にどこが間違っているのか?
1、weightとheightが同じ型であるところが間違っている。これらは型を分けるべき
2、(同じ型であっても)名前が間違っているのは明らかだから、代入したらエラーがでるべき。
3、その他

問2) あなたのいう「機械的に検出」とは具体的にどのような方法で行うのか?
1、weightとheightの型を分ける
2、weightやheightや他の英単語をキーワードとして登録し、その使われ方をチェックする
3、コンパイラや他の何か(例えばLINTやリンカなど)に意味解析をさせる
4、その他

問3) >>474の間違いを検出するフェーズは具体的にどこか?
1、コンパイルの開始前(いわゆるLINT)
2、字句解析時
3、構文解析時
4、構文木を作った後の独自のエラーチェック時
5、コード生成時
6、実行時
7、その他

523 名前:474 mailto:sage [2008/03/28(金) 22:06:15 ]
>>521
> weightとかheightや他の英単語をキーワードとして扱うということ?

No.

> 同一の型の代入を、「変数名が間違っている」という理由でどうやってエラーにするの?

さぁ。
それはあなたが言い出したことなのだから、自分で考えてくださいな。

>>522
> 間違いを検出するのは、コンパイル時ではないということ???

コンパイル時に限らない。

> 問1)

3

> 問2)

4

> 問3)

7


524 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 22:10:35 ]
ワラタ
答えられないのかよ

525 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 22:47:39 ]
>>523
電波に付き合うなよ

526 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 22:56:07 ]
適当に振ったネタが予想以上に好評でウケタw

527 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 23:18:40 ]
そもそも変数名にheightやweightってつけるのは、人の目から見て意味のある名称にして
人間が間違えないようにするため。
それを機械的にって根本的におかしいだろ。

528 名前:デフォルトの名無しさん mailto:sage [2008/03/28(金) 23:26:51 ]
>>527
> なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。

529 名前:デフォルトの名無しさん mailto:sage [2008/03/29(土) 01:45:42 ]
趣味で独自の作法でプログラム書いてる人間には理解できない世界のお話。



530 名前:デフォルトの名無しさん mailto:sage [2008/03/29(土) 16:29:22 ]
>>524の未熟さが微笑ましい

531 名前:デフォルトの名無しさん mailto:sage [2008/03/29(土) 23:11:22 ]
世の中には、

mallocしたものをfreeするとバグの原因になるからfreeしないほうがいい
どうせプロセスが終了するときに解放されるのだから

なんて言う人もいるのですよ。

532 名前:デフォルトの名無しさん mailto:sage [2008/03/29(土) 23:28:43 ]
また古い話を持ち出してきたなぁ。

533 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 00:43:34 ]
そのネタ飽きた

534 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 16:27:19 ]
ていうかmallocするとバグの元になるから
そもそもなるべくmallocしないで済む設計にするのがいいよ

535 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 17:45:10 ]
プログラム組むとバグの元になるから...

536 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 21:25:10 ]
だからデバッグ済みのライブラリを使うのですよ。

537 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 21:51:22 ]
そのライブラリを呼び出すコードがバグの元になるから...

538 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 21:53:52 ]
> なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。

539 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 22:58:15 ]
ネタだから。



540 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 23:37:05 ]
ネタをネタとわからない人には(

541 名前:デフォルトの名無しさん mailto:sage [2008/03/30(日) 23:51:53 ]
>>474 が書いたコードを見てみたい・・・

何か放流してくれないかな?

542 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 07:39:29 ]
typedef int WEIGHT;
typedef int HEIGHT;

WEIGHT weight;
HEIGHT height;

height = weight; // warning: 型の異なる代入ですというコンパイラは存在するのか

543 名前:デフォルトの名無しさん mailto:sage [2008/06/12(木) 07:51:23 ]
PODと非PODを区別しろよ

544 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 23:56:31 ]
そういうのはクラス化するという例をEffective C++で最近読んだ。


545 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 00:44:21 ]
>>543
そう言う問題じゃなくて、POD であることはわかってるけど、
プログラマが別の型と定義したんだから、 警告するようにすれば
身長 × 体重 なんてしてしまうバグを減らせると言うことなんだ
ろう。

>>542
言語は違うけど、Pascal とか Ada はそう言う型を定義できる。
現状の枠内でやろうとするなら、>>544 の方法がいいと思う。

546 名前:デフォルトの名無しさん mailto:sage [2008/09/16(火) 23:54:11 ]
strong typedefを知らずにこんなスレに書き込む奴がいたのか
2008年だぞ今年…

547 名前:デフォルトの名無しさん mailto:sage [2008/09/17(水) 09:21:36 ]
後からのこのこ現れて間抜けな事を書き捨てていく奴って何なの?
流行ってんの?

548 名前:デフォルトの名無しさん mailto:sage [2008/09/17(水) 23:29:21 ]
>>547
よう、低脳

549 名前:デフォルトの名無しさん mailto:sage [2008/09/18(木) 00:57:02 ]
>>548
よう、ド低脳



550 名前:デフォルトの名無しさん mailto:sage [2008/09/18(木) 07:56:04 ]
独自の拡張にメリットを見い出せないからこそBOOST(ライブラリ)やD(派生言語)でstrong typedefを実現しているのだけれど
>>547
間抜けだという理由をどうぞ
さぞかし説得力のある解説をして下さるのだろう

単純に既存のC/C++処理系の拡張としてtypedef警告が実装されていたら
WindowsやOpenGLのプログラムなんてやってられないと思うのだがね

551 名前:デフォルトの名無しさん mailto:sage [2008/09/18(木) 08:41:21 ]
3ヶ月も経ってからレスしてたらやっぱり間抜けだろ。

552 名前:デフォルトの名無しさん mailto:sage [2008/09/18(木) 11:44:15 ]
スレ違い…ってのはまあ、3月以降全部そうか。

553 名前:デフォルトの名無しさん mailto:sage [2008/09/18(木) 17:42:08 ]
>>551
わざわざ煽りレスして理由がそれってのは苦しいと思うが…

554 名前:デフォルトの名無しさん mailto:sage [2008/09/21(日) 05:21:06 ]
IDないと句読点や三点リーダの不備が余計目立つな。

555 名前:デフォルトの名無しさん mailto:sage [2008/09/21(日) 06:25:06 ]
日本語でokというか、独り言なら書かなくてよし

556 名前:デフォルトの名無しさん [2008/10/20(月) 09:05:31 ]
馬鹿な>1っているもんだな

557 名前:デフォルトの名無しさん mailto:sage [2008/10/24(金) 01:19:22 ]
#define strlen(a)
って宣言してみる。






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<137KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef