K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[1478] 質問
投稿者:高校生
2009/11/26 13:04:12

crowbar_book_0_1の string.cとmain.c(memoryフォルダに入ってないほう)の説明がほしいのですが。 ファイル名や中身からしてなんとなくわかる気もするのですが、 簡単にでもいいのでお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1476] オブジェクト指向再入門/「オブジェクトに仕事をさせる、ということ」のソースについて
投稿者:(ぱ)こと管理人
2009/11/22 18:33:00

メールにてご指摘がありました。 以下のページのソースコードにおいて、 http://kmaebashi.com/programmer/object/shigoto.html Java版の以下のソースに間違いがありました。 // コロンで区切るためのStringTokenizerを生成 StringTokenizer st = new StringTokenizer(line, ":"); // 著者名を(複数)取り出す writers = st.nextToken(); // コンマで区切られた著者名を順に切り出すために // 新たなStringTokenizerを生成 StringTokenizer st2 = new StringTokenizer(line, ","); i = 0; while (st2.hasMoreTokens()) { writer[i] = st2.nextToken(); i++; } 著者名を順に切り出す対象は、その前のStringTokenizerで取得した writersですから、以下のようにしなければいけません。 // コンマで区切られた著者名を順に切り出すために // 新たなStringTokenizerを生成 StringTokenizer st2 = new StringTokenizer(writers, ","); 現在海外出張中でオリジナルが直せませんので、取り急ぎお知らせします。 すみませんでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1475] Re:質問
投稿者:(ぱ)こと管理人
2009/11/21 01:33:54

>util.cについて教えてください。 >/* BUGBUG >CRB_NativeFunctionProc * >    . >    . >*/ >とコメントにしたのはなぜでしょうか。 おそらくは昔はネイティブ関数とcrowbarの関数を別々の連結リストで 管理していたところ、あるとき一本化して、この関数だけ残骸として 残ったようです。無視してください。 リリース前にはきれいにしておくべきでした。すみません。 >/*FALLTHRU*/というのは何かの指令なのですか。 >C ソースコード検査プログラムの lint と関係ありますか。 lintと関係あります。 Cのswitch caseというのは、「breakを書かないと下に落っこちていく」という とんでもない仕様になっているので、よくbreakを書き忘れてはまる人が いるわけです。そこでlintはそれを検出する機能があるわけですが、 といって、本当に「下に落っこちていく」動きにしたい場合に警告が出て しまったのでは困りますので、その警告を抑止するコメントが/* FALLTHRU */です。 とはいえいまどき昔ながらのUNIXのlintを使っている人は少ないでしょうし、 gccとかだと無視するようなのであまり意味はないかもしれませんが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1473] 質問
投稿者:高校生
2009/11/18 11:54:00

util.cについて教えてください。 /* BUGBUG CRB_NativeFunctionProc *     .     . */ とコメントにしたのはなぜでしょうか。 /*FALLTHRU*/というのは何かの指令なのですか。 C ソースコード検査プログラムの lint と関係ありますか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1472] Re:DIKSAM_book_0_4のLinuxでの実行結果について (その2)
投稿者:(ぱ)こと管理人
2009/11/18 02:59:27

>UTF-8版がエラーとなり、 >EUC版がうまくいったのはたまたまLANG環境変数が一致したからですか? たまたまというか、たいていのLinux環境はEUCかUTF-8のどちらかであり、 それに対応するためにふたつの配布パッケージを用意しているわけです。 ところで青餓鬼さんにお願いですが、この掲示板で誰かの投稿に返信する際は、 「新規投稿」リンクではなく、対象の投稿の「返信」リンク(右上にあります)を 使っていただけないでしょうか。 「スレッド順インデックス」で見たときに、応答の流れが見えますので。 http://kmaebashi.com/bbs/thread.php?boardid=kmaebashibbs
[この投稿を含むスレッドを表示] [この投稿を削除]
[1471] Re:DIKSAM_book_0_4のLinuxでの実行結果について (その2)
投稿者:yuya
2009/11/18 01:13:48

こちらはVineLinuxでLANG環境変数がja_JP.UTF-8な環境で試してみました。 ちょうど青餓鬼さんと逆に、test.dkmはUTF版では正常動作し、EUC版では Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. アボートしました とのメッセージが出ました。当然といえば当然の結果ですね。 これは納得が行きましたが、あとは青餓鬼さんが前に書いていたMacの結果だけが気になりますね(文字コード以前に、素のバイト列のままだった)。 むし返すようで申し訳ないんですけど、Macでの環境変数LANGは何だったのか、 よければ教えてもらえませんか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1470] DIKSAM_book_0_4のLinuxでの実行結果について (その2)
投稿者:青餓鬼
2009/11/17 14:43:18

Vine Linuxでの echo $LANG の実行結果は ja_JP.eucJP でした。 UTF-8版がエラーとなり、 EUC版がうまくいったのはたまたまLANG環境変数が一致したからですか? 大変勉強になりました。 以上
[この投稿を含むスレッドを表示] [この投稿を削除]
[1469] Re:質問
投稿者:(ぱ)こと管理人
2009/11/17 03:22:16

>crowbar_book_0_1に、debubgフォルダとmemoryフォルダがあったのですが >これらは何のためのフォルダなのですか。 「高校生」さんが書籍版「プログラミング言語を作る」をお持ちなら、 92ページにディレクトリ構成の図があります。メモリ管理モジュール MEM(memoryフォルダ)の説明はp.92からありますし、デバッグ用モジュール DBG(debugフォルダ)の説明はp.96からです。 Web版なら、以下のページに説明があります。 http://kmaebashi.com/programmer/devlang/crowbar_0_1.html こちらにはdebugのほうの説明はないので補足すると、たとえば 以下のソースが例として挙げられると思います。 http://kmaebashi.com/programmer/devlang/crowbar_src_0_1_01/S/22.html#57 >if (cond.type != CRB_BOOLEAN_VALUE) { > crb_runtime_error(statement->u.if_s.condition->line_number, > NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END); >} >DBG_assert(cond.type == CRB_BOOLEAN_VALUE, ("cond.type..%d", cond.type)); このDBG_assert()を通るときにはcond.typeは絶対にCRB_BOOLEAN_VALUEであるに 決まっているわけですが、万一なにかの思い違いでそうでなかったとき、 DBG_assert()はメッセージを2行吐いて異常終了します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1468] 質問
投稿者:高校生
2009/11/16 11:28:34

crowbar_book_0_1に、debubgフォルダとmemoryフォルダがあったのですが これらは何のためのフォルダなのですか。 一通り見たのですが難しいです。 こんな質問ですみません、学校のレポートにまとめなければならないので...。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1467] Re:DIKSAM_book_0_4のLinuxでの実行結果について
投稿者:(ぱ)こと管理人
2009/11/15 21:32:30

>2.UTF-8版の場合 >次のようなメッセージを2回表示しアボートします。 > >Assertion Failure (WC_format != NULL) file .. error.c line .. 92 当方のUbuntu Linuxで再確認しましたが、正常動作しました。 確認ですが、この時のLANG環境変数の値は何になっているでしょうか? Linuxなら、LANG環境変数の値は「echo $LANG」で確認することができます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1466] DIKSAM_book_0_4のLinuxでの実行結果について
投稿者:青餓鬼
2009/11/14 15:35:42

Windows XP上のVirtualPCでVine Linuxを起動し、EUC版とUTF-8版のDIKSAM_book_0_4を実行してみました。 どちらもWindowsの時のようにdiksam.yのソース修正することなくmakeは正常に終了しました。 TEST.DKMを引数にして実行すると次のような差異が生じました。 1.EUC版の場合 実行結果はTESTディレクトリ内のTEST.RESULTと同じ内容が表示されます。 正常終了!! 2.UTF-8版の場合 次のようなメッセージを2回表示しアボートします。 Assertion Failure (WC_format != NULL) file .. error.c line .. 92 アボートしました。 *** とりあえず Linuxでは EUC コードで先に進めていきます。 *** 誰かIntel Macでの実行を試行してみませんか !!! 以上
[この投稿を含むスレッドを表示] [この投稿を削除]
[1464] Re:質問
投稿者:(ぱ)こと管理人
2009/11/05 01:46:09

>CrowbarからCを使うとありましたが,Cで書かれた別アプリケーションからインタプリタを使うことについて、どういうことかイメージがわきません。 「crowbarからCの関数を呼び出すことの意味はわかるけれど、  Cからcrowbarのインタプリタを呼び出せて何が嬉しいのかわからない」 ということでよいでしょうか? Cで書かれたある程度の規模のプログラムがあるとして、そこからcrowbarが 呼び出せると、crowbarを、そのプログラムのカスタマイズ用言語として使うことが できます。 すぐ思いつく例としては、 ・Microsoft WordやExcelはカスタマイズ用言語としてVBAを使うことができる。 ・UNIXのエディタEmacsは、Emacs Lispでカスタマイズできる。 ・CADなどでは、カスタマイズ用スクリプト言語がついているものがある。 などがありますが…考えてみれば高校生はOfficeは使わない気がするし、 UNIXも使っていなければEmacsも知らないかもしれないし、ましてやCADを 見たことがあるとも思えませんねえ。 手近な例としては、秀丸エディタのマクロなんかどうでしょうか。 http://hide.maruo.co.jp/lib/macro/index.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1463] 質問
投稿者:高校生
2009/11/04 11:55:59

CrowbarからCを使うとありましたが,Cで書かれた別アプリケーションからインタプリタを使うことについて、どういうことかイメージがわきません。説明やいいサイトを紹介してくれたら幸いです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1462] Re:DIKSAM_book_0_4のMac/Winでの実行結果について(その2)
投稿者:(ぱ)こと管理人
2009/11/04 02:19:50

>出力結果と文字コード表を付き合わせると、Shift-JISじゃなくてEUCだと思うのですが……。 出力結果: > str[0]..50940 16進数に直すとC6FC 文字コード表を見ると…すみません、確かにEUCでした。ご指摘ありがとうございます。 同じ手順で確認したはずが、なぜShift-JISだと思ってしまったんだろう。 >つよしさんのテストではワイド文字への変換は行われているがUnicode化されていない。 >青餓鬼さんのテストではそもそもワイド文字にも変換されず、素のバイト列のまま、と。 ということですよね。つよしさんの実験がEUC環境下で行われたなら、実質無変換で、 ただしマルチバイトの1文字として変換されたということでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1461] Re:DIKSAM_book_0_4のMac/Winでの実行結果について(その2)
投稿者:yuya
2009/11/03 00:47:46

Mac持ってませんが探究中です。 >なぜか当時追及しなかったようなのですが、Windowsと同じようには動いていませんね。 >この出力だけ見ると、ワイド文字に変換した結果がShift-JISになっているように >見えますが、いくらなんでもそんなはずは…… 出力結果と文字コード表を付き合わせると、Shift-JISじゃなくてEUCだと思うのですが……。 つよしさんのテストではワイド文字への変換は行われているがUnicode化されていない。 青餓鬼さんのテストではそもそもワイド文字にも変換されず、素のバイト列のまま、と。 引き続き調査しまーす。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1460] Re:質問
投稿者:(ぱ)こと管理人
2009/11/02 22:50:27

>crowbar.hを見ていると/*create.c*/や/*string.c*/などが書いてありました。 これですね。 http://kmaebashi.com/programmer/devlang/crowbar_src_0_4_02/S/6.html >これは、例えばcreate.cというファイルが、crowbar.hの/*create.c*/と書いてある以下の部分を使うということですか。 「以下の部分を使う」というのをどういう意味で書かれているのかはわかりませんが、 このコメントは、 「/* create.c */というコメントの下にある関数は、create.c内で定義されている」 ということを意味しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1459] 質問
投稿者:高校生
2009/11/02 10:51:03

crowbar.hを見ていると/*create.c*/や/*string.c*/などが書いてありました。 これは、例えばcreate.cというファイルが、crowbar.hの/*create.c*/と書いてある以下の部分を使うということですか。 気になりまして。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1458] Re:DIKSAM_book_0_4のMac/Winでの実行結果について(その2)
投稿者:(ぱ)こと管理人
2009/11/01 16:07:52

>私が問題にしているのは、Test.dkmの726行目 > if (str[i] == '本') { >の解釈で、WindowのCYGWINのGCCが作成した実行部は2バイト文字として >文字リテラルを解釈しているのに、MacのGCCで作成した実行部は文字リテラル数が >複数あるとしてエラーとしていることです。 まず、Diksamでは、"あいうえお".length()は5を返しますし、"あいうえお"[3]の 値は'え'である、というのが仕様です。つまり、Diksamでは、文字列は「バイトの 並び」ではなく「文字の並び」です。この「文字」は、日本語であっても、 1文字は1文字として解釈されなければなりません。 よって、実行に成功していれば、test.dkmにおける以下のコードの実行結果は、 string str = "日本語"; for (i = 0; i < str.length(); i++) { println("str[" + i + "].." + str[i]); if (str[i] == '本') { println("本"); } } 以下のようになるのが正解です。 str[0]..26085 str[1]..26412 本 str[2]..35486 ところが、青餓鬼さんの環境では、str.length()がEUCではが6, UTF-8では9に なっています。これはマルチバイト文字からUNICODEへの変換が行われておらず、 単にバイト列として読み込まれているように見えます。 マルチバイト文字からUNICODEへの変換処理はロケールに依存するので、 環境変数LANGの値はどうなっているのかが気になっているわけです。 とはいえ私はMacは持っておりませんしOS-Xを使ったこともないので、 見当はずれのことを書いている可能性はあります。詳しい方ご指摘ください。 過去MacOSで動かした人はいたはずだったよな、と思い掲示板の過去ログを 探したところ、以下の投稿が見つかりました。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1196&range=1 なぜか当時追及しなかったようなのですが、Windowsと同じようには動いていませんね。 この出力だけ見ると、ワイド文字に変換した結果がShift-JISになっているように 見えますが、いくらなんでもそんなはずは……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1457] DIKSAM_book_0_4のMac/Winでの実行結果について(その2)
投稿者:青餓鬼
2009/10/31 16:43:49

私が問題にしているのは、Test.dkmの726行目 if (str[i] == '本') { の解釈で、WindowのCYGWINのGCCが作成した実行部は2バイト文字として文字リテラルを解釈しているのに、MacのGCCで作成した実行部は文字リテラル数が複数あるとしてエラーとしていることです。 文字リテラルに関しては、ほかの手段を執るか制限を設けるのか検討が必要だと思います。 以上
[この投稿を含むスレッドを表示] [この投稿を削除]
[1456] Re:質問
投稿者:(ぱ)こと管理人
2009/10/29 07:40:34

>lexicalanalyzer.cを見ていると >#if 0 >と書かれていましたが、どういう意味でしょうか。 #で始まっていることから、#includeと同じようなプリプロセッサの機能であると 見当がつきます。 そこで、「プリプロセッサ」でGoogle検索すると、たとえば以下のようなページが 見つかります。 http://www.cppll.jp/cppreference/preproc_details.html >/*ここから下はテストドライバ*/ >とありました。これはなくてもよいのですか。 >何を意味しているのかを教えてください。 「テストドライバ」でGoogle検索するとWikipediaの以下のページが見つかります。 http://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%83%86%E3%82%B9%E3%83%88#.E3.83.86.E3.82.B9.E3.83.88.E3.83.89.E3.83.A9.E3.82.A4.E3.83.90.E3.81.A8.E3.83.86.E3.82.B9.E3.83.88.E3.82.B9.E3.82.BF.E3.83.96
[この投稿を含むスレッドを表示] [この投稿を削除]
[1455] 質問
投稿者:高校生
2009/10/28 11:56:27

scanf()の件はありがとうございました。 lexicalanalyzer.cを見ていると #if 0 と書かれていましたが、どういう意味でしょうか。 本のほうでは、 /*ここから下はテストドライバ*/ とありました。これはなくてもよいのですか。 何を意味しているのかを教えてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1454] Re:DIKSAM_book_0_4のMac/Winでの実行結果について
投稿者:(ぱ)こと管理人
2009/10/28 08:16:30

すみません、時間がないので手短に。 >◎◎結論 >文字列型stringの内部の表現形式は実行環境のC言語コンパイラに依存するとなると、他のUnix/Linuxは >わかりませんが、Mac/Winでの日本語のリテラル処理は、同じソースでは扱えないと思います。 内部の表現形式以前に、test.dkmの文字コードがunix_euc.tarではEUC、 unix_utf8.tarではUTF8になっており、それがそのまま出力されているように 見えます。 echo $LANG とすると、何が表示されますか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1453] DIKSAM_book_0_4のMac/Winでの実行結果について
投稿者:青餓鬼
2009/10/27 14:48:23

Diksam_book_0_4について、WinとMacの実行結果を次に示します。 ★Windowsの場合(XP ソースファイルはwin_sjis.lzh) 正誤表にあるCompilerディレクトリのdiksam.yのblockに関するソース修正を行い、diksam.yの745行目のソースを catch_clause : CATCH { $$ = dkc_start_catch_clause(); } 次のように修正すると catch_clause : CATCH { $<catch_clause>$ = dkc_start_catch_clause(); } makeは正常に終了し、test.dkmを処理してもtest.resultと同じ結果が得られます。 ★Mac(PPC G5,OS 10.4.11 ソースファイルはunix_euc.tar) diksam.yのソース修正をしなくてもmakeは正常に終了しますが、test.dkmを処理しようとすると 726行目のところでエラーとなります。(たぶんエラー内容は下と同じ) そこで次のようにソース修正すると、 string str = "日本語"; for (i = 0; i < str.length(); i++) { println("str[" + i + "].." + str[i]); // if (str[i] == '本') { if (i>0 && str[i-1] == 203 && str[i] == 220) { println("本"); } } 次のような結果が表示されます。 ・・(前の部分省略) 日本語 str[0]..198 str[1]..252 str[2]..203 str[3]..220 本 str[4]..184 str[5]..236 ★Mac(PPC G5,OS 10.4.11 ソースファイルはunix_etf8.tar) diksam.yのソース修正をしなくてもmakeは正常に終了しますが、test.dkmを処理しようとすると 726行目のところで"文字リテラルが2文字以上あります"というエラーとなります。 そこで次のようにソース修正すると、 string str = "日本語"; for (i = 0; i < str.length(); i++) { println("str[" + i + "].." + str[i]); // if (str[i] == '本') { if (i>2 && str[i-2] == 230 && str[i-1] == 156) && str[i] == 172) { println("本"); } } 次のような結果が表示されます。ただし、結果をファイルに落としてWinで表示させると日本語の部分は文字化けします。 ・・(前の部分省略) 日本語 str[0]..230 str[1]..151 str[2]..165 str[3]..230 str[4]..156 str[5]..172 本 str[6]..232 str[7]..170 str[8]..158 ◎◎結論 文字列型stringの内部の表現形式は実行環境のC言語コンパイラに依存するとなると、他のUnix/Linuxは わかりませんが、Mac/Winでの日本語のリテラル処理は、同じソースでは扱えないと思います。 以上、Mac/Winの実行結果を報告します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1452] Re:質問
投稿者:(ぱ)こと管理人
2009/10/27 02:42:42

>crowbarにはC言語で言うscanf(キーボードから入力)的なものは、ありましたでしょうか。 少なくとも最新バージョン(book_ver.0.4)では、fgets()の入力元を STDINにすることでキーボードからの入力が可能です。 str = fgets(STDIN); print(str); Cのscanf()のように、文字列を数値に変換するような機能はありませんので、 必要であればネイティブメソッドを書き足してみてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1451] 質問
投稿者:高校生
2009/10/26 11:20:14

電卓の件は、ありがとうございました。 crowbarにはC言語で言うscanf(キーボードから入力)的なものは、ありましたでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1450] Re:質問
投稿者:(ぱ)こと管理人
2009/10/23 03:05:44

>mycalc|_exで例えば >..5 >とか入力すると >電卓は終了してしまうのですか。 >それともlexical error とかが出るのですか。 現状では、手書きパーサのほうは syntax error. yacc/lex版のほうは、 lexical error. と表示して終了します。 yacc/lex版の_exありのほうは、パーサのエラーについては対処しており、 たとえば 1++2 のように入力すれば、エラーメッセージを出しますが電卓は終了しません。 確かにレキシカルアナライザの方でエラーが出ると終了してしまうので 実用上は対策がおおいに不完全ですが、ここではyaccのエラー処理の仕方を 説明しているということでご理解ください。 …とはいえ補足記事くらいは書いたほうがよさそうですね。検討します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1449] 質問
投稿者:高校生
2009/10/22 15:26:57

mycalc|_exで例えば ..5 とか入力すると 電卓は終了してしまうのですか。 それともlexical error とかが出るのですか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1448] Re:質問
投稿者:(ぱ)こと管理人
2009/10/22 07:35:27

>win_sjisのcalcフォルダにある電卓にはエラー処理はありますか? 本のほうで説明しているのはyaccのエラー処理の方法なので、 calcフォルダ以下の、mycalc_ex以下のmycalc.yにはエラー処理が入っています。 _exでないほうには入っていません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1447] Re:mingw32-make
投稿者:(ぱ)こと管理人
2009/10/22 07:32:48

>情報ありがとうございました。正直、Makefileの中身を書き換える根性はないのですが、 >補足等の形で近日中にUPさせていただきます。 修羅場だったり出張してたりでここに書くのが遅くなりましたが、 申しわけ程度の説明を↓のページに入れました。 http://kmaebashi.com/programmer/devlang/book/winenv.html 今見返しても本当に申しわけ程度ですが……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1446] 質問
投稿者:高校生
2009/10/21 11:52:38

win_sjisのcalcフォルダにある電卓にはエラー処理はありますか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1445] Re:mingw32-make
投稿者:yuya
2009/10/13 06:49:48

……とは言っても、Makefileにコマンドを書いた時点で、そもそもシェル依存なのか。 cdの構文が(ある程度)共通してるのはラッキーだったというだけで。 すいません、ひとりで納得してますm(_ _)m
[この投稿を含むスレッドを表示] [この投稿を削除]
[1444] Re:mingw32-make
投稿者:yuya
2009/10/13 05:52:44

まず、訂正。 >cd ../dvm; $(MAKE)$ 末尾の$は不要でした。 >makeが起動しようとするコマンド行を受け付けるのが、Cmd.exeの場合に >セミコロンを解釈しない、ということでしょうか。 そういうことだろうと思います。 >正直、Makefileの中身を書き換える根性はないのですが、 パスをダブルクォーテーションで囲んでみたり、 なんとかcmd.exeの機嫌をとろうとしたのですが、 うまく行く方法が見つかりません(^^;) 蛇足ですが、cdと$(MAKE)を別行にしてしまうと、 新しいシェルが立ち上がって、cd前のディレクトリに戻ってしまい、 makeで自分と同じMakefileを読みに行って再帰無限地獄に陥いりますよね。 #ってか、MinGWユーザが全員MSYS入れてるわけでもないでしょうし、 #けっこう普遍的な問題のような気がするのですが、情報が見つかりません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1443] Re:mingw32-make
投稿者:(ぱ)こと管理人
2009/10/13 02:17:46

>> cd ../dvm; gmake; >> 指定されたパスが見つかりません。 >> gmake: *** [../dvm/dvm.o] Error 1 > >といったエラーに悩んでる人が出てきてないでしょうか。 > >MSYSだと起こらないので、今日初めて気づいたんですが、 Cygwinを入れている私の環境でもそのままでは再現しませんが、 makeが起動しようとするコマンド行を受け付けるのが、Cmd.exeの場合に セミコロンを解釈しない、ということでしょうか。実際、コマンドプロンプトから 直接入力すると、同様のエラーが出ます。 情報ありがとうございました。正直、Makefileの中身を書き換える根性はないのですが、 補足等の形で近日中にUPさせていただきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1442] mingw32-make
投稿者:yuya
2009/10/12 17:10:57

mingw32-makeを使うときの一般的な話で、CrowbarやDiksamと直接関係ないのですが……。 Makefileに cd ../dvm; $(MAKE)$ などとなっている箇所で、セミコロン以降も全部パスとみなされてしまい、 > cd ../dvm; gmake; > 指定されたパスが見つかりません。 > gmake: *** [../dvm/dvm.o] Error 1 といったエラーに悩んでる人が出てきてないでしょうか。 MSYSだと起こらないので、今日初めて気づいたんですが、 MinGWだけ入れてcmdから直接makeする人はハマる可能性があると思うのです。 余計なお世話ですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1440] Re:「プログラミング言語を作る」のmycalc
投稿者:(ぱ)こと管理人
2009/09/10 03:05:28

>>・そちらのbisonのバージョンが2.1以外であれば、2.1ではどうでしょうか。 >bison2.1にするとちゃんと動くようになりました。 当方と同じ現象が起きているようですね。 >>・m4のみ別途インストールするか、Cygwinを入れてみるとどうでしょうか。 >m4のみ違うバージョンをインストールしてみましたが、だめでした。 > >bisonを空白のないパスにインストールすると、最新のバージョンでも動きました。 こちらについても、わざわざ報告いただきありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1439] Re:(初歩的な)質問
投稿者:(ぱ)こと管理人
2009/09/10 03:04:01

>gmake [Enter] > >とタイプしたのですが (中略) >というようなメッセージがでて、crowbar.exeがcrowbar_book_0_1のフォルダの中にできました。 おめでとうございます。コンパイルは成功しています。 >crowbar.exeをダブルクリックすればいいのですか?ダブルクリックしても一瞬だけ黒い画面が出るだけです。 crowbarの実行もコマンドプロンプトから行います。 コンパイルしたフォルダにtestというフォルダがあり、この中に、 test.crbというテストプログラムが入っています。 コンパイルしたフォルダから、 cd test[Enter] でtestフォルダに移動してから、 ..\crowbar test.crb[Enter] とタイプしてください。「..\」は「ひとつ上のフォルダ」を意味しますので、 これでひとつ上のフォルダのcrowbar.exeを実行することができます。 あるいは、test.crbをひとつ上のフォルダに移動してから、 コンパイルしたフォルダにて crowbar test.crb[Enter] でもよいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1438] Re:「プログラミング言語を作る」のmycalc
投稿者:wk
2009/09/09 17:08:12

ありがとうございます。 >・そちらのbisonのバージョンが2.1以外であれば、2.1ではどうでしょうか。 bison2.1にするとちゃんと動くようになりました。 >・m4のみ別途インストールするか、Cygwinを入れてみるとどうでしょうか。 m4のみ違うバージョンをインストールしてみましたが、だめでした。 bisonを空白のないパスにインストールすると、最新のバージョンでも動きました。 お忙しいところ、何度もアドバイスありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1437] (初歩的な)質問
投稿者:高校生
2009/09/09 11:58:21

プログラミングを作る の本を使ってやっているのでcrowbar_book_0_1は 「C:\Documents and Settings\s2007070\デスクトップ\win_sjis\crowbar_book_0_1」にあります。そこでコマンドプロンプトで cd C:\C:\Documents and Settings\s2007070\デスクトップ\win_sjis\crowbar_book_0_1[Enter] とタイプして C:\C:\Documents and Settings\s2007070\デスクトップ\win_sjis\crowbar_book_0_1に移動し、そこで gmake [Enter] とタイプしたのですが ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー C:\Documents and Settings\s2007070\デスクトップ\win_sjis\crowbar_book_0_1>gmake cd ./memory; gmake; gmake[1]: Entering directory `c:/Documents and Settings/s2007070/デスクトップ/wi n_sjis/crowbar_book_0_1/memory' gmake[1]: `mem.o' is up to date. gmake[1]: Leaving directory `c:/Documents and Settings/s2007070/デスクトップ/win _sjis/crowbar_book_0_1/memory' cd ./debug; gmake; gmake[1]: Entering directory `c:/Documents and Settings/s2007070/デスクトップ/wi n_sjis/crowbar_book_0_1/debug' gmake[1]: `dbg.o' is up to date. gmake[1]: Leaving directory `c:/Documents and Settings/s2007070/デスクトップ/win _sjis/crowbar_book_0_1/debug' gcc lex.yy.o y.tab.o main.o interface.o create.o execute.o eval.o string.o strin g_pool.o util.o native.o error.o error_message.o ./memory/mem.o ./debug/dbg.o -o crowbar -lm C:\Documents and Settings\s2007070\デスクトップ\win_sjis\crowbar_book_0_1> ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー というようなメッセージがでて、crowbar.exeがcrowbar_book_0_1のフォルダの中にできました。 crowbar.exeをダブルクリックすればいいのですか?ダブルクリックしても一瞬だけ黒い画面が出るだけです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1436] Re:「プログラミング言語を作る」のmycalc
投稿者:(ぱ)こと管理人
2009/09/09 03:26:51

>C:\win_sjis\calc\mycalc>make.bat >> error.txt >m4: cannot open `Files\GnuWin32/share/bison': No such file or directory >m4: cannot open `C:\Program': No such file or directory >m4: cannot open `Files\GnuWin32/share/bison/m4sugar/m4sugar.m4': No such file or > directory (後略) このメッセージは見たことがあります。 以下のページの「bisonのインストール」のところで http://kmaebashi.com/programmer/devlang/book/winenv.html >ただし、私の環境では、m4でエラーが出ました。 >Cygwinのものを使おうがMSYSのものを使おうが、 bisonに付属のものを使おうが >エラーになっています。 >bison2.1は動作したので念のため置いておきます。 と書いていますが、この時に発生したエラーがこれでした。 bisonは内部的にm4を使用するのですが、「MSYSのm4は古いからbisonは動かない」という という記述がいくつかのWebページにありましたし、メッセージを見る限り、 確かにm4がエラーを出しています。ただ、その後MSYSをアンインストールして cygwinを入れなおしても状況が改善されず、bisonの入れ直しで(私のところでは)直りました。 ・そちらのbisonのバージョンが2.1以外であれば、2.1ではどうでしょうか。 ・m4のみ別途インストールするか、Cygwinを入れてみるとどうでしょうか。 はっきりした回答ができず申しわけありません。 私の環境では、bisonはC:\Program Files\GnuWin32\bin\bisonであり、 m4はcygwinのものを使用しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1435] Re:「プログラミング言語を作る」のmycalc
投稿者:wk
2009/09/08 14:43:46

ありがとうございます。 >かつ、その中で、該当のエラーになったのは、mycalc以下のmake.batでよいでしょうか? はい。 >エラーメッセージが出るようであれば、そのままこの掲示板にコピペしてください。 C:\win_sjis\calc\mycalc>make.bat >> error.txt m4: cannot open `Files\GnuWin32/share/bison': No such file or directory m4: cannot open `C:\Program': No such file or directory m4: cannot open `Files\GnuWin32/share/bison/m4sugar/m4sugar.m4': No such file or directory m4: cannot open `C:\Program': No such file or directory m4: cannot open `Files\GnuWin32/share/bison/bison.m4': No such file or directory m4: cannot open `C:\Program': No such file or directory m4: cannot open `Files\GnuWin32/share/bison/c-skel.m4': No such file or director y gcc: y.tab.c: No such file or directory mycalc.l:3:19: y.tab.h: No such file or directory mycalc.l: In function `yylex': mycalc.l:12: error: `ADD' undeclared (first use in this function) mycalc.l:12: error: (Each undeclared identifier is reported only once mycalc.l:12: error: for each function it appears in.) mycalc.l:13: error: `SUB' undeclared (first use in this function) mycalc.l:14: error: `MUL' undeclared (first use in this function) mycalc.l:15: error: `DIV' undeclared (first use in this function) mycalc.l:16: error: `CR' undeclared (first use in this function) mycalc.l:20: error: `yylval' undeclared (first use in this function) mycalc.l:21: error: `DOUBLE_LITERAL' undeclared (first use in this function) bisonをインストールした場所が悪かったのでしょうか。エラーを読んでいると、Program Filesが2つのパスに分割されているようにも思えます。環境変数のpathにC:\Program Files\GnuWin32\binを登録してコマンドプロンプトを実行しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1434] Diksamのmakeが成功しました。
投稿者:青餓鬼
2009/09/08 12:05:49

掲示板#1432に指摘されているdiksam.yのソース修正を施すと、 無事gmakeは正常終了しました。 これで先に進めます。 ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1433] Re:「プログラミング言語を作る」のmycalc
投稿者:(ぱ)こと管理人
2009/09/08 02:45:32

こんにちは。 >ソースファイルをダウンロードして、mycalcをmake.batを実行してgccで >コンパイルすると、lex.yy.cというファイルはできましたが、もう一つの >ファイルはCのファイルではなくy.outputになっています。Windows上で、 >MinGW, MSYS, bison, flexをインストールして実行しています。 >アドバイスいただけないでしょうか。 こちらも確認ですが、そちらで試されたファイルは、以下のページからダウンロード した win_sjis.LZHまたはwin_sjis.zipのいずれかで、 http://kmaebashi.com/programmer/devlang/book/download.html かつ、その中で、該当のエラーになったのは、mycalc以下のmake.batでよいでしょうか? (mycalc_exではなく) lex.yy.cができていて、y.tab.cおよびy.tab.hができていないとすると、 yacc(bison)側が何らかのエラーになっているのではないかと思うのですが、 エラーメッセージの類は出ていないでしょうか? もしmake.batをダブルクリックして実行されているのであれば(それだと仮に エラーメッセージが出ていても読めないので)、以下を参考にコマンドプロンプトから 実行してみてください。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&thread=1426 エラーメッセージが出るようであれば、そのままこの掲示板にコピペしてください。 よろしくお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1432] Re:Diksamのmakeでエラーとなる
投稿者:(ぱ)こと管理人
2009/09/08 02:15:10

>こんにちは。初めて投稿します。 はじめまして。 >8月17日にソースコードをダウンロードして、順にコンパイルしているうち、 >Diksamのcompiler項になったら次のようなエラーメッセージが表示されました。 確認ですが、そちらで試されたファイルは、以下のページからダウンロードした win_sjis.LZHまたはwin_sjis.zipのいずれかで、 http://kmaebashi.com/programmer/devlang/book/download.html かつ、その中で、該当のエラーになったのは、diksam_book_0_1でよいですよね。 >>bison --yacc -dy diksam.y >>diksam.y:428 13-14: $$ for the midrule at $2 of 'block' has no declared type >>gmake: *** [y.tab..h] Error 1 428行目でエラーが出ていますが、確かに、diksam_book_0_1のcompiler\diksam.yの 428行目近辺は、以下のようになっています。 1 2 3 4   12345678901234567890123456789012345678901234567890  425:block 426: : LC 427: { 428: $$ = dkc_open_block(); 429: } 430: statement_list RC 431: { 432: $$ = dkc_close_block($<block>2, $3); 433: } 434: | LC RC 435: { 436: Block *empty_block = dkc_open_block(); 437: $$ = dkc_close_block(empty_block, NULL); 438: } 439: ; 428行目の13~14文字目は「$$」ですが、この$$は、埋め込みアクションの ターゲットを示しています。「プログラミング言語を作る」p.206~207で、 「以下のように書くのと同値です。」と書かれている例におけるdummy_targetです。 メッセージを見る限り、dummy_target相当のターゲットは型の宣言をしていないので、 上記のエラーが出ているようです(「ようです」というのは、当方の環境では エラーにならずに動いているためです)。 428行目を以下のように変更して試してみていただけますでしょうか。 428: $<block>$ = dkc_open_block(); 正直、私はもうずいぶん前からここのところは$$で書いていてLinuxでもWindowsでも 動いていたはずですが、確かに、正しくは「$<block>$」と書くべきところかと 思います。 ご報告ありがとうございました。確認のうえでソースの修正および補足記事を Webで出させていただきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1431] 「プログラミング言語を作る」のmycalc
投稿者:wk
2009/09/07 17:17:55

ソースファイルをダウンロードして、mycalcをmake.batを実行してgccでコンパイルすると、lex.yy.cというファイルはできましたが、もう一つのファイルはCのファイルではなくy.outputになっています。Windows上で、MinGW, MSYS, bison, flexをインストールして実行しています。アドバイスいただけないでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1430] Diksamのmakeでエラーとなる
投稿者:青餓鬼
2009/09/07 16:37:15

こんにちは。初めて投稿します。 8月17日にソースコードをダウンロードして、順にコンパイルしているうち、Diksamのcompiler項になったら次のようなエラーメッセージが表示されました。 >bison --yacc -dy diksam.y >diksam.y:428 13-14: $$ for the midrule at $2 of 'block' has no declared type >gmake: *** [y.tab..h] Error 1 実行環境はWin XPで、MinGWは今回インストールしましたが、CygWinは1年ほど前にインストールしたものを使っています。 システムの起動もツールとソースコードの展開もDドライブで実行していて、「鬼車」もインストール済みです。 Bisonの文法は自信がないので、エラーの内容について御教授ください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1429] Re:test/if.dkmエラー
投稿者:(ぱ)こと管理人
2009/09/05 18:14:02

>[mugenkai@love] % diksam if.dkm >if.dkm: 8:変数名bが重複しています。 これですね。 int a = 10; if (a > 5) { int b = 20; println("<1>b.." + b); } else { int b = 30; println("<2>b.." + b); } わかりにくい仕様ですが、これで「変数名bが重複しています。」エラーになるのは 現状のDiksamでは仕様です。 言語仕様の「ローカル変数」のところで、以下のように書いています。 http://kmaebashi.com/programmer/devlang/dls_0_4_01.html >関数内で宣言された変数はローカル変数(local variable) となる。 >ローカル変数のスコープは、以下の両方の条件を満たす範囲である >(現状で、グローバル変数のスコープは、ブロックの影響を受けない)。 ここでのbは関数内で宣言された変数ではないので、グローバル変数です。 グローバル変数のスコープはブロックの影響を受けないので、ifのブロック内であっても 二重に宣言することはできません。 # 仕様書に書けばバグも仕様に変わる、レベルの話かもしれませんが。 testフォルダにif.dkmが入っているのは、エラーになることを確認した残骸では ないかと思います…… まぎらわしくてすみません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1428] test/if.dkmエラー
投稿者:つんつん
2009/09/04 21:50:47

[mugenkai@love] % diksam if.dkm if.dkm: 8:変数名bが重複しています。 [mugenkai@love] % [/Users/mugenkai/Desktop/diksam_utf8/main/test] main/testフォルダのif.dkmが実行出来ません。 環境:MacOSX10.3.9
[この投稿を含むスレッドを表示] [この投稿を削除]
[1427] Re:(初歩的な)質問
投稿者:(ぱ)こと管理人
2009/09/02 22:33:18

こんにちは。 >mingw32-make.exeというファイル名を gmakeという名前にコピーしたのですが >それをどうすればいいのか分かりません。gmakeをダブルクリックしたのですが >[No such file or directory]と表示され,いくつかファイルが作られるだけです。 「gmakeをダブルクリック」しているところからして、コマンドプロンプトを お使いになったことがないのでは、と想像しています。 crowbarやDiksamは、コンパイルするのも実行するのもコマンドプロンプトから 行うことをを想定しています。 WindowsXPやVistaであれば、スタートメニューから  プログラム → アクセサリ → コマンドプロンプト で、コマンドプロンプトが表示されるはずです。 たとえば、crowbarの圧縮ファイル「crowbar_0_4_02_win.LZH」を C:\直下で展開したのであれば、「C:\crowbar_win」というフォルダができていると 思います。 コマンドプロンプトで cd C:\crowbar_win [Enter] とタイプして C:\crowbar_win に移動し、そこで gmake [Enter] とタイプすることで、crowbarがコンパイルされるはずです。 実行するときも、コマンドプロンプトから、 crowbar xxx.crb のようにタイプして実行します。 コマンドプロンプトの詳細は、たとえば以下のようなページが参考になると思います。 http://ykr414.com/dos/index.html 疑問点があれば遠慮なく書き込んでください。 なお、コマンドプロンプトでエラーが出た場合、それをここに書き込むのであれば かならずエラーメッセージをcopy&pasteしてください(正確なメッセージを知るため です。「エラーが出ました」だけでは何のエラーだかわかりません)。 コマンドプロンプト上のテキストをコピーする際は、コマンドプロンプトの タイトルバーで右クリックし、「範囲指定」→マウスで領域選択→「コピー」で 可能です。 # そのうち「Diksamではじめる12才からのゲームプログラミング」なんてのを # 書いてみたいと思っているのですが、コマンドプロンプトやフォルダ構造のところで # 若い人とはずいぶんギャップがありそうだ、とまさに思っていたところでした…… # とはいえWindowsをちゃんと使うなら、「コマンドプロンプトやフォルダ構造」は # 避けて通れないと思うんですがねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1426] (初歩的な)質問
投稿者:高校生
2009/09/02 11:47:36

crowbarが実行できないのですが Cコンパイラもcygwinもbisonもflexもいれました。電卓(mycalc)は実行形式ができるのですがcrowbarやDiksamは実行形式ができません。 mingw32-make.exeというファイル名を gmakeという名前にコピーしたのですがそれをどうすればいいのか分かりません。gmakeをダブルクリックしたのですが[No such file or directory]と表示され,いくつかファイルが作られるだけです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1425] Re:デバックシステム一応完成
投稿者:(ぱ)こと管理人
2009/08/16 21:38:16

>Diksam 2.0 より流用改変したソースはコンパイルラ部分のみで123K、 >全体の22%。その中はクラス化や、言語仕様の違いで全関数修正している >ため。元の6割ぐらいしか原型が残っていないと思います。VMについては、 >新たに書いているので基本アルゴリズムが同じで、中身は違ったものになっ >ています。 そういえばVMは新規と言う話は以前書いておられたと思うのですけれど、 バイトコードが基本的に同一らしいので、VMも流用かと思い込んでしまいました。 コンパイラをgenerate.cまで含めて流用していれば、そりゃバイトコードは 似たようなものになりますね。 > ソースの件ですが、正式にフリー公開時点でソース公開も考えています。 >現時点ではまだちょっとです。(ぱ)さん以外非公開を条件にVMのソース送り >ましょうか? 了解です。DiksamはGPLとかではないので、現時点では公開されないという 方針でしたらそれでよいかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1423] Re:デバックシステム一応完成
投稿者:
2009/08/14 21:22:27

つ、追記。 いや、ソフトを使って行数カウントしてみた。全体で17,657行ありました。それだけ^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[1422] Re:デバックシステム一応完成
投稿者:
2009/08/14 19:19:24

>山さんのVMがDVMとどれぐらい違うのだろうと思ってダウンロードしてみましたが、 >VM部分のソースはないのでしょうか……  どれぐらい違うのかソースファイルのサイズで定量的に計ってみました。 ・システム管理部分  115K(ソースファイルの合計) ・コンパイラ     150K ・VM         73K ・共用        45K ・組込み関数     34K ・ヘッダーファイル  140K (クラスやテンプレートでヘッダーファイルが大きくなるのはC++の宿命ですね)         合計 557K  プログラムの行数的にはコメント含み1万数千行ほどあります。 Diksam 2.0 より流用改変したソースはコンパイルラ部分のみで123K、 全体の22%。その中はクラス化や、言語仕様の違いで全関数修正している ため。元の6割ぐらいしか原型が残っていないと思います。VMについては、 新たに書いているので基本アルゴリズムが同じで、中身は違ったものになっ ています。  VMは最小になるように作られているので、73K 全体の13%です。ソース の60%は新しく作りこんだ仕様のためでした。内容はマルチVMのシステム・ 言語的にスレッドセーフな仕組み・コンパイルとVM間の協調動作管理、等々です。  私が言ってはいけないのかもしれませんが、結構複雑なシステムになってます。 難しいのもまた楽しくもあります。  ソースの件ですが、正式にフリー公開時点でソース公開も考えています。 現時点ではまだちょっとです。(ぱ)さん以外非公開を条件にVMのソース送り ましょうか?  VMは1つのクラスで、そのクラスのオブジェクトを1つ作ったら、それが1つの VMスレッドになり、VM機能を詰め込んだ、あまりクラスらしくないクラスです。 だから、メモリーがあるだけマルチでVMスレッドを自由に実行できます。  ちなみにコンパイラも見た目は1クラス(内部でいくつかのクラスを使用)で、 機能的にきれいに分離されています。ただその分システム管理で全体の協調 動作制御が必要です。 >あと、フォルダ名の「editer」は固有名詞でしょうか? いえ、LIZA.iniファイルで自由に変えられます。  先のことですが、ライザ言語はC言語のシンタックスにとても似ているので、 ライザ言語をC++のソースにコンパイルすることは簡単です。完成した後、 暇だったらシステムをライブラリー化して、コンパイルしたC++ソースとリンクし、 ネイティブな実行形式作成をやってみたいですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1421] Re:デバックシステム一応完成
投稿者:(ぱ)こと管理人
2009/08/14 00:24:29

>http://ux.getuploader.com/yamamoto/download/3/debug.zip 山さんのVMがDVMとどれぐらい違うのだろうと思ってダウンロードしてみましたが、 VM部分のソースはないのでしょうか…… あと、フォルダ名の「editer」は固有名詞でしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1420] Re:デバックシステム一応完成
投稿者:
2009/08/13 19:38:47

 速いPCでも問題が…、日ごろノートPCで開発しているのですが。 久しぶりにディスクトップでやったら。  デュアルPC以上だと、本体のスピードが早すぎてモニターの処理が 追いつかないです。 約1秒に1000行ぐらいの情報を送っています。  UDP送信後 sleep(0)のウェイトをかけているのですが、シングルCPU だと、それなりに時間がかかるのですが、デュアル以上だと多少のウェイト だけで、高速にUDP送信をしていました。さすがに受けきれない結果に なります。t016.lzp t17.lzp でモニターが動作異常になります。デバック モニターがロックしたような状態、UDP受信例外、等々が発生します。  モニター側で、過負荷のときの処理を追加すべきでした。 そんな訳で、こんなデバックシステムが出来ましたよ程度としてみてください。  その他、ディスアセンブラの行情報異常や、システム変数配列処理ミス、 変数のコンフリクト問題、等々その後見つかった問題も対策終了しています。  見つかったバグのほとんどは、以前は無かったのですが、各種修正と機能 追加で新たにバグを作りこんだようです… 良くあることです orz
[この投稿を含むスレッドを表示] [この投稿を削除]
[1416] Re:デバックシステム一応完成
投稿者:
2009/08/12 18:01:54

 別のPCで実行したところ、MSVCXXXX.DLLが必要でした。 ↓にDLLを添付したファイルをUPしました。申し訳ありません。 http://ux.getuploader.com/yamamoto/download/3/debug.zip  また、add_stringのバイトコードでたまーに、システム変数が コンフリクトを起こす現象を発見しています。  あと、遅いPCでは、UDP通信が大幅に抜ける場合があります。 デバック用に最小時間を指定しているので、遅いPCでは大量の 送信データを受けきれないです。送信後のウェイトを長くすれば 問題ないのですが、デバックターンが長くなるのでこのままに しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1415] デバックシステム一応完成
投稿者:
2009/08/11 19:20:41

 プログラムのブレーク、ステップ処理等を除き一応の完成、ブレーク等は アプリケーションのGUIが出来上がらないとボタンが無いので。その他にも いろいろ修正をしました。  ・言語の内部コードをSJISからワイド文字wchat_tに変更。  ・動的コンパイラの組込み。  ・コンパイルエラーのモニター連携  ・VM実行時エラーのモニター連携  ・デバックシステムの組込み(第1段階終了、全体の80%以上は終わったかな)  ・コンパイラのpool導入による高速メモリー確保と一括開放。  ・VMも一部Pool化。  ・VMの言語関数起動の最適化と高速化。  ・ライザ付属エディターの組込み。  ・LIZA.iniファイルによる初期化設定を組込み  等々いろいろ修正しました。特にデバッグシステムの組み込みは大きかった。 もう、文字で示すのも画像で示すのも困難と思うので。↓にUPしています。 http://ux.getuploader.com/yamamoto/download/2/debug.zip もしお暇がありましたら試してみて、何かありましたらよろしくお願いします。 まだ本体はCUIで出来ています。多分バグだらけです。  手順は、ライザデバックモニタ「LZ_moniter1_001.exe」を実行して、本体の 「lz002.exe」を実行するとデフォルトの「start.lzp」を実行します。以前出した タイマプログラムです。  2つともローカルでUDP通信をしているので、通信許可でお願いします。 初期起動時は、UDP通信がごっそり抜ける時があるので、本体は2回以上起動して みたほうがいいかもしれません。時々モニターのログが抜ける時があります  本体はデバックモードのままなのでEXEも大きく、動作はとても遅いです。 大量のデバックトレースをモニターに送っているので。  また、XXX.lzpの起動をlz002.exeに起動リンクすれば、その他のプログラムは、 ダブルクリックで直接実行できます。そこに入っているXXX.lzpは総て動きます。 ただ、修正するとこける可能性が高いです。試作以前の段階なので。  デバックの組込みで以下の言語仕様が追加されました。 ただ、まだほとんど機能しません。本体のGUIを作る時でないと2度手間に なってしまうので。  次からはようやくアプリケーションの本体です。ああ~~長かった~ 次も長いんだろうな //-- デバック行コントロール ------------- #define DBL        // デバック行有効 //#define DBL       /-/ // デバック行のコメント化 //-- デバック関係関数 ----------------------- #define 一時停止    debug_break //-- デバックログ関係関数 ------------------- #define ファイル表示  debug_file_disp // モニタにファイル表示 #define トレースログ  debug_trace_log // トレースログに表示 #define システムログ  debug_system_log // sysログに表示 #define ログ1      debug_log1 // ログ1に表示 #define ログ2設定    debug_log2_set // ログ2にタブ追加設定 #define ログ2      debug_log2 // ログ2に表示 #define ログsys変数   debug_sysval // ログするシステム変数の登録 #define クリア     "クリア" // ログするシステム変数のクリア //-- デバックモニタ制御関数 ------------------- #define デバックモニタ制御 debug_monitor_control #define 変数ログクリア   1 // モニタ02の変数ログクリア #define 全ログクリア    2 // モニタ01全ログクリア #define トレースログクリア 3 // トレースログクリア #define sysログクリア    4 // sysログクリア #define ログ1クリア     5 // デバックログ1クリア #define ログ2クリア     6 // デバックログ2クリア //-- ログ出力制御用システム変数 --------------- #define 全ログSW      SLI001 // 全てのログ0:停止1:開始 #define トレースログSW   SLI002 // トレースログSW #define システムログSW   SLI003 // #define ログ1SW       SLI004 // #define ログ2SW       SLI005 // #define ローカル変数ログSW SLI006 // #define システム変数ログSW SLI007 // //-- 組込み関数宣言 -------------------- DBL int 一時停止()     // 戻り=0 DBL int デバックモニタ制御(int type); // 戻り=0 DBL int ファイル表示(string fname); // 戻り=0 DBL int システムログ(string str); // 戻り=0 DBL int トレースログ(string str); // 戻り=0 DBL int ログ1(string str); // 戻り=0 DBL int ログ2設定(string tag_name); // 戻り=log2id DBL int ログ2(int log2id,string str); // 戻り=0 DBL int ログsys変数(string str); // 戻り=0 //--------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1412] Re:「プログラミング言語を作る」について
投稿者:名無しの読者
2009/07/27 20:28:42

>この週末は、土曜の夜からなんだかまぶたが腫れ上がってましてほとんど寝てました >(医者には行って薬ももらいましたが、原因は不明です)。 >反応が遅れましてすみません。 いえいえ、十分反応は早いですよ。 最近の投稿の時間を見ると夜中の3時前後・・・。 余計なことかもしれませんが、あまり無理をなさらずに。 ご自愛ください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1411] Re:「プログラミング言語を作る」について
投稿者:(ぱ)こと管理人
2009/07/27 03:09:48

この週末は、土曜の夜からなんだかまぶたが腫れ上がってましてほとんど寝てました (医者には行って薬ももらいましたが、原因は不明です)。 反応が遅れましてすみません。 >プログラミング言語を作るをもう一度読んでいて2つミスプリントを見つけました。 > >p106 3-3-3「解析木の構築---corwbar.yとcreate.c」の第5パラグラフに >「アクションにて、crb_crete_binary_expression()」とありますが、 >「アクションにて、crb_create_binary_expression()」だと思います。 > >p189 補足「別のあるべき姿---Code Set Independent」の最後から3つめのパラグラフに >「それに対し、CSIだと(N-1)必要になります。」とありますが、 >これではUnicodeに正規化する方法よりエンコーディングを変換するコンバーターが少なくなってしまいます。 >(N-1)はN(N-1)の間違いでしょうか? たびたびすみません。ご指摘ありがとうございます。 正誤表に追加しました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1410] Re:「プログラミング言語を作る」について
投稿者:名無しの読者
2009/07/26 21:09:33

プログラミング言語を作るをもう一度読んでいて2つミスプリントを見つけました。 p106 3-3-3「解析木の構築---corwbar.yとcreate.c」の第5パラグラフに 「アクションにて、crb_crete_binary_expression()」とありますが、 「アクションにて、crb_create_binary_expression()」だと思います。 p189 補足「別のあるべき姿---Code Set Independent」の最後から3つめのパラグラフに 「それに対し、CSIだと(N-1)必要になります。」とありますが、 これではUnicodeに正規化する方法よりエンコーディングを変換するコンバーターが少なくなってしまいます。 (N-1)はN(N-1)の間違いでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1409] Re:「プログラミング言語を作る」について
投稿者:(ぱ)こと管理人
2009/07/23 02:11:11

>>確かにPerlのlocalはダイナミックスコープですから、CやJavaのローカル変数とは >>挙動が異なります。とはいえグローバル変数とも明確に違うものだと思います。 >確かにその通りのようです。 一応、「プログラミング言語を作る」では、p.153にて、本当にちょっとだけ ダイナミックスコープの説明をしています。お気づきかもしれませんが念のため 補足します。 今読み返すと、ここでのCRB_LocalEnvironment構造体のnextメンバが何を 指しているのかわかりにくいような気がします…… ここでのnextは、 呼び出し元のCRB_LocalEnvironment構造体を指しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1408] Re:マルチスレッドについて
投稿者:(ぱ)こと管理人
2009/07/23 02:05:08

ひとまずここだけ。 > Windowsのメッセージシステム…、あれは同期非同期以前のシーケンシャル >処理システムなんです。1スレッドでメッセージ取り出しループ処理して、メッセー >ジを受け取り、そのメッセージに対応する関数を呼んでいるだけで、並列処理は >していないです。 Windowsのメッセージシステムが並列でないのは当然ですけど、 ブラウザであれば、コンテンツの取得の方を別スレッドで回せるはずですよね。 IEがどうなっているかは知りませんが、いまどきのアプリですから当然そうなって いるのではないでしょうか。 でも、コンテンツ取得スレッドがネットワークの待ちでブロックされていたり、 ActiveXコンポーネントが動作中だったりすると、結局×ボタンで止められない ような感じがしています。まあいろいろ難しいよね、という程度の意味です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1407] Re:「プログラミング言語を作る」について
投稿者:名無しの読者
2009/07/22 20:51:40

>確かにPerlのlocalはダイナミックスコープですから、CやJavaのローカル変数とは >挙動が異なります。とはいえグローバル変数とも明確に違うものだと思います。 確かにその通りのようです。 >>myがない頃はlocalが使われていたそうですが、なぜmyより先にlocalが作られた >>のでしょう? > >過去のある一時点において、多くの人が「ダイナミックスコープかっこいい!」と >思ったことがある、ということなのではないでしょうか。 そういう歴史があるとは知りませんでした。 わざわざ回答してくださってありがとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1406] Re:マルチスレッドについて
投稿者:
2009/07/22 20:46:20

>一応検索はしたのですが、Googleでは普通に非同期処理の記事しか出てこなかった >ような……  私のほうでは出るのですが…、では「非同期分散処理」という言い方でも いいかな、「非同期処理」までいくと意味合いがちょっと違うんですよね。 >ここのところが、yieldとかwait()とかの方法ではいけないのかな、というのが >私の疑問です。  その場合、キュー処理にいろいろ問題が出てくるのです。まず第1に、キューの 優先順位ができない、全部のスレッドに優先順位処理を作りこめばいいのかも しれませんが、まったく非効率です。次に、キューを送る元と受け側が同期処理 していなければいけない。こえは、たとえば受け側がキューを処理中に、いくつも キューを送れない。これもまた各スレッドに…。つぎに、受け側がスレッドを 終了した場合、送り元に終了した旨の連絡して止めてもらう同期処理をしなければ、 相手がいないのにキューを送って宙ぶらりんとなる。等々キュー処理には(ぱ)さん が示したスレッドの関数だけでは無理なことが多いです。  いろいろと作りこめば非同期もできます。しかしそれには、そのスレッド以外 でキューの管理システムを作らなければならないわけで。使用者にその管理部分 を作れと要求しているわけです。その要求をしている言語は「非同期分散処理」 をサポートしているとはいえません。  (作れば何でもできると考えれば、アセンブラでOKってなってしまう)  また、スレッド起きに監視ループが必要になってきますが。私が作りたい のは何十何百ものスレッドをターゲットに考えているので、そのスレッドの待機 処理時間が馬鹿にならないのです。私の言語は100スレッドあっても、待機時は 負荷0です。  「非同期分散処理」を純粋にサポートしようと思ったら、今のスレッド仕様で は無理があるのです。C言語でも、OOPの様にクラスやカプセル化のようなことが 出来ます。でもだれもC言語がOOP言語とは言いません。それと同じことを言って いるように感じます。単純な基本機能があれば、その組み合わせでほとんどの ことが出来ます。しかし、その言語でできる事をサポートしているとはいえま せん。 >固定個のスレッドプールを持っているようなので、それを使い切った場合を想定して >いるのでしょうか? うーん。  いえ、「非同期分散処理」を言語レベルでサポートするためにです。 >脱線しますけど、よく言われるマルチスレッドのメリットで、GUIのスレッドを >処理のスレッドと分けておけば、ユーザの操作にすぐ反応できる、というのが >ありますけど、じゃあ重たいページをIEで表示してしまった時、×ボタンですぐに >停止できるのかというと、さっぱり押せないことばっかりで……  Windowsのメッセージシステム…、あれは同期非同期以前のシーケンシャル 処理システムなんです。1スレッドでメッセージ取り出しループ処理して、メッセー ジを受け取り、そのメッセージに対応する関数を呼んでいるだけで、並列処理は していないです。だからその関数が終わらないと次の処理ができないシステム です。IEの中身がどうなっているかわかりませんが。即応できるシステムを作る のは難しいと思います。  だからと言って、私の言語は即応かというと、作り方いかんで幾らでも遅く 作れますし、シングルスレッドでも作り方いかんでは早く処理できるし。  マルチスレッドの方が融通は利きますが、その件は本質ではないと思います。 「非同期処理」だとイメージが違ってくるんです。掲示板で説明するのは難しい ので、作ったソフトを動かしてもらえれば…、ずいぶん先になりますが…。  PS.終了だけを考えれば、私の言語は終了は遅いです。言語上のスレッドの 終了処理、VMスレッドの終了処理、その他組み込みスレッドの終了処理、 それぞれにリソースの開放処理等々、多分重い。  終了は結構大変です。問題なければ1秒以内に終わると思いますけど。 何か問題があって、タイムアウト待ちでもしようものなら。冷汗たらー
[この投稿を含むスレッドを表示] [この投稿を削除]
[1405] 言語のデバックシステム
投稿者:
2009/07/22 20:10:38

 下記に示すURLに言語デバックシステムのプロトタイプイメージが あります。 http://dl7.getuploader.com/g/yamamoto/1/lz_db.gif こんな感じのデバックシステムを作る予定。エラーが発生したら、 モニターにファイルと行を表示して修正ができます。ただし、行番号 はないので、好みのエディターを使いたい場合は編集を押押すか エディターを登録してそのエディターを起動します。  ファイルタブは、ファイルリストとファイルが表示され編集可能 です。簡単な修正ならここでできます。  関数のトレースとログ1はスレッド置きにタブが作成されるので、 トレースが混合してわけワカメにならない予定。タブは200まで自動 で増えるので問題なし。  システム情報のログはsysログに、自由に定義して使用可能なのが ログ2です。また、モニタ02がローカル変数とシステム変数のログ を表示します。全部でモニター2種、本体1を起動します。  通信はUDPを使うので、LAN内の他PCでモニターできます。  これはまだGUIを作ったものなので、これから詳細の実装です。 また、本体の表示部分はできていないので、真っ黒です。それ に、右上の実行・ステップ・ステップインのボタンはイメージで、 画像合成です。こんなボタンとシステムログが透過で表示される 予定。  久しぶりにC#触ったけど、ユーザーインターフェース作るのが簡単だった。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1403] Re:マルチスレッドについて
投稿者:(ぱ)こと管理人
2009/07/22 03:33:57

回答が遅れましてすみません。 >でも、初期起動の中で必要なことを実行して、終了リターン >すれば、普通のスレッドと同じことが出来ます。 ここは了解です。 >違いは待機リターンが有りキュー待ち状態で待機できることです。 ここのところが、yieldとかwait()とかの方法ではいけないのかな、というのが 私の疑問です。 もちろん、yieldとかwait()とかで待つためには、VMがその状態を保持しなければ ならないので、固定数のネイティブスレッドのスレッドプールしか持たないのであれば 理解できます。これは前回 >固定個のスレッドプールを持っているようなので、それを使い切った場合を想定して >いるのでしょうか? うーん。 と書いたとおりです。 >これを説明しようとすると、とても長くなってしまいます。もしよろしけ >れば、「非同期協調処理」「非同期協調作業」「非同期分散処理」を検索 >していただければ嬉しいです。 一応検索はしたのですが、Googleでは普通に非同期処理の記事しか出てこなかった ような…… > 普通のスレッドを使用しないの理由は、起動するのも遅いし、終わる >のも遅い、非同期協調作業が出来るほど軽いものじゃないです。それに、 >キュー処理にはまったく対応していない。 脱線しますけど、よく言われるマルチスレッドのメリットで、GUIのスレッドを 処理のスレッドと分けておけば、ユーザの操作にすぐ反応できる、というのが ありますけど、じゃあ重たいページをIEで表示してしまった時、×ボタンですぐに 停止できるのかというと、さっぱり押せないことばっかりで……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1402] Re:「プログラミング言語を作る」について
投稿者:(ぱ)こと管理人
2009/07/22 02:58:59

>P85の補足「各言語のグローバル変数の扱い」のPerlの部分に「localとかmyとかを >付けて宣言するとローカル変数となる。」とあります。 >しかし、Cやjavaをおもに使っている人にとってlocalがローカル変数というのは >かなり違和感があると思います。 確かにPerlのlocalはダイナミックスコープですから、CやJavaのローカル変数とは 挙動が異なります。とはいえグローバル変数とも明確に違うものだと思います。 以下のサンプルで、きっぱり再帰できていますし。 ================================================== &hoge(0); sub hoge { my $depth = shift; #print 'depth..' . $depth; if ($depth > 2) { return; } local $i; for ($i = 1; $i <= 3; $i++) { print ' ' x $depth . '$i..' . $i . "\n"; hoge($depth + 1); } } ================================================== 私の感覚だと、ダイナミックスコープの変数は、自分自身とそこから呼び出された 関数からしか見えないという点でローカルだと思うのですが、確かに単に 「localとかmyとかを付けて宣言するとローカル変数となる。」とだけ書いて しまうのは確かに乱暴かもしれません。まあでもここはPerl, Ruby, PHPそれぞれの 言語の特徴をさらりと書いているだけのところなので、正誤表に載せるような ことではないのでは、と思います。 後日、補足記事をWebに上げようかと思います。 >myがない頃はlocalが使われていたそうですが、なぜmyより先にlocalが作られた >のでしょう? 過去のある一時点において、多くの人が「ダイナミックスコープかっこいい!」と 思ったことがある、ということなのではないでしょうか。 http://hagi.is.s.u-tokyo.ac.jp/pub/essay/hagiya/h/tensai | 僕は、Schemeの開発こそ、コンピュータ・サ | イエンスの典型的なセンスの一つではないかと | 思うのである。それまでは、LISPの考案者 | McCarthyのまやかしともいえる「変数の動的な | スコープ」に、皆がだまされ続けていたわけで | ある。 http://www.rubyist.net/~matz/20041025.html#p01 | 歴史的にはLispは(少なくともインタプリタ処理系では)、ダイナミックスコープが | 当たり前だったのだが、SchemeやCommonLisp以来すっかりスタティックスコープの | 言語になってしまっている。ダイナミックスコープなら外側のローカル変数もごく | 自然に見える。変数名の重複にだけ気をつければ良い(そういう意味ではcondやcommの | ようなありふれた引数名は良くない)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1401] Re:「プログラミング言語を作る」について
投稿者:名無しの読者
2009/07/21 21:32:14

もう一つ間違いとは言い切れないのですが、気になったところがあるのでついでに書いておきます。 P85の補足「各言語のグローバル変数の扱い」のPerlの部分に「localとかmyとかを付けて宣言するとローカル変数となる。」とあります。 しかし、Cやjavaをおもに使っている人にとってlocalがローカル変数というのはかなり違和感があると思います。 例えば、localを使った次のようなプログラムだとおかしな結果になります。 =============================================================== #!/usr/bin/perl $hoge = "global"; &func_local; &func_my; sub print_hoge { print "hoge is $hoge\n"; } sub func_local { local $hoge = "local"; print "func_local: "; print_hoge; } sub func_my { my $hoge = "my"; print "func_my: "; print_hoge; } =============================================================== 上記のプログラムを実行すると出力結果は func_local: hoge is local func_my: hoge is global になります。 myをつけた変数はCのローカル変数と同じように使えますが、localをつけた変数はCのローカル変数とは違います。 ちなみに、「初めてのPerl 第3版」の4.7 local演算子には「しかしlocalという名前は間違っています---あるいは、少なくとも、誤解を招く名前です。(中略)そうです、local変数と呼ばれる変数の正体は、実はグローバル変数なのです!」と書かれています。 myがない頃はlocalが使われていたそうですが、なぜmyより先にlocalが作られたのでしょう? 実装が楽だったとかなのでしょうか。 Cより新しい言語なのにCと同じローカル変数が使えなかったというのはどうなんだ・・・。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1400] Re:「プログラミング言語を作る」について
投稿者:(ぱ)こと管理人
2009/07/21 03:04:21

「名無しの読者」様 >「プログラミング言語を作る」を読ませていただきました。 >前橋さまの本は「C言語 ポインタ完全制覇」から読んでいるのですが、 >今回もおもしろい内容でした。 ありがとうございます。 >と書かれていますが、「Javaならファイナライザ、C++やC#なら・・・」の >間違いではないでしょうか? ご指摘ありがとうございます。正誤表に載せておきました。 普通に読んで変だと思う(たとえJavaやC++やC#をまったく知らなかったとしても!)であろう 文章であるにもかかわらず、チェック時に見落とすとは、人間の思い込みとは 侮れないものです……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1399] 「プログラミング言語を作る」について
投稿者:名無しの読者
2009/07/20 15:43:49

前橋さま 「プログラミング言語を作る」を読ませていただきました。 前橋さまの本は「C言語 ポインタ完全制覇」から読んでいるのですが、 今回もおもしろい内容でした。 ところで、ミスプリントらしい部分を見つけました。 303ページの補足「ファイナライザというかデストラクタというか」の第1パラグラフに 「Javaならデストラクタ、C++やC#ならデストラクタというメソッドが呼び出されます。」 と書かれていますが、「Javaならファイナライザ、C++やC#なら・・・」の 間違いではないでしょうか? まだ、正誤表には載っていなかったようなので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1398] Re:マルチスレッドについて
投稿者:
2009/07/19 23:45:20

以下の2行がミスです > なぜこうしたのかは、真に意味で完全な非同期協調処理をするためです。   ↓ > なぜこうしたのかは、真の意味で完全な非同期協調処理をするためです。 > この説明で、疑問に答えられてのかまったく持って不安です。   ↓ > この説明で、疑問に答えられたのかまったく持って不安です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1397] Re:マルチスレッドについて
投稿者:
2009/07/19 10:35:19

>「終了指示」を含めると8回になるように思えるのですが……  タイマ表示関数に終了指示の処理がありますが、それのデバックのために 書いた部分が残っていました。このプログラムでは終了指示は出していない ので、7回です。 終了待ちをする関数コール > rtn[0] = スレ終了待ち(sid[0],終了待ち,10); 終了指示を出し終了を待ちをする関数コール > rtn[0] = スレ終了待ち(sid[0],終了指示待ち,10);  出したプログラムは上のコールを使っていました。 誤解を与えるようなプログラムですみません。 >私が不思議なのは、なぜユーザプログラムの側をこのように細切れに >呼び出さなければならないのか、ということです。ユーザプログラムが >自ら処理を明け渡す必要がないことが、マルチスレッドの利点だと思う >のですが。  一般的なマルチスレッドと、私が組み込みたいマルチスレッドは性格が 少し違います。でも、初期起動の中で必要なことを実行して、終了リターン すれば、普通のスレッドと同じことが出来ます。違いは待機リターンが有り キュー待ち状態で待機できることです。  なぜこうしたのかは、真に意味で完全な非同期協調処理をするためです。 これを説明しようとすると、とても長くなってしまいます。もしよろしけ れば、「非同期協調処理」「非同期協調作業」「非同期分散処理」を検索 していただければ嬉しいです。いいHPでもあれば紹介するのですが、 びみょーに全部専門的で、びみょーに違うので。  簡単に言うと、真のマルチ処理(複数CPU)環境における、同期処理を 必要としないで協調してひとつの処理を実行する。ああ、言葉を長くした だけだ。orz  私はそれを、理論的に構築しようと思っているわけではなく、今のプロ グラミングパラダイム、この場合一番単純なC言語ライクな関数言語パラダ イムの上で、実際的に動くものを構築しようとしている、実利主義的に 泥臭いことをやっているわけです。動けばなんでもOK、きれいな理論なん て求めてません。^^ 的な立場で作っています。 (動けばなんでもOKだから、シートなんて取って付けた物を使うあたりが)  orz orz  その目的に必衰だったのが、今回のスレッドの仕様です。  普通のスレッドを使用しないの理由は、起動するのも遅いし、終わる のも遅い、非同期協調作業が出来るほど軽いものじゃないです。それに、 キュー処理にはまったく対応していない。  この説明で、疑問に答えられてのかまったく持って不安です。 もしよろしければ、説明不足な点をご指摘ください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1396] Re:マルチスレッドについて
投稿者:(ぱ)こと管理人
2009/07/18 23:59:26

まず訂正です。 >>その「タイマ表示」関数は、引数のqidを順に >>変えながら、3回呼び出されているように見えますが……(そして毎回、自ら >>returnしている) 3回ではないですね。指定回数分だけqidが「タイマ」で呼び出されるのだろう、 ということは前回投稿時も認識していたはずですが、書き損じました。 >例えば、6回実行のスレは、初期1回とタイマー6回で、合計7回実行 >しています。 「終了指示」を含めると8回になるように思えるのですが…… それはさておき。 私が不思議なのは、なぜユーザプログラムの側をこのように細切れに呼び出さなければ ならないのか、ということです。ユーザプログラムが自ら処理を明け渡す必要が ないことが、マルチスレッドの利点だと思うのですが。 確認ですが、「スレ開始」(#defineをはがした実体はthread_start)は、山さんの 言語自体が提供しているシステム関数的なものですよね? そして、「タイマ表示」は、ユーザプログラマが作成することを想定したものですよね? マルチスレッドというのなら、ユーザのプログラムがreturnすることで処理を 手放さなくても、別のスレッドは動くわけですから、こんなふうに細切れに 呼び出さなくてもよいと思うのですが。この形式だと、ユーザプログラムは、 毎回カウンタを見て処理を切り替える必要があります。 固定個のスレッドプールを持っているようなので、それを使い切った場合を想定して いるのでしょうか? うーん。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1395] Re:マルチスレッドについて
投稿者:
2009/07/18 00:47:27

>2:キュー処理開始 vm=3 procid=0 Qid=1 p1=999 >2:キュー処理開始 vm=4 procid=1 Qid=1 p1=6 >2:キュー処理開始 vm=2 procid=2 Qid=1 p1=5 >2:キュー処理開始 vm=0 procid=3 Qid=1 p1=4 >2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=3 Qid=2 p1=1 >2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=1 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=3 Qid=2 p1=1 >2:キュー処理開始 vm=2 procid=1 Qid=2 p1=1 >2:キュー処理開始 vm=4 procid=2 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=1 Qid=2 p1=1 >2:キュー処理開始 vm=2 procid=3 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 >2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 >2:キュー処理開始 vm=1 procid=3 Qid=2 p1=1  こ、これはVM1の実行が多い… タイマ処理が周期に比べて短くなったので、VMの待機状態が多くなったのでしょう。 その結果、VM1がキューをGETしやすいタイミングになったのではないかと思わ れます。VM3はmainが占有しているので。私のPCはデュアルなので、たまたま VM1が、空きCPUに割り振られたのかもしれませんね。  面白い結果だと思います。もう少し重くなれば結果的にCPUの処理に対して 均等に負荷が割り振られるでしょう。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1394] Re:マルチスレッドについて
投稿者:
2009/07/18 00:37:21

連投すみませんです。 このタイミングでスレを起動したときの実行結果です デバックトレースはそのままです。それらしい出力になったと思いますよ。   sid[0] = スレ開始("タイマ表示",200,6," 200ms"," で6回実行");   sid[1] = スレ開始("タイマ表示",300,5," 300ms"," で5回実行");   sid[2] = スレ開始("タイマ表示",400,4," 400ms"," で4回実行");   ↓   ↓   ↓ 3:### スレッド起動 ### 3: sid[0] =1 sid[1] =2 sid[2] =3 3:眠る前 ms=36239130 3:タイマ表示スレッド開始 SID=1 QID=1 回数=6 200ms で6回実行 3:タイマ表示スレッド開始 SID=2 QID=1 回数=5 300ms で5回実行 3:タイマ表示スレッド開始 SID=3 QID=1 回数=4 400ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=1 200ms で6回実行 3:眠る後 ms=36239440 3:タイマ表示 SID=2 QID=2 cnt=1 300ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=1 400ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=2 200ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=2 300ms で5回実行 3:タイマ表示 SID=1 QID=2 cnt=3 200ms で6回実行 3:タイマ表示 SID=3 QID=2 cnt=2 400ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=4 200ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=3 300ms で5回実行 3:タイマ表示 SID=1 QID=2 cnt=5 200ms で6回実行 3:タイマ表示 SID=3 QID=2 cnt=3 400ms で4回実行 3:タイマ表示 SID=2 QID=2 cnt=4 300ms で5回実行 3:タイマ表示 SID=1 QID=2 cnt=6 200ms で6回実行 3:タイマ表示スレッド終了 SID=1 QID=2 3:タイマ表示 SID=2 QID=2 cnt=5 300ms で5回実行 3:タイマ表示スレッド終了 SID=2 QID=2 3:タイマ表示 SID=3 QID=2 cnt=4 400ms で4回実行 3:タイマ表示スレッド終了 SID=3 QID=2 3: rtn[0] =0 rtn[1] =0 rtn[2] =0 3:### 全スレッド終了 ### 2:### システム開始----- 2:### 組込み関数登録処理開始----- 2:### 組込み関数登録処理終了----- 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=0 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=1 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=2 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=3 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=4 2:### コンパイル初期化処理開始----- 2:### コンパイル開始----- 2:### コンパイル終了----- 2:### コンパイルの総てのリソースを開放----- 2:キュー処理開始 vm=3 procid=0 Qid=1 p1=999 2:キュー処理開始 vm=4 procid=1 Qid=1 p1=6 2:キュー処理開始 vm=2 procid=2 Qid=1 p1=5 2:キュー処理開始 vm=0 procid=3 Qid=1 p1=4 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=1 procid=3 Qid=2 p1=1 2:スレッドRUN終了 vmid=3 2:スレッドRUN終了 vmid=1 2:スレッドRUN終了 vmid=0 2:スレッドRUN終了 vmid=2 2:スレッドRUN終了 vmid=4 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:#debugMsg 残っているメモリーを開放 66 66 2:#debugMsg 残っている配列メモリーを開放 26 26 2:### システム終了----- 2:### CL_systemスレッド 終了 2:### CL_systemスレッドハンドルをクローズしました 2:### ダミーmain終了-----
[この投稿を含むスレッドを表示] [この投稿を削除]
[1393] Re:マルチスレッドについて
投稿者:
2009/07/17 21:55:22

ミスです… orz >  初期化とパラメーターをセーブして、待機終了 returnする >  初期化とパラメーターをセーブして、待機returnする
[この投稿を含むスレッドを表示] [この投稿を削除]
[1392] Re:マルチスレッドについて
投稿者:
2009/07/17 21:31:11

 追記の追加。  このプログラムは、周期タイマーを例に挙げていますが。本来の使い方は、 メッセージキューによる、完全非同期協調作業のための機能です。 おもに、スレが起動されたらすぐにキュー待ちになり。作業要求が来たら 処理するためにあります。仮にスレッドが100有っても、キュー待ち状態 のときは、CPU負荷が0なのでなんら問題は有りません。  う~~これ以上は、絵に描いた餅になりそうなのでこれで終わって。 実物のソフトで示して行きたいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1391] Re:マルチスレッドについて
投稿者:
2009/07/17 20:40:51

 追記、オンメモリーだけでも切り替わりのタイミングを調べるのは困難かも しれない。切り替わったことを調べるためには、それぞれのタイミングで どこかにその情報を書くのですが、書き先は順番が分かるために共通の場所に 書かなくてはいけないのだけど、共通の場所とは、セマホ等で排他処理をする わけで、排他処理の時点でスレッドが切り替わってしまうので。意味が無い。  物理的に信号監視できるICEがほしいと思ってしまう。^^ まあ問題が起こらなければ、いつ起ころうが関係が無いですけどね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1390] Re:マルチスレッドについて
投稿者:
2009/07/17 20:30:56

>ここで、スレッドを3本起動しており、「タイマ表示」という関数名の関数を >呼び出しているようですが、その「タイマ表示」関数は、引数のqidを順に >変えながら、3回呼び出されているように見えますが……(そして毎回、自ら >returnしている)  ああ、やっぱりそう見えましたか。実は裏のデバックトレースが重過ぎて 実行が周期内に終わっていないのです。常にオーバフロー状態なんです。 で、デバックトレースOFFにすると、表示自体がデバックモニターの分類3 を使っているので、表示も消えてしまうと言うジレンマが…  なので、最後にデバックトレースのサンプルを出したのですが、やはり^^; 実際は、VMの実行がトレースのためにめちゃくちゃ遅いのです。プログラムの 途中で処理が変わるどころか、バイトコード1命令の実行の中で2-4回VMが 変わって、VMがそれぞれの担当処理を実行しようとがんばっています。 しかし、デバックトレースは、UDP通信でデバックモニターに送っているので、 その通信をしたタイミング(通信処理のためのスレ一時中断)でスレッド チェンジが起こってしまっています。デバック情報1行送るたびにスレッドが ころころ変わってしまっています。  まあでも、とてもいいデバック環境でした、ほんの些細なタイミングミスも、 ころころ引っかかるので、もう異常が出まくりでした。つぶすのは大変で したが、つぶし終わった後いろいろ変えてもなんら問題がおきませんでした。  で、そのまま使ってたデータで文を作ってUPした後、これまずいかなーと 思って、デバックトレースサンプルを追加してみました。  間違いなく、main+3スレッド=4スレッド、細切れどころかミジン切れの 状態で動いています。後で、タイミングを長くしたものの出力でもUPします。 今ちょっとノートPCシステム入れ直ししてて、それにかかりっきりで… 手順を簡単に説明すると。下のスレ開始から > sid[0] = スレ開始("タイマ表示",40,6," 40ms"," で6回実行"); 1、スレッド初期起動キューが作成される 2、空きVMがキューをGET位して、タイマ表示関数を実行 3.タイマ表示関数は初期起動なので、システム変数を生成し   初期化とパラメーターをセーブして、待機終了 returnする 4、管理部分が、周期起動のスレッドが有るので、そのスレッド向けに   時間が来たら、周期起動のキューを作る。 5.空きVMが周期起動キューを取り出し、その関数を実行する。 6.タイマ表示関数は周期起動キューで起動されたことを理解して   カウンタを+1して、そのカウンタを表示する。そして待機return 7.また4に戻り周期キューが作成されるー>4に戻り 8.タイマ表示関数は周期起動キューの中で、回数値とカウンタを   比較してカウンタ>=回数なら、終了returnして、スレッドが終わる。  こんな感じで動いています。たぶん説明が抜けていたのは、システムが 周期キューを生成している部分だと思います。 例えば、6回実行のスレは、初期1回とタイマー6回で、合計7回実行 しています。  スレ1が7回、スレ2が6回、スレ3が5回実行しています。 で、タイマ表示関数は周期に追いついていないので、システムは回数以上 の周期タイマーキューを生成していて、VMが実行しようとしています。 また、ちがうVMが同じスレッドの周期キューを平行して実行しようと してしまいます。もちろんこれは問題が起こるので、そうならないように 作られています。言葉で言うと簡単そうですが、複雑な制御をしています。  常に重い状態で動いているので、キューが溜まってヘビーな状態で デバックをしていました。 >「タイマ表示」関数がreturnしないまま、別のスレッドに制御を奪われることって >あるんでしょうか? もう、1回のキュー処理で数十回はVMのスレッドチェンジが起こっています。 各スレッド処理は、みじん切りの細切れで並列に動いています。 デバックトレースを止めればそのようなことは無いと思います。  デバックトレースを止めた時に、どの様なタイミングで切り替わるかは 興味があります。しかしそれを調べるためには、表示は一切使えないんで すねね、なんに表示してもその間に切り替わるから。オンメモリーだけで 高速のトレーサでも作りこまないと、それでも、VMの方が早いかもしれ ない。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1389] Re:【業務連絡】雑記帳が使えなくなっています
投稿者:(ぱ)こと管理人
2009/07/17 03:09:23

ホイヘンスさん、はじめまして。 情報ありがとうございます。 >駄文なページの「表計算ソフトって」のページで >Parse error: syntax error, unexpected '^' in /home/km3943/public_html/essay/excel.html on line 62 > >「15パズルの作り方」のページで >Parse error: syntax error, unexpected '^' in /home/km3943/public_html/essay/puzzle.html on line 181 ただのHTMLファイルのはずなのに、なぜかPHPが動いていますね…… .htaccess等でそのような設定にすることはできますが(そして雑記帳では、 その設定を入れていますが)、ここにはそのような設定ファイルは置いていません。 実は今、トップのディレクトリに.htaccessがなぜかあるのを発見し、 これのせいかと思ったのですが中身は0バイトでした(削除しても直らないですし)。 さすがに今は眠いので週末もう少し追ってみます。 情報ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1388] Re:マルチスレッドについて
投稿者:(ぱ)こと管理人
2009/07/17 02:59:59

すみません、今みっつくらいよくわからないのですが、 > sid[0] = スレ開始("タイマ表示",40,6," 40ms"," で6回実行"); > sid[1] = スレ開始("タイマ表示",60,5," 60ms"," で5回実行"); > sid[2] = スレ開始("タイマ表示",80,4," 80ms"," で4回実行"); ここで、スレッドを3本起動しており、「タイマ表示」という関数名の関数を 呼び出しているようですが、その「タイマ表示」関数は、引数のqidを順に 変えながら、3回呼び出されているように見えますが……(そして毎回、自ら returnしている) >int タイマ表示(int sid, int qid,int p1, string p2, string p3) >{ > string questr = " SID=" + sid + " QID=" + qid; > if(qid == スレッド開始) { > // スレッド起動時のみ時実行 -------------- > println("タイマ表示スレッド開始"+questr+" 回数="+p1+p2+p3); > システム変数("HAI000-HAI001",生成); > カウント = 0; > 回数 = p1; > システム変数("HAS000-HAS001",生成); > P2STR = p2; > P3STR = p3; > } elsif(qid == タイマ) { > // タイマキューにより実行 -------------- > カウント++; > println("タイマ表示"+questr+" cnt="+カウント+P2STR+P3STR); > if(カウント >= 回数) { > println("タイマ表示スレッド終了" + questr); > return スレッド終了; > } > } elsif(qid == 終了指示) { > println("タイマ表示 終了指示により終了" + questr); > return スレッド終了; > } else { > println("タイマ表示スレッド エラー終了" + questr); > return スレッドエラー終了; > } > return スレッド待機; >} 「タイマ表示」関数がreturnしないまま、別のスレッドに制御を奪われることって あるんでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1387] 参考までにデバックトレース
投稿者:
2009/07/16 01:47:59

 参考までに今の2+VM5の7スレッド実行状態でのデバックトレースを 下記に示しますが、もうなんというか、7スレッド入り乱れたトレースで わけわからん状態です。デバックモニターシステムは4分類あるのですが スレ起きに無いともう分けわかめで、デバックモニターシステムも修正です。  下記ではVM内でぶちぶちにスレッドが入れ替わっている状態が見れます。 ---------------------------------------------------- 1:eq_int PC=25 sp=292 1:eq_int PC=25 sp=292 1:add_string PC=6 sp=416 1:add_string PC=6 sp=424 1:00B5FF54 : ES_INT size=12605 ref=NON int=1 1:00B6FF94 : ES_INT size=12605 ref=NON int=1 1:00BA2160 : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始 SID=1 QID=1 回数=6 40ms で6回実行 " 1:00B916B8 : ES_STRING size=40 ref=NON string="眠る前 ms=40224457 " 1:jump_if_false PC=26 sp=276 1:jump_if_false PC=26 sp=276 1:call_function PC=7 sp=376 1:call_function PC=7 sp=384 1:00B5FF64 : ES_FUNCTION size=244 1:00B6FFA4 : ES_FUNCTION size=244 1:#-C_NF_print::funcexe() 1:#-C_NF_print::funcexe() 3:タイマ表示スレッド開始 SID=1 QID=1 回数=6 40ms で6回実行 1: 関数からの戻りプログラムカウンタ = 0 3:眠る前 ms=40224457 1: 関数からの戻りプログラムカウンタ = 0 1:00BA2178 : ES_INT size=16 ref=NON int=0 1: 関数からの戻りスタックポイント = 0 1:00B916D0 : ES_INT size=16 ref=NON int=0 1: 関数からの戻りスタックポイント = 0 1:pop PC=16 sp=352 1: VMが起動する関数情報 = 00BC60F0 1:pop PC=16 sp=360 1: VMが起動する関数情報 = 00BC60F0 1:00BA2188 : ES_FUNCTION size=320 1: ローカル変数数 = 6 1:00B916E0 : ES_FUNCTION size=352 1: ローカル変数数 = 6 1: 関数からの戻りプログラムカウンタ = 62 1:push_string_const PC=29 sp=260 1: 関数からの戻りプログラムカウンタ = 168 1:push_string_const PC=29 sp=260 1: 関数からの戻りスタックポイント = 65276 1:00B5FF3C : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始" 1: 関数からの戻りスタックポイント = 65268 1:00B6FF7C : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始" 1: VMが起動する関数情報 = 00BC6F48 1:push_stack_string PC=32 sp=300 1: VMが起動する関数情報 = 00BC6F48 1:push_stack_string PC=32 sp=300 1: ローカル変数数 = 1 1:00B5FF14 : ES_STRING size=40 ref=00B5FFB8 string=" SID=2 QID=1" 1: ローカル変数数 = 1 1:00B6FF54 : ES_STRING size=40 ref=00B6FFF8 string=" SID=3 QID=1" 1:push_int_1byte PC=17 sp=336 1:add_string PC=35 sp=340 1:push_int_1byte PC=17 sp=344 1:add_string PC=35 sp=340 1:00BA2178 : ES_INT size=16 ref=NON int=0 1:00B5FF3C : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始 SID=2 QID=1" 1:00B916D0 : ES_INT size=16 ref=NON int=0 1:00B6FF7C : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始 SID=3 QID=1" 1:return PC=19 sp=352 1:push_string_const PC=36 sp=300 1:return PC=19 sp=360 1:push_string_const PC=36 sp=300 1:00BA21C4 : ES_INT size=16 ref=NON int=0 1:00B5FF14 : ES_STRING size=40 ref=NON string=" 回数=" 1:00B9171C : ES_INT size=16 ref=NON int=0 1:00B6FF54 : ES_STRING size=40 ref=NON string=" 回数=" 1:pop PC=62 sp=276 1:add_string PC=39 sp=340 1:pop PC=168 sp=284 1:add_string PC=39 sp=340 1:00BA21D4 : ES_FUNCTION size=244 1:00B5FF3C : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始 SID=2 QID=1 回数=" 1:00B9172C : ES_FUNCTION size=124 1:00B6FF7C : ES_STRING size=40 ref=NON string="タイマ表示スレッド開始 SID=3 QID=1 回数=" 1: 関数からの戻りプログラムカウンタ = 0 1:push_stack_int PC=40 sp=300 1: 関数からの戻りプログラムカウンタ = 0 1:push_stack_int PC=40 sp=300 1: 関数からの戻りスタックポイント = 0 ----------------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1386] Re:システム変数について
投稿者:
2009/07/16 01:17:37

あれからもいろいろ考えましたが、システム変数をシート形式でやる方法 以上の良い案が浮かびませんでした。ワーク用のグローバル変数を作ること は簡単なのですが、サービスのほとんどはシート上にて提供されるため、 これを越える案が今の所出そうに無いです。  もしよろしければ、システム変数が座標であることは少し目をつぶって いただけたら嬉しいです。確かに私も抵抗が有りますが、良い代替案が浮か ばない、有れば変えるのもそう難しくないと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1385] プログラムのアセンブラコード
投稿者:
2009/07/16 01:00:50

 下記はプログラムのアセンブラコードです、特に何も変わっていませんが、 ごく普通のコードでマルチスレッドを問題なく実行しています。 1:*** 一般関数情報ダンプ ****************** 1:int main_001() 1:*** ローカル変数の表示 no = 2 *** 1: 0:int [3] sid 1: 1:int [3] rtn 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 25 *** 1: 0: "main_001" 1: 1: "sid" 1: 2: "rtn" 1: 3: "### スレッド起動 ###" 1: 4: "println" 1: 5: "タイマ表示" 1: 6: " 40ms" 1: 7: " で6回実行" 1: 8: "thread_start" 1: 9: " 60ms" 1: 10: " で5回実行" 1: 11: " 80ms" 1: 12: " で4回実行" 1: 13: " sid[0] =" 1: 14: " sid[1] =" 1: 15: " sid[2] =" 1: 16: "眠る前 ms=" 1: 17: "get_ms_time" 1: 18: "sleep" 1: 19: "眠る後 ms=" 1: 20: "thread_exit_waiting" 1: 21: " rtn[0] =" 1: 22: " rtn[1] =" 1: 23: " rtn[2] =" 1: 24: "### 全スレッド終了 ###" 1:*** 使用予定のスタックサイズ = 2116 1:*** 関数コードのディスアセンブラ size = 348 1: 0 push_string_const 3 1: 3 call_function 4 0 0 1 1: 12 pop 1: 13 push_string_const 5 1: 16 push_int_1byte 40 1: 18 push_int_1byte 6 1: 20 push_string_const 6 1: 23 push_string_const 7 1: 26 call_function 8 0 0 5 1: 35 push_stack_array 0 1: 38 push_int_1byte 0 1: 40 pop_array_int 1: 41 push_string_const 5 1: 44 push_int_1byte 60 1: 46 push_int_1byte 5 1: 48 push_string_const 9 1: 51 push_string_const 10 1: 54 call_function 8 0 0 5 1: 63 push_stack_array 0 1: 66 push_int_1byte 1 1: 68 pop_array_int 1: 69 push_string_const 5 1: 72 push_int_1byte 80 1: 74 push_int_1byte 4 1: 76 push_string_const 11 1: 79 push_string_const 12 1: 82 call_function 8 0 0 5 1: 91 push_stack_array 0 1: 94 push_int_1byte 2 1: 96 pop_array_int 1: 97 push_string_const 13 1: 100 push_stack_array 0 1: 103 push_int_1byte 0 1: 105 push_array_int 0 1: 107 cast_int_to_string 1: 108 add_string 1: 109 push_string_const 14 1: 112 add_string 1: 113 push_stack_array 0 1: 116 push_int_1byte 1 1: 118 push_array_int 0 1: 120 cast_int_to_string 1: 121 add_string 1: 122 push_string_const 15 1: 125 add_string 1: 126 push_stack_array 0 1: 129 push_int_1byte 2 1: 131 push_array_int 0 1: 133 cast_int_to_string 1: 134 add_string 1: 135 call_function 4 0 0 1 1: 144 pop 1: 145 push_string_const 16 1: 148 call_function 17 0 0 0 1: 157 cast_int_to_string 1: 158 add_string 1: 159 call_function 4 0 0 1 1: 168 pop 1: 169 push_int_2byte 300 1: 172 call_function 18 0 0 1 1: 181 pop 1: 182 push_string_const 19 1: 185 call_function 17 0 0 0 1: 194 cast_int_to_string 1: 195 add_string 1: 196 call_function 4 0 0 1 1: 205 pop 1: 206 push_stack_array 0 1: 209 push_int_1byte 0 1: 211 push_array_int 0 1: 213 push_int_1byte 0 1: 215 push_int_1byte 10 1: 217 call_function 20 0 0 3 1: 226 push_stack_array 1 1: 229 push_int_1byte 0 1: 231 pop_array_int 1: 232 push_stack_array 0 1: 235 push_int_1byte 1 1: 237 push_array_int 0 1: 239 push_int_1byte 0 1: 241 push_int_1byte 10 1: 243 call_function 20 0 0 3 1: 252 push_stack_array 1 1: 255 push_int_1byte 1 1: 257 pop_array_int 1: 258 push_stack_array 0 1: 261 push_int_1byte 2 1: 263 push_array_int 0 1: 265 push_int_1byte 0 1: 267 push_int_1byte 10 1: 269 call_function 20 0 0 3 1: 278 push_stack_array 1 1: 281 push_int_1byte 2 1: 283 pop_array_int 1: 284 push_string_const 21 1: 287 push_stack_array 1 1: 290 push_int_1byte 0 1: 292 push_array_int 0 1: 294 cast_int_to_string 1: 295 add_string 1: 296 push_string_const 22 1: 299 add_string 1: 300 push_stack_array 1 1: 303 push_int_1byte 1 1: 305 push_array_int 0 1: 307 cast_int_to_string 1: 308 add_string 1: 309 push_string_const 23 1: 312 add_string 1: 313 push_stack_array 1 1: 316 push_int_1byte 2 1: 318 push_array_int 0 1: 320 cast_int_to_string 1: 321 add_string 1: 322 call_function 4 0 0 1 1: 331 pop 1: 332 push_string_const 24 1: 335 call_function 4 0 0 1 1: 344 pop 1: 345 push_int_1byte 98 1: 347 return 1:*** 行情報 数 = 14 *** 1: 36: from 0 size 13 1: 38: from 13 size 28 1: 39: from 41 size 28 1: 40: from 69 size 28 1: 41: from 97 size 48 1: 43: from 145 size 24 1: 44: from 169 size 13 1: 45: from 182 size 24 1: 49: from 206 size 26 1: 50: from 232 size 26 1: 51: from 258 size 26 1: 52: from 284 size 48 1: 53: from 332 size 13 1: 54: from 345 size 3 1:*** end of main_001() -------------- 1:--------デバックログ中止-------- 1:--------デバックログ開始-------- 1:*** 一般関数情報ダンプ ****************** 1:int タイマ表示(int sid, int qid, int p1, string p2, string p3) 1:*** ローカル変数の表示 no = 6 *** 1: 0:int sid 1: 1:int qid 1: 2:int p1 1: 3:string p2 1: 4:string p3 1: 5:string questr 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 19 *** 1: 0: "タイマ表示" 1: 1: "sid" 1: 2: "qid" 1: 3: "p1" 1: 4: "p2" 1: 5: "p3" 1: 6: "questr" 1: 7: " SID=" 1: 8: " QID=" 1: 9: "タイマ表示スレッド開始" 1: 10: " 回数=" 1: 11: "println" 1: 12: "HAI000-HAI001" 1: 13: "sysval" 1: 14: "HAS000-HAS001" 1: 15: " cnt=" 1: 16: "タイマ表示スレッド終了" 1: 17: "タイマ表示 終了指示により終了" 1: 18: "タイマ表示スレッド エラー終了" 1:*** 使用予定のスタックサイズ = 1612 1:*** 関数コードのディスアセンブラ size = 282 1: 0 push_string_const 7 1: 3 push_stack_int 0 1: 6 cast_int_to_string 1: 7 add_string 1: 8 push_string_const 8 1: 11 add_string 1: 12 push_stack_int 1 1: 15 cast_int_to_string 1: 16 add_string 1: 17 pop_stack_string 5 1: 20 push_stack_int 1 1: 23 push_int_1byte 1 1: 25 eq_int 1: 26 jump_if_false 127 1: 29 push_string_const 9 1: 32 push_stack_string 5 1: 35 add_string 1: 36 push_string_const 10 1: 39 add_string 1: 40 push_stack_int 2 1: 43 cast_int_to_string 1: 44 add_string 1: 45 push_stack_string 3 1: 48 add_string 1: 49 push_stack_string 4 1: 52 add_string 1: 53 call_function 11 0 0 1 1: 62 pop 1: 63 push_string_const 12 1: 66 push_int_1byte 1 1: 68 call_function 13 0 0 2 1: 77 pop 1: 78 push_int_1byte 0 1: 80 pop_sysval_int 1-364-0 1: 85 push_stack_int 2 1: 88 pop_sysval_int 1-364-1 1: 93 push_string_const 14 1: 96 push_int_1byte 1 1: 98 call_function 13 0 0 2 1: 107 pop 1: 108 push_stack_string 3 1: 111 pop_sysval_str 3-364-0 1: 116 push_stack_string 4 1: 119 pop_sysval_str 3-364-1 1: 124 jump 279 1: 127 push_stack_int 1 1: 130 push_int_1byte 2 1: 132 eq_int 1: 133 jump_if_false 227 1: 136 push_sysval_int 1-364-0 1: 141 increment 1: 142 pop_sysval_int 1-364-0 1: 147 push_string_const 0 1: 150 push_stack_string 5 1: 153 add_string 1: 154 push_string_const 15 1: 157 add_string 1: 158 push_sysval_int 1-364-0 1: 163 cast_int_to_string 1: 164 add_string 1: 165 push_sysval_str 3-364-0 1: 170 add_string 1: 171 push_sysval_str 3-364-1 1: 176 add_string 1: 177 call_function 11 0 0 1 1: 186 pop 1: 187 push_sysval_int 1-364-0 1: 192 push_sysval_int 1-364-1 1: 197 ge_int 1: 198 jump_if_false 224 1: 201 push_string_const 16 1: 204 push_stack_string 5 1: 207 add_string 1: 208 call_function 11 0 0 1 1: 217 pop 1: 218 push_int_1byte 1 1: 220 return 1: 221 jump 224 1: 224 jump 279 1: 227 push_stack_int 1 1: 230 push_int_1byte 3 1: 232 eq_int 1: 233 jump_if_false 259 1: 236 push_string_const 17 1: 239 push_stack_string 5 1: 242 add_string 1: 243 call_function 11 0 0 1 1: 252 pop 1: 253 push_int_1byte 1 1: 255 return 1: 256 jump 279 1: 259 push_string_const 18 1: 262 push_stack_string 5 1: 265 add_string 1: 266 call_function 11 0 0 1 1: 275 pop 1: 276 push_int_1byte 2 1: 278 return 1: 279 push_int_1byte 0 1: 281 return 1:*** 行情報 数 = 29 *** 1: 65: from 0 size 20 1: 66: from 20 size 6 1: 89: from 26 size 3 1: 68: from 29 size 34 1: 69: from 63 size 15 1: 70: from 78 size 7 1: 71: from 85 size 8 1: 72: from 93 size 15 1: 73: from 108 size 8 1: 74: from 116 size 8 1: 89: from 124 size 3 1: 75: from 127 size 6 1: 89: from 133 size 3 1: 77: from 136 size 11 1: 78: from 147 size 40 1: 79: from 187 size 11 1: 83: from 198 size 3 1: 80: from 201 size 17 1: 81: from 218 size 3 1: 83: from 221 size 3 1: 89: from 224 size 3 1: 83: from 227 size 6 1: 89: from 233 size 3 1: 84: from 236 size 17 1: 85: from 253 size 3 1: 89: from 256 size 3 1: 87: from 259 size 17 1: 88: from 276 size 3 1: 90: from 279 size 3 1:*** end of タイマ表示() -------------- 1:--------デバックログ中止-------- 1:--------デバックログ開始-------- 1:*** 一般関数情報ダンプ ****************** 1:int println(string str) 1:*** ローカル変数の表示 no = 1 *** 1: 0:string str 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 4 *** 1: 0: "println" 1: 1: "str" 1: 2: " " 1: 3: "print" 1:*** 使用予定のスタックサイズ = 356 1:*** 関数コードのディスアセンブラ size = 20 1: 0 push_stack_string 0 1: 3 push_string_const 2 1: 6 add_string 1: 7 call_function 3 0 0 1 1: 16 pop 1: 17 push_int_1byte 0 1: 19 return 1:*** 行情報 数 = 2 *** 1: 95: from 0 size 17 1: 96: from 17 size 3 1:*** end of println() --------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1384] マルチスレッドの仕組み
投稿者:
2009/07/16 00:59:49

 下図に示すように、ダミーmainで1スレッド、システム管理で1スレッド VMスレッドが20、トータル22スレッドが動きます、VMが20がいいのか10が いいのかは、今後の調査により決まると思います。 実際の動作はVMの一つ が言語のmain関数が占有します。main関数が終了すると、サブのVMは強制 終了されます。だから、実際に作業するのは残りの19VMスレッドで処理が 自由に割り振られます。優先順位に従い、空いたVMから処理が行われます。 だから、言語上のスレッドはある時はVM3で実行しても次は空いていたVM12 が実行します。この構造が出来たことにより、普通の関数起動と同じよう な負荷でスレッドが起動できる軽いシステムになりました。  ちなみにVMの待ち状態は、極微小の負荷しかありません。  ダミーmainは、アプリケーションの各種表示処理の担当に使います。  このシステムが出来たので言語上のファイバーは、比較的簡単に実装 できます。そのときの実行負荷も軽いです。 ダミーmain         システム管理  -----    ----------------------------------------  |  | スレ起動 |                   |  |  | -> |                   |  -----    ----------------------------------------          ↓     ↓ VMスレッド起動  ↓   ------------------  --------       --------   |        |  |   |       |   |   ----------| 言 |  | V | VMスレッド | V |     ↓  | 語 |  | M | 20個が常に | M |   -------- | 管 |  | 0 |  起動し  | 1 |   | コ | | 理 |  | 0 | キュー待ち | 9 |   | ン | |   |  |   |       |   |   | パ | |   |  |   |       |   |   | イ | |   |  |   |       |   |   | ラ | |   |  |   |       |   |   -------- --------  --------       -------- -----------------------------     ↓   上の構造が実行した場合の、トレース情報。   デバック用にVMは5個起動しています。   このトレースではVM1がmainスレッドに割り当てられています。     ↓ ----------------------------- 2:### ダミーmain開始----- 2:### CL_systemスレッド 開始 2:### システム開始----- 2:### 組込み関数登録処理開始----- 2:### 組込み関数登録処理終了----- 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=0 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=1 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=2 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=3 2:### CL_VMexeスレッド 開始 2:スレッドRUN開始 vmid=4 2:### コンパイル初期化処理開始----- 2:### コンパイル開始----- 2:### コンパイル終了----- 2:### コンパイルの総てのリソースを開放----- 2:キュー処理開始 vm=1 procid=0 Qid=1 p1=999 2:キュー処理開始 vm=2 procid=1 Qid=1 p1=6 2:キュー処理開始 vm=3 procid=2 Qid=1 p1=5 2:キュー処理開始 vm=0 procid=3 Qid=1 p1=4 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=0 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=0 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=4 procid=1 Qid=2 p1=1 2:キュー処理開始 vm=0 procid=3 Qid=2 p1=1 2:キュー処理開始 vm=3 procid=2 Qid=2 p1=1 2:キュー処理開始 vm=2 procid=1 Qid=2 p1=1 2:スレッドRUN終了 vmid=1 2:スレッドRUN終了 vmid=4 2:スレッドRUN終了 vmid=0 2:スレッドRUN終了 vmid=2 2:スレッドRUN終了 vmid=3 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:### CL_VMexeスレッド 終了 2:### CL_VMexeスレッドハンドルをクローズしました 2:#debugMsg 残っているメモリーを開放 66 66 2:#debugMsg 残っている配列メモリーを開放 26 26 2:### システム終了----- 2:### CL_systemスレッド 終了 2:### CL_systemスレッドハンドルをクローズしました 2:### ダミーmain終了-----
[この投稿を含むスレッドを表示] [この投稿を削除]
[1383] マルチスレッドについて
投稿者:
2009/07/16 00:58:48

 ようやくマルチスレッドの組込みが終わりました。テストモデルは比較的 早くできたのですが、実際の組込みは多少時間がかかりました。全体的なり ファクタリングが必要だったし。  下記プログラムのように、同じ関数を3スレッドで平行実行しています。 この言語の特徴は、なんらマルチスレッドを意識することなく、ただ関数を 書くだけでマルチで実行可能な点です。関数の入り口の書式は決まっていま すが、そこから呼ばれているprintln()等は何も意識していません。ちなみ にHシートのシステム変数はスレッド置きに作成され、そのスレッドが所有 権を持ちます。スレッドが100個あれば100枚のHシートができます。  この様にシートによって各種特徴やサービスがあるシートと、自由に使え る汎用シートがあります。  システム変数は総て所有権が有り、一つのスレッドが所有者になります。 もちろん委譲したり戻したり出来ますが、一度に1つのスレッドしか所有権 を持ちません。  また、一般的なスレッドと多少性格が違い、1つのスレッドを起動すると、 初期起動実行後、メッセージ(キュー)が来るまで待ち状態で待機します。 待機時のCPU消費は0です。メッセージ駆動型のスレッドです。普通に関数 を書くだけで、いくら並列に起動されようと問題なく動きます。特別な知識 も要りません。 //-- スレッド操作関数 ---------------- #define スレ開始 thread_start #define スレ終了待ち thread_exit_waiting #define 終了待ち   0 // 終了を待つ #define 終了指示待ち 1 // 終了指示を出し終了を待つ #define 強制終了待ち 2 // 強制終了を出し終了を待つ //-- スレ終了待ち関数の戻り値 --------- #define 正常終了   0 // スレ正常終了 #define タイムアウト 1 // スレ終了待ちがタイムアウト //-- スレッド終了コード -------------- #define スレッド待機 0 // スレッドはキュー待ちに #define スレッド終了 1 // スレッド終了 #define スレッドエラー終了 2 // スレッドエラー終了 //-- キューID ------------------------ #define スレッド開始 1 // スレッド開始キューID #define タイマ    2 // タイマキューID #define 終了指示   3 // 終了指示キューID //------------------------------------ #define 時間取出し  get_ms_time #define 眠る     sleep #define システム変数 sysval #define 生成 1 // システム変数生成 //-- 組込み関数宣言 ------------------- int print(string str); int スレ開始(string fname,int ms,int p1,string p2,string p3); int スレ終了待ち(int sid,int type,int timeout); int システム変数(string str,int type); int 眠る(int time); int 時間取出し(); //------------------------------------------------------ int main() { //-- 同じ関数を違う周期でマルチスレッド起動する ------- int[3] sid; println("### スレッド起動 ###"); // 関数名, ms周期,P1, P2, P3 sid[0] = スレ開始("タイマ表示",40,6," 40ms"," で6回実行"); sid[1] = スレ開始("タイマ表示",60,5," 60ms"," で5回実行"); sid[2] = スレ開始("タイマ表示",80,4," 80ms"," で4回実行"); println(" sid[0] ="+sid[0]+" sid[1] ="+sid[1]+" sid[2] ="+sid[2]); println("眠る前 ms=" + 時間取出し()); 眠る(300); // 300ms眠る println("眠る後 ms=" + 時間取出し()); //-- スレッドが終了するまで待つ --------------------- int[3] rtn; rtn[0] = スレ終了待ち(sid[0],終了待ち,10); // 10秒でタイムアウト rtn[1] = スレ終了待ち(sid[1],終了待ち,10); rtn[2] = スレ終了待ち(sid[2],終了待ち,10); println(" rtn[0] ="+rtn[0]+" rtn[1] ="+rtn[1]+" rtn[2] ="+rtn[2]); println("### 全スレッド終了 ###"); return 98; } //-- システム変数の定義 -------------------------------- #define カウント HAI000 // タイマのカウンタ #define 回数 HAI001 // p1の終了回数 #define P2STR HAS000 // p2の文字列 #define P3STR HAS001 // p3の文字列 //-- 複数スレッド起動される周期タイマー処理関数 --------- int タイマ表示(int sid, int qid,int p1, string p2, string p3) { string questr = " SID=" + sid + " QID=" + qid; if(qid == スレッド開始) { // スレッド起動時のみ時実行 -------------- println("タイマ表示スレッド開始"+questr+" 回数="+p1+p2+p3); システム変数("HAI000-HAI001",生成); カウント = 0; 回数 = p1; システム変数("HAS000-HAS001",生成); P2STR = p2; P3STR = p3; } elsif(qid == タイマ) { // タイマキューにより実行 -------------- カウント++; println("タイマ表示"+questr+" cnt="+カウント+P2STR+P3STR); if(カウント >= 回数) { println("タイマ表示スレッド終了" + questr); return スレッド終了; } } elsif(qid == 終了指示) { println("タイマ表示 終了指示により終了" + questr); return スレッド終了; } else { println("タイマ表示スレッド エラー終了" + questr); return スレッドエラー終了; } return スレッド待機; } //------------------------------------------------------ int println(string str) { print(str + "\n"); return 0; } //------------------------------------------------------     ↓    実行結果     ↓ -------------------------------------------- 3:### スレッド起動 ### 3: sid[0] =1 sid[1] =2 sid[2] =3 3:タイマ表示スレッド開始 SID=1 QID=1 回数=6 40ms で6回実行 3:タイマ表示スレッド開始 SID=2 QID=1 回数=5 60ms で5回実行 3:タイマ表示スレッド開始 SID=3 QID=1 回数=4 80ms で4回実行 3:眠る前 ms=33696948 3:タイマ表示 SID=1 QID=2 cnt=1 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=1 60ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=1 80ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=2 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=2 60ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=2 80ms で4回実行 3:タイマ表示 SID=1 QID=2 cnt=3 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=3 60ms で5回実行 3:タイマ表示 SID=3 QID=2 cnt=3 80ms で4回実行 3:眠る後 ms=33697360 3:タイマ表示 SID=1 QID=2 cnt=4 40ms で6回実行 3:タイマ表示 SID=2 QID=2 cnt=4 60ms で5回実行 3:タイマ表示 SID=1 QID=2 cnt=5 40ms で6回実行 3:タイマ表示 SID=3 QID=2 cnt=4 80ms で4回実行 3:タイマ表示 SID=2 QID=2 cnt=5 60ms で5回実行 3:タイマ表示スレッド終了 SID=3 QID=2 3:タイマ表示スレッド終了 SID=2 QID=2 3:タイマ表示 SID=1 QID=2 cnt=6 40ms で6回実行 3:タイマ表示スレッド終了 SID=1 QID=2 3: rtn[0] =0 rtn[1] =0 rtn[2] =0 3:### 全スレッド終了 ### --------------------------------------------  上の例は、多少時間的な数値や前後がおかしいですが、この裏で大量の デバックトレースが動いているので、ずれています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1382] Re:【業務連絡】雑記帳が使えなくなっています
投稿者:ホイヘンス
2009/07/16 00:15:04

>どうやら、(また勝手に)PHPのバージョンが5に上げられていて、 >しかもなぜか雑記帳のページだけで「Call to undefined function mysql_connect()」と、 >mysqlモジュールがインストールされていないかのようなエラーが出ています…… ポインタ本にいつもお世話になっております。 突然ですがおそらく↑に関連したことだと思いますが 駄文なページの「表計算ソフトって」のページで Parse error: syntax error, unexpected '^' in /home/km3943/public_html/essay/excel.html on line 62 「15パズルの作り方」のページで Parse error: syntax error, unexpected '^' in /home/km3943/public_html/essay/puzzle.html on line 181 上記のエラーが出てページが見れません・・・
[この投稿を含むスレッドを表示] [この投稿を削除]
[1381] 【業務連絡】雑記帳が使えなくなっています
投稿者:(ぱ)こと管理人
2009/07/09 02:14:54

このところ更新していませんが、雑記帳 http://kmaebashi.com/zakki/index.html のページが使えなくなっています。 どうやら、(また勝手に)PHPのバージョンが5に上げられていて、 しかもなぜか雑記帳のページだけで「Call to undefined function mysql_connect()」と、 mysqlモジュールがインストールされていないかのようなエラーが出ています…… 見てのとおり、掲示板は動いているのに。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1380] Re:システム変数について
投稿者:(ぱ)こと管理人
2009/07/05 13:18:44

> なぜこの様になったかを説明しても理解してもらうのは困難と思います。 >結局(ぱ)さんにとって、奇妙な言語ができたに過ぎないのではないかと思う >にいたりました。少し残念です。 ええと、私が先の投稿で書きたかったことは、「私から見れば変に見えるけど、 (NScripterがそうであるように)それがよいという人もいるのでしょう」という ことです。お気を悪くされましたらすみません。 私から見れば奇妙な言語であることは確かですが、Domain Specific Languageが 奇妙な言語に見えるのはよくあることですし、奇妙な言語でなければ、わざわざ 自作する価値がない、とも言えるでしょう(その意味で、crowbarやDiksamは 「おとなしすぎる」んだよなー)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1379] Re:システム変数について
投稿者:
2009/07/03 22:04:56

 ここ数日いろいろ考えたすえ、プロのプログラマやプログラミングに精通して いる人ほど抵抗が大きいと思いました。当初は#defineでは、との返信もありま したが、結局の所シートを前面に出す以上、座標の変数が使われることが多いで しょう。  なぜこの様になったかを説明しても理解してもらうのは困難と思います。 結局(ぱ)さんにとって、奇妙な言語ができたに過ぎないのではないかと思う にいたりました。少し残念です。  今は、マルチスレッド化に専念しています。仕組みのベースがほぼ出来上がっ たので、より深く検証した上で本体に組み込と試験になります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1378] Re:システム変数について
投稿者:(ぱ)こと管理人
2009/07/01 02:35:56

> 変数名は 「シート+列+データ型+項目番号」 = AAI000 となります。だから >自由に変数名はつけれない。それを解消するために#defnieが必衰でした。 こ、これは…… 名前が連番というのは私にはちょっと、と思いますし、この方法でプログラムを 作るとなると、「システム変数レイアウトシート」みたいなドキュメント(方眼紙か Excelシート?)上で、「ここからここまでにはこのデータを入れて…」といった 管理をしなければならなさそうです。ソースから離れたところにドキュメントが 必要になるのは、メンテナンスされないのでは、と心配になります。 ……というのが私の感想ですが、たとえばゲーム業界ではNScripterという言語が 結構広く使われているようなのですが、この言語は変数名が連番です。 http://kamakura.cool.ne.jp/o_show/nscripter/syo/08.htm 私の感覚ではのけぞってしまいますが、ユーザがいる以上、この仕様がよいという 人がいるということなのでしょう(山さんは、#defineでセル名を隠そうとして いますから、連番がよいと思っておられるわけではないと思いますが)。 あと、システム変数がこういう形式だと、入力フォームや出力帳票に直接 結びつけることができると便利かもしれませんね。 なつかしのRPGあたりを彷彿とさせますが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1377] Re:システム変数について
投稿者:
2009/06/30 19:08:00

 さすが(ぱ)さんと言うか、鋭い突っ込みありがとうございます。実はシステム変数に ついては多少触れるのを避けていました。。なぜなら(ぱ)さんの「表計算ソフトって」 のコラムで表についての意見を読んでいて、まさにその表を言語に組み込もうとしている のです。だから、完成する前にキツイ指摘を受けるのではないかと…  システム変数は、簡単に説明すると。項と列によって構成されるシートが基本で、この シートによって複数の機能と特徴を持っています。   Aシート    ・・・~・・・     Zシート (26シート)   ----------- ------------   | | | |   | | | |   ----------- ------------  このシート名が変数の最初の「A」にあたり   000 ...................................... 999 (1000個の項目) ------------------------------------------------- A | | ・・・ | | : | | --------------------- | | Z | | | int double string | | | a | | --------------------- | | : | | ↑一つのセルの中に | | : | | 3つのデータがある | | z | | ・・・ | | ------------------------------------------------- (52の列)  変数名は 「シート+列+データ型+項目番号」 = AAI000 となります。だから 自由に変数名はつけれない。それを解消するために#defnieが必衰でした。  ちなみに、システム変数にアクセスする方法は、直値=AAI001と言う形と、相対配列 =ABI010「X][Y] これは、指定の座標から項にX値の相対座標指定、列にY値の相対座標を 指定してアクセスします。 ABI010[X] は項目のX相対座標指定です。  もともとこのシート形式は、目的アプリケーションで必要だった機能を実現する為の 些細なアイデアでした。しかし、言語を作っていく上でシステムの基本となり。言語上 でもかなめ的要素(中心的要素)になったのです。注意、EXCELを作るわけではありません。  ここからは既存の言語的常識を一時保留にして読んでください。  例えば、市役所等での情報の伝達はシート、書式を持った紙です。市民登録、婚姻届等に 必要な項目を記入し提出する。それを受け取り保存する。別にガッシリとデータ定義された 構造体やclassがあるわけではありません。記入する方も総ての項目を初期化したり記入し たりしません、必要な項目のみ記入して提出します。  このイメージをモジュール間の情報伝達に使用しようと考えたのです。例えばシートAに に必要なことを書いて、他のモジュールに動作指示を出す。その時シート名を伝達するだ けでいい、構造体やclassは不要です。なおかつしたい事の種類のよって、多くの構造体や 多くのクラス定義が必要になったりしますが、シートでは必要な部分だけを書けばいい。  と発想したのが元です。  情報伝達の単位は、最小のint,double,string、そして一つのセル、相対X領域,相対Y領域、 相対矩形の領域、列、シート、そしてパックされた情報の8つの単位で情報伝達を考えてい ます。この処理単位で情報伝達するために、言語は関数内では普通の言語的整合性を持って いますが、一歩外のグローバルではシステム変数で情報伝達する。その結果グローバル変数 はシステム変数となり、言語的整合性ではなくシステムの目的にそって作られています。 補足 1、一つのセルの中にint,double,stringデータの情報が入っているのは、もともとはデータ の型別にシートが分かれていました。しかし、リストやソート、検索、辞書(map)の場合、 3つのデータをまとめて処理したほうが利便性がいいとの理由です。そのため1セルに3つの 情報を入れました。しかし、変数としては別々にアクセスします。  例えばstringでソートした場合、intもdoubleもいっしょにソートされます。  例えば、intに優先NOが入っていたら、intでソートしたら文字列もいっしょにソート されます。  利便性の目的のためだけに、3つの情報を一セルに入れました。 2、パックされた情報は、stringデータに入ります。なのでstringデータは複数のデータ を大量に保持することが出来ます。 3.システム変数を言語内の変数と同じように、透過的にアクセスできるように作れたため、 システム変数の操作を速くする事ができた。これは、関数を用いてシステム変数を操作する ことを思えば、スレッドセーフでも、格段に融通が利き速い動作を保証できる。 最後に  この言語だけでは、奇妙な言語が一つ出来ただけの事です。この仕組が受け入れられる かは、その上に乗ったアプリケーションが洗練されていて使いやすく受け入れるか如何に かかっています。ここから先はいかにいい物を作るかだけでしょう。それに、言語の 初心者を対象にしているので、ここからはバリバリな日本語化に走ります。  プログラミング言語ができる人は、C/C++なりJavaなり、その他各種汎用言語を使って ください。がベースにあります。^^  今ある汎用言語は洗練されていて複雑で優秀です。だから私がいまさら作る意味が無い ですし。 追加の補足  上記のことを書いた後に、グローバル変数でもいいのではないか。の発想もありますが、 その場合、情報の集合体としての構造体やclassが必要です。でも、移転届用紙のような 多数の関係の薄そうなデータ総てを構造体やclassに入れるのは、根本的にシステム設計 が間違っている方向でしょう。やはり書式用紙に代表されるデータ構造と、プログラム上の データ構造とは明らかに違っています。プログラムでは関連のあるデータを参照やキー 情報、その他関連情報で持ちます。しかし、この構造は前にも話したように他の何かの サポート無しに完全な一意の意味を保証することは不可能です。  でも、シート形式なら完全かと言うとそうでもありません。実は時系列な情報変化の 保証は出来ないのです。これはあきらめています。時系列的な情報の変化とは、転移届を 受理して完全に処理される前に。同じ人から違う転移届を受け取ってしまった場合の矛盾 です。 これは外部の何らかのサポート、受理処理が完全に終了するまで受け付けない フラグ等のサポートが必要になり。これはシステムではなく、プログラマがそれを理解し 作らなければならないのです。  完全なデータフローマシンでも作ればいいのですが、そのプログラミングはまた違った、 別の複雑な知識が必要になってきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1376] Re:システム変数について
投稿者:(ぱ)こと管理人
2009/06/30 01:22:32

> システム変数は宣言だけが違い、多少特殊ですが普通の変数と同じように >使用できます。なおかつスレッドセーフで使用できます。 (中略) > sysval("AAS001",CREATION); 割と素朴な疑問だと思うんですが、システム変数の宣言がこのように関数形式だとすると、 システム変数の型について、コンパイラは知らないままだということになりませんか? ……と思ったのですが、「AAS」という名前がstring型だという型宣言を兼ねている (かつそれをコンパイラが解釈する)のでしょうか? > sysval("AAI001-ACI005",CREATION); そして、こういう書き方だと、AA「I」なので、intの配列の宣言になる、と。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1375] システム変数について
投稿者:
2009/06/29 17:53:00

 ようやくシステム変数の組込みが終わりました。下記に示すような感じで 使用します。上にある#defineは、システムのヘッダーファイルになり。 #includeされます。 また今回は日本語プログラムにするとこんな感じに なります。と言った感じのプログラムリストです。  システム変数は宣言だけが違い、多少特殊ですが普通の変数と同じように 使用できます。なおかつスレッドセーフで使用できます。 //-- システム変数定義ヘッダーファイル -------------- #define システム変数 sysval #define 生成 1 // システム変数使用 #define 廃棄 2 // システム変数廃棄 #define クリア 3 // システム変数を初期化 #define リスト 4 // システム変数のリスト宣言 #define 辞書 5 // システム変数の辞書宣言(予約) #define 昇順ソート 6 // システム変数をソート #define 降順ソート 7 // システム変数をソート #define システム変数検索 sysval_find #define 線形 1 // システム変数リストを線形検索 #define 二分 2 // システム変数リストを二分検索 #define 辞書 3 // システム変数辞書検索(予約) #define システム変数リスト挿入 sysval_push_list #define システム変数リスト取出 sysval_pop_list #define 先頭 1 // システム変数リストの先頭 #define 最後 2 // システム変数リストの最後 //-- 日本語定義ヘッダーファイル ------------------ #define メイン main #define 表示 print #define 文字列 string #define 整数 int //------------------------------------------------ //-- 日本語で書いた場合 ----------------- 整数 表示(文字列 str); 整数 システム変数(文字列 str,整数 type); 整数 メイン() { システム変数("AAS001",生成); システム変数("AAI001-ACI005",生成); システム変数("BAD001-BCD005",生成); システム変数("CAS001-CCS005",生成); AAS001 = "testdata"; 表示("AAS001 = " + AAS001 + "--\n\n"); AAI001[3][1] = 33; BAD002[2] = 3.2; CAS003[1] = "aaa"; 表示("AAI001 = " + AAI001[3][1] + "--\n\n"); 表示("BAD002 = " + BAD002[2] + "--\n\n"); 表示("CAS003 = " + CAS003[1] + "--\n\n"); } //-----------------------------------    ↓    ↓まったく同じプログラムで英語で書いた場合    ↓ //----------------------------------- int print(string str); int sysval(string str,int type); int main() { sysval("AAS001",CREATION); sysval("AAI001-ACI005",CREATION); sysval("BAD001-BCD005",CREATION); sysval("CAS001-CCS005",CREATION); AAS001 = "testdata"; print("AAS001 = " + AAS001 + "--\n\n"); AAI001[3][1] = 33; BAD002[2] = 3.2; CAS003[1] = "aaa"; print("AAI001 = " + AAI001[3][1] + "--\n\n"); print("BAD002 = " + BAD002[2] + "--\n\n"); print("CAS003 = " + CAS003[1] + "--\n\n"); } -----------------------------------    ↓    ↓日本語版も英語版まったく同じ下記のコードになります。    ↓ ------------------------------------ 1:*** 一般関数情報ダンプ ****************** 1:int main() 1:*** 配列定数 数 = 0 ********** 1:*** 文字列 数 = 23 *** 1: 0: "main" 1: 1: "AAS001" 1: 2: "sysval" 1: 3: "AAI001-ACI005" 1: 4: "sysval" 1: 5: "BAD001-BCD005" 1: 6: "sysval" 1: 7: "CAS001-CCS005" 1: 8: "sysval" 1: 9: "testdata" 1: 10: "AAS001 = " 1: 11: "-- " 1: 12: "print" 1: 13: "aaa" 1: 14: "AAI001 = " 1: 15: "-- " 1: 16: "print" 1: 17: "BAD002 = " 1: 18: "-- " 1: 19: "print" 1: 20: "CAS003 = " 1: 21: "-- " 1: 22: "print" 1:*** 使用予定のスタックサイズ = 1292 1:*** 関数コードのディスアセンブラ size = 223 1: 0 push_string_const 1 1: 3 push_int_1byte 1 1: 5 call_function 2 0 0 2 1: 14 pop 1: 15 push_string_const 3 1: 18 push_int_1byte 1 1: 20 call_function 4 0 0 2 1: 29 pop 1: 30 push_string_const 5 1: 33 push_int_1byte 1 1: 35 call_function 6 0 0 2 1: 44 pop 1: 45 push_string_const 7 1: 48 push_int_1byte 1 1: 50 call_function 8 0 0 2 1: 59 pop 1: 60 push_string_const 9 1: 63 pop_sysval_str 3-0-1 1: 68 push_string_const 10 1: 71 push_sysval_str 3-0-1 1: 76 add_string 1: 77 push_string_const 11 1: 80 add_string 1: 81 call_function 12 0 0 1 1: 90 pop 1: 91 push_int_1byte 33 1: 93 push_sysval_array 1-0-1 1: 98 push_int_1byte 3 1: 100 push_array_int 1 1: 102 push_int_1byte 1 1: 104 pop_array_int 1: 105 push_double_8byte 3.200000e+000 1: 114 push_sysval_array 2-52-2 1: 119 push_int_1byte 2 1: 121 pop_array_double 1: 122 push_string_const 13 1: 125 push_sysval_array 3-104-3 1: 130 push_int_1byte 1 1: 132 pop_array_string 1: 133 push_string_const 14 1: 136 push_sysval_array 1-0-1 1: 141 push_int_1byte 3 1: 143 push_array_int 1 1: 145 push_int_1byte 1 1: 147 push_array_int 0 1: 149 cast_int_to_string 1: 150 add_string 1: 151 push_string_const 15 1: 154 add_string 1: 155 call_function 16 0 0 1 1: 164 pop 1: 165 push_string_const 17 1: 168 push_sysval_array 2-52-2 1: 173 push_int_1byte 2 1: 175 push_array_double 0 1: 177 cast_double_to_string 1: 178 add_string 1: 179 push_string_const 18 1: 182 add_string 1: 183 call_function 19 0 0 1 1: 192 pop 1: 193 push_string_const 20 1: 196 push_sysval_array 3-104-3 1: 201 push_int_1byte 1 1: 203 push_array_string 0 1: 205 add_string 1: 206 push_string_const 21 1: 209 add_string 1: 210 call_function 22 0 0 1 1: 219 pop 1: 220 push_int_1byte 0 1: 222 return 1:*** 行情報 数 = 14 *** 1: 20: from 0 size 15 1: 21: from 15 size 15 1: 22: from 30 size 15 1: 23: from 45 size 15 1: 24: from 60 size 8 1: 25: from 68 size 23 1: 26: from 91 size 14 1: 27: from 105 size 17 1: 28: from 122 size 11 1: 29: from 133 size 32 1: 30: from 165 size 28 1: 31: from 193 size 27 1: 154: from 220 size 2 1: 32: from 222 size 1 1:*** end of main() -------------- --------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1374] Re:関数の再起について
投稿者:
2009/06/25 00:09:10

お返事遅れてすみません。 >ええと、細かいことですが「再起」ではなく「再帰」ですね。 うはは~~指摘ありがとうございます。思わぬミスをよくします。 >ファイバーとか考えるなら再考の必要がありますね……  ファイバーのことを考えてたら、 「ファイバーは関数ではなく、コードの一部を空きスレッドに渡すだけで実行だな」 と考えていたら下記の点を気がつきました。  今までは、スレッドは実行時にオブジェクト生成とスレッド起動を考えていま したが、良くよく考えれば毎回不必要ですね。初期に10なり20なり起動して待ち 状態で待たせ、その後プログラムのスレッド実行は空きスレッドで即実行を^^  この方法で組み込むことにしました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1373] Re:関数の再起について
投稿者:(ぱ)こと管理人
2009/06/23 02:34:39

ええと、細かいことですが「再起」ではなく「再帰」ですね。 >その後言語内の関数実行部を >作ったのですが。そのまま、再起で実行する部分を使って組み込んだために、関数実行 >はVM実行部の再起になっています。 了解です。 再帰を使わずに作ると、例外処理機構でCの呼び出し階層を遡らなくてよいとか、 ファイバーのような機能を作るときに現在の実行状態を退避できるとかの メリットがあると思いますが、例外処理をDiksamで作ってみたら、再帰を使っている crowbarの例外処理よりもかえって大変だったような気がしますし、再帰なら 再帰でかまわないと思います。 実はDiksamでもネイティブ関数からDiksam関数を呼ぶところは再帰なので、 ファイバーとか考えるなら再考の必要がありますね…… >う~~んどうしようか、当面このままでいこうと思います。既に出来てしまっ >てるし。スタックを増やさない限り再起が450回しか出来ない欠点はあるけど。 実用的には使われてないであろうcrowbarはさておき、RubyやPerlもCのスタックを 使ってガンガン再帰してますからねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1372] Re:関数の再起について
投稿者:
2009/06/22 19:06:01

>すみません、いまいちよくわからないです。関数呼び出しのたびにVM起動して >いるわけではないですよね? そうだった、VMが違うものでした。簡単にVMの構造を説明します。 ↓AP管理からVMとして起動される -------------------------------------- |      VM管理システム      | --------------------------------------  ↓     ・・・       ↓    ------    ------    |   |    |   |    | V |    | V |    | M |    ・・・     | M |    | 実 |    | 実 |    | 行 |    | 行 |    | 部 |    | 部 |    |   |    |   |    ------    ------  VMは上記のような構造をしています。VM管理システムは1つのスレッドで、VM実行 部のスレッド実行管理と各種サービスを提供します。機能は、  ・マルチスレッドでVM実行部の起動・停止・廃棄等の実行管理  ・動的コンパイルの管理、関数の管理  ・タイムスケジュールの管理(タイマーキューの生成と管理)  ・スレッドの実行優先順位管理(キューに優先順位がありその管理)  ・メッセージキューの管理(スレッドの実行はキューによって行われる)  ・グローバル変数の管理  ・その他各種IOや外部機能インターフェースの管理  ・言語のデバック機能  ・上記サービスをスレッドセーフで提供するための排他制御管理 等のいろいろな機能があり、それなりに大きなプログラムです。  それに対し、VM実行部は純粋にバイトコードを実行する以外何の機能も持っていま せん。VM実行部は1つのクラスで、そのオブジェクト一つが1スレッドになり、マルチ スレッドが実行可能であり、VM実行部が再起実行しても問題の無い仕様です。 そして、出来る限り単純で最小になるように作られています。  で^^;、最初に組込み関数部分を作りましたが、その時組込み関数から言語内の関数 を自由に起動したり廃棄したり、スレッド起動したり出来るように作ったので、それを 実行する一番いい方法はVM実行部の再起的実行でした。その後言語内の関数実行部を 作ったのですが。そのまま、再起で実行する部分を使って組み込んだために、関数実行 はVM実行部の再起になっています。今思えば別に再起しなくても良かったかな。^^;  今の実装の欠点は、VMのスタックを消費することと、ほんの少しのオーバーヘッド。 今の方法の利点は関数実行や管理が一元管理されて、プログラム的にすっきりしている。 かな、う~~んどうしようか、当面このままでいこうと思います。既に出来てしまっ てるし。スタックを増やさない限り再起が450回しか出来ない欠点はあるけど。 >なお、現在はDiksamはシングルスレッドですが、スレッドを分けるなら、 >VMのスタックも分離する必要があると考えています。 こちらも、1スレッドおきにスタック領域が作られます。そのためスタック領域はあまり 大きくしたくなっかったので。 ちなみにVM実行部の起動は S_Func_Val * CL_VMexe::execute(CL_Function *sfp,int stackp); 引数は関数情報と戻りスタックポインターです。ローカル変数をスタックに作成後すぐに S_Func_Val * CL_VMexe::execute_code(); のコード実行部が呼ばれる単純な構造です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1371] Re:関数の再起について
投稿者:(ぱ)こと管理人
2009/06/22 01:46:36

> 関数の再起についてですが、VC++ の標準スタックでデバックビルドの時、 >約460回の再起が可能です。その結果上限として450回を超えたらエラーとし、 >エラー表示とともに関数コールをせずにリターンする処理としました。 >リリースビルドでは多分この数倍いけると思いますが、450回も出来ればOK >だと考えています。スレッド分複数VM起動もしますから。 >diksamではどの様にしていますか? ええと、解析木を再帰でほじって実行するcrowbarならいざしらず、Diksamでは、 Diksamの関数をいくら再帰呼び出ししても、Cのスタックは消費しません。 DVMのスタック(ヒープに確保される)が伸びていくだけです。 なお、現在はDiksamはシングルスレッドですが、スレッドを分けるなら、 DVMのスタックも分離する必要があると考えています。 すみません、いまいちよくわからないです。関数呼び出しのたびにVM起動して いるわけではないですよね?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1370] 関数の再起について
投稿者:
2009/06/22 00:27:40

 関数の再起についてですが、VC++ の標準スタックでデバックビルドの時、 約460回の再起が可能です。その結果上限として450回を超えたらエラーとし、 エラー表示とともに関数コールをせずにリターンする処理としました。 リリースビルドでは多分この数倍いけると思いますが、450回も出来ればOK だと考えています。スレッド分複数VM起動もしますから。 diksamではどの様にしていますか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1369] Re:配列の実装について
投稿者:
2009/06/20 21:10:37

>本のページの準備やらに追われていまして遅くなりましてすみません。 いえいえ >つまり、Cと同じですね。現実的な落としどころかと思います。 はい、まさにその通りです。スタックに固定で配列を既述する以上。 定数指定も固定にした方が統一的であるし、中身を替えたければ 個別に入れ替えればいいので、この方法にしました。 配列アクセスも直接インデックスなので多少速いですし。 diksamのテストプログラムは、配列の修正とnull削除で総て正しく 動いています。nullは参照の操作が無いのでなくなりました。 今は、システムグローバル変数の組み込みを行っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1368] Re:プログラミング言語を作る 書籍
投稿者:(ぱ)こと管理人
2009/06/20 13:46:11

>木曜日に三省堂神保町店で購入しました。ジュンク堂池袋店では、水曜日に入荷してたみたいです。 >http://twitter.com/junkudo_ike_pc/status/2203461804 お買い上げいただきありがとうございます (_o_) 編集さんからは19日ごろからと聞いていたので、サンプルコードをダウンロードできる ページについて、トップからリンクしたのが木曜の晩(というか金曜明け方)、 リンクはしないが暫定公開として配置したのが水曜の晩(というか木曜明け方)でした。 微妙に間に合いませんでした。こころあたりの方は再度見に来ていただきたく、 よろしくお願いいたします……(ここに書いても仕方がないかもしれませんけど) >書店で見つけて、お!と思ったのが書籍のサイズでした。コンパイラ系の本は大学の教科書(まえがきにある∩とかの)風でサイズはA5版が多いように思います(ドラゴンブックも)。 版型の決定については私は関わっていませんが、ゲラを見たとき、思ったより 文字サイズや余白が大きいな、とは思いました。かなり書きすぎた自覚があったので(^^; もっと詰め込まれるのではないかと。少なくとも版型に関しては読みやすい形で まとめていただけたと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1367] Re:配列の実装について
投稿者:(ぱ)こと管理人
2009/06/20 13:31:48

本のページの準備やらに追われていまして遅くなりましてすみません。 > 下記のように、配列の定数は配列定数バッファーに詰め込んで保持し、1命令で >配列変数に書き込みです。 つまり、Cと同じですね。現実的な落としどころかと思います。 リテラルに定数式しか書けなくなっているかとは思いますが。 つまりC同様、 double[] sin_table = {sin(0), sin(0.2*M_PI), sin(0.4*M_PI), ...}; のような書き方はできませんよね。実際使用することがそうそうあるとは 思えないので、問題ないと思いますが。 そういえば、昔のCは、ローカル変数の配列に初期化子を書くときはstaticしか許さない、 ということになっていました。でも、これで困ることも別段なかった気がしますし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1366] Re:プログラミング言語を作る 書籍
投稿者:さとう
2009/06/20 00:46:11

木曜日に三省堂神保町店で購入しました。ジュンク堂池袋店では、水曜日に入荷してたみたいです。 http://twitter.com/junkudo_ike_pc/status/2203461804 書店で見つけて、お!と思ったのが書籍のサイズでした。コンパイラ系の本は大学の教科書(まえがきにある∩とかの)風でサイズはA5版が多いように思います(ドラゴンブックも)。 Webの連載を見ていなかったので、GC、VM、クラス、クロージャなどと類書にはなかなか見られない内容までを含むとは思ってもみませんでした。読みこなすのは大変ですが、なんとか読んでいこうと思います。 はてなをみて、ページ下部のおまけに気がつきました^^。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1365] Re:配列の実装について
投稿者:
2009/06/17 20:22:31

 これで、diksam0.2.0の機能で必要な部分は総て組み込むことが出来ました。 これからが本当の目的部分です。グローバルシステム変数関係、マルチスレッド システム関係。等々を組み込んだら言語としては完了となります。  そして、本当の目的アプリケーション…、まて、言語のデバックシステムの 組み込みが。簡単なIDEを組み込みます。まだまだです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1364] Re:配列の実装について
投稿者:
2009/06/17 20:17:37

 配列の組み込みにより、バイトコードもまた変わりました、下記に。 S_OpcodeInfo D_opcode_info[] = { {"dummy", "", 0}, {"push_int_1byte", "b",16}, {"push_int_2byte", "s",16}, {"push_int_4byte", "i",16}, // 実際の値を持つ {"push_double_0", "", 16}, {"push_double_1", "", 16}, {"push_double_8byte", "d",16}, // 実際の値を持つ {"push_string_const", "s",40}, // 文字列の位置NOを持つ0~ {"push_null", "", 16}, /**********/ {"push_stack_array", "s", 16}, // 配列情報をスタックに {"push_stack_int", "s", 16}, // intローカル変数をi {"push_stack_double", "s", 16}, // {"push_stack_string", "s", 40}, // {"pop_stack_int", "s", -16}, // スタックのintをローカル変数に {"pop_stack_double", "s", -16}, // {"pop_stack_string", "s", -40}, // /**********/ {"push_static_array", "s", 16}, // 配列情報をスタックに 予約 {"push_static_int", "s", 16}, // int静的変数をスタックに 予約 {"push_static_double","s", 16}, // {"push_static_string","s", 40}, // {"pop_static_int", "s", -16}, // スタックのintを静的変数に 予約 {"pop_static_double", "s", -16}, // {"pop_static_string", "s", -40}, // /**********/ {"push_sysval_array", "i", 16}, // 配列情報をスタックに {"push_sysval_int", "i", 16}, // システムグローバル変数をスタックに {"push_sysval_double","i", 16}, // {"push_sysval_str", "i", 40}, // {"pop_sysval_int", "i", -16}, // スタックからシステムグローバル変数に {"pop_sysval_double", "i", -16}, // {"pop_sysval_str", "i", -40}, // /**********/ {"push_array_int", "", -1}, // int配列処理 {"push_array_double", "", -1}, // {"push_array_string", "", -1}, // {"pop_array_int", "", -1}, // スタックからint配列に {"pop_array_double", "", -1}, // {"pop_array_string", "", -1}, // /**********/ {"add_int", "", -16}, // 以下は総て算術演算子 {"add_double", "", -16}, {"add_string", "", -40}, {"sub_int", "", -16}, {"sub_double", "", -16}, {"mul_int", "", -16}, {"mul_double", "", -16}, {"div_int", "", -16}, {"div_double", "", -16}, {"mod_int", "", -16}, {"mod_double", "", -16}, {"minus_int", "", 0}, {"minus_double", "", 0}, {"increment", "", 0}, {"decrement", "", 0}, // ここまで算術演算子 {"cast_int_to_double", "", 0}, // 以下はキャスト処理 {"cast_double_to_int", "", -0}, {"cast_boolean_to_string", "", 24}, {"cast_int_to_string", "", 24}, {"cast_double_to_string", "", 24}, // ここまでキャスト処理 {"eq_int", "", -16}, // 以下は総て論理演算子 {"eq_double", "", -16}, {"eq_string", "", -40}, {"gt_int", "", -16}, {"gt_double", "", -16}, {"gt_string", "", -40}, {"ge_int", "", -16}, {"ge_double", "", -16}, {"ge_string", "", -40}, {"lt_int", "", -16}, {"lt_double", "", -16}, {"lt_string", "", -40}, {"le_int", "", -16}, {"le_double", "", -16}, {"le_string", "", -40}, {"ne_int", "", -16}, {"ne_double", "", -16}, {"ne_string", "", -40}, // ここまで論理演算子 {"logical_and", "", -16}, // {"logical_or", "", -16}, // {"logical_not", "", 0}, // {"pop", "", -1}, // スタックを1つ減らす {"duplicate", "", 16}, // スタック内容をコピーしてスタックに {"jump", "s", 0}, // 指定ポインターにjump {"jump_if_true", "s", -16}, // スタックがtrueならjump {"jump_if_false","s", -16}, // スタックがfalseならjump /**********/ {"push_function", "", 0}, // 関数情報をスタック、未使用 {"call_function","ssss", 1}, // 関数コール {"return", "", -1}, // 関数戻り /**********/ {"set_array_literal_int", "ss", 0}, // int定数配列を変数にコピー {"set_array_literal_double","ss", 0}, // double定数配列を変数にコピー {"set_array_literal_string","ss", 0}, // string定数配列を変数にコピー };
[この投稿を含むスレッドを表示] [この投稿を削除]
[1363] 配列の実装について
投稿者:
2009/06/17 20:11:21

 配列の実装は、結果的にまったく違うものになっています。配列領域を固定で スタックに持つことでGCを無くす。この目的のために結果的に多くの修正をしま した。下記のようなプログラムとディスアセンブルコードを見てください。  この並列はずいぶん悩みましたが、結果的に一番良いであろう方法に落ち着き ました。 ---------------------------------- int main() { int[2][3] i5dim; int id = 33; boolean[2] bdim1 = { true , false }; int[2][3] idim21 = {{1,2,3},{4,300,65536}}; int[2][3][4] idim3 = {{{1,2,3,4},{5,6,7,300},{8,9,10,11}}, {{11,12,13,65536},{14,15,16,17},{18,19,20,21}}}; double[4] ddim1 = { 0.0, 1.0, 4.1, 5.1 }; string[5] sdim1 = {"aa","bb","cc","dd","ee"}; int a1; i5dim[1][2] = 1; a1 = i5dim[i5dim[1][2]][0]; } ----------------------------------   ↓  下記のように、配列の定数は配列定数バッファーに詰め込んで保持し、1命令で 配列変数に書き込みです。もちろん配列数と一致したデータ以外はエラーです。 また、変数の配列次元数が一致しない場合もエラーになる処理が入っています。 int[10] P; P = P; の様なポインター的なコードが書けない仕様です。   ↓ バイトコード   ↓ 1:*** 一般関数情報ダンプ ****************** 1:int main() 1:*** ローカル変数の表示 no = 8 *** 1: 0:int [2][3] i5dim 1: 1:int id 1: 2:boolean [2] bdim1 1: 3:int [2][3] idim21 1: 4:int [2][3][4] idim3 1: 5:double [4] ddim1 1: 6:string [5] sdim1 1: 7:int a1 1:*** 配列定数 数 = 5 ********** 1: 0:int 配列 [2] size=20 1:int[0] = 1 1:int[1] = 0 1: 1:int 配列 [2][3] size=36 1:int[0][0] = 1 1:int[0][1] = 2 1:int[0][2] = 3 1:int[1][0] = 4 1:int[1][1] = 300 1:int[1][2] = 65536 1: 2:int 配列 [2][3][4] size=108 1:int[0][0][0] = 1 1:int[0][0][1] = 2 1:int[0][0][2] = 3 1:int[0][0][3] = 4 1:int[0][1][0] = 5 1:int[0][1][1] = 6 1:int[0][1][2] = 7 1:int[0][1][3] = 300 1:int[0][2][0] = 8 1:int[0][2][1] = 9 1:int[0][2][2] = 10 1:int[0][2][3] = 11 1:int[1][0][0] = 11 1:int[1][0][1] = 12 1:int[1][0][2] = 13 1:int[1][0][3] = 65536 1:int[1][1][0] = 14 1:int[1][1][1] = 15 1:int[1][1][2] = 16 1:int[1][1][3] = 17 1:int[1][2][0] = 18 1:int[1][2][1] = 19 1:int[1][2][2] = 20 1:int[1][2][3] = 21 1: 3:double 配列 [4] size=44 1:double[0] = 0.000000 1:double[1] = 1.000000 1:double[2] = 4.100000 1:double[3] = 5.100000 1: 4:string_no 配列 [5] size=32 1:string[0] = 9 1:string[1] = 10 1:string[2] = 11 1:string[3] = 12 1:string[4] = 13 1:*** 文字列 数 = 14 *** 1: 0: "main" 1: 1: "i5dim" 1: 2: "id" 1: 3: "bdim1" 1: 4: "idim21" 1: 5: "idim3" 1: 6: "ddim1" 1: 7: "sdim1" 1: 8: "a1" 1: 9: "aa" 1: 10: "bb" 1: 11: "cc" 1: 12: "dd" 1: 13: "ee" 1:*** 使用予定のスタックサイズ = 426 1:*** 関数コードのディスアセンブラ size = 63 1: 0 push_int_1byte 33 1: 2 pop_stack_int 1 1: 5 set_array_literal_int 0 2 1: 10 set_array_literal_int 1 3 1: 15 set_array_literal_int 2 4 1: 20 set_array_literal_double 3 5 1: 25 set_array_literal_string 4 6 1: 30 push_int_1byte 1 1: 32 push_stack_array 0 1: 35 push_int_1byte 1 1: 37 push_array_int 1: 38 push_int_1byte 2 1: 40 pop_array_int 1: 41 push_stack_array 0 1: 44 push_stack_array 0 1: 47 push_int_1byte 1 1: 49 push_array_int 1: 50 push_int_1byte 2 1: 52 push_array_int 1: 53 push_array_int 1: 54 push_int_1byte 0 1: 56 push_array_int 1: 57 pop_stack_int 7 1: 60 push_int_1byte 0 1: 62 return 1:*** 行情報 数 = 10 *** 1: 4: from 0 size 5 1: 5: from 5 size 5 1: 6: from 10 size 5 1: 8: from 15 size 5 1: 9: from 20 size 5 1: 10: from 25 size 5 1: 13: from 30 size 11 1: 14: from 41 size 19 1: 19: from 60 size 2 1: 15: from 62 size 1 1:*** end of main() --------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1362] Re:その後のVM
投稿者:
2009/06/17 19:52:00

>ここで埋め込まれる関数インデックスって、VM内で一意になるんですよね? >だとすれば、コンパイル単位の破棄の際に破棄対象の関数が使っていたインデックスの >ところをぎゅっと圧縮しようとさえ思わなければ、そもそも振りなおし自体不要なのでは >ないかと思うのですが…… 同じ所に、こう書いてあります。 >> 次にスピードの点ですが、現在はVMメイン管理で一元的にカウンターを持ってい >>ますが、これを関数単位でもてば、(ぱ)さんの指摘する問題は回避できます。 >> ただ、初期は出来る限り単純なもので済ませたいとの思いがあり。簡単な機構で >>すめばそのままにしています。 上記のように、今のところ優先順位が低いので、後回しにしています。 もちろん、圧縮等はしていないので、比較的簡単に実装出来ると思います。 たぶん二人とも同じことを考えてると思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1361] 管理者により削除されました
2009/06/16 22:54:54

なんだか意味不明の投稿が3連投されています。削除しました。 普通に考えれば広告なのですが、それっぽいページへのリンクもメールアドレスもないので、 何を意図したものかさっぱり。
[この投稿を含むスレッドを表示]
[1359] Re:その後のVM
投稿者:(ぱ)こと管理人
2009/06/16 01:14:21

> コンパイル時の負荷はまず棚においておいて、実際問題、再コンパイルが頻繁に >行わなければならない処理が多いと思われますか?、実際的に考えればそんな設計は >良い設計とは思えません。 うーん、再コンパイルの頻度は低くても、それが起きるたびに以後の関数呼び出しに ついてすべて一度ずつリンクが入るのはちょっと心配ですがそれはさておき、 ここで埋め込まれる関数インデックスって、VM内で一意になるんですよね? だとすれば、コンパイル単位の破棄の際に破棄対象の関数が使っていたインデックスの ところをぎゅっと圧縮しようとさえ思わなければ、そもそも振りなおし自体不要なのでは ないかと思うのですが……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1358] Re:その後のVM
投稿者:
2009/06/14 08:20:38

>この方法だと、コンパイル単位が増えてきたとき、プログラムの端のほうでちょろっと >動的リンクが発生しただけで、それこそprint()みたいにあちこちで使われる関数の >呼び出し箇所すべて(通るところだけですが)に対し再リンクが必要になるような……  必ず突っ込まれるで有ろうと予測した部分が突っ込まれました^^。確かに再コンパ イルが頻繁に行われるようであれば、当然負荷が増えるでしょう。でもその場合、 コンパイル時に再リンクも大きな負荷に思えます。  コンパイル時の負荷はまず棚においておいて、実際問題、再コンパイルが頻繁に 行わなければならない処理が多いと思われますか?、実際的に考えればそんな設計は 良い設計とは思えません。  ではなぜ、動的コンパイルが必要だったか。それは、複数の違った処理を一元的 にメニュー管理する目的があったのです。利用目的ですね。このような利用目的が 無い場合、動的コンパイラは不要です。だからdiksamとは指向性が多少違います。  次にスピードの点ですが、現在はVMメイン管理で一元的にカウンターを持ってい ますが、これを関数単位でもてば、(ぱ)さんの指摘する問題は回避できます。  ただ、初期は出来る限り単純なもので済ませたいとの思いがあり。簡単な機構で すめばそのままにしています。  うう~~上記文は多々説明不足な気がすごくしますが、説明を始めると長くなっ てしまいそうなので短文にしています。「もっと説明しろ!」との指摘がありまし たら、ぜひ言ってくださいませ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1357] Re:その後のVM
投稿者:(ぱ)こと管理人
2009/06/14 01:49:31

>はい、一つ目は文字列バッファーにある関数名インデックスを示し、二つ目はコン >パイル単位カウンター、三つ目は関数ID=インデックス、四つ目はパラメターの数 >です。P2,P3は実行時に埋め込まれます。コンパイルカウンターは、1~最大値ま >でのループカウンターで動的コンパイル実行時かコンパイル単位の消滅処理時に >+1されます。コード上は最初は0そしてカウンターは1なので、値が違うためP1の >関数名から動的リンクをしてP2に1、P3に関数インデックスが埋めこめられ、この >関数インデックスで直接関数が起動されます。以後、P2のコンパイルカウンターが >一緒なら、P3で直接関数起動です。直接起動の前にIF文が一回入る程度です。 うーん、いまいちわかりませんが、 ・call_functionのふたつめのオペランドを「P2」として、 ・「コンパイルカウンター」は、「動的コンパイル実行時かコンパイル単位の  消滅処理時に+1」というくらいだから、VMにひとつだけ存在するカウンタですよね? つまり、動的コンパイルが動いたり、逆にバイトコードを破棄したりするたびに VMの状態が変わるわけですが、この「状態」に対して、1から始まる連番が振られて いるわけですね。 で、call_functionごとに、それがリンクされた時点の連番(コンパイルカウンター)が 埋め込んであり、呼び出しごとに現在のコンパイルカウンターと比較して違っていたら 再リンクする、と。 この方法だと、コンパイル単位が増えてきたとき、プログラムの端のほうでちょろっと 動的リンクが発生しただけで、それこそprint()みたいにあちこちで使われる関数の 呼び出し箇所すべて(通るところだけですが)に対し再リンクが必要になるような…… ちなみにDiksamでは、バイトコード中の関数インデックスはコンパイル時に 決めています。これは「バイトコードごと」の関数インデックスであり、 ver.0.2~0.3系列では、リンク時に、これを「DVMごと」のインデックスに置き換えます。 ver.0.4では、置換は行わず、変換テーブルをバイトコードごとに持っています。 今のところ動的なバイトコードのアンリンクは実装していません。実装する場合、 DVM上のFunctionテーブルのis_implementedをfalseにすることになるかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1356] Re:その後のVM
投稿者:
2009/06/12 20:46:52

 追記、変数名とか関数名も文字列バッファーに入れています。これは言語のIDE サポートのためです。今デバックのために使っているモニターシステムがあるの ですが、これを高機能にすればIDEになるので、言語デバック用に簡単なIDEをと 思い追加しています。このデバックモニターシステムはC#で作られています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1355] Re:その後のVM
投稿者:
2009/06/12 20:27:59

>2つ目と3つ目のオペランドは全部0, 0なのですが、関数の方はprintf, sprintf, printの はい、一つ目は文字列バッファーにある関数名インデックスを示し、二つ目はコン パイル単位カウンター、三つ目は関数ID=インデックス、四つ目はパラメターの数 です。P2,P3は実行時に埋め込まれます。コンパイルカウンターは、1~最大値ま でのループカウンターで動的コンパイル実行時かコンパイル単位の消滅処理時に +1されます。コード上は最初は0そしてカウンターは1なので、値が違うためP1の 関数名から動的リンクをしてP2に1、P3に関数インデックスが埋めこめられ、この 関数インデックスで直接関数が起動されます。以後、P2のコンパイルカウンターが 一緒なら、P3で直接関数起動です。直接起動の前にIF文が一回入る程度です。  このような感じで、スレッドセーフな動的リンクを実現しています。実はこれには 面白い副作用があって、例えば画面に文字を出す関数を動的コンパイル単位にすれば。 メインは一切い変更せず。あるときはゴシックで表示、コンパイル単位の消滅そして、 最コンパイルすると、その時から丸文字表示で文字が出される等が可能です。  関数の内部機能を動的に変えることが出来ます。もちろん総てのスレッドにスレッ ドセーフで。でも、使い道はそんなに無いかもしれませんけどね。^^; そうそう、今の所同じ関数名でも違う文字列IDですが、暇が出来たら同一IDにする 予定。 VMを作り始めてから何度もも構文処理からの修正が必要になり。なかなか前に進み ません。書きあがって動いても、スレッドセーフの問題点が見つかり、書き直しも ごそごそと。言語としては最終的なつめなので、すぐには終わりそうにないです。  でも、思った通りに作れるのはいい感じです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1354] Re:その後のVM
投稿者:(ぱ)こと管理人
2009/06/11 23:44:05

自己フォロー。 >おそらく4つ目のオペランドが引数の数、2つ目か3つ目が関数のインデックス >なのだと思いますが(確か分割コンパイルはなかったと思うので、ひとつ余りますね…) >最初のオペランドは何でしょう? 2つ目と3つ目のオペランドは全部0, 0なのですが、関数の方はprintf, sprintf, printの 3種類ありますので、これが直接関数のインデックスということはないですね。 単なる場所取りで、実行前に第1オペランドの文字列を使ってインデックスを検索して ここに埋め込むとか……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1353] Re:その後のVM
投稿者:(ぱ)こと管理人
2009/06/11 23:40:18

おお、私はDiksamのほうにさっぱり手を付けられないでいる間に、 だいぶ進んでいますね。 ぱっと見で目を引くのは関数呼び出しのインストラクションのオペランドの 数の多さですが、 >1: 9 call_function 3 0 0 4 おそらく4つ目のオペランドが引数の数、2つ目か3つ目が関数のインデックス なのだと思いますが(確か分割コンパイルはなかったと思うので、ひとつ余りますね…) 最初のオペランドは何でしょう? 関数名を文字列のコンスタントプールで保持していて、そのインデックスに 見えますが、用途がよくわかりません。リンク用の情報で、実行時には使わない? >1:*** 文字列 数 = 9 *** >1: 0: "main" >1: 1: "str" >1: 2: "printf P1 = %d P2 = %d P3 = %d >" >1: 3: "printf" >1: 4: "sprintf P1 = %d >" >1: 5: "sprintf" >1: 6: "print" >1: 7: "---------- test ---------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1352] Re:その後のVM
投稿者:
2009/06/11 22:46:28

 追記で、バイトコードも結構変わっています。下記に。 >---------------------------------- >int printf(string str); >string sprintf(string str); >int print(string str); > >int main() >{ > string str; > printf("printf P1 = %d P2 = %d P3 = %d\n",12,20,30); > str = sprintf("sprintf P1 = %d\n",13); > print(str); > print("---------- test ---------\n"); >} >---------------------------------- ↓  バイトコード ↓ 1:*** 一般関数情報ダンプ ****************** 1:--- int main() 1:*** ローカル変数の表示 no = 1 *** 1: 0:string str 1:*** 文字列 数 = 9 *** 1: 0: "main" 1: 1: "str" 1: 2: "printf P1 = %d P2 = %d P3 = %d " 1: 3: "printf" 1: 4: "sprintf P1 = %d " 1: 5: "sprintf" 1: 6: "print" 1: 7: "---------- test --------- " 1: 8: "print" 1:*** 使用予定のスタックサイズ = 240 1:*** 関数コードのディスアセンブラ size = 65 1: 0 push_string_const 2 1: 3 push_int_1byte 12 1: 5 push_int_1byte 20 1: 7 push_int_1byte 30 1: 9 call_function 3 0 0 4 1: 18 pop 1: 19 push_string_const 4 1: 22 push_int_1byte 13 1: 24 call_function 5 0 0 2 1: 33 pop_stack_string 0 1: 36 push_stack_string 0 1: 39 call_function 6 0 0 1 1: 48 pop 1: 49 push_string_const 7 1: 52 call_function 8 0 0 1 1: 61 pop 1: 62 push_int_1byte 0 1: 64 return 1:*** 行情報 数 = 6 *** 1: 8: from 0 size 19 1: 9: from 19 size 17 1: 10: from 36 size 13 1: 11: from 49 size 13 1: 13: from 62 size 2 1: 12: from 64 size 1 1:*** end of main() --------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1351] その後のVM
投稿者:
2009/06/11 22:03:54

 ようやく下記のようなプログラムがVMで実行可能になりました。可変長 パラメータ用の書式は作らず、一部の組込み関数のみ可能にしました。 言語としての美しさは…、スタック情報も大きく変わり、VMはほとんど別の ものになりつつあります。VMの完成にはまだまだです。printfはCのprintf と同等ですが、中身はエミュレートを被せてオーバラン等の危険は一切 ありません。 ---------------------------------- int printf(string str); string sprintf(string str); int print(string str); int main() { string str; printf("printf P1 = %d P2 = %d P3 = %d\n",12,20,30); str = sprintf("sprintf P1 = %d\n",13); print(str); print("---------- test ---------\n"); } ----------------------------------  前に出した、組込み関数とのインターフェースは大幅に変更となり。 下記のようになっています。 //== スタック上の組込み関数データ =================================== struct NFstartDat { ushort vtype; // データタイプ E_StackDType ushort size; // スタック消費サイズ ushort m_vmid; // VMID = スレッドID ushort m_prm_inno; // 引き渡されたパラメータ数 void *m_sdatp; // スレッド別データ用ポインター S_Value *m_prmp[PRMMAX]; // 引き渡されたパラメータ S_Value m_return; // 関数からの戻り値データ }; //=================================================================== // 組み込み関数用定義 //=================================================================== class C_NFBase { protected: //-- VMから受け取る情報 ---------------- int m_fid; // 関数ID //-- VMに送る情報 ---------------------- char *m_name; // 関数名 int m_prmno; // 要求するパラメータ数0-10まで20は可変関数 ES_ValueType m_type[PRMMAX]; // 要求するパラメータの型 ES_ValueType m_return_type; // リターン変数タイプ public: C_NFBase() { this->m_name = NULL; this->m_prmno = 0; for(int i=0;i<PRMMAX;i++) { this->m_type[i] = ES_NON; } //----------------------- this->m_fid = 0; this->m_return_type = ES_INT; } virtual ~C_NFBase() { } virtual void * VMstart() { } // VM起動時実行 virtual void VMend() { } // VM終了時実行 virtual void funcexe(NFstartDat *nfd) { } // 関数起動メソッド inline char ** getname() { return &this->m_name; } inline int getprmno() { return this->m_prmno; } inline ES_ValueType getprmtype(int no) { return this->m_type[no]; } inline void setfid(int fid) { this->m_fid = fid; } inline ES_ValueType getrtntype() { return this->m_return_type; } };
[この投稿を含むスレッドを表示] [この投稿を削除]
[1350] Re:Traits (was Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/06/10 09:31:57

>今度印刷してじっくり読んでみます。 ぜひ是非。Diksam でも活用可能かもしれません。 #ご出版、おめでとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1349] Re:プログラミング言語を作る 書籍
投稿者:(ぱ)こと管理人
2009/06/09 02:31:35

>アマゾン詣でをしていたら、、 >こんなんありました!! > >http://www.amazon.co.jp/dp/4774138959 >2009/6/20 あっ、まだ私のところに見本誌も届いていないのに! 価格とかページ数とか、今はじめて知りました。いやマジで。 >いやー楽しみです。 ありがとうございます(表紙がどんな感じになるのかとか、私も楽しみにしています)。 いやそのなんと言いますか、マイナーな分野だけに、ぜひともよろしくお願いいたします(_o_)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1348] Re:Traits (was Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:(ぱ)こと管理人
2009/06/09 02:13:16

>ちゃんと知るには発案者のシェルリ自身が >書いたものに一度目を通しておくのが無難かと思います。 紹介ありがとうございます。片方はsumimさんのページから辿ってちょっと読みかけたのですが、 けっこう量が挫折してました。今度印刷してじっくり読んでみます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1347] Re:Traits (was Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/06/08 22:53:26

そうですね。C++ のテンプレートテクニックにも同名のがありますね。ややこしやー。w そんなかんじで Traits にはいろいろと別物がある上、ブラックたち(というかシェルリ) の Traits にインスパイヤされたと言明されたものでも、たとえば Scala の Traits の ように一部機能を限定した実装もあるので、ちゃんと知るには発案者のシェルリ自身が 書いたものに一度目を通しておくのが無難かと思います。 Flattening Traits http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.64.5836&rep=rep1&type=pdf Traits: Composable Units of Behavior http://web.cecs.pdx.edu/~black/publications/TR_CSE_02-012.pdf
[この投稿を含むスレッドを表示] [この投稿を削除]
[1346] プログラミング言語を作る 書籍
投稿者:さとう
2009/06/08 22:07:05

アマゾン詣でをしていたら、、 こんなんありました!! http://www.amazon.co.jp/dp/4774138959 2009/6/20 いやー楽しみです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1345] Re:blockの重複について
投稿者:
2009/06/07 15:32:25

>すみません、ちょっと一筋縄ではいかないようです。 やっぱりそうでしたか、yaccエラーを無くすまでは出来たのですが。内部的な 問題が発生してしまって、当面は無視して先に進むことにします。^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[1344] Re:blockの重複について
投稿者:(ぱ)こと管理人
2009/06/07 11:51:11

>下記のようなプログラムで、ただのブロックを書いた場合、diksamで構文エラー >になります。4.01でも。これをエラーにしないように、diksam.yを修正したいの >ですが、お暇がありましたら何かアドバイスをお願いいたします。 そういえば、Diksamはぶら下がりifの類を許していないので、複合文も 作っていませんでした。 Cと同じように文の一種としてcompound_statementを導入すればよいのでは、 とちょっと試してみたのですが、yaccでconflictが出ました。 考えてみればDiksamでは配列リテラルがあるので、「{」の後に式が来たとき ブロックなのか配列リテラルの始まりなのかがわからないわけです。 こういう場合、構文規則を変形してreduceのタイミングを遅らせる手法が 使えることがありますが、現状のDiksamのブロックは、「{」の直後で 埋め込みアクションが動くようになっており、そのためにはreduceが必要です。 すみません、ちょっと一筋縄ではいかないようです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1343] Re:Traits (was Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:(ぱ)こと管理人
2009/06/07 11:16:39

返信が遅くなりましてすみません。 >それは SELF の trait ですね。ここでいう Traits は、メソッドのセットを用いた多重 >継承機構で、従来のクラスやそれに準ずるものを用いた多重継承から一歩踏み込んだもの >です。Squeak Smalltalk で実効性が示されて、その後、各種言語で応用されています。 >新しい言語では言語組み込みのものもあったりと、ちょっとした流行りの機能かと。 > >http://www.slideshare.net/hiratara/traitmooserole/7 URLを紹介いただきありがとうございます。 Java上がりの私には、Scalaをベースとしたこちらの説明がわかりやすかったです。 http://www.ibm.com/developerworks/jp/java/library/j-scala04298.html 検索してみるとC++のテンプレートのテクニックとしてEffective C++第3版で 紹介されているものがあるようですが、これはまた別物……ですよね。 # うちにあるEffective C++は第2版まででした。 このところ日々の仕事に追われるばかりで、各種情報が追いかけられていないです。 いかんなぁ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1342] blockの重複について
投稿者:
2009/06/07 02:19:50

下記のようなプログラムで、ただのブロックを書いた場合、diksamで構文エラー になります。4.01でも。これをエラーにしないように、diksam.yを修正したいの ですが、お暇がありましたら何かアドバイスをお願いいたします。 -------------------------- int func01() { { int a1; } } --------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1341] Traits (was Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/06/04 01:52:13

>traitsは、「プロトタイプベース言語でクラスを実現するもの」ぐらいの認識でしたが、 >これも元祖はSmalltalk? ……と思ったら別物? それは SELF の trait ですね。ここでいう Traits は、メソッドのセットを用いた多重 継承機構で、従来のクラスやそれに準ずるものを用いた多重継承から一歩踏み込んだもの です。Squeak Smalltalk で実効性が示されて、その後、各種言語で応用されています。 新しい言語では言語組み込みのものもあったりと、ちょっとした流行りの機能かと。 http://www.slideshare.net/hiratara/traitmooserole/7
[この投稿を含むスレッドを表示] [この投稿を削除]
[1340] Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:(ぱ)こと管理人
2009/06/03 20:56:30

>他方で古くはデザパタ、ユニットテストやアジャイル的な手法、比較的新しいところでも >Classbox や Traits などのような静的型でも応用の利く役立つ物を次々と編み出して >くるのも、また Smalltalk 愛好者たちなので、 今日検索して知ったのですが、ケント・ベックってSmalltalkの開発者だったんですね。 知りませんでした。 http://biography.sophia-it.com/content/%E3%82%B1%E3%83%B3%E3%83%88%E3%83%BB%E3%83%99%E3%83%83%E3%82%AF traitsは、「プロトタイプベース言語でクラスを実現するもの」ぐらいの認識でしたが、 これも元祖はSmalltalk? ……と思ったら別物? http://sumim.no-ip.com:8080/wiki/818
[この投稿を含むスレッドを表示] [この投稿を削除]
[1339] Re:コード生成部分について
投稿者:
2009/06/03 19:56:14

>山さんの言語でこのあたりを変えるとなると、fix_tree.cでのTypeSpecifierの >扱いが変わってくるはずです。 はい、実質中では同じような構造を持っていますが意味が多少違ってきました。  いまようやくVM 入り口まで書けるようになりました。可変スタックはなかなか やっかいです。まずは動くことを目指してスピードUPはまた今度で書いています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1338] Re:スレッドセーフについて
投稿者:
2009/06/03 19:51:23

>ひとつのVMで複数のスレッドを動かすのではなく、VMごと分けてしまって、 >それぞれ別のスレッドで動かせばよいのではないでしょうか。  大きな単位でのスレッドのことだと思いますが、当初はそう考えていましたが、 結局言語を作ることになったので、理想を少しあげてみました。 >Rubyのまつもとゆきひろさんが以前こんなことを書いています。 > (中略) >>という(むしろforkを活用すべきという)意見を述べています。  言語としての統一性と、インタープリター言語としてのスレッド化は、理想的な 形で両立するのは難しいと思います。なので、私はスレッド向けに参照操作を すっぱりなくしました。グローバルシステム変数にいたっては…、いやこれは目的 アプリケーションのためで…。  でも、せっかくだから殆どの面でスレッドセーフにすることで、利用者は並列動作 のためのプログラミングルールを気にすることなく書けるようになるのではないか と思いチャレンジしています。  それに、一般的な言語だったら、C/C++なりJavaなりその他のもっといい言語が あるので、作る気なんてしません。^^ どうせ作るなら一般言語では出来ないよう な事を、です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1337] Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/06/02 21:52:56

>おお、ご本人が降臨されるとは。 降臨だなんて勘弁してください。^^; >主義者を殲滅というのは物騒でいかんですねえ。反省。 型安全性を重視する人にとっては、Smalltalk 愛好者やそのやり方・考え方は、正気の 沙汰とは思えないいい加減さがあるでしょうから、「自分の周りからできれば排除した い…」と思うのも、やむを得ない反応だと思います。 他方で古くはデザパタ、ユニットテストやアジャイル的な手法、比較的新しいところでも Classbox や Traits などのような静的型でも応用の利く役立つ物を次々と編み出して くるのも、また Smalltalk 愛好者たちなので、そういう成果物はどんどん活用したいと 思っている人には、生かさず殺さずのさじ加減が難しい存在でもあるでしょうね。w
[この投稿を含むスレッドを表示] [この投稿を削除]
[1336] Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/06/02 21:08:18

>この BBS では、だいぶ久しぶりですよね。 恐縮です。 >実は Actor よりも Alan Kay のアイディアの方が先だったとは... >勉強になりました。_o_ ストラウストラップによるOOの再定義(抽象データ型のOOの提唱)が後にくるので アクターが先、OOはあと、というのが定説になってしまったようです。ふたつのOOを 無理矢理ひとくくりにしてしまうと、こんな歴史的な事実も歪曲されてしまうのですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1335] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/06/02 01:28:02

>int func(p1[],p2[]) >{ > p1[2]=10; // これはOK > p2[4]=9;    // これはOK > p1=p2;     // これがエラーです >} >ひょっとしてdiksamはOKでしたか? DiksamではOKです。Diksamの配列の仕様はJavaとほぼ同じですので。 よって、[]は演算子です。 int[][]という型の式に対し、1回適用すればその式の型はint[]になりますし、 2回適用すればintになります。 山さんの言語でこのあたりを変えるとなると、fix_tree.cでのTypeSpecifierの 扱いが変わってくるはずです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1334] えーっと。
投稿者:(ぱ)こと管理人
2009/06/02 00:41:17

>私は「クラス単位」で「オブジェクト」で分割です。 前から思っていたのですが、「クラス」と「オブジェクト」の区別、ついてます? >しかしこれは構造化ですよ。オブジェクト指向ではありません。 すてぜりふ?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1333] Re:スレッドセーフについて
投稿者:(ぱ)こと管理人
2009/06/02 00:29:53

> では、スレッド間で複数のデータを渡す場合の方法が無いのではないだろうかと思われ >るでしょう。これには、変数集合体のパック、アンパック機能を提供し、複数の情報を >パックして他スレッドに渡すことで、スレッドセーフを保障しています。 いまさらなのかも知れませんが、スレッド間のデータの受け渡しがこれぐらい疎結合で よいのなら、ひとつのVMで複数のスレッドを動かすのではなく、VMごと分けてしまって、 それぞれ別のスレッドで動かせばよいのではないでしょうか。 このスレッドでは、まさにそういうことを話していたつもりでした。 http://kmaebashi.com/bbs/thread.php?boardid=kmaebashibbs&from=1221&range=1 >この要求に対しポインターや参照を操作することは、スレッドセーフを著しく >阻害する要因です。 >なぜなら、2つのスレッドで同じ参照を持った場合、そのデータアクセスに対し >スレッドセーフを自動で行うことはとても大変であり重い処理となります。 少なくともDiksamの設計なら、ヒープもグローバル変数もDVMの配下にあります。 よって、DVMを複数生成すれば、ふたつのスレッドで同じオブジェクトへの参照を 持つことはありませんし、グローバル変数も別です。 その上で、VM共有変数とかを導入して、VM間のデータのやり取りを考えれば よいのではないかと。 スクリプト言語において、ひとつのVMで複数のネイティブスレッドを使うことに関しては、 Rubyのまつもとゆきひろさんが以前こんなことを書いています。 http://www.rubyist.net/~matz/20070530.html >global interpreter lockを使っているので、native threadを使ってもさほど >並列性はあがらず性能もあがりません。 >というのも、オブジェクトアクセスひとつひとつを排他制御しなければならないので、 >コンフリクトは無視して問題が起きそうなら自分で対処というようなC++のような >対応はスクリプト言語では難しいでしょう。 (中略) >また、PythonのGuido van Rossumはスクリプト言語の並列性について >http://mail.python.org/pipermail/python-3000/2007-May/007414.html >という(むしろforkを活用すべきという)意見を述べています。 まあ、JVMなんかでも、doubleの操作はアトミックであることを保証してはいないので、 割り切ってしまう、という考え方もあるかもしれませんけれど。 # ポインタが不正になってクラッシュするのはさすがにまずいのかなあ。 # でも、黙って間違った答を吐くアプリケーションはもっとひどいと思うけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1332] SEさんの継承の使い方
投稿者:(ぱ)こと管理人
2009/06/01 22:57:31

で、以下の指摘については、何の反論も弁明もなしですか? >仮に実装継承による差分プログラミングを(いろいろの弊害は度外視して)認めると >しても、それが趣旨ならUpperStackをStack型の変数に代入してはいけないし、 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1269&range=1 >Stack st = new Stack(); にて、SEさんは、なぜUpperStackをStackに代入しているのですか? そうすることによるメリットは何ですか? >スタックから要素を取得するメソッドはget()をオーバーライドしてはいけません。 >getUpper()のような別のメソッドを作るべきです。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1260&range=1 にて、なぜget()をオーバーライドしたのですか? そうすることによるメリットは何ですか? >>FileWriterを例にした方がいいかもしれません。内容的には同じ意図です。 >「同じ意図です」って、どういう意図でしょうか? で、どういう意図でしょうか? #「抽象化」とか、まるっきり意味のない回答をしないでくださいよ。 >FileWriterがこういう継承関係になっている「意図」を理解しているのなら、 >オセロ盤に棋譜を吐かせるのに、Boardクラスによりによって「ファイル名」を >渡すなどという設計がでてくるはずがないのですけど。 >http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1303&range=1 私には、SEさんが、継承やポリモルフィズムを理解しているようにはとても見えないのですけど。 # ていうか「インスタンス」も理解してなさそうな。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1331] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/06/01 22:42:23

>>http://kmaebashi.com/programmer/c_yota/module.html >まずモジュールの定義が私と違っていたようです。 >(ぱ)さんの所で言うモジュールは「ヘッダファイル単位」で、私の言っていたのは「ライブラリ単位」だったようです。 むちゃくちゃですね。 「ヘッダファイル単位」っていったいどういう意味ですか? 私がどこかにそんなことを 書きましたか? (書いてあるというのなら引用してください) ご自分が何を言っているか 自分で理解していますか? 「モジュール」が先に決まって、それに対応するヘッダファイルを作ることはあっても、 ヘッダファイルが先に決まることはありえないでしょう。常識的に考えて。 よってモジュールが「ヘッダファイル単位」などということがあるわけがありません。 これではモジュール切り分けの指針がどこにもないではないですか。 件のページで、私はこう書いています。 >さて、Cでは、ソースファイル単位で名前空間の隠蔽が出来ますが、プログラムの >規模がさらに大きく、ソースファイルの数自体が膨大になってくると、今度は、 >いくつかのソースファイルをまとめて、もう1段階大きな固まりを作る必要が >出てきます。以下、この文章中では、この固まりのことを「モジュール」と呼びます。 ># こういうのは「ライブラリ」と呼ばれることもありますが、「ライブラリ」と ># 言うとどうも「下請け」的なイメージがあって、私にはちょっとしっくり来ません。 SEさんは、Cでは、「せいぜいDBアクセスとか通信部分など」しかモジュール化しない そうですが、これはやはり私と同様、「ライブラリ」には下請け的なイメージを 持っていて、DBアクセスとか通信部分のような下請け部分しかモジュール(SEさん用語の ライブラリ)にはしない、と言っているわけでしょう。 では、「せいぜいDBアクセスとか通信部分など」以外の部分は、Cの時代には、 どのように作っていたのですか? いっさい分割なしのぐちゃぐちゃですか? >私は、実装隠蔽の単位としてクラスは適当だと思っていて、機能を単位とするのは間違いだと思います。 で、なぜそう思うわけですか? 具体的にどのような例で、クラスで分割するとうまくいって、機能を単位とすると うまくいかないわけですか? 具体例としてSEさんから出てきたのは、[1287]のこの例だけです。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1287&range=1 >ちなみに簡単に変更できた例は、 >メモリ上で頻繁に検索するデータが100件から6万件に変わった時の事でした。 >検索にキャッシュやヒストリー機能などあらゆる機能を組み込み高速化しましたが、 >修正したクラスは1つです。もしCの構造化で組んでいたら、修正箇所と影響範囲を >調べるだけで嫌になっていたと思います。 これを普通に読めば、なにかの検索機能という「機能を単位とした」モジュールが あって、それがうまいこと隠蔽されていたから修正箇所がそこだけで済んだ、という 話にしか読めません(誤読であればご指摘ください)。 そこで私は、「そんなものはオブジェクト指向以前の、モジュール化で達成している ことではないか(よって、オブジェクト指向の利点ではない)」と指摘しているわけです。 ここでそう書いてますよね? http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1292&range=1 >関連する操作やデータをまとめる、というのは普通にモジュール化であって、 >私が「疑りぶかい~」で書いたオセロの例の、Cでstaticで隠蔽を行った >board.cで達成していることでは? 機能単位のモジュール化では実現できず、オブジェクト指向なら実現できることの 具体例を示してもらわないと、SEさんにとってのオブジェクト指向の定義がさっぱり わからないです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1330] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/06/01 20:47:24

(ぱ)さんも感じているのではないかと思いますが、何か全てが少しづつ違うようです。 ただこの違和感は経験があります。構造化とオブジェクト指向の違いによる違和感です。 (ぱ)さんは、モジュールは「ヘッダ単位ファイル」で「機能」で分割ですね。 私は「クラス単位」で「オブジェクト」で分割です。 プログラムの組み方も変わります。イメージ的に言うと縦割りと横割りぐらい違います。 話が噛み合わないのは、この縦割りと横割りで見方が違うためでしょう。 実際、構造化プログラミングの観点で言えば、(ぱ)さんの意見は納得出来ます。 私もその観点で言えば、「クラスとカプセル化した関数は同じ」とか、 「利点をあげるとしたら見やすさ」などと言うと思います。 しかしこれは構造化ですよ。オブジェクト指向ではありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1329] Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:kit
2009/06/01 20:07:19

>おお、ご本人が降臨されるとは。 この BBS では、だいぶ久しぶりですよね。 実は Actor よりも Alan Kay のアイディアの方が先だったとは... 勉強になりました。_o_ >「殲滅」ではなくて「粉砕」でしたね。 >しかも対象は「Smalltalk原理主義者」ではなく「Smalltalk原理主義」。 > >主義者を殲滅というのは物騒でいかんですねえ。反省。 字面はたしかにそうでも、内容からすると「河野さんを殲滅せよ!」って感じなので、 実は合ってるかも。:-) 河野さんのボケっぷりが懐かしいですな。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1328] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/06/01 14:39:00

>そういう経験もあって、2000年2月ころに書いたのがこちら。 >http://kmaebashi.com/programmer/c_yota/module.html まずモジュールの定義が私と違っていたようです。 (ぱ)さんの所で言うモジュールは「ヘッダファイル単位」で、私の言っていたのは「ライブラリ単位」だったようです。 ただ、ヘッダーファイル単位だとしてもクラス単位とは違うので、CでJavaと同じ単位ではないと思います。 >なお、なにせCなのでモジュール化の単位はクラスではないですけど、 >これはその方が都合がよいという考えでそうしています。 >Javaでも、メンバのアクセスレベルがデフォルトで「パッケージ」になっている >あたり、「実装隠蔽の単位としてクラスは適当ではない」というのが現状の >コンセンサスでいいんじゃないかと思っています。 私は、実装隠蔽の単位としてクラスは適当だと思っていて、機能を単位とするのは間違いだと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1327] スレッドセーフについて
投稿者:
2009/06/01 11:32:47

 会話の上で言語仕様に食い違いがあった原因を今理解しました。私の考慮不足だったの ですが、当初より言語に求める基本機能に、スレッドセーフなシステムでした。この要求 に対しポインターや参照を操作することは、スレッドセーフを著しく阻害する要因です。  なぜなら、2つのスレッドで同じ参照を持った場合、そのデータアクセスに対しスレッド セーフを自動で行うことはとても大変であり重い処理となります。同一スレッド内でも その機構の一部が動いてしまいます。これは避けたいことです。  次の問題がもっと深刻です。参照先が複数データの場合、他の何らかのサポートなしに 参照された複数のデータをスレッドセーフにすることは原理的に不可能です。  以上2つの理由により、一番最初から、ポインターや参照を直接操作する行為は無いとの、 大前提が私の思考基本にありました。そのため、無意識にそれが前提で思考や会話をして いたことを気がつきました。よくある事ですが考慮不足です。  では、スレッド間で複数のデータを渡す場合の方法が無いのではないだろうかと思われ るでしょう。これには、変数集合体のパック、アンパック機能を提供し、複数の情報を パックして他スレッドに渡すことで、スレッドセーフを保障しています。これは始めて 説明しています。その他にもスレッドセーフを自動保障するシステムがあります。まだ 説明されていません。しばらくお待ちください。なにぶん自己検証を先にしたくて。 本当に申し訳ありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1326] Re:コード生成部分について
投稿者:
2009/06/01 01:48:27

>>int[] func(p1,p2,p3); >>これの int[] 配列の戻りが禁止になっています。 > >対策するのであれば、ユーザには、配列への参照自体を取得できないようにしておかな Cで言う所のポインターの存在がありません。だから、グローバル変数に参照を 入れることが出来ません。 int func(p1[],p2[]) { p1[2]=10; // これはOK p2[4]=9;    // これはOK p1=p2;     // これがエラーです } ひょっとしてdiksamはOKでしたか? (駄目だと思い込んでいました)仕様が変わっています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1325] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/06/01 01:30:54

>int[] func(p1,p2,p3); >これの int[] 配列の戻りが禁止になっています。 具体的にどうされているのかがよくわかりませんが、少なくとも、関数の戻り値の型として 配列型を返せないようにするだけでは不完全ではないでしょうか。 ユーザが、配列への参照を取得できるのなら、それをグローバル変数に代入することも できるはずで、もしそれをされたら、関数を抜けてスタックが開放された時点で 不正なポインタになってしまいます。 対策するのであれば、ユーザには、配列への参照自体を取得できないようにしておかないと だめなのでは。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1324] Re:コード生成部分について
投稿者:
2009/06/01 01:11:00

>ええと、ということは、そもそもユーザは配列への参照を取ることができない >(配列を引数として別関数に渡すときは内部的には参照が作られるが、ユーザがそれを >変数に代入したりすることはできない)ということでしょうか? >それなら問題ないように思います。CやJavaに慣れた身にはちょっと不便そうですが。 言葉足らずですみません。 int[] func(p1,p2,p3); これの int[] 配列の戻りが禁止になっています。 int func(p1[][],p2[]) これは問題ありません。内部で操作しても問題なく処理されます。 配列は参照渡しなので、子関数で操作したものは、呼びだし関数の配列内が変わります
[この投稿を含むスレッドを表示] [この投稿を削除]
[1323] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/31 22:03:45

>>Cですごくありがちなバグである、 > 配列の参照戻しは今エラーにしています。もともと、配列は参照渡しなので、 >リターンで戻す必要を感じなかったので。 ええと、ということは、そもそもユーザは配列への参照を取ることができない (配列を引数として別関数に渡すときは内部的には参照が作られるが、ユーザがそれを 変数に代入したりすることはできない)ということでしょうか? それなら問題ないように思います。CやJavaに慣れた身にはちょっと不便そうですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1322] Re:コード生成部分について
投稿者:
2009/05/31 03:19:58

 やはり寝ながら思いついたアイデアは細部まで検討されていませんでした。 出来なくは無いのですが、副作用が見つかったし。やはりトリッキーでnew事態の 一般的な意味の仕様も変えてしまうのは問題が有るので、上のアイデアは 無かったことにしてください。 orz  今日は寝れそうに無くなってしまった…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1321] Re:コード生成部分について
投稿者:
2009/05/31 02:48:40

>Cですごくありがちなバグである、  配列の参照戻しは今エラーにしています。もともと、配列は参照渡しなので、 リターンで戻す必要を感じなかったので。  いや~~寝ようとしたら、動的配列生成でトリッキーな方法を思いついてしまって 眠れなくなってしまいました、ここ2日間の作成をチャラにして元に戻そうかな~~  何を思いついたかと言うと、配列をnew宣言したときにスタック上の配列データの所を 開ける、その為にスタックを移動することです。スタックにリアルアドレスを持ってい るわけではないし、アドレス操作をするときは移動してないわけで。たぶん問題ないかと。  ああ~~~だめだ、思いついたらやらないでおけなくなってしまう。寝ながら だめだ、だめだ、こんな変なこと考えてはと、何度繰り返したことか。でも、どうせ 好きに作れるんだからやってしまおう^^ どう思いますか? 
[この投稿を含むスレッドを表示] [この投稿を削除]
[1320] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/31 02:10:17

>>(1)Cのように、配列の領域をスタック上に取る。 >ご指摘ありがとうございます。前の書き込みからVMをいろいろ調べていましたが、 >まさに(1)の方法を取ろうと思っています。このレス読んだのがちょうど今日なん >ですよ。 この方法を取るとして、ローカルな配列への参照を、別関数に渡すことは できるのでしょうか? できるとしたら、配列への参照がプログラマの思いのままにできるということですから、 Cですごくありがちなバグである、 char *get_line() { char buf[256]; /* bufに値をつめる処理 */ return buf; } みたいなのも許すことになりませんか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1319] 配列の仕様について
投稿者:
2009/05/30 21:54:58

 上記の仕様変更により。yacc,lex部分からの修正をしています。 下に示すようなプログラムに。diksamの言語仕様と離れていってしまうのは 仕方の無いことかもしれません。それに、ほぼC言語に近くなってしまう。 ちなみに、配列変数宣言時に[]内に変数を入れるとエラーになります。 ---------------------------------------- int main(int p1,int p2) {   int aa;   string[1+2] msg = { "asd","qwe","zzz"};   int[1+1+1] i1 = {1,2,65537};   int[10][9] id;   id[5][4] = 321;   aa =id[9][8]; } ----------------------------------------  結局の所、GCを装備して配列の動的確保を可能にし、管理のための処理及び間接 アクセスのためのオーバーヘッドを許すか。領域を固定にもって直接スアクセス し、高速で単純な処理だが配列領域は宣言時に固定で確保しなければならないか。 のチョイスで有ったのではないかと思います。  私は今回、連続的な処理(一般的なプログラム)より。マルチスレッドで複数の 小さな処理の集合体による制御を優先しているので下の方を選びました。単にGCを 入れたくなかっただけかもしれませんが^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[1318] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/30 12:38:04

>一応、抽象化されていますが、確かに分かりにくいかもしれません。 「分かりにくい」とか「一応、抽象化」といった話ではなくて、SEさんの出した UpperStackでの継承の使い方は *間違っています*。 仮に実装継承による差分プログラミングを(いろいろの弊害は度外視して)認めると しても、それが趣旨ならUpperStackをStack型の変数に代入してはいけないし、 スタックから要素を取得するメソッドはget()をオーバーライドしてはいけません。 getUpper()のような別のメソッドを作るべきです。 たとえ「リスコフの置換原則」とかの名前を知らなくても、ポリモルフィズムを 理解していれば、当然そう考えると思うんですが。 >FileWriterを例にした方がいいかもしれません。内容的には同じ意図です。 「同じ意図です」って、どういう意図でしょうか? FileWriterがこういう継承関係になっている「意図」を理解しているのなら、 オセロ盤に棋譜を吐かせるのに、Boardクラスによりによって「ファイル名」を 渡すなどという設計がでてくるはずがないのですけど。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1303&range=1
[この投稿を含むスレッドを表示] [この投稿を削除]
[1317] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/30 12:29:14

>Cではモジュール化しようと思った所しかモジュール化しません。 >具体的に言うと、せいぜいDBアクセスとか通信部分などでしょう。 えーっ! 私がある程度大きなプログラムを最初にCで設計から実施したのは、入社2年目でしたから かれこれ15年くらいは前の話ですけれど、すべての関数をモジュールに入れていました。 5万行程度の、UNIX上のシステムで、XとMotifで画面描画するようなシステムでした。 他にもいろいろなシステムを見ましたが、数万行以上の規模なら、誰が設計しても、 まずモジュール分割はやっていたように思います。ヘッダファイルをちゃんと分離して なかったりして変なことになっているケースはよくありましたが。 そういう経験もあって、2000年2月ころに書いたのがこちら。 http://kmaebashi.com/programmer/c_yota/module.html 現在作っているcrowbarやDiksamといった言語も、モジュール分割はしています。 Diksam ver.0.2のソースにGLOBALをかましたのはこちら。 http://kmaebashi.com/programmer/devlang/diksam_src_0_2/index.html メモリ管理モジュールMEMやデバッグ用モジュールDBGの上に、コンパイラDKCと 仮想マシンのDVMがあります。その中でも機能ごとにソースファイルを分けると いったようなことはしています。 なお、なにせCなのでモジュール化の単位はクラスではないですけど、 これはその方が都合がよいという考えでそうしています。 Javaでも、メンバのアクセスレベルがデフォルトで「パッケージ」になっている あたり、「実装隠蔽の単位としてクラスは適当ではない」というのが現状の コンセンサスでいいんじゃないかと思っています。 ……それはさておき。 私も長いことこの仕事をやってますから、いろいろアレな設計やナニなソースを 見てきたつもりでいましたけど、なんだかんだでずいぶん恵まれた環境にいたのかなあ。 これでも。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1316] Re:Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:(ぱ)こと管理人
2009/05/30 12:11:31

おお、ご本人が降臨されるとは。 >それらしいのを見つけましたがこれですか? >http://groups.google.co.jp/group/fj.comp.oops/msg/973f372a89455de2 そうですそうですこれです。 「殲滅」ではなくて「粉砕」でしたね。 しかも対象は「Smalltalk原理主義者」ではなく「Smalltalk原理主義」。 主義者を殲滅というのは物騒でいかんですねえ。反省。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1315] Re:コード生成部分について
投稿者:
2009/05/29 23:00:15

> {"new_array_int", "b", 16}, // 次元数 基本データ-型の配列生成 > {"new_array_double", "b", 20}, // 次元数 基本データ-型の配列生成 > {"new_array_object", "b", 16}, // 次元数 基本データ-型の配列生成 > {"new_array_literal_int", "s", 16}, // int定数配列を変数に接続 > {"new_array_literal_double","s", 20}, // double定数配列を変数に接続 > {"new_array_literal_object","s", 16}, // object定数配列を変数に接続 補足  このnewは構文のnewではなくスタック上に実配列生成のnewです。 ちなみに、言語上の総ての関数は特に何も記述することなくスレッドセーフに なります。複数のスレッドから関数AAAを同時に呼んでも問題が無いです。 もちろん組み込み関数も。利用者はスレッドを意識することなく自由に組んでも 問題の無い言語になります。  しかしよくよく考えてみると、この仕様がOOのクラスに合わないんです。OOP 好きな私がOOPに合わない言語を作るとは、考えてしまいます。早く作って検証 したくてなりません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1314] Re:コード生成部分について
投稿者:
2009/05/29 22:32:50

>(1)Cのように、配列の領域をスタック上に取る。 ご指摘ありがとうございます。前の書き込みからVMをいろいろ調べていましたが、 まさに(1)の方法を取ろうと思っています。このレス読んだのがちょうど今日なん ですよ。  ちなみに、配列の添え字記述が宣言時決定でnewは無くなる方向しかないかなと 思っています。スタック上に取る以上は動的確保は無理のようで。VMコードも多少 変わってしまいました。 下記がVMコードの現在の案です。 S_OpcodeInfo D_opcode_info[] = { {"dummy", "", 0}, {"push_int_1byte", "b", 8}, {"push_int_2byte", "s", 8}, {"push_int_4byte", "i", 8}, // 実際の値を持つ {"push_double_0", "", 12}, {"push_double_1", "", 12}, {"push_double_8byte", "d", 12}, // 実際の値を持つ {"push_string", "s", 40}, // 文字列の位置NOを持つ0~ {"push_null", "", 8}, /**********/ {"push_stack_int", "s", 8}, // intローカル変数をスタックに {"push_stack_double", "s", 12}, // {"push_stack_string", "s", 40}, // {"pop_stack_int", "s", -8}, // スタックのintをローカル変数に {"pop_stack_double", "s", -12}, // {"pop_stack_string", "s", -40}, // /**********/ {"push_static_int", "s", 8}, // int静的変数をスタックに {"push_static_double", "s", 12}, // {"push_static_string", "s", 40}, // {"pop_static_int", "s", -8}, // スタックのintを静的変数に {"pop_static_double", "s", -12}, // {"pop_static_string", "s", -40}, // /**********/ {"push_sysval_int", "i", 8}, // システムグローバル変数をスタックに {"push_sysval_double", "i", 12}, // {"push_sysval_str", "i", 40}, // {"pop_sysval_int", "i", -8}, // スタックからシステムグローバル変数に {"pop_sysval_double", "i", -12}, // {"pop_sysval_str", "i", -40}, // /**********/ {"push_array_int", "", 16}, // int配列値をスタックに {"push_array_double", "", 20}, // {"push_array_string", "", 16}, // {"pop_array_int", "", -16}, // スタックからint配列に {"pop_array_double", "", -20}, // {"pop_array_string", "", -16}, // /**********/ {"add_int", "", -8}, // 以下は総て算術演算子 {"add_double", "", -12}, {"add_string", "", -40}, {"sub_int", "", -8}, {"sub_double", "", -12}, {"mul_int", "", -8}, {"mul_double", "", -12}, {"div_int", "", -8}, {"div_double", "", -12}, {"mod_int", "", -8}, {"mod_double", "", -12}, {"minus_int", "", 0}, {"minus_double","", 0}, {"increment", "", 0}, {"decrement", "", 0}, // ここまで算術演算子 {"cast_int_to_double", "", 4}, // 以下はキャスト処理 {"cast_double_to_int", "", -4}, {"cast_boolean_to_string" "", 32}, {"cast_int_to_string", "", 32}, {"cast_double_to_string", "", 28}, // ここまでキャスト処理 {"eq_int", "", -8}, // 以下は総て論理演算子 {"eq_double", "", -12}, {"eq_string", "", -40}, {"gt_int", "", -8}, {"gt_double", "", -12}, {"gt_string", "", -40}, {"ge_int", "", -8}, {"ge_double", "", -12}, {"ge_string", "", -40}, {"lt_int", "", -8}, {"lt_double", "", -12}, {"lt_string", "", -40}, {"le_int", "", -8}, {"le_double", "", -12}, {"le_string", "", -40}, {"ne_int", "", -8}, {"ne_double", "", -12}, {"ne_string", "", -40}, {"logical_and", "", -8}, {"logical_or", "", -8}, {"logical_not", "", 0}, // ここまで論理演算子 {"pop", "", -1}, // スタックを1つ減らす {"duplicate", "", 12}, // スタック内容をコピーしてスタックに {"jump", "s", 0}, // 指定ポインターにjump {"jump_if_true", "s", -1}, // スタックがtrueならjump {"jump_if_false","s", -1}, // スタックがfalseならjump /**********/ {"push_function", "sss", 0},// 関数情報をスタックに {"invoke", "", -1}, // 関数コール {"return", "", -1}, // 関数戻り /**********/ {"new_array_int", "b", 16}, // 次元数 基本データ-型の配列生成 {"new_array_double", "b", 20}, // 次元数 基本データ-型の配列生成 {"new_array_object", "b", 16}, // 次元数 基本データ-型の配列生成 {"new_array_literal_int", "s", 16}, // int定数配列を変数に接続 {"new_array_literal_double","s", 20}, // double定数配列を変数に接続 {"new_array_literal_object","s", 16}, // object定数配列を変数に接続 };  (注:ちなみに1とか-1は未定です)  上の構造だとstringがやたらスタックを食っているのは、string自体の大きさ からです。このへんが、stringを使用するのを変えてしまいそうな気分です。 ちなみに、配列は3次元まで、要素の最大は60KByteまでの制限をする予定。汎用の 言語を作るわけではないし、あくまでもローカル変数の制限だけなので、目的と 効率を優先にしています。  また、スタック構造ですが、VC++だとenumが4byte取るのでスタック対応する フラグは消して、下記のようなS_Valueに変えて、タイプとサイズを持つことに しました。で結局の所、関数のローカル変数は総てスタックに持つことでint用と double当のプールはなくしました。前に話したようにVMは出来るだけシンプルに したいので、持つデータ構造は違う形になりそうです。配列の仕様も変えてし まったし。下記の構造体をスタックで使用します //=================================================================== typedef struct { ushort dimno; // 配列の次元数 ushort dimsno[DIMMAX]; // 配列の添え字数 union { int *intDim; // int配列実態 double *doubleDim; // double配列実態 string *stringDim; // string配列実態 }u; } SV_array; //=================================================================== typedef struct { ushort vtype; // データタイプ E_StackDType ushort size; // スタック消費サイズ union { int int_value; // intデータ double double_value; // doubleデータ string *string_value // string参照 SV_array *i_array; // int配列参照 SV_array *d_array; // double配列参照 SV_array *s_array; // string配列参照 }u; } S_Value;  以上が、今日までに想定した仕様です。まだVM自体を作っていないので、まだ 変更があるかもしれません。ちなみに、組み込み関数についてはラフ案で下記の ようなクラスを使用しようと思っています。組み込み関数からのリターンはエラー コードにする予定。パラメータ可変の関数も対応します。それと変数リファレンス 情報を持って一部の関数は総ての変数をリファレンスに操作します。この点は悩み ました。文字列と配列以外は実数渡しなのですが、一部のシステム関数のみリファ レンス操作してしまうんですよ。その一部のために構文を作るべきか特殊仕様とす るかで、たった2つの関数のために構文を変えることは止めにしました。 目的優先に^^; //=================================================================== typedef struct { char *name; // 変数名 ushort gval_x; // グローバル変数横軸数 ushort gval_y; // グローバル変数縦軸数 S_Value *val_ref; // 変数参照データ S_Value val; // 変数コピーデータ } S_Value_info; //=================================================================== class C_NFBase { //-- VMに送る情報 ---------------------- char *m_name; // 関数名 int m_prmno; // 要求するパラメータ数0-10まで20は可変関数 E_ValueType m_type[PRMMAX]; // 要求するパラメータの型 E_ValueType m_rtntype; // 関数戻り値の型 //-- VMから受け取る情報 ---------------------- int m_prninno; // 引き渡されたパラメータ数 S_Value_info m_prm[PRMMAX]; // 引き渡されたパラメータデータ //-- 関数の戻り情報 ---------------------- S_Value m_return; // 関数からの戻り値データ
[この投稿を含むスレッドを表示] [この投稿を削除]
[1313] Re:>(ぱ)こと管理人さん
投稿者:yuya
2009/05/29 20:02:21

>Cではモジュール化しようと思った所しかモジュール化しません。 主語は誰なんでしょうか……。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1312] Re:>(ぱ)こと管理人さん
投稿者:774RR
2009/05/29 16:59:07

そりゃ単にプログラマの技量の問題ぢゃん。 きれいにモヂュール化された C ソースや Fortran ソースを何度も見たことあるし ぜんぜんモヂュール化されていないグチョグチョ Java ソースも見たことあるよ。 モヂュール化を言語の仕様レベルで推し進める機構があるかないか という点ならば御意。 そしてその機構に関係なくグチョグチョソースを書く下手プログラマが どこにでも、いくらでも、いるのが現実。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1311] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/29 16:54:50

>本質は抽象化だと仰っているのにSEさんが出してるスタックの例はまったく >抽象化されていないような気がするのですが…。 一応、抽象化されていますが、確かに分かりにくいかもしれません。 FileWriterを例にした方がいいかもしれません。内容的には同じ意図です。 ----------------------------------------------------------- java.lang.Object  |  +--java.io.Writer     |     +--java.io.OutputStreamWriter        |        +--java.io.FileWriter -----------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1310] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/29 16:49:09

>Cで「単位を合わせて」モジュール化する困難さと、クラスの階層構造を適切に設計する困難さは、 >あまり違いがないように思うんですが、人によるのかな。 Cではモジュール化しようと思った所しかモジュール化しません。 具体的に言うと、せいぜいDBアクセスとか通信部分などでしょう。 Javaの場合は全てのクラスがモジュール化なのです。 現実的に実システムでは、CでJavaと同様の単位でモジュール化するのは不可能です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1309] Smalltalk原理主義を粉砕せよ! (was Re: オブジェクト指向の…
投稿者:sumim
2009/05/29 09:01:02

>全然完璧に関係ないですが、大昔、fjに高木浩光さんが >「Smalltalk原理主義者を殲滅せよ」なんてことを書いていて(もちろんネタですが)、 >今これを探そうとしてGoogleグループを見てみたのですが… それらしいのを見つけましたがこれですか? http://groups.google.co.jp/group/fj.comp.oops/msg/973f372a89455de2
[この投稿を含むスレッドを表示] [この投稿を削除]
[1308] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/29 00:51:22

>それと、GCは不要なシステムになります。INT用とdouble用の固定長プール、そして >文字列はstringに任せてしまうのでVMとしてのGCは無くなりました。 intとdoubleが固定長のプールに保持されてGCがないということは、 配列はグローバルなものだけなのでしょうか? ローカルな配列が使えないのはちょっと不便なような。 ローカルな配列を使えるようにする場合、再帰を考えれば (1)Cのように、配列の領域をスタック上に取る。  →現状のDVMには、スタック上でインデックスを指定して要素を参照する   インストラクションがないので、追加が必要。 (2)配列の領域はヒープに取るが、その参照をスタックに持つ。  →最低でも参照カウンタのGCが必要。 ということになりそうな…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1307] オブジェクト指向の利点の話
投稿者:(ぱ)こと管理人
2009/05/29 00:39:49

件名変えました。 >>関連する操作やデータをまとめる、というのは普通にモジュール化であって、 >>私が「疑りぶかい~」で書いたオセロの例の、Cでstaticで隠蔽を行った >>board.cで達成していることでは? >ここが重要です。 >構造化プログラミングの「モジュール化」は基本的にモジュール化した所でしか有効ではありません。 >1つの関数で考えた場合は分かりにくいかと思いますが、関連する複数の関数での場合を考えてください。 いや、だから私が例に出したboard.cにはちゃんと複数の関数があるんですけど。 http://kmaebashi.com/programmer/object/othello.html もうSEさんが何を言いたいのかさっぱりです。 >オブジェクト指向の >利点は「再利用性が高まる事」=「変更がしやすい、変更しても壊れにくい」。 >本質は「抽象化」 >だと言う事です。 「抽象化」なんてのはおよそあらゆるプログラミングパラダイムの目的みたいなもので、 それだけでは何がなんだかさっぱりです。 >774RRさんの言う通り、「対象読者層が異なる」というだけの話のようです。 >つまり「インスタンスが複数あっていい」というあたりを理解していないプログラマ向けの文書で、 >私の指摘は「インスタンスが複数あるのは当たり前」と理解しているプログラマの視点という事です。 私もそう思っていたのですが、ちょっと疑い始めているところです。 >棋譜をセーブデータとして残すために、コンストラクタかセッターにファイル名を渡すと >言うならボードクラスに入れるのはいいと思いますが、 >名人戦の障害発生対応が違うかもしれないので、エラーログクラスを受け渡すと言うのは >おかしいと思います。 まあそのへんは要件次第で、エラーログならstaticでよいという考え方もあるでしょう (Boardが持つのは「おかしい」と言われると、それは何故かと聞きたくなりますが)。 ええと、しかも、「コンストラクタかセッターに『ファイル名を』渡す」んですか? 棋譜をファイルに吐かず、こっちの画面に出したい、とかの場合はどうするんですか? もともとLoggerの話は、SEさんの[1269]における http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1269&range=1 >これを次のように変更します。1行で済みます。 とか、 [1273]における http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1273&range=1 >遠くの所でnewした特有の処理の入ったクラスを、引数で使い回すのは、 >構造化のスタンプ結合的で、オブジェクト指向的には良くない設計です。 とかの話から出てきたものです。Loggerを引数で引き回そうが、staticで保持しようが、 遠いところでnewされたオブジェクトを、その実際のクラスがわからない状態で 使用するということに変わりはありません。そのとき、うまく使えばポリモルフィズムで 動きが変えられるというのがよく言われるオブジェクト指向の利点です。 その点、SEさんのUpperStackは、使う側がUpperStackであることを意識して使わなければ ならない(リスコフの置換原則を破っている)のでダメだ、と言っているわけです。 CばっかりずっとやってきたプログラマにJavaで設計させると、機能単位でクラス分割は するものの、 (1)何もかもstaticフィールドとメソッドで作ってしまう。 (2)staticメソッドにしない代わりに、毎回オブジェクトをnewして、いくつか  メソッドを呼んだら使い捨てにしてしまう。 このどちらかの設計にしてしまうことがあります。 正直なところ、SEさんはこの(2)のタイプの人に見えてしょうがないんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1306] Re:>(ぱ)こと管理人さん
投稿者:こくぼ
2009/05/28 18:55:50

>つまり私の言いたいのは、 >オブジェクト指向の >利点は「再利用性が高まる事」=「変更がしやすい、変更しても壊れにくい」。 >本質は「抽象化」 >だと言う事です。 >利点は「見通しの良さ」 >本質は「マルチプルインスタンス」 >ではないと思います。 本質は抽象化だと仰っているのにSEさんが出してるスタックの例はまったく 抽象化されていないような気がするのですが…。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1305] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:こくぼ
2009/05/28 18:42:42

>まるで3つのオブジェクト指向があるように思えますが、実質的にはオブジェクト指向は2です。 >1はメッセージが焦点になっていますが、本質はオブジェクトで2と同様です。 1の本質はオブジェクトではなくてメッセージだと書いてあるはずですが…。 #Smalltalkの文法やクラスやオブジェクトといった概念もおまけでしかない、とアランケイはのたまっています >もし初心者が見たら混乱するだけだと思います。2の説明だけあればいいと思います。 きちんと分類して書いてあるから少なくとも混乱することはないと思いますけどね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1304] Re:>(ぱ)こと管理人さん
投稿者:yuya
2009/05/28 16:49:04

クラスの階層構造のおかげで、モジュール化も適切な階層構造で行いやすくなる、ってことでしょうか。 少なくとも私自身は、そんなメリットを実感したこと、一度もないなぁ。 Cで「単位を合わせて」モジュール化する困難さと、クラスの階層構造を適切に設計する困難さは、 あまり違いがないように思うんですが、人によるのかな。 無地のノートより罫線の引いてあるノートのほうが書きやすい、ぐらいの違いはあるかもしれないけど。 Cで適切な階層構造のモジュール化が行えない人が、オブジェクト指向言語でクラス設計したところで、 (しかも実装継承で組んだりしたら)余計ぐちゃぐちゃになっちゃうような気がするんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1303] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/28 15:24:23

>関連する操作やデータをまとめる、というのは普通にモジュール化であって、 >私が「疑りぶかい~」で書いたオセロの例の、Cでstaticで隠蔽を行った >board.cで達成していることでは? ここが重要です。 構造化プログラミングの「モジュール化」は基本的にモジュール化した所でしか有効ではありません。 1つの関数で考えた場合は分かりにくいかと思いますが、関連する複数の関数での場合を考えてください。 つまり拡張を見越して単位を合わせてモジュール化しておく必要があると言う事です。 オブジェクト指向の場合はクラス単位でモジュール化されているような物であると言う事です。 つまり末端のクラスから上位のクラスまで、全ての単位でモジュール化されているため、 あらゆる単位で変更が可能だと言う事です。 つまり私の言いたいのは、 オブジェクト指向の 利点は「再利用性が高まる事」=「変更がしやすい、変更しても壊れにくい」。 本質は「抽象化」 だと言う事です。 利点は「見通しの良さ」 本質は「マルチプルインスタンス」 ではないと思います。 >いや、「世間のCプログラマはstaticで実装を隠蔽するような気の効いたことは >していない。だからお前の認識はズレているのだ」ということならそうなのかも >しれませんけど(1ソースファイル1関数、という規約のプロジェクトとかって、 >今でもあるんでしょうか)。 774RRさんの言う通り、「対象読者層が異なる」というだけの話のようです。 つまり「インスタンスが複数あっていい」というあたりを理解していないプログラマ向けの文書で、 私の指摘は「インスタンスが複数あるのは当たり前」と理解しているプログラマの視点という事です。 >うーん、Loggerくらいならstaticでもかまわないとは確かに思いますけれど、 >私ならアプリケーションのインスタンスのフィールドに持ちますね。 >オセロの例なら、Boardクラスで障害発生時とかのログを残すとして、Loggerは >Boardに持たせます。名人戦のBoardだけ障害発生時の対応が違ったりするかも >知れませんし。よって、BoardのコンストラクタかsetLogger()メソッドの >引数でLoggerを渡すことになります。 棋譜をセーブデータとして残すために、コンストラクタかセッターにファイル名を渡すと 言うならボードクラスに入れるのはいいと思いますが、 名人戦の障害発生対応が違うかもしれないので、エラーログクラスを受け渡すと言うのは おかしいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1302] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:SE
2009/05/28 14:39:32

>>>これもひどい内容ですね。 > >とSEさんがおしゃるのか、さっぱりわからないんですけど。 1.メッセージ指向 2.クラス指向 3.手続き抽象化 のまるで3つのオブジェクト指向があるように思えますが、実質的にはオブジェクト指向は2です。 1はメッセージが焦点になっていますが、本質はオブジェクトで2と同様です。 3は少なくとも私は知りませんし、一般的ではないと思います。HP筆者の独自解釈では? もし初心者が見たら混乱するだけだと思います。2の説明だけあればいいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1301] 管理者により削除されました
2009/05/29 00:42:36

テスト投稿らしいものだったので、削除しました。 テスト投稿はテスト用掲示板にお願いします。
[この投稿を含むスレッドを表示]
[1298] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:(ぱ)こと管理人
2009/05/27 02:24:13

>#自分も特にSmalltalkに思い入れがあるわけではありません^^; ありゃ、そうですか。了解です。 全然完璧に関係ないですが、大昔、fjに高木浩光さんが 「Smalltalk原理主義者を殲滅せよ」なんてことを書いていて(もちろんネタですが)、 今これを探そうとしてGoogleグループを見てみたのですが…Googleグループって、 NewsGroupの検索ができるのだと思っていましたが、いつのまに2ch検索エンジンに?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1297] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:こくぼ
2009/05/26 08:58:11

>こくぼさんには「Smalltalkが不憫で仕方ありません」と言われそうですが、 >職業プログラマである我々が、現状、仕事でSmalltalkを使うことはまあまずないわけで、 >JavaやC++やC#を使うのに「メッセージ」がどうこう言われたら誤解を招く、というのは >わかります。 Smalltalkが不憫っていうのは、SEさんが紹介している説明を見ると まるでSmalltalkが悪いせいでオブジェクト指向が理解されてない みたいな書き方をされてるせいです。 #自分も特にSmalltalkに思い入れがあるわけではありません^^; >とSEさんがおしゃるのか、さっぱりわからないんですけど。 ですよね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1296] Re:コード生成部分について
投稿者:
2009/05/25 19:44:20

見ていただきありがとうございます。 >要点は、文字列以外はコンスタントプールを使わずに、直接定数を >バイトコードの中に埋め込むようにした、ということですよね。 はい >効率を考えてバイトコードではなくワードコード)中に埋め込んでいるそうです。 管理面とスピードを考えて、コードに埋め込みましたが問題なさそうでよかった。 >あと、もしシステムグローバル変数がDVM_Valueを保持しているのなら、 コード生成が一応落ち着いたのでVM部分を見ました。計算スタックはDVM_Value なんですね。VMを複数スレッド起動させるので、VMは極力最小にしようと思って います。その為に、省ける分はがさがさ省いていっています。コンスタントプール も、まさに、文字列を詰め込んだ配列とそのアクセスポインタテーブルのみです。 それと、GCは不要なシステムになります。INT用とdouble用の固定長プール、そして 文字列はstringに任せてしまうのでVMとしてのGCは無くなりました。この部分は VM管理システムで一括管理する予定。コード生成もそうでしたが、必要機能のた めに実行部分は最小に、その結果管理部分が大きくなっています。  新しく組み込んでいる部分をあいまいに表現して申し訳ありません。なにぶん 出来てみないとなんとも言えなくて、絵に描いたもちを説明するのも気が引けて。 その部分はある程度完成するまでお待ちください。構想したものを組み込んで、 自身が確認しないとなんとも^^;  追記、目的ターゲットでは、細かい文字列操作は多量にあると思いますが、長い 文字列は無いと思われますので、stringの管理でも問題は無いと思っています。 しかし、実際やってみての部分は有ります。その時は専用の文字列だけを管理する 処理を組み込む予定です。その場合も文字列だけなのでGCは不要で出来ます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1295] Re:コード生成部分について
投稿者:(ぱ)こと管理人
2009/05/25 01:16:56

> {"push_int_4byte", "i", 1}, // 直接持に変更 > {"push_double_8byte", "d", 1}, // 直接持に変更 要点は、文字列以外はコンスタントプールを使わずに、直接定数を バイトコードの中に埋め込むようにした、ということですよね。 Diksamは、JVMを真似したのと、将来的にバイトコードをファイルに 吐き出すことを考えてコンスタントプールを持ちましたが、 たとえばYARVでは、効率を考えて定数をバイトコード(ていうかこれも 効率を考えてバイトコードではなくワードコード)中に埋め込んでいるそうです。 http://www.atdot.net/yarv/yarvarch.ja.html > {"push_sysval_int", "s", 1}, // システムグローバル変数アクセス用 > {"push_sysval_double", "s", 1}, // > {"push_sysval_str", "s", 1}, // > {"pop_sysval_int", "s", -1}, // > {"pop_sysval_double", "s", -1}, // > {"pop_sysval_str", "s", -1}, // あと、もしシステムグローバル変数がDVM_Valueを保持しているのなら、 実はpush_sysval_intやpush_sysval_doubleのようにインストラクションを 型ごとに分ける必要はありません。 Diksamの場合、スタックはDVM_Valueの配列のくせにこのインストラクションを 分けているのは、将来的にint型ローカル変数は4バイトしか消費しないようにする、 といった改善を入れるときのためです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1294] コード生成部分について
投稿者:
2009/05/24 19:18:12

 コード生成部分を作っています。基本部以外がほとんど新たなプログラムに なっています。下にバイトコードの変更およびコードのディスアセンブラです。  もしお時間が有りましたら見て、何か気になる点が有りますでしょうか? --- 修正したバイトコード ------------ {"push_int_4byte", "i", 1}, // 直接持に変更 {"push_double_8byte", "d", 1}, // 直接持に変更 // 今考えると、リアル値を持つのはまずい? --- 追加したバイトコード ------------ {"push_sysval_int", "s", 1}, // システムグローバル変数アクセス用 {"push_sysval_double", "s", 1}, // {"push_sysval_str", "s", 1}, // {"pop_sysval_int", "s", -1}, // {"pop_sysval_double", "s", -1}, // {"pop_sysval_str", "s", -1}, // -------------------------------------------------------- int main(int p1,int p2) { string[] msg = { "asd","qwe","zzz"}; int[] i1 = {1,2,65537}; double d1; d1 =3.1; } --------------------------------------------------------   ↓ コード生成後のダンプ   ↓   ↓ 上のコード修正で、constデータは文字列だけになりました。 -------------------------------------------------------- 1:*** 関数情報ダンプ ****************** 1:--- int main(int p1, int p2) 1:*** ローカル変数の表示 no = 3 *** 1: 0:string [] msg 1: 1:int [] i1 1: 2:double d1 1:*** 文字列定数 数 = 3 *** 1: 0: "asd" 1: 1: "qwe" 1: 2: "zzz" 1:*** 使用予定のスタックサイズ = 10 1:*** 関数コードのディスアセンブラ size = 45 1: 0 push_string_ptr 0 1: 3 push_string_ptr 1 1: 6 push_string_ptr 2 1: 9 new_array_literal_object 3 1: 12 pop_stack_object 2 1: 15 push_int_1byte 1 1: 17 push_int_1byte 2 1: 19 push_int_4byte 65537 1: 24 new_array_literal_int 3 1: 27 pop_stack_int 3 1: 30 push_double_8byte 3.100000e+000 1: 39 pop_stack_double 4 1: 42 push_int_1byte 0 1: 44 return 1:*** 行情報 数 = 5 *** 1: 3: from 0 size 15 1: 4: from 15 size 15 1: 6: from 30 size 12 1: 8: from 42 size 2 1: 7: from 44 size 1 1:*** end of main() -------------- --------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1293] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/23 13:51:39

>デザインパターンと言うのは、世の中にある数多くのOOで組まれたプログラムの中から、 >共通性のある物を抜き出して分類し、その特徴や利点/欠点を解析する学問的な物です。 >重要なのは解析する能力を付ける事です。 なるほど、「学問的な物です」というのはよくわかりませんが、 おっしゃりたいことはだいたいわかったように思います。 >誰かの分類したパターンと特徴を暗記しても意味はありません。 しかしこれを「意味はありません」と言い切っちゃうのはどうかと。 kitさんが既に書いておられますが、デザインパターンはパターンに名前をつけて プログラマ間のコミュニケーションに使うことに意味があるわけですから。 >ITproのHPの人も言っていますが、「言語」→「実践」→「デザパタ」と進むのが >いいと思います。実践無しでデザパタを見たら、大抵の人は勘違いすると思います。 ここに異論はありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1292] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/23 13:47:59

SEさんが何をおっしゃりたいのかますますわからなくなっていくのですが、 >ちなみに簡単に変更できた例は、 >メモリ上で頻繁に検索するデータが100件から6万件に変わった時の事でした。 >検索にキャッシュやヒストリー機能などあらゆる機能を組み込み高速化しましたが、 >修正したクラスは1つです。もしCの構造化で組んでいたら、修正箇所と影響範囲を >調べるだけで嫌になっていたと思います。 関連する操作やデータをまとめる、というのは普通にモジュール化であって、 私が「疑りぶかい~」で書いたオセロの例の、Cでstaticで隠蔽を行った board.cで達成していることでは? http://kmaebashi.com/programmer/object/othello.html 「疑りぶかい~」を書いたときの私の認識は、 「Cなどでプログラムを書いている普通のプログラマは、staticで情報隠蔽するような  モジュール化は普通に行っているだろう。でもそれは、オブジェクト指向ではない。  オブジェクト指向(C++流の)といえばカプセル化、継承、ポリモルフィズムと言われるけれど、  カプセル化は普通のCプログラマも理解していそうだし、継承やポリモルフィズムに  至る前にマルチプルインスタンスを理解しなければいけないのに、世間にあふれる  オブジェクト指向の説明からはそこがすっぽり抜けている。  多くの人がここで引っかかるように思うので、このミッシングリンクは埋めておく  べきではないか」 というものです。 この認識がズレている、という批判ならお受けしますけれども。 マルチプルインスタンスのさらに手前の事例を持ってきて、オブジェクト指向の 成果だと言われても…… 継承の話はどこにいったんでしょうか。 いや、「世間のCプログラマはstaticで実装を隠蔽するような気の効いたことは していない。だからお前の認識はズレているのだ」ということならそうなのかも しれませんけど(1ソースファイル1関数、という規約のプロジェクトとかって、 今でもあるんでしょうか)。 >普通のLoggerは、staticのフィールド変数として作成して直接使用するため、Logger自体を >メソッドの引数にして使用する事は少ないと思います。 うーん、Loggerくらいならstaticでもかまわないとは確かに思いますけれど、 私ならアプリケーションのインスタンスのフィールドに持ちますね。 オセロの例なら、Boardクラスで障害発生時とかのログを残すとして、Loggerは Boardに持たせます。名人戦のBoardだけ障害発生時の対応が違ったりするかも 知れませんし。よって、BoardのコンストラクタかsetLogger()メソッドの 引数でLoggerを渡すことになります。 >敢えてLoggerを例にするとすると、 >void write(Logger l){} >なら、 >class Logger{ >  void write(){} >} >にすべきと言う事です。 ええと、write()メソッドがログを吐くメソッドなら、 >class Logger{ >  void write(){} >} となるのは当たり前だと思うんですが……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1291] Re:オブジェクト指向の概念の発明者は誰ですか?
投稿者:(ぱ)こと管理人
2009/05/23 12:26:48

件名変えました。 >アランケイの「メッセージ指向」は、C++の登場した当たりから軽視されるようになっていて、 >現在のオブジェクト指向の実装や環境から考えると、誤解しやすい物になっているからです。 >(ぱ)さんも「ただの関数呼び出し」と言っていますが、私もそう思います。 こくぼさんには「Smalltalkが不憫で仕方ありません」と言われそうですが、 職業プログラマである我々が、現状、仕事でSmalltalkを使うことはまあまずないわけで、 JavaやC++やC#を使うのに「メッセージ」がどうこう言われたら誤解を招く、というのは わかります。 で、当のsumimさんのページにはまさにそういうことが書いてあるわけで、 >なお、この文脈の「オブジェクト指向」において、メッセージングはぜんぜん関係ない >無用のもの and/or 動的性実現のための(仮想関数より効率の悪い)実装のひとつに >過ぎない…ということを強く意識する必要があります。ケイの影響で「オブジェクト >指向=メッセージ」と脳に染みついている人には酷かもしれませんが、いっそ排除して >考えたほうがすっきりしますし、可能な限りそうすべきです。 >しがらみのない初学者へのレクチャーに際しては、ぜひとも「オブジェクトにメッセー >ジを送って…」とか「世の中のあらゆるものを(ry」なんて説明は後々無用な混乱を >招くだけなので、やめて欲しいと思います。 なぜこのページについて >これもひどい内容ですね。 とSEさんがおしゃるのか、さっぱりわからないんですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1289] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/22 16:57:12

デザインパターンと言うのは、世の中にある数多くのOOで組まれたプログラムの中から、 共通性のある物を抜き出して分類し、その特徴や利点/欠点を解析する学問的な物です。 重要なのは解析する能力を付ける事です。 誰かの分類したパターンと特徴を暗記しても意味はありません。 ただ私もGoFのパターンは見ました。学者的で実務に使えるのは2割程度だと思いましたが。 ITproのHPの人も言っていますが、「言語」→「実践」→「デザパタ」と進むのが いいと思います。実践無しでデザパタを見たら、大抵の人は勘違いすると思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1288] Re:>(ぱ)こと管理人さん
投稿者:こくぼ
2009/05/22 16:36:27

>アランケイの「メッセージ指向」は、C++の登場した当たりから軽視されるようになっていて、 >現在のオブジェクト指向の実装や環境から考えると、誤解しやすい物になっているからです。 >(ぱ)さんも「ただの関数呼び出し」と言っていますが、私もそう思います。 >歴史に関してはウィキペディアに詳しく記載されています。 あぁ…。抽象データ型のオブジェクト指向が現代のオブジェクト指向だと解釈されているのですね。 そこらへんの各人のオブジェクト指向への認識の違いを理解していただくことも含めて sumimさんの説明ページへとリンクしたつもりでしたが伝わってないみたいで…。 #Wikipediaの説明も見ましたがあれではSmalltalkが不憫で仕方ありません >オブジェクト指向自体の話ではありませんが、オブジェクト指向の間違いやすい所に関しては、 >以下の記載がかなりいい所をついていると思います。(全て賛成できる訳ではありませんが) >http://itpro.nikkeibp.co.jp/article/COLUMN/20060921/248617/?ST=develop&P=1 ザッと見ました。 このページを見る限りではSEさんが例示しておられる 実装継承を使ったオブジェクト指向プログラミングを推奨しているわけではなさそうですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1287] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/22 16:25:01

>関数等に切り出されて一箇所にまとめられていれば修正するのは一箇所です。 >ここまではオブジェクト指向は関係ありません。 ここがミソです。1つの関数を考えた場合はそうですが、関数群で考えると違います。 例えばファイル操作を考えてみましょう。 クラスなら以下のようになるとします。 class File{   public void open(){}   public void read(){}   public void write(){}   public void close(){} } これなら明確です。ファイルからメモりに変わっても簡単に変更できるでしょう。 しかしCの構造化なら関数同士の関連はありません。 そのため、もしかしたらread()は業務ロジックに組み込まれ関数化されていないかもしれませんし、 write()は3つに分割されているかもしれません。例がファイルなのでそんな簡単な間違いは しないと言うかもしれませんが、もしこれが業務ロジックなら簡単に判断出来ないかもしれません。 これが関数化(プロセス中心アプローチ(POA)または、データ中心アプローチ(DOA))と、 クラス化(オブジェクト中心アプローチ(OOA))の違いです。 POA、DOA、OOAの特徴と違いについては、以下のサイトがよく分かります。 (分かりにくい表現もありますが) http://itpro.nikkeibp.co.jp/article/COLUMN/20061019/251255/ ちなみに簡単に変更できた例は、 メモリ上で頻繁に検索するデータが100件から6万件に変わった時の事でした。 検索にキャッシュやヒストリー機能などあらゆる機能を組み込み高速化しましたが、 修正したクラスは1つです。もしCの構造化で組んでいたら、修正箇所と影響範囲を 調べるだけで嫌になっていたと思います。 Loggerのようないわゆる「横断的関心事」はOOに適さないので例としては良くないと思いますが、 普通のLoggerは、staticのフィールド変数として作成して直接使用するため、Logger自体を メソッドの引数にして使用する事は少ないと思います。 敢えてLoggerを例にするとすると、 void write(Logger l){} なら、 class Logger{   void write(){} } にすべきと言う事です。 >
[この投稿を含むスレッドを表示] [この投稿を削除]
[1286] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/22 15:27:15

>どこがひどいと思われるのでしょうか? >「この当たりの話は知っています」と書かれていることから類似のWebページなどをご存知なのでしょうか。 >できればその情報のソースを教えていただきたいです。 >(自分的にこの手の情報はsumimさんの日記くらいしか知らないので) アランケイの「メッセージ指向」は、C++の登場した当たりから軽視されるようになっていて、 現在のオブジェクト指向の実装や環境から考えると、誤解しやすい物になっているからです。 (ぱ)さんも「ただの関数呼び出し」と言っていますが、私もそう思います。 歴史に関してはウィキペディアに詳しく記載されています。 >#できれば他にもSEさんが比較的マシだと思ってる本やWebページを >#いろいろ教えていただきたいところですが オブジェクト指向自体の話ではありませんが、オブジェクト指向の間違いやすい所に関しては、 以下の記載がかなりいい所をついていると思います。(全て賛成できる訳ではありませんが) http://itpro.nikkeibp.co.jp/article/COLUMN/20060921/248617/?ST=develop&P=1
[この投稿を含むスレッドを表示] [この投稿を削除]
[1285] Re:>(ぱ)こと管理人さん
投稿者:yuya
2009/05/22 11:47:06

懐かしいお名前がいっぱいでうれしくなりました。 kitさんも >でも、そもそもデザインパターンの多くは、それなりのプログラマーだったら、 >自分で似たようなものを必要に応じて考えて既に使っているものですよね。 と書かれていますが、SEさんのご意見が、 「天下りに与えられたパターンを憶える(=学習する?)んじゃなくて、 自分で同じものを作ってみるなりしてきちんと理解する(=解析する?)べきだ」、 ということならば、賛成ですけどね。 議論の行く末が気になるので、SEさんにはまた登場していただきたいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1284] Re:>(ぱ)こと管理人さん
投稿者:kit
2009/05/22 10:49:48

>ちょっと穿って解釈すると、 > > ちなみにデザインパターンは学習(に値)する(ような)物ではなく、 > (こんなものを調子こいて使ってしまうとソースが読みにくくなって > 必死に)解析する(ハメになるような)物です。 > >という意味なんでしょうか。 > >そういう趣旨ならわからなくはないし、部分的には賛同しないでもないのですが、 なるほど。 勉強したばかりで調子にのって *必要ないのに* 使いすぎると、問題は問題ですね。 でも、そもそもデザインパターンの多くは、それなりのプログラマーだったら、 自分で似たようなものを必要に応じて考えて既に使っているものですよね。 各種パターン本の意義は、そういうものにきちんと名前をつけて、いちいち説明 しなくても意思の疎通を可能にするという側面が大きいわけです。これにはソース 中の名前づけを標準化して、可読性を高めることを含みます。 したがって、経験のあるプログラマーにとって、デザインパターンの学習という のは、既知の設計手法について、規範となる名前を学習するという意味になります。 また、デザインパターンとして標準化された名前を使うことによって、ソース等を 解析することなく (すなわち、名前を見ただけで) モジュールの役割を理解する ことが可能になります。 また、もちろん初学者にとっては、設計パターンを自分で一から考える手間を省く という学習の意義があります。 というわけで、もしそういう意味だったとしても、やっぱり賛成できませんねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1283] Re:疑い深い・・・
投稿者:(ぱ)こと管理人
2009/05/22 02:16:37

横から口を出しますけど、 >>そもそも OO (というか継承-派生というシステム) のおいしいところは >>・「基底クラスを使う人」と「派生クラスを作る人」が分離できる >>・基底クラス(のメンバー)を使う人は、派生クラスについて知らなくていい >>・派生クラスを作る人は、基底クラス側で期待している動作(=契約)に反しない限り、 >> 自動的に正しく使ってもらえる、と判断してよい >これが利点ですか?ちょっと他人に説明するのが難しいです。 前回私が例に出したLoggerクラスで考えると、 >>・「基底クラスを使う人」と「派生クラスを作る人」が分離できる 「Loggerクラスを使う人」は、logger.write()のようなメソッドを単に呼べばよく、 「ログをファイルに出力するFileLoggerクラスを作る人」と分離できる。 >>・基底クラス(のメンバー)を使う人は、派生クラスについて知らなくていい 「Loggerクラスを使う人」は、logger.write()のようなメソッドを単に呼べばよく、 FileLoggerクラスについては知らなくていい。 >>・派生クラスを作る人は、基底クラス側で期待している動作(=契約)に反しない限り、 >> 自動的に正しく使ってもらえる、と判断してよい 「FileLoggerクラスを作る人」は、基底クラス側で期待している動作(=契約)に 反しない限り、自動的に正しく使ってもらえる、と判断してよい わけで、私から見れば、774RRさんはごく普通にオブジェクト指向の利点を 挙げていると思うんですけど。 もちろん、何にでも利点と欠点はあるものですし、その重み付けは用途によって 変わります。SEさんの過去の業務で実装継承がすごく役に立ったのなら、 それはそれで興味深いことです。 だからこそ、実際に役に立ちそうな現実的な例を挙げていただきたいと思いますし、 上記774RRさんが挙げられたような利点をあまり重視しておられないように見える割に、 [1260]のUpperStackにおいて、getUpper()のようなメソッドを作らずにget()を オーバーライドしていたり、 [1270]で >>「要素をgetする側は、大文字が欲しいとき、そのことを意識しないで済む」 >>ということにしたいのでしょうか? という問いに対して >そうです。 と答えていたり、 同じく[1270]で new LinkedHashMap<String, String>()の戻り値を Map<String, String>型の変数に代入したりしている 意図がさっぱりわからないわけです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1282] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/22 01:53:22

kitさん、おひさしぶりです。 >>>ちなみにデザインパターンは学習する物ではなく、解析する物です。 >> >>?? >>すみません、仰っておられる意味がわかりません…。 > >素直に解釈すると、SEさんは GoF本や PofEAA あたりも読んだことがないって >ことになります (こういった本を読むこと == デザインパターンを学習すること >ですから)。 私にもSEさんのおっしゃる意味はよくわからないのですが、ちょっと穿って解釈すると、  ちなみにデザインパターンは学習(に値)する(ような)物ではなく、  (こんなものを調子こいて使ってしまうとソースが読みにくくなって  必死に)解析する(ハメになるような)物です。 という意味なんでしょうか。 そういう趣旨ならわからなくはないし、部分的には賛同しないでもないのですが、 もしそういう意図なら、もっとわかりやすく書いていただきたいです……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1281] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:
2009/05/21 21:05:59

>こちらの返信が遅くなってしまいました。 いえいえ、お返事いただけるだけで嬉しいので、気にしないでゆっくりして下さい。 >(私の感覚では)かなり実用的な問題でして。 了解しました >また、ヘッダファイルの依存関係が漏洩するという問題もあるでしょう。 >あるライブラリがウインドウに絵を描いたりするのでprivateメンバで >windows.hで定義されている型などを使っていたりすると、それを使う人にまで >もれなくwindows.hがプレゼントされ名前空間が汚染されてしまったりとか。 賛同です。これは問題ですね。OOP以前C言語の時は、それはキッチリとヘッダーが きれいに分割され必要な所だけが#includeされていたのですが。OOPになって、 必要も無いようなヘッダーが次から次へと#includeされているのを見るのは、 正直止めてほしいと思っています。特にVCはひどい、プリコンパイルヘッダーを 作ったのは苦肉の策ではないかと疑ってしまうほどです。  しかし、現実に自身が作っている内容でも、結局多くのヘッダーが#include してしまっているのを見るにつけ、何かの対策がほしいと思います。 >これを問題と思わない人が多かったようなので、私のような心配をするのは >少数派なのかもしれませんけれども。 私もそうですが、目をつぶっているだけなのかも知れません。  ちょっと真剣に考えて見ます。軽はずみな返事をしたくないと思っているので ちょっと期間をくださ。今は、作っている言語仕様に頭がいっぱいなんです。 いま佳境に入ってて、最近はプログラムではなく仕様書の書き込み書き直しばか りしています。楽しくもあり苦しくもある時間です。  いやほんと、こんな仕様を発表したら、けちょんけちょんにけなされっるので はないかとか、本当に良いんだろうかとか、でも当面第1弾はこれしかないよな~ とか、悩んだりしています。   今作っている言語そしてシステムの最大の目的は。   「簡単なルールを持った言語で、いかに複雑な処理を簡単に書けるか」 なので、熟練のプログラマーのほうが抵抗が大きいのではないかと…  プログラミング言語というものは論理的に整然と矛盾が無く、どんな形でも 記述可能であり。その中においてさえ、書きやすくセーフティーな環境を提供し 見やすさを追求している、と私は思っています。でも、私が目指しているのは。 記述目的を限定することで、自由が無くなる分、普通では考えられないような 記述で複雑なものを簡単に記述すシステムを出してみたい。  大風呂敷はこのへんで終わって、早く実物が出来るようにがんばります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1280] Re:>(ぱ)こと管理人さん
投稿者:kit
2009/05/21 10:32:18

>>ちなみにデザインパターンは学習する物ではなく、解析する物です。 > >?? >すみません、仰っておられる意味がわかりません…。 素直に解釈すると、SEさんは GoF本や PofEAA あたりも読んだことがないって ことになります (こういった本を読むこと == デザインパターンを学習すること ですから)。 そう解釈していいんですかね?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1279] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:(ぱ)こと管理人
2009/05/21 01:45:56

SEさんとの議論がアツいので、こちらの返信が遅くなってしまいました。 > カプセル化という言葉に対して、きっちりとした完全な意味を求めてるのだ >ろうと思いますが、私はそこまでのことを意識してこの言葉を使っていません。 ええと、用語定義の問題と言うよりは、(私の感覚では)かなり実用的な問題でして。 > 必要なこと意外一切情報を出さないほうがいいのか。内部がある程度想像 >できるほうがいいのか?Cはたとえ使えなくともクラスのデータやメソッドが見 >える。これが良いか悪いかでしょう。私は後者のほうが気分的には良いです。 チームで開発するとき、ライブラリとそれを使うアプリケーションがあったとして、 これらを平行して開発することがあります。そういう場合、ライブラリの ヘッダファイルだけ先に作ってしまえばアプリケーション側のコンパイルが通せますが、 その時、空実装のメソッドを暫定で書いて後で差し替えるような作業は バージョン管理が面倒になるので避けたい。また、ヘッダファイルはドキュメント的な 性格も大きいですから、ここに実装やprivateメンバを書いてごちゃごちゃして しまうのも避けたい。 また、ヘッダファイルの依存関係が漏洩するという問題もあるでしょう。 あるライブラリがウインドウに絵を描いたりするのでprivateメンバで windows.hで定義されている型などを使っていたりすると、それを使う人にまで もれなくwindows.hがプレゼントされ名前空間が汚染されてしまったりとか。 ……という話題が昔JavaHouseであったとき、 http://java-house.jp/ml/archive/j-h-b/048357.html#body http://java-house.jp/ml/archive/j-h-b/048360.html#body これを問題と思わない人が多かったようなので、私のような心配をするのは 少数派なのかもしれませんけれども。 > 言語の設計において、理想的なものを作っていくのもあります。私の場合は >目的が実現できれば簡単なものでいいと思って設計しています。その代表が >#defineです。古い仕様で問題点も内包しますが、実に使いやすく融通が利きます。 >今では#defineはあまり良くないとされていますが、私は利点を選びました。 これは同意です。「わかって使う」分には、#defineは便利ですよね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1278] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/21 00:40:14

>大文字小文字の例が悪かったのか、話がそこから進まないようです。 では、よい例を出してもらえませんか。具体的な例なしでこの手の話をしても 意味がありません。 774RRさんへの返信に >例えば総合試験で性能目標に達しなかった場合、従来の方法では普通は大変更に >なりますが、オブジェクト指向の場合、一部のクラスの取得処理を変更しただけで >修正できた例もあります。 とありますが、これも具体的にどういうケースだったのかわかりません。 普通に考えて、どこかの処理がボトルネックになっていたのなら、そこだけ 書き直せば速くなるでしょう。もちろん、その処理がプログラムのあっちこっちに コピペされていれば大変更になるでしょうが、関数等に切り出されて一箇所に まとめられていれば修正するのは一箇所です。ここまではオブジェクト指向は 関係ありません。 オブジェクト指向であったがゆえにうまくいった、とのことなので、 関数化ではうまくいかないケースだったのでしょう。どういう理由で、関数化では うまくいかず、オブジェクト指向(実装継承?)でうまくいったのでしょうか。 仕事のソースをここに貼ることができないのはわかっていますが、概要だけでも 教えてもらえませんか。興味深いので。 >遠くの所でnewした特有の処理の入ったクラスを、引数で使い回すのは、 >構造化のスタンプ結合的で、オブジェクト指向的には良くない設計です。 オブジェクト指向の最大の特徴のひとつであるポリモルフィズムは、遠いところで newしたオブジェクトのメソッドを呼ぶと、呼ぶ側が意識しなくても、 そのオブジェクトに応じたメソッドが呼び出される、というものですよね? デザインパターンなどでは生成に関するパターンだけでいくつもあって、 うちいくつかは、具体的なクラスが何であるかを意識させないようにするための ものですし、DI(Dependency Injection)なんかも考え方はそっち方面です。 まあ、この手のことは、当面用途もないのに調子に乗って柔軟性を求めると ソースが追えなくなってしまうので、私はあまり好きではないのですけれど。 ありがちな例では、たとえばログを出力するLoggerクラスをabstractクラスもしくは interfaceとして作って、それを継承またはimplementsしてファイルに吐くLoggerや syslogに吐くLoggerを作ったりしますが、これは、遠く離れたところでnewした Loggerを引数等で持って回ることになると思うんですが。 >オブジェクト指向の場合は処理は関連するデータと共にクラスに >まとめられるため、その引数を必要とするメソッドを、引数のクラス内 >に実装できるか検討すべきです。 意味がわかりません。 さっきのLoggerの例で言えば、Loggerクラスを引数として受け取るメソッドは Loggerを使うアプリケーションですが、アプリケーションのメソッドを Loggerクラスの中に作れ、という主張……ではないですよね。 >>ひとつ伺いたいのですが、SEさんはどんな本でオブジェクト指向の勉強をされたの >>でしょうか。 こくぼさんからも質問が出ていますが、私もSEさんが「比較的マシ」だと思ってる 本やWebページを教えていただきたいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1277] Re:>(ぱ)こと管理人さん
投稿者:こくぼ
2009/05/20 18:32:43

>ちなみにデザインパターンは学習する物ではなく、解析する物です。 ?? すみません、仰っておられる意味がわかりません…。 >これもひどい内容ですね。 詳しく教えていただきたいのですが、 どこがひどいと思われるのでしょうか? 「この当たりの話は知っています」と書かれていることから類似のWebページなどをご存知なのでしょうか。 できればその情報のソースを教えていただきたいです。 (自分的にこの手の情報はsumimさんの日記くらいしか知らないので) >これならまだ「ウィキペディア」の「オブジェクト指向プログラミング」の >方がマシです。 >一度読んでみてはいかがですか? ありがとうございます。 読んでみます。 #できれば他にもSEさんが比較的マシだと思ってる本やWebページを #いろいろ教えていただきたいところですが
[この投稿を含むスレッドを表示] [この投稿を削除]
[1276] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/20 15:47:40

>デザインパターンを学習されているなら継承を使う機会は減ると思うんですけど。 >#減るというか注意深くなるというか デザインパターンは知っています。 ちなみにデザインパターンは学習する物ではなく、解析する物です。 >ちなみにこのページはオブジェクト指向を学ぶうえにおいてとても参考になります。 >一読してみてください。 >http://d.hatena.ne.jp/sumim/20040525/p1 これもひどい内容ですね。 この当たりの話は知っていますが、参考にするのはまずいでしょう。 これならまだ「ウィキペディア」の「オブジェクト指向プログラミング」の 方がマシです。 一度読んでみてはいかがですか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1275] Re:疑い深い・・・
投稿者:SE
2009/05/20 15:31:59

>俺も (ぱ) 氏ももっとマクロな=大規模プログラムでの応用の話をしているわけです。 >そういうレベルでは、提示のコードのような派生はうまくいきません。 なぜ大規模プログラムでうまくいかないのかが分かりません。 実際、大規模プログラムで使用していますが、効果が出ています。 例えば総合試験で性能目標に達しなかった場合、従来の方法では普通は大変更に なりますが、オブジェクト指向の場合、一部のクラスの取得処理を変更しただけで 修正できた例もあります。 オブジェクト指向ではオブジェクト単位であるため、大きいレベルから小さいレベル まで対応できるのが特徴です。 >そもそも OO (というか継承-派生というシステム) のおいしいところは >・「基底クラスを使う人」と「派生クラスを作る人」が分離できる >・基底クラス(のメンバー)を使う人は、派生クラスについて知らなくていい >・派生クラスを作る人は、基底クラス側で期待している動作(=契約)に反しない限り、 > 自動的に正しく使ってもらえる、と判断してよい これが利点ですか?ちょっと他人に説明するのが難しいです。 私の例では、処理に大修正が入った場合(例えばDB変更や、ローカルファイルから 通信を使ったリモートファイルへの変更)、これだけの修正で済みますなどと 言えますが、上記の場合はどう説明しますか? >んで、マルチプルインスタンスの件のほうはもういいのでしょうか? >俺としては既に書いたとおり「対象読者層が異なる」というだけの話だと思っております。 了解しました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1274] Re:>(ぱ)こと管理人さん
投稿者:こくぼ
2009/05/20 14:40:28

スタックの例とかあんまり細かく見ずにコメントしますが…。 >それぞれ用途が違いますが、オブジェクト指向特有で強力なのが2,3です。 >別に全て2でやれと言っているわけではなく、2の使い方が出来るのが >利点だと言っている訳です。 >... >つまり、分かりやすいとか間違えやすいとか言う話は別として、 >4種類の変更方法を選択できるため、再利用性が高いと言っている訳です。 そもそも継承というメカニズムを使うのが間違いのもとになっちゃうような。 デザインパターンを学習されているなら継承を使う機会は減ると思うんですけど。 #減るというか注意深くなるというか >本は色々読みましたが、全てが同意できる物はありません。 となると、ここで力説されていらっしゃる実装継承を使ったOOP をどこから学ばれたのか興味深いですね。 ちなみにこのページはオブジェクト指向を学ぶうえにおいてとても参考になります。 一読してみてください。 http://d.hatena.ne.jp/sumim/20040525/p1
[この投稿を含むスレッドを表示] [この投稿を削除]
[1273] Re:>(ぱ)こと管理人さん
投稿者:SE
2009/05/20 13:42:06

大文字小文字の例が悪かったのか、話がそこから進まないようです。 修正方法には以下の4つがあります。 ----------------------------------------------------------- 1.別名でメソッド追加  別々の処理として追加したい場合に使用 2.継承  関連処理をまとめて変更したい場合に使用 3.分割して親クラスを継承  関連処理をグループ化して、片方のグループを変更したい場合に使用 4.staticメソッドを作成  関連のない任意の場所で使用したい場合に使用 ----------------------------------------------------------- それぞれ用途が違いますが、オブジェクト指向特有で強力なのが2,3です。 別に全て2でやれと言っているわけではなく、2の使い方が出来るのが 利点だと言っている訳です。 間違いやすいとか分かりにくいと言うのは、実装者のスキルの話で、 よく見て追えば分かるし、変な設計をすれば分かりにくくなります。 遠くの所でnewした特有の処理の入ったクラスを、引数で使い回すのは、 構造化のスタンプ結合的で、オブジェクト指向的には良くない設計です。 オブジェクト指向の場合は処理は関連するデータと共にクラスに まとめられるため、その引数を必要とするメソッドを、引数のクラス内 に実装できるか検討すべきです。 つまり、分かりやすいとか間違えやすいとか言う話は別として、 4種類の変更方法を選択できるため、再利用性が高いと言っている訳です。 >ひとつ伺いたいのですが、SEさんはどんな本でオブジェクト指向の勉強をされたの >でしょうか。 本は色々読みましたが、全てが同意できる物はありません。 殆どが、オブジェクト指向と言いつつ、デザインパターンの説明本や、UMLの説明本、 プログラミング言語の小技本、翻訳がおかしい本、中にはWEBアプリケーションの 作り方本もありました。 WEBサイトも同意できる物もあれば、出来ない物もあり、半々ぐらいです。 オブジェクト指向関係の書籍のひどさは、(ぱ)さんもご存じだと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1272] Re:疑い深い・・・
投稿者:774RR
2009/05/20 11:17:08

# 題名にハンドル入れるのやめてほしい > SE 氏 変えちゃいました # [1269] に返信してもよかったんだけどこっちにつなぐことにする [1269] > これを次のように変更します。1行で済みます。 ものすごく近視眼的コメントがついていて思わず苦笑してしまったのだけど、 *** そういう範囲でしか変更がありえない **** のであれば [1260] [1269] で提示のような修正もまぁあり、の範疇に収まります。 が、実世界においてはそういう局所な話ですまないことのほうが多く、 俺も (ぱ) 氏ももっとマクロな=大規模プログラムでの応用の話をしているわけです。 そういうレベルでは、提示のコードのような派生はうまくいきません。 そもそも OO (というか継承-派生というシステム) のおいしいところは ・「基底クラスを使う人」と「派生クラスを作る人」が分離できる ・基底クラス(のメンバー)を使う人は、派生クラスについて知らなくていい ・派生クラスを作る人は、基底クラス側で期待している動作(=契約)に反しない限り、  自動的に正しく使ってもらえる、と判断してよい という点にあるのであって、 決して「ソースの再利用のためのテクニック」ではないのです。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&thread=270 このへんとか。 基底クラスを使っている側にとって 基底クラス側が本来期待している挙動と異なる動きをするような派生クラス というのはまずいのです。 しかも、基底クラスユーザと派生クラス作者はたいてい別人なのです。 基底クラスを使うソースファイルと派生クラスを作るソースファイルも別ファイルなのです。 [あたかも便利そうに見える] [が、正しく設計されているとは必ずしも言い切れない] 派生クラスを安直に作り、使ってしまうと 異なる開発者がいて、複数のファイルから構成されていて、各プログラマは自分の担当範囲しか理解しきれない という大規模開発では見えにくい/直しにくいバグの元となります。 LSP (Liskov Substitution Principle) という概念も、この辺から来ています。 んで、マルチプルインスタンスの件のほうはもういいのでしょうか? 俺としては既に書いたとおり「対象読者層が異なる」というだけの話だと思っております。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1271] Re:>(ぱ)こと管理人さん
投稿者:(ぱ)こと管理人
2009/05/20 03:49:06

# どうもサーバの調子が悪いようで…… まずSEさんにお願いですが、投稿に返信を付ける際には各投稿の右上にある 「返信」リンクを使ってください。そうすることでスレッドがつながりますので [この投稿を含むスレッドを表示]をクリックすると関連する投稿をまとめて 読むことができます。 この掲示板の上のほうにある「スレッド順インデックス」をクリックすると、 他の投稿はちゃんとスレッドがつながっているのに、SEさんの投稿だけ 切り離されていることがわかるでしょう。 http://kmaebashi.com/bbs/thread.php?boardid=kmaebashibbs >>まあ、オセロの例で注記したように、マルチプロセスにはオブジェクト指向と似た面は >>ありますけど。「その論理で行くと」の「その論理」がどういう論理か、教えて >>いただきたいです。 >「マルチプルインスタンスがオブジェクト指向」と言う論理です。 >マルチプルインスタンスと言うのが何を指すのがよく分かりませんが、 >状態(内部の変数の値)の違う複数の処理群(クラス)と解釈しました。 「状態(内部の変数の値)の違う複数の"オブジェクト"」ですよね? まあ、クラスベースのオブジェクト指向ではオブジェクトの生成の雛形として クラスを使うわけで、「疑りぶかい~」ではクラスベースのオブジェクト指向の 話しかしていないわけですけれども。 実のところオブジェクト指向という用語は定義などないも同然なのですが、 「状態(内部の変数の値)の違う複数の"オブジェクト"を持てること」が たいていのオブジェクト指向の定義の必要条件である、ぐらいのことはたぶん 言ってもよいでしょう。 で、そうするとなぜ「マルチプロセスやマルチスレッドはオブジェクト指向になる」 のですか? 「DOSを乗っけたPCを2台もってこれば同時に複数のプログラムを動かせるので、 DOSはマルチプロセスだ!」という主張は誰もしないと思いますけど。 >>・Stackが引数かなにかで渡されたとき、本家StackなのかUpperStackなのかわからなくて危険。 >引数の型を見れば分かると思います。 void hoge(Stack s) { …… } というメソッドがあったとき、sがStackなのかUpperStackなのかは 「わからない」と思いますが? >>・別の誰かがLowerStackを作ったら、いつかマージするの? >もし別機能として作るなら、Stackを継承してLowerStackを作ります。 >例えば大文字にした後に先頭に0を付加するような、UpperStackの処理結果に追加する物なら、 >UpperStackを継承して作ります。 >すでにLowerStackが出来てしまっているならマージしません。 で、同一インスタンスのスタックに放り込んだデータについて、ある場所では 大文字で取り出したいし、ある場所では小文字で取り出したい、という場合、 どのクラスを使えばよいのですか? >>「要素をgetする側は、大文字が欲しいとき、そのことを意識しないで済む」 >>ということにしたいのでしょうか? >そうです。 だとすれば比較対象にget(boolean up)を持ってきているのはおかしいですね。 get(boolean up)を使う人は、大文字が欲しいとき、意識して引数にtrueを 渡さなければならないからです。 774RRさんへの返信に >ダウンキャストでなく、newするときに新しいクラスを使うと考えてください。 とありますが、(かなり離れた場所でnewされたかもしれない)Stackが UpperStackなのかStackなのかを意識しなければ、UpperStackのget()を 便利に使うことはできません。SEさんの主張は矛盾しています。 >>この改修により、プログラムにUpperStackという「異物」が実行時に紛れ込むわけで、 >>「Stackにputしたんだから、当然同じものがgetできるだろう」と思い込んでいる >>既存コード(Stackそのものを含む)にはおもいっきり影響を与えます。 >既存コードはソースに手を入れないので、影響はないと思いますが。 既存コードに引数でUpperStackを渡したら、入れたものを勝手に大文字に 変換するおかしなStackが紛れ込むことになります。ここではそういうことを 書いています。 >もう少し分かりやすい例をあげます。 Javaのコレクションクラスライブラリは、StackがVectorを継承していたりして いろいろトホホなので、「良い例」として出せるものではないと思います。 現実的に許容範囲内の例ではあるかもしれませんけど。 で、LinkedHashMapやTreeMapですが、これらがHashMapを継承してしまったために、 ・同じコレクションに対し、ある時は入力順に表示したいし、ある時は ソートして表示したい、という場合どうすればよいのか? (要件としてはすごくありそうだと思いますけれども) ・サブクラスにアクセスさせるために、HashMapのフィールドであるtableが  パッケージアクセスになってしまっているがこれはカプセル化の破壊では  ないのか。 (protectedにしなかったのはSunのエンジニアの良識だと思います) ・ていうかLikedHashMapではaddEntryとかcreateEntryとかパッケージアクセスの メソッドをばんばんオーバーライドしているけれど大丈夫か(スーパークラスの 実装に強く依存している)。 といった問題があるわけです。 それでもまあなんとか「現実的に許容範囲」なのは、オーバーライドした メソッドが、スーパークラス側のメソッドに対し「最低限同等の責務を果たす」と いうオーバーライドにおける大原則を守っているからでしょう。 その点においてもSEさんのUpperStackはだめです。同じget()でありながら、 勝手に大文字に変換してしまうためです。 で、 >Map<String, String> mp = new LinkedHashMap<String, String>(); ここでMapに代入しているのはなぜですか? 入力順に出てくることを期待するのなら、LinkedHashMapのまま持ち歩くほうが 安全です。あるMapがLinkedHashMapのつもりだったのに実はそうでなかった、 というケースは、プログラムが大きくなって、newする場所と使う場所が離れれば 離れるほどいくらでも発生することです。そうなってしまえば、入力順に 取り出せないのですから致命的な上、コンパイルエラーどころか実行時のエラーも出ず、 黙って間違った順番でデータを吐き続けることになります。 これを避けるには、ダウンキャストするか、instanceofでクラスを確認する 必要があるでしょう。危険ですけれども。774RRさんがおっしゃっているのは そういうことです。 Mapに代入するメリットと言えば、たとえばMapの中身をダンプする void dumpMap(Map m);というメソッドに対し、LinkedHashMapを渡せば 入力順に表示されるしTreeMapを渡せばソートして表示される、という動きを 期待したいときでしょう。でもこれは、dumpMap()という既存メソッドに 新たに開発したオブジェクトを混入させることに他ならず、それでうまく 動くかどうかは保証の限りではありません。『「異物」が実行時に紛れ込む』と 書いたのはそういうことです。 # これをうまく動かすためには、やはり先ほどの「オーバーライドにおける大原則」 # を守る必要があるわけです。 で、 >ひとつ伺いたいのですが、SEさんはどんな本でオブジェクト指向の勉強をされたの >でしょうか。 これについては答えていただけないのでしょうか。ぜひ書名を教えて欲しいのですけれども。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1270] >(ぱ)こと管理人さん
投稿者:SE
2009/05/19 16:21:52

>まあ、オセロの例で注記したように、マルチプロセスにはオブジェクト指向と似た面は >ありますけど。「その論理で行くと」の「その論理」がどういう論理か、教えて >いただきたいです。 「マルチプルインスタンスがオブジェクト指向」と言う論理です。 マルチプルインスタンスと言うのが何を指すのがよく分かりませんが、 状態(内部の変数の値)の違う複数の処理群(クラス)と解釈しました。 >そこでわざわざ継承してクラスを作ったって、以下のような問題が起きるだけです。 >・Stackが引数かなにかで渡されたとき、本家StackなのかUpperStackなのかわからなくて危険。 引数の型を見れば分かると思います。 >・別の誰かがLowerStackを作ったら、いつかマージするの? もし別機能として作るなら、Stackを継承してLowerStackを作ります。 例えば大文字にした後に先頭に0を付加するような、UpperStackの処理結果に追加する物なら、 UpperStackを継承して作ります。 すでにLowerStackが出来てしまっているならマージしません。 >「要素をgetする側は、大文字が欲しいとき、そのことを意識しないで済む」 >ということにしたいのでしょうか? そうです。 >この改修により、プログラムにUpperStackという「異物」が実行時に紛れ込むわけで、 >「Stackにputしたんだから、当然同じものがgetできるだろう」と思い込んでいる >既存コード(Stackそのものを含む)にはおもいっきり影響を与えます。 既存コードはソースに手を入れないので、影響はないと思いますが。 新たに作るコードはどちらを使うか意識する必要はありますが。 >上のほうで『実のところ「要素を大文字に変換して返すスタック」がどんな時に >役に立つのか想像できません』と書きましたが、結城浩さんが「例は嘘をつかない」 >と書いておられるように、こういうところで現実のプログラムに即した適切な例が >出てこないなら、おそらくそれは考え方のほうが間違っています。 もう少し分かりやすい例をあげます。 --------------------------------------------------------------------- Map<String, String> mp = new HashMap<String, String>(); mp.put("aa", "11"); mp.put("cc", "33"); mp.put("bb", "22"); for(String key : mp.keySet()){   System.out.println(key); } --------------------------------------------------------------------- 入力した順番に表示したい場合 --------------------------------------------------------------------- Map<String, String> mp = new LinkedHashMap<String, String>(); mp.put("aa", "11"); mp.put("cc", "33"); mp.put("bb", "22"); for(String key : mp.keySet()){   System.out.println(key); } --------------------------------------------------------------------- ソート表示したい場合 --------------------------------------------------------------------- Map<String, String> mp = new TreeMap<String, String>(); mp.put("aa", "11"); mp.put("cc", "33"); mp.put("bb", "22"); for(String key : mp.keySet()){   System.out.println(key); } ---------------------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1269] >774RRさん
投稿者:SE
2009/05/19 15:22:44

>あえて言わせていただくと、提示例はやっちゃダメな「実装継承」の典型例であって >俺の後輩君がこんなコードかいてたら0点つけるですよ。 大文字変換は何かしらの処理の例として出したので、getで何かの処理を行った結果を返すと考えてください。 >これは、実体が Stack であるインスタンスに対して UpperStack にダウンキャストして使う、としか読めない。 >そんな危険なことをさせるわけにはいかないと思うのだが。 ダウンキャストでなく、newするときに新しいクラスを使うと考えてください。 --------------------------------------------------------------------- Stack st = new Stack(); st.put("aa"); st.put("bb"); st.put("cc"); System.out.println(st.get()); System.out.println(st.get()); System.out.println(st.get()); --------------------------------------------------------------------- これを次のように変更します。1行で済みます。 --------------------------------------------------------------------- UpperStack st = new UpperStack(); st.put("aa"); st.put("bb"); st.put("cc"); System.out.println(st.get()); System.out.println(st.get()); System.out.println(st.get()); ---------------------------------------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1268] Re:状況その4
投稿者:
2009/05/18 20:59:24

Kmyaccを使用していましたが、エラー復帰がうまくいかず。1回の構文エラーで yaccが終了してしまう問題を抱えてしまいました。いろいろ調査したが、どう にも情報が見つからなかったため、Bisonに変更。問題なくエラー処理および エラー復帰が出来るようになりました。堅牢なシステムへまた1歩です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1267] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:
2009/05/18 18:28:11

>これなんですが、C++だと、privateなメンバ変数とかは、外から参照すれば >コンパイラにエラーで怒られるとはいうものの、.hファイル中には記述されて >しまいますよね。  カプセル化という言葉に対して、きっちりとした完全な意味を求めてるのだ ろうと思いますが、私はそこまでのことを意識してこの言葉を使っていません。 問題は。  必要なこと意外一切情報を出さないほうがいいのか。内部がある程度想像 できるほうがいいのか?Cはたとえ使えなくともクラスのデータやメソッドが見 える。これが良いか悪いかでしょう。私は後者のほうが気分的には良いです。 使わない情報が見えたとしても、実質的にカプセル化されていれば問題ないと 考えます。  言語の設計において、理想的なものを作っていくのもあります。私の場合は 目的が実現できれば簡単なものでいいと思って設計しています。その代表が #defineです。古い仕様で問題点も内包しますが、実に使いやすく融通が利きます。 今では#defineはあまり良くないとされていますが、私は利点を選びました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1266] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:(ぱ)こと管理人
2009/05/17 20:50:06

> 私にとってOOPを使う最大の理由は。 > > 「カプセル化により見透視のよさ!」これに尽きます。 これなんですが、C++だと、privateなメンバ変数とかは、外から参照すれば コンパイラにエラーで怒られるとはいうものの、.hファイル中には記述されて しまいますよね。Javaだとメソッドの実装も書くことになるのでもっと深刻です。 これでは利用者側の再コンパイルが必要になりますし、ライブラリの実装が 終わる前にアプリケーションを作り始めたいという場合にも困る、ということで、 (Javaで言えば)インタフェースのみ公開してHogeImplみたいなクラスを作る、 なんてパターンが知られています。 私にはこれは必須に思えるので、Diksamではもうちょっと言語で積極的に サポートしたかったんですけどね。うまい文法が思いつかずにJavaと同等に なってしまっています。うーん、いつかそのうち。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1265] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:(ぱ)こと管理人
2009/05/16 22:40:50

>その論理で行くと、マルチプロセスやマルチスレッドはオブジェクト指向になると >思いますが、 ならないと思いますが…… まあ、オセロの例で注記したように、マルチプロセスにはオブジェクト指向と似た面は ありますけど。「その論理で行くと」の「その論理」がどういう論理か、教えて いただきたいです。 >例えばこれを修正して、大文字に変換して返す物を使いたいとします。 >----------------------------------------------------------- >public class UpperStack extends Stack { >  public String get(){ >    return super.get().toUpperCase(); >  } >} >----------------------------------------------------------- 774RRさんがすでに書いていますけど、これは典型的な「ダメな実装継承の例」でしょう。 # 「実装継承」でGoogleしてみることをお勧めします。 実のところ「要素を大文字に変換して返すスタック」がどんな時に役に立つのか 想像できませんが、それはまあ、「あくまで例だから」ということにしても、 このケースは、 「要素をgetする側は、大文字が欲しいとき、そのことを意識している」 のでしょうか。 意識しているのであれば、そもそも「stack.get().toUpperCase();」で済む話です。 大文字に変換する、という単純な処理でないのなら、ユーティリティメソッドを 作ればよいでしょう。 そこでわざわざ継承してクラスを作ったって、以下のような問題が起きるだけです。 ・Stackが引数かなにかで渡されたとき、本家StackなのかUpperStackなのか  わからなくて危険。 ・別の誰かがLowerStackを作ったら、いつかマージするの? ・ユーティリティメソッドではprivateメンバにアクセスできないが、  継承なら、protectedにしておけばサブクラスからアクセスできる、というのが  趣旨なら、それはカプセル化の破壊以外の何者でもない。 ところで、SEさんの例では、get()メソッドがオーバーライドされています。 「要素をgetする側は、大文字が欲しいとき、そのことを意識している」のであれば、 仮に継承を使うとしても、getUpper()メソッドをつけることでしょう。 オーバーライドしているということは、 「要素をgetする側は、大文字が欲しいとき、そのことを意識しないで済む」 ということにしたいのでしょうか? # それにしては、get(boolean up)と対比しているのでよくわかりませんが。 もしそうなら、 >そのため、変更により以前の機能のまま使用したい場所には影響がありません。 というわけにはいきません。 この改修により、プログラムにUpperStackという「異物」が実行時に紛れ込むわけで、 「Stackにputしたんだから、当然同じものがgetできるだろう」と思い込んでいる 既存コード(Stackそのものを含む)にはおもいっきり影響を与えます。 しかも、get(boolean up)とは違い、実際に動かしてみなければ検出できない バグになりますからさらにタチが悪いです。 上のほうで『実のところ「要素を大文字に変換して返すスタック」がどんな時に 役に立つのか想像できません』と書きましたが、結城浩さんが「例は嘘をつかない」 と書いておられるように、こういうところで現実のプログラムに即した適切な例が 出てこないなら、おそらくそれは考え方のほうが間違っています。 ひとつ伺いたいのですが、SEさんはどんな本でオブジェクト指向の勉強をされたの でしょうか。 いまどきこんなバリバリの実装継承でオブジェクト指向を説明している教科書は そうそうないと思っていたので、もし新しい本にそういうことが書いてあったのなら 興味があります。ぜひ書名を教えてください。 ところで、私が現在作っているクラスベースオブジェクト指向言語Diksamでは、 「concreteクラスは継承できない」ということにしてしまっています。これは 実装の手抜きではなく、意図して行っています。 ここまでやってしまうと異論はあるかもしれませんが、Effective Javaとか GoFのデザパタ本とかで、かなり昔から、散々「抽象クラス以外は継承するな」と 言われてますし、SEさんのような誤解を防止するためにもこの方がよいのではないかと。 http://java-house.jp/ml/archive/j-h-b/050862.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1264] [業務連絡]掲示板が復旧したようです
投稿者:(ぱ)こと管理人
2009/05/16 21:47:05

原因は不明ですが、しばらくこの掲示板が投稿できない状態になっていました。 閲覧は通常通り可能でしたが、送信ボタンを押してもプレビュー画面に遷移しない、という状態でした。 それでしばらくテスト掲示板で様子を見ていましたが、どうも直ったようです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1263] 状況その3
投稿者:
2009/05/15 18:56:21

 yacc,lecの修正とプリプロセッサの作成が終わりました。ファイルの多重#includeと 多重の#define宣言を処理できるようになりました。  次の3つのファイルをt001.dkmで起動すると。 --ファイルt001.dkm--------------------------- // aaaaaaaa #include "t001-01.dkm" #define DEF1 DEF2 + "def1 " // aa int main() { string str; str = DEF1; str = DEF2; str = DEF3; } --ファイルt001-01.dkm------------------------ //ssssssssssss #define DEF2 DEF3 + "def2 " // bb #include "t001-02.dkm" //aaaa int print (string str); --ファイルt001-02.dkm------------------------ //ssssssssssss #define DEF3 "def3 " // cc int printnl(string str) { print(str + "\n"); } -------------------------------------   ↓  プリプロセッサ   ↓ ------------------------------------- int printnl (string str ) { print (str +"\n"); } int print (string str ); int main () { string str ; str ="def3 "+"def2 "+"def1 " ; str ="def3 "+"def2 " ; str ="def3 " ; } -------------------------------------  になってコンパイラに渡されます。もちろんメモリ渡し、エラーもファイル名+行番号で出さ れます。コメントやインデントは内部的に不要なので無くなっています。  最上位の制御構造がマルチスレッドを意識した構造を作りこみ、コンパイラは単独で動作する 構造になりつつあります。ジェネレータは関数単位で実行される予定です。  これでようやく中断前に戻れます。  関数のリンクは総て動的リンクにする予定です。最初の1回だけ動的リンクが行われ、その後 コンパイラが起動されるか、中間コードが破棄された時のみ再度動的リンク試験が行われます。 これでほとんどの関数コールは、直接起動されることになり。スピード的に問題ないと思って います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1262] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:
2009/05/15 18:53:09

 私にとってOOPを使う最大の理由は。  「カプセル化により見透視のよさ!」これに尽きます。  継承や多態化はそのサポートのために。再利用性は設計の問題であり。OOとは 関係が薄い場合がある。ただし、OOを使っても見透視の悪いコードはいくらでも かける。が、よく整理されたクラスの見透視の良さは、OOが無い言語に比べて 格段にいい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1261] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:774RR
2009/05/15 14:56:25

「再入門」のそのあたりの記述は、そもそも「インスタンスが複数あっていい」というあたりを理解していないプログラマ向けの文書。 SE氏の指摘は「インスタンスが複数あるのは当たり前」と理解しているプログラマの視点なわけで。 そういう意味で、対象読者層が異なるだけのことだと思う。 あえて言わせていただくと、提示例はやっちゃダメな「実装継承」の典型例であって 俺の後輩君がこんなコードかいてたら0点つけるですよ。 > そして、大文字で取得したい場所では、このUpperStackを使うようにします。 これは、実体が Stack であるインスタンスに対して UpperStack にダウンキャストして使う、としか読めない。 そんな危険なことをさせるわけにはいかないと思うのだが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1260] 疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:SE
2009/05/15 14:06:45

疑りぶかいあなたのための「オブジェクト指向再入門」を読みました。 部分的に同意できる所もありますが、オブジェクト指向の「本質」はマルチプル インスタンスだと言うのは全く違うと思います。 その論理で行くと、マルチプロセスやマルチスレッドはオブジェクト指向になると 思いますが、これらはオブジェクト指向云々以前から存在する、別の話だと思います。 オブジェクト指向プログラミングの利点は、 「変更がしやすい」事と「変更しても以前の機能が失われない」事です。 簡単に説明します。 先入れ後出し形式のデータ(スタック)をクラス化したとします。 エラー処理を考慮しなければ、大体以下のようになるでしょう。 ----------------------------------------------------------- public class Stack {   private String[] data = new String[100];   private int index = 0;   public Stack(){   }   public void put(String val){     data[index] = new String(val);     index++;   }   public String get(){     String ret = "";     index--;     ret = data[index];     return ret;   } } ----------------------------------------------------------- 例えばこれを修正して、大文字に変換して返す物を使いたいとします。 ----------------------------------------------------------- public class UpperStack extends Stack {   public String get(){     return super.get().toUpperCase();   } } ----------------------------------------------------------- そして、大文字で取得したい場所では、このUpperStackを使うようにします。 ここで重要なのは、基のクラスのStackには全く修正が入らない事です。 そのため、変更により以前の機能のまま使用したい場所には影響がありません。 ちなみに、Stackに別名の大文字で返すメソッドを追加すると言う方法もありますが、 基のソースに修正が入るため、デグレートの危険が発生します。 やたらに継承をしたくない場合は、それでも構いませんが、以下の方式はダメです。 ----------------------------------------------------------- public class Stack {   private String[] data = new String[100];   private int index = 0;   public Stack(){   }   public void put(String val){     data[index] = new String(val);     index++;   }   public String get(boolean up){     String ret = "";     index--;     if(up){       ret = data[index].toUpperCase();     }else{       ret = data[index];     }     return ret;   } } ----------------------------------------------------------- なぜダメかは、構造化プログラミングを行っていて、度重なる修正で スパゲッティープログラム化しているのを見た事のある人なら分かるでしょう。 これを使用している所で、変更の必要ない既存部分にも手が入り、処理にも分岐が 入って複雑化するためです。 適切にオブジェクト指向プログラミングされていれば、修正が入っても劣化せず、 むしろ抽象化され使いやすいクラスになっていきます。 オブジェクト指向プログラミングの目的はこれだけです。 カプセル化、継承や多態化もこれを実現するための手段に過ぎません。 そのため「オブジェクト指向の目的は、再利用性を高める事」は正しいです。 しかしこの場合の再利用性は、関数化などの話ではなく、変更の時の使いやすさを 指しています。 新人が誤解するので「オブジェクト指向はマルチプルインスタンス」と言う記述は 修正か注意書きをしてほしいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1259] Re:状況(日記?)
投稿者:(ぱ)こと管理人
2009/05/12 02:16:16

>> 見間違いかもしれないけど、0.2.0はメモリーストレージを使ってないような・・・ >見間違いかと思います (^^; >了解しました、構文解析の所を今見た所確かにそうです。失礼いたしました。 >しかし、以前メモリートラブルでと話したとき、いつもmallocの中でこけてた >んです。 補足ですが、構文解析部分はMEM_Storageを使用してまとめて開放していますが、 コンパイルにより作られるDVM_Executableは各オブジェクトを個々にMEM_malloc()して 作っています。こちらは、配列のオーバーランなどすると、次のmalloc()で こける可能性が高いと思います(いまどきはそうでもないかも)。 malloc()で確保した領域を配列のオーバーランで壊したことを検出するために、 MEMではアプリケーションに渡す領域の前後を0xCDで埋めていて、これをチェックする 関数MEM_check_all_blocks()を用意しています。実際これでバグを見つけたことも 多いのですが、最近はLinux環境ではとっととvalgrindを使っていたりします。 Windowsで、フリーなvalgrind相当品があるかどうかは不勉強にて知りません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1257] Re:状況(日記?)
投稿者:
2009/05/10 23:54:32

>見間違いかと思います (^^; 了解しました、構文解析の所を今見た所確かにそうです。失礼いたしました。 しかし、以前メモリートラブルでと話したとき、いつもmallocの中でこけてた んです。それで思い違いをしたかな、結局追いきれなくてあきらめたんですけ ど。いや、相当粘ったんですよこれでも… >fix_tree.cでは主にTypeSpecifierを解析木に付加しますが、おっしゃるとおり、 >たとえばある式がintのTypeSpecifierを持っていて、それにマイナス演算子を適用した >このへんのことは以下にちょっとだけ書いてありました。 了解しました、と言うかまとめて開放だから無問題です。単に私がちょっとfixtree で手間取ったのが、それが理由だったんです。結局、メモリー監視デバックルーチ ンが、shared_ptrのような機能を持ってメモリー管理になってしまいましたんです。 もともとスマートポインターは重いからやめようと思ってた矢先の出来事で。 ええ、Boostのpoolに変えます… >「一番外側のブロック」ではなく、その名のとおり「現在のブロック」です。 了解しました。実はコメントを書き換えなおすの忘れてた。昔のままだった。 何も考えずに、有るのそのままコピペしてました。 >> ST_MemberExpression member_expression; // 使用していない? >クラスを導入していないver.0.2では確かに使っていませんね。 了解しました。ありがとうございます。これなんだろう?調べなきゃと思っていました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1256] Re:状況(日記?)
投稿者:(ぱ)こと管理人
2009/05/10 19:05:32

> 見間違いかもしれないけど、0.2.0はメモリーストレージを使ってないような・・・ 見間違いかと思います (^^; create.cで解析木のノードを確保する際も、fix_tree.cで主にTypeSpecifierを 確保する際も、最終的にはdkc_malloc()を呼んでいますし、dkc_malloc()は コンパイラが保持してるMEM_Storageを使用してメモリ確保しています。 http://kmaebashi.com/programmer/devlang/diksam_src_0_2/S/11.html#22 > 実は、構文解析で構文ツリーが出来た時点では、TOPのCT_Compilerのオブジェクトを >deleteすればディストラクタ繋がりできれいに総てのメモリーを解放できたのですが >Fixtreeを作ってみると、多重リンクはするはリンクが切れてフリーが山ほど出てくる >はで。 fix_tree.cでは主にTypeSpecifierを解析木に付加しますが、おっしゃるとおり、 たとえばある式がintのTypeSpecifierを持っていて、それにマイナス演算子を適用した ような場合には、マイナス演算子の式のTypeSpecifierは、その子ノードのものを 直接使用していたはずです(多重リンク)。また、[]演算子を適用するとTypeDeriveが 1段階外されますが、この時、[]演算子のノードのTypeSpecifierは、TypeDeriveの 連結リストの途中のノードを指します(その下のノードでは根元を参照していますが)。 このへんのことは以下にちょっとだけ書いてありました。 http://kmaebashi.com/programmer/devlang/diksam_0_1_comp.html | コンパイル時のTypeSpecifierは、なにしろ解析木のすべての式のノードに | 割り当てられます。たとえば「a + 1」という式がありaがint型の時、 | intを表現するためのTypeSpecifierが(「a」と「1」と「a + 1」のために) | (現状の実装では)3つ確保されています。でもよく考えれば「a + 1」のノードの | TypeSpecifier は左辺か右辺かどっちかのを直接参照してもよいはずで、 | 実際マイナス演算子ではそうしています。 | このように、TypeSpecifier構造体は、誰が所有者なのかわけがわからんような | こんがらがった参照で保持されているので、解析木の他の部分同様、 | コンパイル終了時に(MEM_Storageの機能を使用して)一括で破棄しています。 >class CT_Compiler : public CBase >{ >public: > CT_Block * current_block; // 一番外側のブロック 微妙に気になるのですが、current_blockは、少なくとも元のソースでは、 「一番外側のブロック」ではなく、その名のとおり「現在のブロック」です。 create.cにおいてBlockを生成する際に、親のブロックへの参照をセットするために 使用しています。 >class CT_Expression : public CBase >{ ... > union { > ST_MemberExpression member_expression; //    使用していない? これは、オブジェクトのメンバを参照するためのノードですが、 クラスを導入していないver.0.2では確かに使っていませんね。 ていうかソースには一応入っていたことに私の方が驚きました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1255] Re:状況(日記?)
投稿者:
2009/05/09 22:51:48

お疲れ様です。返事をもらえると嬉しいのですが、ごゆっくりどうぞ。  ↓のクラスを見てわかるとおりに、ほとんどstructをクラスにしたままです。内部 データが少し変わっていますが、structの全体接続構造はほとんどそのままです。  私も意味もなくポリモルフィズムするのは好きではないし。本来の目的は クラスでパッキングして見通しを良くしよう。そして、書くことによる自身の 理解、そして必要機能の追加のためです。それと、diksamもほぼ同じ量のメモリー 確保をしていますよ。  見間違いかもしれないけど、0.2.0はメモリーストレージを使ってないような・・・ class CT_Compiler : public CBase { public: int function_count; // 関数の数 CT_FunctionDefinition * function_list; // 関数のリスト CT_DeclarationList * declaration_list; // トップの宣言リスト CT_StatementList * statement_list; // トップのステートメントのリスト CT_Block * current_block; // 一番外側のブロック //== 式のツリーノード =========================================== class CT_Expression : public CBase { public: CT_TypeSpecifier *type; // E_ExpressionKind kind; // 式の種類 int line_number; union { E_Boolean boolean_value; // boolデータ リテラル int int_value; // intデータ リテラル double double_value; // doubeデータ リテラル string *string_value; // stringデータ リテラル ST_IdentifierExpression identifier; // 関数又は宣言文の識別子 ST_CommaExpression comma; // カンマ(,)式 ST_AssignExpression assign_expression; // 代入式 ST_BinaryExpression binary_expression; // 演算式 CT_Expression *minus_expression; // マイナス式 CT_Expression *logical_not; // 論理否定式 ST_FunctionCallExpression function_call_expression; // 関数式 ST_MemberExpression member_expression; //    使用していない? CT_ExpressionList *array_literal; // 配列データ リテラル ST_IndexExpression index_expression; // 配列の添え字式 ST_IncrementOrDecrement inc_dec; // ++,--,式 ST_CastExpression cast; // キャスト演算式 ST_ArrayCreation array_creation; // 配列生成式 } u;  実は、構文解析で構文ツリーが出来た時点では、TOPのCT_Compilerのオブジェクトを deleteすればディストラクタ繋がりできれいに総てのメモリーを解放できたのですが Fixtreeを作ってみると、多重リンクはするはリンクが切れてフリーが山ほど出てくる はで。メモリー監視・チェック・報告のデバックプログラムが、一躍メモリー管理 プログラムに昇格して、多重リンクや放置されたメモリーを管理して、きれいに掃除 することになりました。思わぬ副作用が・・・  今大改造中で動かせなかったのですが、構文解析時点で5千数百のnewをしていました。  実は、ジェネレータとVM部分を始めていたのですが、ほしい仕様のための変更部分が 目立って見えてきたため、yacc,lex部分から大きく改造を始めてしまいました。 いま、#include #define 構文の追加と最外枠のステートメント禁止、main()関数起動 を組み込み始めました。そして上の二つの構文のためにプリプロセッサを書いています。 だから、コンパイルは+1増えて4ステージになりました。#includeは単に外部ファイルを 同一ファイルとしてコンパイルできる普通の機能です。でも、その為にライン数管理が ファイル名+ライン数になってその部分が全体的改造に。  本当は、一通り終わるまで新機能は入れないつもりでしたが、チョコチョコ変えている 時点で、もう全体変更しようと思ってしまった。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1254] Re:状況(日記?)
投稿者:(ぱ)こと管理人
2009/05/09 02:35:53

世間では連休で私も会社は休みだったはずですが何かとどたばたしてまして お返事が遅れましてすみません。 > ちなみに、test.dkmで最高6800ぐらいnewします。 これで速度低下しないかと心配して、crowbarやDiksamではMEMモジュールを作って MEM_storage_malloc()を使ったのですが、C++でクラスを使おうとすると単純に 置き換えはできませんね(newのオーバーロードで置き換えはできますが、私には、 演算子のオーバーロード自体相当に腰が引けます。boostのように、汎用的で 一般的に知られたライブラリを使うのなら、だいぶ軽減されると思いますけど)。 ところで、DiksamをC++で書き直し、fix_tree.cppでたくさんnewが起きるということは、 DiksamでのExpressionやStatementの構造体をクラスにしておられるのだと思いますが、 これはやっぱり、fix_tree.cppではfix()、generate.cppではgenerate()という メンバ関数を作って、クラスごとにポリモルフィズムで呼び出しているのでしょうか? オブジェクト指向の教科書にはそう書いてありますが、実際にやってみると クラスごとに細かい制御ができなかったりモデルにロジックが侵食したりして あまりうまくいかない、と経験上思っておりますので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1253] 状況(日記?)
投稿者:
2009/05/07 19:00:06

 fix_treeのところで多少手間取っていますが一応終了。トータルの結合 試験で多分たくさんのがバグが・・・  少し長いプログラムを読み込ませるだけで、細かいサイズのメモリーを 7千ぐらい、newとdeleteしているのを見るにつけ、これは結構システムに 負担ではないと思いつつ、区切りが出来たらboostの高速メモリー管理poolに 変えようとかと考えています。一括削除が可能だし。また、メモリー上のトラ ブルが起こったら追うだけでも大変だと思う、今のところそのトラブルには 遭遇していないのが救いです。バグは当たり前のようにありますが・・・  ちなみに、test.dkmで最高6800ぐらいnewします。  特に新しいところがなく日記的なので、不要だったら削除してください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1252] Re:関数実装について
投稿者:
2009/05/04 22:30:19

>Diksam ver.0.4以降だと、ファイルをrequireしておけば、 >呼ぶ際は普通の関数呼び出しですけれど、 そうなんですか、同じものを再発明しそうですね。 >Emacs Lispはダイナミックロードですが、私としては初回呼び出しのタイムラグは >気にならないと思っているので、まあ問題ないと思っているのですけれども。 私の場合、スレッドが必要だと思うほどクリティカルな部分を意識しているので やはり、利用者がコンパイラ起動を意識したほうがいいかなと思っています。 >ということはDVMはひとつでグローバル変数とヒープ領域は共有ですね。 >結構ロックが大変そうな気はします。  この辺はまだ希望的観測の部分が多いので、実際に作りこんでみないと なんともいえない感じです。  今現在はfix_tree部分を作っていますが、途中でnew、deleteが頻発するので 思わず。new、deleteに被せて、newのアドレスとサイズをコンテナMAPに総て入れ、 deleteで検証する監視プログラムやサポ-トプログラムばかり作ってて脱線気味 です。目的プログラム70%残り30%は監視やデバックプログラムです・・・ 文字列リテラルも、wchar_tを使ってもポータビリティーが上がらないのでstring に変えてしまったし、diksam言語部分だけでも一通り動くようになるのはまだまだ 先です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1251] Re:関数実装について
投稿者:(ぱ)こと管理人
2009/05/04 19:33:38

> 言語仕様から見ると、Aプログラムの内部からBファイル内にある関数B1を普通に >コールすることです。当初は、ファイル名.関数名();で起動しようか、関数プロ >タイプ宣言で"ファイル名":関数名();で内部的には普通の関数記述と思いましたが。 Diksam ver.0.4以降だと、ファイルをrequireしておけば、 呼ぶ際は普通の関数呼び出しですけれど、 >いつ重いコンパイラが走るかコントロール出来ないので、 .dkhにシグニチャ宣言だけ書いて.dkmに実装を書くと、関数呼び出し時にコンパイラが 動きますから、状況によって問題になるかもしれません(実装まで.dkhに書いてしまえば いいわけですけど)。 Emacs Lispはダイナミックロードですが、私としては初回呼び出しのタイムラグは 気にならないと思っているので、まあ問題ないと思っているのですけれども。 >スレッド起動の仕様 >普通に関数名(P1,,,Pn);を書くと戻ってくるまでコール元は待ちます。 >start(関数名,起動P,,,Pn);と書くとスレッド起動となります。 ということはDVMはひとつでグローバル変数とヒープ領域は共有ですね。 結構ロックが大変そうな気はします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1250] 関数実装について
投稿者:
2009/05/02 18:30:12

>これは、CからDiksamの関数を関数名を指定して呼び出すということですよね。 内部的に見るとそうです。  言語仕様から見ると、Aプログラムの内部からBファイル内にある関数B1を普通に コールすることです。当初は、ファイル名.関数名();で起動しようか、関数プロ タイプ宣言で"ファイル名":関数名();で内部的には普通の関数記述と思いましたが。 いつ重いコンパイラが走るかコントロール出来ないので、プログラムファイル読込 み関数と破棄関数(中間コードリソースの破棄)を作ることにしました。  この仕様でVMの変更が発生します。それは、1ファイル内の関数コールはコンパ イラで関数アドレスを生成しますが。ファイル外の場合、関数アドレスではなく関 数名を持って、実行時リンクして関数コールする仕様が追加になります。 (最外枠ブロックの実行構文はなくなり、ファイル名起動ではmain()が実行) 中間コードの構造は。 親 ファイル1  ファイル親ー>子    ファイルn ↓   |----------¬    |----------¬ 子   関数1 ・・・・・・ 関数n  関数1 ・・・・・・ 関数n  の様に、階層構造の親子関係で関数置きに分離した中間コードになる予定です。 この、ファイルnの部分が必要時にコンパイルされ中間コードに追加される感じです。  この構造はちょうど関数単位のマルチスレッドに適応できます。 スレッド起動の仕様 普通に関数名(P1,,,Pn);を書くと戻ってくるまでコール元は待ちます。 start(関数名,起動P,,,Pn);と書くとスレッド起動となります。 例   thread_ID1 = start(fnc1,,,);   thread_ID2 = start(fnc1,,,);   thread_ID3 = start(fnc1,,,); と書くとメインスレッドと3つのfnc1スレッドが同時に動きます。 関数については、この様な仕様を組込みたいと考えています。 また、グローバルシステム変数とスレッド起動された関数は一般的なCのグローバ ル変数やスレッドとは、かなり性格が違ったものになります。でも、この点は実物 のめどが出来そうなときにでも、評価していただければ嬉しいと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1249] Re:その後の状況
投稿者:(ぱ)こと管理人
2009/05/02 03:39:28

訂正します。 >と思って見ていたらbaseが初期化されていない >ことに気付きました。またバグです。すみません (_o_) いくらなんでもこれじゃ動かないよな、と思ってよく考えると baseはローカル変数の参照に使うので関数内でしか使用されず、 関数を読んだ際にセットされるので問題ありませんでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1248] Re:その後の状況
投稿者:(ぱ)こと管理人
2009/05/02 03:14:14

>追加したい機能 >・関数指定起動、スクリプトファイル名と関数名を指定して起動 > (スクリプトファイル間の連携したプログラミングのために) これは、CからDiksamの関数を関数名を指定して呼び出すということですよね。 特定の関数を実行するには、dvm/execute.cのexecute()関数を、 http://kmaebashi.com/programmer/devlang/diksam_src_0_2/S/18.html#544 ・事前にdvmのcurrent_executableとcurrent_functionとpcを設定して  (プログラムカウンタは関数ごとなのでpcは0に設定)、 ・execute()関数を、適切な引数で呼び出す ことで可能なはずです。 ただ、実際にはDiksamからネイティブ関数を呼び出して そのネイティブ関数からさらにDiksamの関数を呼び出す、というケースも あるので、スタックポインタを設定の上、execute()関数のローカル変数 baseも引数で渡してやらないと… と思って見ていたらbaseが初期化されていない ことに気付きました。またバグです。すみません (_o_) gccの-Wallでは当てにならないですし、山さんがされたようにVisual Studioでも コンパイルしたいのですがなかなか時間が取れない状態です。明日からは連休ですが、 連休は連休でまた色々と… 編集さんはゲラを発送されたとのことですし(ん?) >その結果、diksam0.2.0の系譜をもつ別の言語になってしまいます。 >なので、言語名は別のものになります。そこでお聞きしたいので >す。diksam0.2.0の系譜をもつ別のものを作ることになりましたが、 >ここでお話しすることは可能でしょうか? まったく問題ありません。 > ぶちゃけて言います。気分を害したりしませんか?>< それはないです(^^) Diksamベースで新しい言語ができるのであれば、 どこをどう直されるのか興味深いです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1247] その後の状況
投稿者:
2009/05/01 07:40:30

 各種機能を追加しようとdiksam0.2.0を解析修正をトライしていましたが、メモリ破壊トラブル に数回遭遇しメモリーダンプ解析を行う状態になってしまいました。さすがにこれは私の手に負え る状態ではないと感じ、diksam0.2.0を元にOOで新たに言語を作るほうが早いと思い、現在作成し ています。今は構文解析ツリーの生成まで終了しています。 ちなみに、yaccはkmyaccを使用、lex部分は自作です。 追加したい機能 ・グローバルシステム変数への透過的アクセス ・関数指定起動、スクリプトファイル名と関数名を指定して起動  (スクリプトファイル間の連携したプログラミングのために) ・関数単位でのスレッドセーフなマルチスレッド起動 ・関数単位でのスレッドセーフな通信 ・#define構文の追加(別名定義のみ)  等の、APとして必要な要件を組み込む必要がありました。その結果、diksam0.2.0の系譜をもつ 別の言語になってしまいます。なので、言語名は別のものになります。そこでお聞きしたいので す。diksam0.2.0の系譜をもつ別のものを作ることになりましたが、ここでお話しすることは可能 でしょうか?  ぶちゃけて言います。気分を害したりしませんか?><
[この投稿を含むスレッドを表示] [この投稿を削除]
[1246] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/28 00:49:20

>ちなみにlex.zz.cを見ればわかりますが >トークンを漢字に変えると、なでしこのようにすぐになってしまいます。 それだけだと、ぴゅう太の日本語BASICとか http://labs.yaneu.com/20090401/ 年刊Ah!SKI第1号のアレみたいなのになりそうです。 トシがばれますねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1245] Re:日本語対応diksam
投稿者:
2009/04/27 19:56:19

>ただ、書くのはともかく、読むほうは「あそこまで日本語化」したほうが >よいというニーズはあるかと思います。 なでしこのHP見に行きましたが、結構すごいことになっていますね。 私のイメージが古かった。ちなみにlex.zz.cを見ればわかりますが トークンを漢字に変えると、なでしこのようにすぐになってしまいます。 それが良いか悪いかは別の話ですが。  言語の意味合いをもう少し膨らませて、len.zzで「if」と「もし」を同じ 意味にして、プログラムを日本語変換するソフトを作ると・・・ 日本語英語両用自由自在のなでしこをこ・・・ げほんげほん  今は目的を先に
[この投稿を含むスレッドを表示] [この投稿を削除]
[1244] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/26 23:24:49

>なでしこは知っていますが、あそこまで日本語化するのは反対の立場です。 確かに。わかります (^^; ただ、書くのはともかく、読むほうは「あそこまで日本語化」したほうが よいというニーズはあるかと思います。 >>よろしければPXU00211@nifty.ne.jpまで送付ください。 >送りました。内容はメールにて書いています。 受け取りました。ありがとうございます。 さっそく購入以来数度しか使っていないVisual Studio2005でビルドしてみました。 includeパスが絶対指定されていましたが、相対に直したらビルドできました。 >>(例外処理機構がないため)exit()以外に選択肢がなく、実用上問題が出るかも >>しれません。 >この辺が今の課題の一つです、 ver.0.4系だと例外処理機構があるのですが、ビルドが難航しているわけですよね。 >手を着けていないものに、「初期値が設定されていない変数が使われています」が >数十出ています。 これがそんなに出るようではいけないわけですが… こちらでも調べてみたほうがよさそうです。 >コンパイラも何かあるとexitで落ちてしまいます。 ダイナミックリンクである以上確かにこれも問題です。 実用に使い始める前にコンパイルエラーぐらいは取ってくれるだろう、と思うので、 優先度は下げているのですけれども。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1243] Re:diksam0.4.03のトラブル
投稿者:
2009/04/25 22:27:43

ご返答ありがとうございます。  う~~ん、ある程度予測をして、場所を下に移すも等いろいろやってはいたのですが・・・  うまく動かずにここに書き込みました。しかし、いまだにdiksam4.0.3はトラブル で落ちてしまいます。VC++への移植にミスがあると思うのですが。エラーが数百近く 出たのを端からつぶしていったのに問題があるのかもしれません、いまだにワーニン グエラーはたくさん残っています。手を着けていないものに、「初期値が設定されて いない変数が使われています」が数十出ています。対処しないといけないのですがい まだにそこまでは。  やはり、4.0は一時保留にして、いまは2.0で問題なく動いています。2.0ソースの 拡張子を.cから.cppに総て変えて、ワーニングも総てつぶして、diksam内部からclass を扱えるようにしました。私が使用しているデバッククラスも使えるようになったの で、多少楽になりました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1242] Re:diksam0.4.03のトラブル
投稿者:(ぱ)こと管理人
2009/04/25 19:56:21

>1.argcの中身は初期化されていません。 これは明らかにおかしいですね。ご指摘ありがとうございます。 argcによる判定は、parse_parameter()実行後に行うべきことです。 今までは偶然動いてしまっていたようです…… >2.GetCommandLine();は何もやっていない・・・ GetCommandLine()はコマンドライン引数を取得するWindowsの関数です。 http://msdn.microsoft.com/ja-jp/library/cc429108.aspx これの戻り値はワイド文字列なので、 >3.DVM_wcstombs(command_line_wc);のcommand_line_wcはアドレスなのですが・・・ DVM_wcstombs()により、マルチバイト文字列に変換し、parse_parameter()で 引数列に分解しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1241] diksam0.4.03のトラブル
投稿者:
2009/04/24 22:22:17

再度、diksam0.4.03のコンパイルを試していますが。 どう見てもWinmMainがおかしいように思います。 WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow ) { DKC_Compiler *compiler; FILE *fp; DVM_ExecutableList *list; DVM_VirtualMachine *dvm; int argc; char **argv; DVM_Char *command_line_wc; char *command_line_mb; if (argc < 2) { fprintf(stderr, "usage:%s filename arg1, arg2, ...", argv[0]); exit(1); } command_line_wc = GetCommandLine(); command_line_mb = DVM_wcstombs(command_line_wc); argv = parse_parameter(command_line_mb, &argc); MEM_free(command_line_mb); 1.argcの中身は初期化されていません。 2.GetCommandLine();は何もやっていない・・・ 3.DVM_wcstombs(command_line_wc);のcommand_line_wcはアドレスなのですが・・・ やはり、私には手に余りそうです。何をしたいのかわからないので対処が出来そうに ありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1240] Re:日本語対応diksam
投稿者:
2009/04/24 19:41:03

追記、ソースはタブ4スペースできれいに見えます。タブ8だとがたがたに・・・ 上に出したソースもがたがただった。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1239] Re:日本語対応diksam
投稿者:
2009/04/24 19:35:33

>ご存知かと思いますが、日本語プログラミング言語としては「なでしこ」が有名です。 >http://nadesi.com/ なでしこは知っていますが、あそこまで日本語化するのは反対の立場です。わざと やっているのではないかと思うぐらい読みづらいです。日本語の中にも和製英語が かなりたくさん入っています。それが当たり前に使われている現状を考えてみるに、- なでしこは、古文を読むような感じで現代的では有りません。日本語プログラミン グにおいても、和英混合で問題がないと私は思っています。 >よろしければPXU00211@nifty.ne.jpまで送付ください。 送りました。内容はメールにて書いています。 >http://kmaebashi.com/programmer/devlang/diksam_src_0_1_01/S/20.html ありがとうございます。意外と簡単に組み込めそうです。 >(例外処理機構がないため)exit()以外に選択肢がなく、実用上問題が出るかも >しれません。 この辺が今の課題の一つです、コンパイラも何かあるとexitで落ちてしまいます。 堅牢なシステムを作る予定なのでこの改善が必要です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1238] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/24 03:22:22

>うわぁ、これはなかなか破壊力がありますね。ずっと半角英数でプログラムを書いてきた >ロートルな私などからするとかなり違和感がありますが、メールとかで「Windows」 >みたいに書くおじさんは実際いましたから、需要はあるかもしれません。 >ていうかプロポーショナルフォントのおかげで全角と半角の区別がつきにくくなったのは >よいことなのか悪いことなのか… 投稿後にちょっと考えたのですが、 私の世代の感覚からすると、全角英数字と半角英数字の区別がつかないのは コンピュータリテラシの欠けたおっさんであり、そもそも全角英数字なんか いらんだろ、ぐらいに思っているのですが、 そんなふうに思うこと自体、端境期のおっさんの戯言かもしれませんねえ。 http://onisci.com/802.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1237] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/24 03:12:38

> 下記のような半角全角入り混じったようなプログラムも意味的に言語仕様と有って >いれば動くようになりました。 うわぁ、これはなかなか破壊力がありますね。ずっと半角英数でプログラムを書いてきた ロートルな私などからするとかなり違和感がありますが、メールとかで「Windows」 みたいに書くおじさんは実際いましたから、需要はあるかもしれません。 ていうかプロポーショナルフォントのおかげで全角と半角の区別がつきにくくなったのは よいことなのか悪いことなのか… そういえば、失敗プロジェクトとして名高い「Σプロジェクト」はUNIXベースのOSだった のですが、全角で「ls」とか書いても通ったという話を聞いたことがあります。 裏は取っていませんが。 なお、せっかくの(数少ない)Diskamユーザをなくしたくはないですし有名なので ご存知かと思いますが、日本語プログラミング言語としては「なでしこ」が有名です。 http://nadesi.com/ >ソース必要でしたらVCのソリューションごと送りましょうか? 私はロートルプログラマなので本体に取り込むことはないと思いますが、 一般公開してよいものでしたら、興味を持つ方がいるかもしれません。 よろしければPXU00211@nifty.ne.jpまで送付ください。 > 次は関数の組み込みおよびVMのスレッドセーフ化かな。関数の組み込みの仕方を >習得したら、本格的にdiksamを組み込んだアプリケーションの作成に入れます。 ネイティブ関数の自作についてであれば、dvm/native.cが参考になるかと思います。 http://kmaebashi.com/programmer/devlang/diksam_src_0_1_01/S/20.html ただ、ver.0.1ベースだと、引数に変な値が渡されたりしたときに (例外処理機構がないため)exit()以外に選択肢がなく、実用上問題が出るかも しれません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1236] 日本語対応diksam
投稿者:
2009/04/23 19:29:57

 下記のような半角全角入り混じったようなプログラムも意味的に言語仕様と有って いれば動くようになりました。もちろん総て全角で書いても動きます。付属の test.dkmも問題なく動作しました。 ------------------------------------------------- int print (string str); string 今時; int 時間;  今時="朝"; 挨拶(今時);  今時="昼"; 挨拶(今時);  今時="夜"; 挨拶(今時);  今時="わからん"; 挨拶(今時); int 挨拶(string 今 ) { print("パラメータ 今=" + 今 + "\n"); if(今=="朝")  { print("------ おはようございます\n"); }elsif(今=="昼")  { print("------ こんにちは\n"); }elsif(今=="夜")  { print(”------ こんばんは¥n”); }else  { print ( "------ おいすー\n" ) ;  } } ---(注:デバック用に故意に半角全角入り乱れています)------------- lex部分を独自に書くことで問題がないようです。ソース必要でしたらVCのソリュー ションごと送りましょうか? VC++2005で書かれてSJIS専用になっています。またdiksam1.0対応のみです。  次は関数の組み込みおよびVMのスレッドセーフ化かな。関数の組み込みの仕方を 習得したら、本格的にdiksamを組み込んだアプリケーションの作成に入れます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1235] Re:VM間排他制御について
投稿者:
2009/04/22 22:41:02

>これなんですが、「誰にとって」簡単であることを目指しているのでしょうか。  う~~ん、正直言いまして、私の方法論もいいのか悪いのか、わからない結果となりました。やっぱり聞いてみて正解です。したがってアプリがある程度で来た時点で両方を実装して実際に使ってみてから判断がよさそうであると考えました。だいぶ先になるかもしれませんが、実装して使ってみて感想・批評・訂正・修正・駄目押し、ぜひよろしくお願いします。  この他にも、いろいろ、単純に出来るのではないかと構想しています。なにぶん逆の目から見た発想なので実際に実装してみるまでは評価は難しいのかもしれません。複雑なことを意識せずに複雑な操作をプログラムするアプリケーションなので、お暇がありましたらお付き合いください。特に言語の構造に深くかかわる可能性もあります。よろしくお願いいたします。  また、現在字句解析が7割ほどかけました。書き終わった後接続試験です。ifもifも10も10も123400も受け付ける字句解析は結構大変です。漢字を受け付ける以上、10と10は同じ意味なのでやはり数字リテラルとして処理しなければ^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[1234] Re:VM間排他制御について
投稿者:(ぱ)こと管理人
2009/04/22 02:53:50

>私の目的は、最も簡単な方法だけを提供しそれ以上のことは出来ない、 >知らなくていい、とても初期の段階のプログラミングを想定しています。 これなんですが、「誰にとって」簡単であることを目指しているのでしょうか。 VMを作る山さんの立場からすれば、ネイティブスレッドを相手に共有変数の整合性を 保持しようと思ったら、結局、セマフォというかミューッテクスによるロックが 必要であるように思います。 それにより、個々の変数が任意の時点で正しい値を持つことが保証されるなら、 アプリケーションを作成するユーザの立場からすれば、困らないように思います。 あるいはもし、複数の変数の整合性まで保証しなければならないのであれば (たとえば点の座標をx, yのふたつの共有変数で持つとき、点を(10, 10)から (20, 20)に移動させる際、(10, 20)のようなハンパな状態を見せてはいけないとか)、 これはトランザクションになりますから、トランザクションの終了を宣言する 方法が必要になると思うのですが…… >それは「Diksam言語仕様自体が複雑ではないのか?」と、実は利用者に説明するのは、 >関数と計算式とif,thin,elseif,else,while,continue,break。以外は使わないようにと >説明します。 そうそう、この程度の機能でも、組み込み言語が使えれば便利な局面は多々ありますよね。 Diksamやcrowbarは少なからずこういう用途を想定しているので、使っていただけることは 作者としては嬉しいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1233] Re:VM間排他制御について
投稿者:(ぱ)こと管理人
2009/04/22 02:25:43

>新プログラミング言語「BF-BASIC(ここの上カンマ)n」 >上の(ここの上カンマ)の半角記号があると書き込めませんでした。 えっ? ……これはつまりSQLインジェクションが可能なわけで、重大なセキュリティー ホールです。修正しました。ご指摘ありがとうございました。 以下、経緯です。 この掲示板は、↓の注記とか、 http://kmaebashi.com/programmer/bbs_dev/index.html こことかにも書いたとおり、 http://kmaebashi.com/programmer/bbs_dev/newbbs.html PHPのmagic quotesの機能を使用しています。 そして、私が借りているレンタルサーバでは、magic quotesはずっとonに なっていました。 少なくとも今年の1月の時点でシングルクオートを含む投稿に成功しています。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=1195&range=1 これがいつの間にかoffにされていたようです。 http://kmaebashi.com/test.php サーバ業者からのお知らせはなかったと思います。以前、PHPを5に上げるという 連絡はありましたがそれもなんだかうやむやになったような(現に今、4で動いてますし)。 # もちろんそれ自体、私を含めてちょっとどうかという話ではありますが。 magic quotesについては、私自身やり方として間違ってるよなあと思いつつ、 郷に入れば郷に従え精神で利用「してしまった」わけですが、当時の私が無知で バカでアホで軽率であったことは認めるとしても、それを前提としたスクリプトは たくさんあるはずで、告知なしにoffにされてはたまったものではないです。 ここはJoe'sウェブホスティングから借りていて、今までさほど大きな問題は なかったと思うのですが、今回の件で過去最大の不信感を持ちました。 ご指摘ありがとうございました。重ねて御礼いたします > 山さん
[この投稿を含むスレッドを表示] [この投稿を削除]
[1232] Re:VM間排他制御について
投稿者:
2009/04/21 10:39:48

SQL障害のため書き込めませんでした、どの部分が問題か調べるために2度のテスト書き込みと削除をしています。お騒がせして申し訳ありません。障害点は下記の部分。 新プログラミング言語「BF-BASIC(ここの上カンマ)n」 上の(ここの上カンマ)の半角記号があると書き込めませんでした。 お騒がせしました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1231] Re:VM間排他制御について
投稿者:
2009/04/21 10:34:28

説明不足で申し訳ありません。 >だとすると、配列やオブジェクトのような参照型ではどうなるのでしょう。 配列やオブジェクトのような参照渡しはしないです。と言うかその点をまったく説明していませんでした。非同期の単一のデーターのみを対象にしていす。複数のデータを渡したい場合は、string変数に、","区切りでと考えていました。申し訳ありません。もちろん、パラメータを簡単に構築分解する関数を用意します。非同期渡しなので、送るほうが3回変数を書き換えても、受けは1回か2回しか読めない場合もあります。もし間違いなく渡したい場合は、スレッドセーフなキューシステムを、完全な同期をしたい場合は、それ様のシステムがいりますが。私の目的は、最も簡単な方法だけを提供しそれ以上のことは出来ない、知らなくていい、とても初期の段階のプログラミングを想定しています。 C++熟練者にとっては、最小高速なセマフォーがあればほぼ何でも出来ます。しかしプログラム間で正しく通信するための必要知識は膨大なものが必要です。(それを補間するために、いろいろなライブラリーが作られているが、それがまた複雑さを・・・) まさに「新プログラミング言語「BF-BASIC n」を作ろう」的な構想のアプリケーションです。だから、スレッドセーフな最小限の一方通行情報伝達だけを意識せずに提供できればいいのではないだろうか?との発想で書いています。これで本当に足りるのかは、アプリがある程度出来てこない事には想像がつきません。 決まり事を極力最小にして、複雑さはシステムで吸収できるよう設計したい。そんな目標が有ります。ここで1つ疑問が沸くと思います。それは「Diksam言語仕様自体が複雑ではないのか?」と、実は利用者に説明するのは、関数と計算式とif,thin,elseif,else,while,continue,break。以外は使わないようにと説明します。それ以外は、トラブルがあっても自分で対処回避できる人のみ「Diksam言語仕様」を見てくださいと言う予定です。  当初は独自で言語を作りはじめましたが、「俺が作りたいのは言語じゃない!!!」との思いが強くなり。いろいろなコンパイラーやインタープリタを調査した結果、Diksamに当たりました。特にしっかりとした言語仕様とVM部分がいいです。この上で複雑さをどれだけ吸収出来るものが作れるのか、がんばってみたいです。  まだまだ説明不足な点が多々あると思いますが、懲りずによろしくお願いいたします。 >>もっと簡単にしてグローバルは1VM内でのみ有効であるとして、 >>VM間変数と言う特殊な変数を作って、セマフォー処理をしてもいいと思う。 >山さんの投稿を見て私が最初にイメージしたのはこれだったのですが… はい、これがあれば一般的なプログラミングが可能です。しかし複雑な制御知識が必要になってしまいます。なのであえて上記のようなシステムを考えています。 >「変数の値取得用の関数」 変数の形をした、まさにこれなんです。説明不足申し訳ありません。ただ、関数にしてしまうと何度も読んでしまうミスを防げないので、あえて1回のみとしてシステム側で制限を加えたわけです。なぜこうしたかは、出来るだけ問題点をシステム側で見つけ出せるか?(目標)です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1228] Re:VM間排他制御について
投稿者:(ぱ)こと管理人
2009/04/21 02:07:14

>4.2回目を読みたい時は、変数更新の関数を呼びまた1回のみ読める。 あ、この「変数更新の関数」を呼んでから、変数を読み出すまでの間、 配布元VMでは変数の変更を禁止する(待つ)、ということでしょうか? だとすれば、余計な処理を間に挟めないように、「変数の値取得用の関数」を 用意したほうがよさそうにも思いますが…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1227] Re:VM間排他制御について
投稿者:(ぱ)こと管理人
2009/04/21 01:50:42

>以下が私の考える見えない排他制御です すみません、いまいちよくわかりません。 まず前提として、山さんの案では、複数のVMが、別々のネイティブスレッドで 動作するんですよね? だとしたら、いずれにせよ共有の変数を読み書きする際は きっちりスレッド間でロックの取り合いをしなければならないわけで、この案で どこが簡素化できるのかがどうもよくわからないです。 >1.システム変数は1つのVMのみ読み書きが出来る、配布元VMとする。 また、この「システム変数」は、ユーザプログラムがこれを利用して同期を取るための ものではなく、まさにユーザプログラムがデータとして共有したいものなんですよね? だとすると、配列やオブジェクトのような参照型ではどうなるのでしょう。 int[] a = {1, 2, 3, 4}; という配列を共有したかったとして、 int[] tmp = a; // aを1回だけ読み出し 以後、tmp経由で配列aの中身は触り放題なわけですが、これでよいのでしょうか? >もっと簡単にしてグローバルは1VM内でのみ有効であるとして、 >VM間変数と言う特殊な変数を作って、セマフォー処理をしてもいいと思う。 山さんの投稿を見て私が最初にイメージしたのはこれだったのですが…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1226] VM間排他制御について
投稿者:
2009/04/20 20:09:57

以下が私の考える見えない排他制御です 1.システム変数は1つのVMのみ読み書きが出来る、配布元VMとする。 2.他の受信VMは1回のみ変数を読むことが出来る。  (ローカル変数に代入し各種処理をする) 3.2回目を読もうとすると実行時エラーとなる。 4.2回目を読みたい時は、変数更新の関数を呼びまた1回のみ読める。  これで意識しない排他制御が可能になると考えています。 (変数更新を毎回呼んだら意味はありませんが・・・) これが私が実装しようとするスレッド間セーフなシステム変数です。 もしよろしければ、ご意見をお聞かせください。 diksamでスレッドセーフのVMが出来ても、グローバル変数が可能な方法があります。それは、セマフォーグローバル変数を宣言するとともに、ロックとフリーの関数を提供します。C++などでは、変数の排他管理は自分でしろと最小高速なセマフォーがあります。これと同じものを提供すれば、スレッドセーフなVM間の通信制御も可能になります。もちろん、もっと簡単にしてグローバルは1VM内でのみ有効であるとして、VM間変数と言う特殊な変数を作って、セマフォー処理をしてもいいと思う。もしお暇でありましたら、スレッドセーフなVMもご検討ください。 (なにぶんVMもほとんど知らないのに適当なことを言っているのかもしれません、その時は申し訳ありません)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1225] Re:ライセンスというか使用許諾というかについて
投稿者:
2009/04/20 18:09:44

>ここですが、現状のVMでも、DVM_VirtualMachine構造体は複数生成できると >思いますので(試してませんが)、yieldのような予約語を入れて中断できるように >すれば「複数起動され個々がいつでも中断再開できる」という用途は達成できそうに >思います。 はい、まだVM部分はざくっとしか見ていないので、内容のアドバイス大変にうれしいです。イメージ的には複数スレッドでVMが動くを目指しています。なおかつ中断状態をディスクに書き込み、読み出し再開を目指しています。(ちょっと無茶な仕様ですが^^;) Diksam上でのグローバル変数は禁止します。システムが固有に持っているグローバル変数を用いてVM間のコミュニケーションをする予定です。この変数へのアクセスは、理想的にはDiksamの変数と同等に扱えればいいのですが、当面はアクセス関数からのアクセスかな。このシステム変数を使うことでスレッド間排他制御を自動でやりたいと思っています。利用者は排他制御を意識できない、しないレベルにしたい。(目標) >そうではなくて、VMはあくまでひとつで、グローバル変数やヒープを共有し、 >複数のスレッドというかコルーチンというかファイバーというかを立ち上げられる >ようにしようと思ったら、DVM_VirtualMachineのpcやらcurrent_executableやら >current_pcやらをもうすこし整理する必要がありそうです。 今一番簡単にVMを考えるなら、総ての変数領域を、クラスの中にパックしてしまえばグローバル変数がないという条件で、完全なスレッドセーフのVMになるのではないかと思います。その場合、ヒープ領域も指定して持つと言う富豪プログラミングです。 私はまだVMもちらりとしか見ていないので、上記構想がどんなものかの評価が出来ていません。こうしたほうがよりよい等アドバイスが有りましたらよろしくお願いします。 ここ数日、Diksam0.4.01をVC++2005上で動作させることをトライしていましたが、多くのエラーとトラブルに遭遇し、まだ内容もわからずに修正するのは早計であった為、今現在はDiksam0.1を、VC++上に移植して作業をはじめています。0.1は少しの修正で移植できました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1224] Re:ライセンスというか使用許諾というかについて
投稿者:(ぱ)こと管理人
2009/04/20 01:30:57

そちらのソースを見たわけでもなく、私が趣旨を誤解している可能性もありますので あくまでご参考としてですが、 >また、VM部分はひとつのclassに入るように修正しようと思っています。 >使用上複数起動され個々がいつでも中断再開できる用途を考えているので、 >1つのまとまりとしてクラス化をして1パッケージで扱えるためにと。 ここですが、現状のVMでも、DVM_VirtualMachine構造体は複数生成できると 思いますので(試してませんが)、yieldのような予約語を入れて中断できるように すれば「複数起動され個々がいつでも中断再開できる」という用途は達成できそうに 思います。 そうではなくて、VMはあくまでひとつで、グローバル変数やヒープを共有し、 複数のスレッドというかコルーチンというかファイバーというかを立ち上げられる ようにしようと思ったら、DVM_VirtualMachineのpcやらcurrent_executableやら current_pcやらをもうすこし整理する必要がありそうです。 また、スレッドを分けるなら、MEMがstaticであるのはそれなりに問題になりそうに 思います。 >いつ完成するかはわかりませんが、何かありましたら必ずここでご報告いたします。 >ある程度めどが出来ましたら、フリーで公開するプログラムになります。 楽しみにしています。 >最後に1つ、「Diksam言語仕様 ver.0.4.01 」のページをパッケージに添付す >ことになると思いますが、その時はよろしくお願いいたします。 これについてもまったく問題ありません(明記しておくべきですね…)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1223] Re:ライセンスというか使用許諾というかについて
投稿者:
2009/04/19 18:09:47

>Diksamについてですが、mycalc, crowbarと同じで結構です。 とてもありがとうございます。 簡素に現状をご報告いたします。字句解析については日本語関数や日本語の定義や変数を使いたいために、独自で書いています。スピードもそれほど要らない部分ですから。また、VM部分はひとつのclassに入るように修正しようと思っています。使用上複数起動され個々がいつでも中断再開できる用途を考えているので、1つのまとまりとしてクラス化をして1パッケージで扱えるためにと。(私がクラス好きなんでつ)ヒープとGCはまったく別の形でなくすかもしれません。なにぶん趣味で作っているものなので、いつ完成するかはわかりませんが、何かありましたら必ずここでご報告いたします。ある程度めどが出来ましたら、フリーで公開するプログラムになります。 最後に1つ、「Diksam言語仕様 ver.0.4.01 」のページをパッケージに添付すことになると思いますが、その時はよろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1222] Re:ライセンスというか使用許諾というかについて
投稿者:(ぱ)こと管理人
2009/04/19 13:56:13

>はじめまして、山と言うもので。 はじめまして。 >このページでは、mycalc, crowbar共に、商用、非商用を問わず、自由に複製、改変、 >とプログラム名を指定して記入してあります。私どもは、Diksamを改変し、プログラムの中に組み込もうと思っていますが。ライセンス条項がどこにも見当たりません。 光栄です。 Diksamについてですが、mycalc, crowbarと同じで結構です。このライセンス条件を 書いた時点でDiksamは公開前だったのですが、追加を忘れていました。 さっそくDiksamを追記しておきました。ご指摘ありがとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1221] ライセンスというか使用許諾というかについて
投稿者:
2009/04/18 22:54:38

はじめまして、山と言うもので。 ライセンスというか使用許諾というかについてお聞き致します。 このページでは、mycalc, crowbar共に、商用、非商用を問わず、自由に複製、改変、 とプログラム名を指定して記入してあります。私どもは、Diksamを改変し、プログラムの中に組み込もうと思っていますが。ライセンス条項がどこにも見当たりません。 よろしければどの様なライセンス条項であるかお聞かせ願えませんでしょうか? 当初は、同一であると思って作業を進めていましたが、よくよく見るとDiksamの名前がありませんでした。まことに不注意ではあったのですが、よろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1220] Re:リンク変更
投稿者:(ぱ)こと管理人
2009/04/04 10:11:46

こんにちは。 >C言語 FAQ 日本語訳 >http://www.kouno.jp/home/c_faq/ 情報ありがとうございます。修正しておきました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1219] リンク変更
投稿者:時々訪れる人
2009/04/01 19:18:16

C言語 FAQ 日本語訳 http://www.kouno.jp/home/c_faq/ リンクが変わっているかも?? 上が正しい?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1218] Re:読みました
投稿者:(ぱ)こと管理人
2009/03/29 12:53:07

はじめまして。書き込みありがとうございます。 最近かなり忙しく返信が遅くなりましてすみません。 >PHP掲示板の勉強をしてみようとぐぐり、(ぱ)さんのページを見つけました。 今にして思うと、言い訳しながらmagic_quote使うくらいなら使うな、とか、 テーブルのレコードには作成日時のフィールドぐらいデフォルトで入れとけ、 とか、ツッコミどころはあるのですが、役に立てたようなら何よりです。 >BF Basic笑いました。 ありがとうございます。 もうじきエイプリルフールですが、今年はネタを仕込むヒマもないなあ…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1217] 読みました
投稿者:bourbon
2009/03/26 08:57:42

PHP掲示板の勉強をしてみようとぐぐり、(ぱ)さんのページを見つけました。 テクニカルでかつ気ままな仕様書は読み物としても秀逸。 知りたいこともちゃんと読みとれました。 ありがとうございました。 BF Basic笑いました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1215] Re:windowsでpthread
投稿者:tos
2009/02/24 09:30:36

返信、ありがとうございます。 Boostとかいうライブラリに関しても調べてみたのですが、 こちらも優先順位の設定が出来なそうに見えました。 (間違っていたら、すみません)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1214] Re:windowsでpthread
投稿者:(ぱ)こと管理人
2009/02/24 02:23:36

> pthreadを使用し、Windows上でスレッド優先順位を指定するには、 >どのようにすれば良いのでしょうか? または、そんなことは出来ないのでしょうか? 長々と放置しましてすみません。 私はpthreadは使ったことがないので、有効な助言はできないかと思います。 # ざっとぐぐってみた範囲では、やはり管理者権限がないと優先順位の設定は # できないように思えるのですが。 詳しい方からの情報をお待ちしております。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1213] windowsでpthread
投稿者:tos
2009/02/19 18:46:36

皆さんこんにちは、tosです。 現在、Windows XPにてpthread-win32 libraryを使用した プログラムの変更を行なっています。 あるスレッドの優先順位を変更する必要があるため調べたところ、 「優先度は、スケジューリングポリシーが SCHED_OTHER の時には意味を持たず、 リアルタイムポリシー SCHED_RR と SCHED_FIFO に対してのみ有効である。」 とのことでした。 スケジューリングポリシーは「SCHED_OTHER」であったため、「SCHED_FIFO」 に変更しようとしたところ、 「リアルタイムスケジューリングポリシーである SCHED_RR と SCHED_FIFO は、 スーパーユーザ権限のプロセスに限って使用できる。」 とのことで、「SCHED_FIFO」を指定することが出来ません。 pthreadを使用し、Windows上でスレッド優先順位を指定するには、 どのようにすれば良いのでしょうか? または、そんなことは出来ないのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1210] Win << Mac::GUI (継承)
投稿者:つよし
2009/01/25 21:00:18

>「WindowsのGUIの悪いところは全部Macが起源だ」的な記事を > はてなの日記にでも書こうと思ってました。 楽しみに待っています。 前橋さんは、プログラミングの基礎の構築はバリバリlinuxを使ってるのですね!
[この投稿を含むスレッドを表示] [この投稿を削除]
[1208] Re:os
投稿者:(ぱ)こと管理人
2009/01/25 03:19:20

>前橋さん >は、Winndowsな人ですね!? 私も以前はアンチWindows的なことを言ってたこともありますが、2000あたりからはまあ不満はないですね。 今まさにここに書き込んでいるのはWindows(Vista)です。Web閲覧やメールは基本的にWindowsです。このVistaの上に、VMWare playerでUbnutuが入っています。 crowbarやDiksamはもともとUbuntuで作りました。今でも言語本体はUbuntuで作っています。本の原稿やら何やらもLinux上でLaTeXで書いています。エディタはEmacs、かな漢字変換はSKKです。 会社に入ってほぼ最初の仕事がX Window上だったこともあり、私自身は、WindowsのAPIで画面にウインドウを出したり線を引いたりするより、Xlibの方が経験は多いです(WindowsのAPIはほとんど今回勉強しながらやっています。以前、ちょとだけMFCとかを使ったことはありますが)。 >オープンソースlinuxなUFOゲームは、作れないのかな!? Diksamのdiksam.windowパッケージのXlib版を作ることはできるでしょうし、それでUFOゲーム程度なら作れるでしょうが、あるレベル以上のものはクライアントサーバモデルのXでは辛いでしょうねえ。 >MacOSXのインターフェースは、Windouseの比では、ありません。 私はMacは10年以上前(Windows95以前)に仕事で使っていたきり、ほとんど触っていません。なので今のMacのUIについては、何を語る資格もないですが、最近、ちょうど「WindowsのGUIの悪いところは全部Macが起源だ」的な記事をはてなの日記にでも書こうと思ってました。 (1)フォルダの中身の閲覧が、デフォルトでアイコンであるとか、  →少なくとも私の周囲では、みんな一覧表示に切り替えています。このへん   VistaになってさらにクソになりましたがこれはさすがにMacの責任ではない。 (2)そのアイコンをドラッグすると、デフォルトで(コピーではなく)移動になるとか、  →移動よりコピーの方がずっと使用頻度高くないですかね。 (3)デスクトップにファイルが置けるとか。  →これは反論ありそうですが、これを認めることで、結果的にファイルシステムが   循環した複雑怪奇なものになってしまっています。Windows3.1時代の   ファイルマネージャではいかんのか。 上記のような特徴は確かに初心者にはとっつきやすいのかもしれませんが、とっつきやすいだけで実用には向かないんじゃないかと。 >前橋言語で金儲け考えていないのであれば、Linuxでどうぞ! 金儲けは考えてないですが、かけられる時間が限られているので、やっぱり一番ユーザ層が厚いところを、と思いWindowsを選んだわけですが。 いざそうしてみたら、掲示板に、つよしさんといいたろうさんといいMacな人ばかりが書き込んでいるという…… 私が思うよりずっと、最近はMacユーザが増えているのかもしれませんね。私もMacBook Airが出た時にはかなり心を動かされました。まあお金に困っているわけじゃなし1台Macを買ってもいいけど、使う時間が……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1207] Re:os
投稿者:つよし
2009/01/24 23:10:30

前橋さん は、Winndowsな人ですね!? オープンソースlinuxなUFOゲームは、作れないのかな!? ちなみに、web閲覧位にしか使いませんが 僕は、linux,macosxな人です。 オープンソースでは、ありませんが MacOSXのインターフェースは、Windouseの比では、ありません。 windows,osの2バージョン位 進んでいます。 対応アプリは、windowsが圧倒しています。 macのハード1社独占は、いかがなものか(麻生節) オープンソース Linux の UFO 期待します。 前橋言語で金儲け考えていないのであれば、Linuxでどうぞ! いま、酒飲んでます。自身:醒めたらこの文どうかんじるかなぁ
[この投稿を含むスレッドを表示] [この投稿を削除]
[1206] Re:os
投稿者:(ぱ)こと管理人
2009/01/11 00:25:15

>ここが解せないんですよ。たとえば >int >dvm_mbstowcs_len(const char *src) >{ > return mbstowcs(NULL, src, 0); >} >で良い筈なので、繰り返しは必要ないと思うんですが... やったのがかなり昔のことなのでもはや覚えていないのですが、 考えられる原因としては、以下のようなものが考えられます。 (1)Windowsでは、mbsrtowcs()だけでなくてmbstowcs()も動かなかった。  →当時はXPだったのですが、今Vistaで試したらあっさり両方動いてしまったので   検証不能です… (2)mbstowcs()なら動いたが、rがついていないのでよろしくない関数だと  思い込んでいた。  →この使い方なら、mbstowcs()側に状態を覚えさせないので、問題ないと   思いますが。 (3)mbstowcs()の第1引数にNULLを渡すと変換を行わない、という仕様を知らなかった。  →実のところ現在は完璧に忘れていました。当時はちゃんとマニュアル読んだので、   知らなかったということはないと思うのですが…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1205] Re:os
投稿者:kit
2009/01/09 12:50:45

>で、manの続きを読むと、 > > This representation is recommended over --all-locates one, > due being the system wide supported values. > >(超訳)この(SUPPORTEDファイルの)表現は、locale -a で出てくるヤツより推奨される。 >なぜならシステム全体でサポートされてるものだから。 > >なんて書かれていて、それなりのポリシーはあるようですが……。 >歴史的ないざこざがあったのでしょうなぁ。 まあ Linux の世界に限れば、 http://web.archive.org/web/20040114120121/http://www.openi18n.org/docs/text/LocNameGuide-V11.txt という標準が決まっているので、ja_JP.EUC-JP の方が正式と言えば正式です。 しかし、この標準を決めた時点で、既に Linux を含む全ての UNIX 系 OS で ja_JP.eucJP が使える状態にあり、互換性のためには当然 ja_JP.eucJP を 引き続きサポートする必要もあったわけで、実質的には混乱の種を増やした だけだったと私は思ってます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1204] Re:os
投稿者:kit
2009/01/09 12:10:51

>また、mbstowcs()とかは引数にlenを取りますが、実際の文字列長に上限を >置くわけにはいかないので、どうせ繰り返し呼ぶなら1文字ずつやるほうが >(効率を考えなければ)楽なこと、 ここが解せないんですよ。たとえば int dvm_mbstowcs_len(const char *src) { return mbstowcs(NULL, src, 0); } で良い筈なので、繰り返しは必要ないと思うんですが... (第一引数が NULL の場合、mbstowcs() は第三引数を無視します。) dvm_mbstowcs() の方は len 用に引数が一つ増えてしまいますが、呼び出し側では 当然 len は分かっている筈なので、それでも構わないというか、今時のコーディング スタイル的にもその方が良いんじゃないでしょうか? (len が分かってないのに dvm_mbstowcs() を呼ぶなんていうのは、設計上の誤りな わけですから)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1203] Re:os
投稿者:yuya
2009/01/09 10:03:05

>ただ、Ubuntuだとxdmで文字コードが選べるのですが、そこでEUCを選んだ >時のデフォルトのLANGはやっぱりja_JP.EUC-JPなんですよね… 私もUbuntu使っていますが、localeのmanページに FILES: /usr/share/i18n/SUPPORTED List of supported values とあり、ファイルを覗くと ja_JP.EUC-JP がエントリーされていますね。 で、manの続きを読むと、 This representation is recommended over --all-locates one, due being the system wide supported values. (超訳)この(SUPPORTEDファイルの)表現は、locale -a で出てくるヤツより推奨される。 なぜならシステム全体でサポートされてるものだから。 なんて書かれていて、それなりのポリシーはあるようですが……。 歴史的ないざこざがあったのでしょうなぁ。 あと、前回の投稿で、他人のマシンでsudoを試させるような書き方をしてしまい、すみませんでした。 (locale -a の結果は ja_JP.ccb となります。)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1202] Re:os
投稿者:(ぱ)こと管理人
2009/01/09 01:53:16

>>標準の mbstowcs() や wcstombs() を使わずに、dvm_mbstowcs() や >>dvm_mbstowcs_len() を用意している理由も良く分かりませんでした。 > >これらは、現状ではmbstowcs()とかの単なるラッパ関数です。 訂正です。dvm_mbstowcs()等に関しては単なるラッパではないですね。 理由のひとつは、昔 http://kmaebashi.com/programmer/devlang/regexp.html にちょっと書いたのですが、少なくとも当時の私には、Windowsで mbsrtowcs()を動かすことができなかったため(rなしの方は動いたんだったかな)、 また、mbstowcs()とかは引数にlenを取りますが、実際の文字列長に上限を 置くわけにはいかないので、どうせ繰り返し呼ぶなら1文字ずつやるほうが (効率を考えなければ)楽なこと、 あたりが理由だったと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1201] Re:os
投稿者:(ぱ)こと管理人
2009/01/09 00:06:34

こんにちは。いつもお世話になります。 >ja_JP.eucjp と設定しても動きます。 本当だ。今試したところ動きました。 前に試したときは動かなかったと思うのですが、なにかミスしていたようです。 >日本語EUC locale 名としては ja_JP.eucJP を使うのが最も一般性があり、 >Linux に限らず、多くの UNIX 系 OS で通用するので、そちらを勧めます。 ただ、Ubuntuだとxdmで文字コードが選べるのですが、そこでEUCを選んだ 時のデフォルトのLANGはやっぱりja_JP.EUC-JPなんですよね… >#include <limits.h> して MB_LEN_MAX を使わないのはなぜなんでしょう? これは単純に知りませんでした。毎度ながらご指摘ありがとうございます。 >標準の mbstowcs() や wcstombs() を使わずに、dvm_mbstowcs() や >dvm_mbstowcs_len() を用意している理由も良く分かりませんでした。 これらは、現状ではmbstowcs()とかの単なるラッパ関数です。 わざわざ1枚かぶせている理由ですが、たとえばどこかのタイミングで 独自の変換テーブルを持つようにする、といった改修を行う可能性はあると 思っています。実際、今回こうやっていくつかの環境で動かないのを 目の当たりにすると、内部コードなんかユニコード固定でいいし 日本語以外に対応しなくてもいいから、全部自前でやりたい、という気にも なりますです……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1200] Re:os
投稿者:yuya
2009/01/07 15:49:13

ごぶさたしています。今年もよろしくお願いします。 >そもそも私の環境でも >ja_JP.eucjp >は出ても、 >ja_JP.EUC-JP >は出ないんですよね。 % sudo localedef -i ja_JP -f euc-JP ja_JP.C-C-B とでも入れてみて、懐かしのバンド名を使ったダミーのロケールを作り、すぐ消そうとしても % sudo localedef --delete-from-archive ja_JP.C-C-B locale "ja_JP.C-C-B" not in archive あれ?と思って % locale -a とすると……。kitさんのおっしゃるとおり、変態的であることを垣間見ることができますね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1199] Re:os
投稿者:kit
2009/01/07 13:57:56

>>Debian(etch) にて >>上の方にある同じ abort エラーがでました. この etch のエラーは、日本語EUC localeがインストールされてないため出ている エラーでしょう。Debian でのやり方は知りませんが、日本語 EUC locale をイン ストールすれば直るのでは? つまりdiksamではなく、利用環境の側の問題だと思います。 >>% printenv LANG >>ja_JP.EUC-JP >>% locale -a >>locale: Cannot set LC_CTYPE to default locale: No such file or directory >>locale: Cannot set LC_MESSAGES to default locale: No such file or directory >>locale: Cannot set LC_COLLATE to default locale: No such file or directory >>C >>POSIX >>ja_JP.utf8 > >locale -aで出てこないものをLANGにセットしても無駄だ、というのが >マニュアル的な解釈だと思うのですが、 そうです。したがって、locale -a で ja_JP.eucjp が表示されるような環境設定が必須です。 >そもそも私の環境でも > >ja_JP.eucjp > >は出ても、 > >ja_JP.EUC-JP > >は出ないんですよね。でも、LANGやsetlocaleで効くのはja_JP.EUC-JPのほうで、 >ja_JP.eucjpではないという。 ja_JP.eucjp と設定しても動きます。 Linux の locale 名解釈ルーチンは変態的で、ja_JP.EUC-JP, ja_JP.eucjp, ja_JP.eucJP を全て同一視します。こんな動作をするUNIX系OSは、知る限り Linuxだけです。 日本語EUC locale 名としては ja_JP.eucJP を使うのが最も一般性があり、 Linux に限らず、多くの UNIX 系 OS で通用するので、そちらを勧めます。 あと、 #define MULTIBYTE_CHAR_SIZE_MAX (6) というのは良くないコーディングスタイルだと思うんですが、 #include <limits.h> して MB_LEN_MAX を使わないのはなぜなんでしょう? (Linux の場合でも MB_LEN_MAX は 16、NetBSD あたりだと MB_LEN_MAX は 32 です。) 標準の mbstowcs() や wcstombs() を使わずに、dvm_mbstowcs() や dvm_mbstowcs_len() を用意している理由も良く分かりませんでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1198] Re:os
投稿者:(ぱ)こと管理人
2009/01/05 01:36:22

>Debian(etch) にて >上の方にある同じ abort エラーがでました. 情報提供ありがとうございます。 >status. -1. errno=84: Invalid or incomplete multibyte or wide character >[28] src=不正なマルチバイト文字です。 >status. -1. errno=84: Invalid or incomplete multibyte or wide character >len=-1 >Assertion failure (wc_format != NULL) file..error.c line..92 >wc_format is null. >Assertion failure (wc_format != NULL) file..error.c line..92 >wc_format is null. >Abort これは、現象としては、明らかにerror_message.c内の日本語エラーメッセージを マルチバイト文字列に変換しようとしているところで失敗していることに起因する エラーです。詳細な情報ありがとうございます。 ……と、ここまではすぐにわかるのですが、原因のほうは私にはさっぱりです。 >% printenv LANG ja_JP.EUC-JP >% locale -a >locale: Cannot set LC_CTYPE to default locale: No such file or directory >locale: Cannot set LC_MESSAGES to default locale: No such file or directory >locale: Cannot set LC_COLLATE to default locale: No such file or directory >C >POSIX >ja_JP.utf8 locale -aで出てこないものをLANGにセットしても無駄だ、というのが マニュアル的な解釈だと思うのですが、そもそも私の環境でも ja_JP.eucjp は出ても、 ja_JP.EUC-JP は出ないんですよね。でも、LANGやsetlocaleで効くのはja_JP.EUC-JPのほうで、 ja_JP.eucjpではないという。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1197] Re:os
投稿者:つよし
2009/01/04 14:15:52

Vine4.2で試行しました。 OK!!です。 $ sh test.sh test array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename こちらのMacOSXは、開発環境がうまくインストール出来ているか疑問です? 他の人の追試を、、、、。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1196] Re:os
投稿者:つよし
2009/01/04 14:05:11

MacOSXで試行しました。 $ sh test.sh test 276,277c276,277 < str[0]..26085 < str[1]..26412 --- > str[0]..50940 > str[1]..52188 279c279 < str[2]..35486 --- > str[2]..47340 array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename
[この投稿を含むスレッドを表示] [この投稿を削除]
[1195] Re:os
投稿者:(ぱ)こと管理人
2009/01/04 09:23:39

昨日は帰省してネットから切り離された上、風邪で実家で寝込んでまして、 すっかり遅くなりましてすみません。 >>(2)725~728行目のみをコメントアウト … >----上の変更を加えて sh test.sh を実行 これでかなり原因が絞れました。ありがとうございます。 最近追加した文字リテラル関連でバグを入れてしまったかな、と思い、 追求したところ、怪しいところがあっさり見つかりました… compiler以下のstring.cの中に、以下の関数があります(59行目)。 int dkc_close_character_literal(void) { DVM_Char buf[1]; ここの 誤) DVM_Char buf[1]; を 正) DVM_Char buf[2]; に直してコンパイル/実行を試していただけますか。 # mainの下でmakeするだけではここのコンパイルは通らないので、 # compilerの下でいったんmakeしてからmainの下でもmakeするか、 # mainの下で touch main.c してからmainの下でmakeしてください。 ここは文字リテラル(「'本'」のような1文字の定数)の値を抽出しているところで、 1文字であることはその前後の判定で明らかなので、1文字分のバッファを取っておけば よいかと思っていたのですが、 dvm_mbstowcs(st_string_literal_buffer, buf); 実際に変換しているこの関数では、末尾にL'\0'を補っているので、 領域破壊が起きていました。末尾ナル文字分を忘れるとは初心者並みのポカでした。 4バイトかそこらのスタック領域の破壊だと、(現にうちの環境で動いていたように) たまたま動いてしまう場合も多く、つよしさんのところでこの現象で死んでいるか どうかはわかりませんが、可能性は高いと思います。 いろいろと情報いただきありがとうございました。送球に修正してリリースします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1194] diksam テスト中
投稿者:つよし
2009/01/04 08:33:15

前橋さんの言語 diksam のテスト中です。 どなたか検証お願いします。(前橋さんに変わって書き込み??) EUC-jpの環境 http://kmaebashi.com/programmer/devlang/diksam_0_4_02_unix.tgz UTF-8の環境 http://kmaebashi.com/programmer/devlang/diksam_0_4_02_unix_utf8.tgz コンパイルは、UNIX版は上記ソースを展開したディレクトリの mainフォルダの下でmake!! また、その下の test ディレクトリで sh test.sh を実行して結果を教えてください!! お願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1193] Re:os
投稿者:つよし
2009/01/03 11:52:41

・Linux(Vine Linux 4.2)  →utf-8では正常動作  →EUCでは、××× ・MacOS  →utf-8では、×××  →EUCでは、×××
[この投稿を含むスレッドを表示] [この投稿を削除]
[1192] Re:os
投稿者:つよし
2009/01/03 11:21:55

>・MacOS > →utf-8では正常動作 最近のMacOSXのデフォルトの文字コードは、何なのかわかりません。 10.3.9のデフォルトの文字コードは、EUC-jpですが、ターミナルでUTF-8に設定して 実行するとdiffが差分を出します。 sh test.shの結果 test 1,279c1 < hoge piyo < \nabc < abccde < 0x123..291 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1 != 3.0..true < 3.0 != 3.0..false < 3.0 >= 1..true < 1 >= 3.0..false < 3.0 > 1..true < 1 > 3.0..false < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1.0 != 3..true < 3 >= 1.0..true < 1.0 >= 3.0..false < 3 > 1.0..true < 1.0 > 3..false < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < int_val..5 < int_val..3 < int_val..9 < int_val..3 < int_val..1 < double_val..5.000000 < double_val..3.000000 < double_val..9.000000 < double_val..3.000000 < double_val..1.000000 < str_val..strhoge3 < int_val..3 < double_val..0.000000 < a..3, b..4.000000 < no_arg < a + b..28 < a + b + c..10.000000 < boolean_func..true < int_func..3 < double_func..3.000000 < string_func..hoge < ********** recursive call ********** < a..10 a..9 a..8 a..7 a..6 a..5 a..4 a..3 a..2 a..1 a..0 < a..0 a..1 a..2 a..3 a..4 a..5 a..6 a..7 a..8 a..9 a..10 < boolean_value..true < !boolean_value..false < true < boolean_value || false < true == true good < true != false good < ! operator good. < true_value == true good < true_value != false good < ! operator good. < true < good < good < good < ********** while statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < ********** for statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < ********** break with label in while ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** break with label in for ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** continue in while ********** < i..5 i..6 i..7 i..8 i..9 i..10 < i..10 < ********** continue in for ********** < i..5 i..6 i..7 i..8 i..9 < i..10 < ********** continue with label in while ********** < i..1 j..0, i..2 j..0, i..3 j..0, < i..3 j..0 < ********** continue with label in for ********** < i..0 j..0, i..1 j..1, i..2 j..2, < i..3 j..3 < *** i..0*** < i == 0 < i != 3 < i != 2 && i != 3 < *** i..1*** < i == 1 < i != 3 < i != 2 && i != 3 < *** i..2*** < i == 2 < i != 3 < i == 2 || i == 3 < i == 2 && j == 3 < *** i..3*** < i == else < i == 2 || i == 3 < *** i..4*** < i == else < i != 3 < i != 2 && i != 3 < i..11 < ii = 10..10 < array[3][0]..10 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < array2[0]..1 < array2[1]..2 < array2[2]..3 < array2[3]..4 < array2[4]..5 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < darray[0]..0.000000 < darray[1]..1.000000 < darray[2]..2.000000 < darray[3]..3.000000 < darray[4]..4.000000 < darray[5]..5.000000 < darray[6]..6.000000 < darray[7]..7.000000 < darray[8]..8.000000 < darray[9]..9.000000 < darray[0]..1.000000 < darray[1]..2.000000 < darray[2]..3.000000 < darray[3]..4.000000 < darray[4]..5.000000 < darray[5]..6.000000 < sarray[0]..str0 < sarray[1]..str1 < sarray[2]..str2 < sarray[3]..str3 < sarray[4]..str4 < sarray[5]..str5 < sarray[6]..str6 < sarray[7]..str7 < sarray[8]..str8 < sarray[9]..str9 < sarray[0]..1 < sarray[1]..2 < sarray[2]..3 < sarray[3]..4 < null_str..null < abcnull < null < OK < OK < OK < OK < 日本語 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 --- > test.dkm:726:文字リテラルが2文字以上あります。 array 6,7c6,7 < len..6 < substr..eほげほ --- > len..10 > substr..eほ class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename
[この投稿を含むスレッドを表示] [この投稿を削除]
[1191] Re:os
投稿者:つよし
2009/01/03 10:59:30

>Vine Linuxにて、以下の修正を実施して、../diksam test.dkmで実行して、 >セグメンテーション違反が出るかどうか、よければ試してみてください。 > >(1)test.dkmの720行目以降をコメントアウト(Diksamでは/* */で囲んでコメントアウト) >/* >println("日本語"); > >string str = "日本語"; >for (i = 0; i < str.length(); i++) { > println("str[" + i + "].." + str[i]); > if (str[i] == '本') { > println("本"); > } >} > >exit(1); >println("これは出ない"); >*/ ----上の変更を加えて sh test.sh を実行 $ sh test.sh test 275,279d274 < 日本語 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename $ > >(2)725~728行目のみをコメントアウト >string str = "日本語"; >for (i = 0; i < str.length(); i++) { > /* > println("str[" + i + "].." + str[i]); > if (str[i] == '本') { > println("本"); > } > */ >} > >exit(1); >println("これは出ない"); > >また、うちのPCでは動かなかった、という方は他にいらっしゃらないでしょうか。 >情報募集中です (_o_) ----上の変更を加えて sh test.sh を実行 $ sh test.sh test 276,279d275 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename $
[この投稿を含むスレッドを表示] [この投稿を削除]
[1190] Re:os
投稿者:まりーえ
2009/01/02 23:40:43

>また、うちのPCでは動かなかった、という方は他にいらっしゃらないでしょうか。 >情報募集中です (_o_) Debian(etch) にて 上の方にある同じ abort エラーがでました. printf デバッグを行って, <<---------------------------------------- --- diksam_unix.org/share/wchar.c 2008-12-08 08:57:15.000000000 +0900 +++ diksam_unix/share/wchar.c 2009-01-02 23:31:16.000000000 +0900 @@ -1,4 +1,5 @@ #include <stdio.h> +#include <errno.h> #include <string.h> #include <wchar.h> #include "DBG.h" @@ -44,10 +45,12 @@ int status; mbstate_t ps; +printf("[%d] src=%s\n", strlen(src), src); memset(&ps, 0, sizeof(mbstate_t)); for (src_idx = dest_idx = 0; src[src_idx] != '\0'; ) { status = mbrtowc(NULL, &src[src_idx], MULTIBYTE_CHAR_SIZE_MAX, &ps); if (status < 0) { +printf("status. %d. errno=%d: %s\n", status, errno, strerror(errno)); return status; } dest_idx++; >>---------------------------------------- [6] src=日本語 status. -1. errno=84: Invalid or incomplete multibyte or wide character [28] src=不正なマルチバイト文字です。 status. -1. errno=84: Invalid or incomplete multibyte or wide character len=-1 Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. Abort ------- % printenv LANG ja_JP.EUC-JP % locale -a locale: Cannot set LC_CTYPE to default locale: No such file or directory locale: Cannot set LC_MESSAGES to default locale: No such file or directory locale: Cannot set LC_COLLATE to default locale: No such file or directory C POSIX ja_JP.utf8 ------- こんな EUC になりきれていない環境です.
[この投稿を含むスレッドを表示] [この投稿を削除]
[1189] Re:os
投稿者:(ぱ)こと管理人
2009/01/02 19:47:50

状況を整理してみます。 ・Linux(Ubuntu 4.1.2-Oubuntu4)←私のところ  →utf-8, EUCともに正常動作 ・Linux(Vine Linux 4.2)  →utf-8では正常動作  →EUCでは、test.dkmにてセグメンテーション違反 その他のスクリプトは、日本語を扱うarray.dkmのようなものを含め、 正常動作。 ・MacOS  →utf-8では正常動作  →EUCでは、以下の現象が発生  ・test.dkmの726行目の'本'という文字リテラルについて、ワイド文字に変換したら   2文字以上と解釈された。  ・array.dkmの46行目の「"hogeほげ".length()」が6を返している。   また、47行目の「"hogeほげほげ".substr(3, 4)」が「eほ&#65533;」を返している。 念のため確認ですが、 ・EUCで動かすときは、「diksam_0_4_02.unix.tgz」をダウンロードして、  これをtar xvzfで展開したフォルダにて、コンパイル、実行をしていますよね?  文字コードの変換等はしていないですよね? ・test.dkmやarray.dkmは、エディタ等で日本語部分を含めちゃんと読めていますよね?  その際、文字コードがEUCであることも、確認できていますよね? MacOSの方はともかくとして、Vine Linuxではarray.dkmの日本語 関連の処理が正常に動いているので、実は文字コード云々は関係 なかった、というオチも考えたのですが、UTF-8版が正常動作して いるなら、やはり何らかの文字コード関係の問題のようです。 うちには今遊んでいるPCはないので、Vineの環境はすぐには作れません。 お手数ですがそちらで以下のテストは可能でしょうか? Vine Linuxにて、以下の修正を実施して、../diksam test.dkmで実行して、 セグメンテーション違反が出るかどうか、よければ試してみてください。 (1)test.dkmの720行目以降をコメントアウト(Diksamでは/* */で囲んでコメントアウト) /* println("日本語"); string str = "日本語"; for (i = 0; i < str.length(); i++) { println("str[" + i + "].." + str[i]); if (str[i] == '本') { println("本"); } } exit(1); println("これは出ない"); */ (2)725~728行目のみをコメントアウト string str = "日本語"; for (i = 0; i < str.length(); i++) { /* println("str[" + i + "].." + str[i]); if (str[i] == '本') { println("本"); } */ } exit(1); println("これは出ない"); また、うちのPCでは動かなかった、という方は他にいらっしゃらないでしょうか。 情報募集中です (_o_)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1188] os
投稿者:つよし
2009/01/02 05:58:45

前橋さん vine linux 4.2 な環境では、再現できませんか? 遊んでいるパソコンあれば環境作れそうですが、むり??
[この投稿を含むスレッドを表示] [この投稿を削除]
[1187] 試行
投稿者:つよし
2009/01/02 05:53:15

>main/main.cの26行目あたりに >setlocale(LC_CTYPE, ""); >という行があるはずですが、これを、 >setlocale(LC_ALL, "ja_JP.EUC-JP"); >に変更し、再コンパイルするとどうなるでしょうか? エラーが出ます。 ------------------vine: sh test.sh test.sh: line 1: 2490 セグメンテーション違反です ../diksam test.dkm >test_.result 2>&1 test 1,279d0 < hoge piyo < \nabc < abccde < 0x123..291 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1 != 3.0..true < 3.0 != 3.0..false < 3.0 >= 1..true < 1 >= 3.0..false < 3.0 > 1..true < 1 > 3.0..false < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1.0 != 3..true < 3 >= 1.0..true < 1.0 >= 3.0..false < 3 > 1.0..true < 1.0 > 3..false < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < int_val..5 < int_val..3 < int_val..9 < int_val..3 < int_val..1 < double_val..5.000000 < double_val..3.000000 < double_val..9.000000 < double_val..3.000000 < double_val..1.000000 < str_val..strhoge3 < int_val..3 < double_val..0.000000 < a..3, b..4.000000 < no_arg < a + b..28 < a + b + c..10.000000 < boolean_func..true < int_func..3 < double_func..3.000000 < string_func..hoge < ********** recursive call ********** < a..10 a..9 a..8 a..7 a..6 a..5 a..4 a..3 a..2 a..1 a..0 < a..0 a..1 a..2 a..3 a..4 a..5 a..6 a..7 a..8 a..9 a..10 < boolean_value..true < !boolean_value..false < true < boolean_value || false < true == true good < true != false good < ! operator good. < true_value == true good < true_value != false good < ! operator good. < true < good < good < good < ********** while statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < ********** for statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < ********** break with label in while ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** break with label in for ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** continue in while ********** < i..5 i..6 i..7 i..8 i..9 i..10 < i..10 < ********** continue in for ********** < i..5 i..6 i..7 i..8 i..9 < i..10 < ********** continue with label in while ********** < i..1 j..0, i..2 j..0, i..3 j..0, < i..3 j..0 < ********** continue with label in for ********** < i..0 j..0, i..1 j..1, i..2 j..2, < i..3 j..3 < *** i..0*** < i == 0 < i != 3 < i != 2 && i != 3 < *** i..1*** < i == 1 < i != 3 < i != 2 && i != 3 < *** i..2*** < i == 2 < i != 3 < i == 2 || i == 3 < i == 2 && j == 3 < *** i..3*** < i == else < i == 2 || i == 3 < *** i..4*** < i == else < i != 3 < i != 2 && i != 3 < i..11 < ii = 10..10 < array[3][0]..10 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < array2[0]..1 < array2[1]..2 < array2[2]..3 < array2[3]..4 < array2[4]..5 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < darray[0]..0.000000 < darray[1]..1.000000 < darray[2]..2.000000 < darray[3]..3.000000 < darray[4]..4.000000 < darray[5]..5.000000 < darray[6]..6.000000 < darray[7]..7.000000 < darray[8]..8.000000 < darray[9]..9.000000 < darray[0]..1.000000 < darray[1]..2.000000 < darray[2]..3.000000 < darray[3]..4.000000 < darray[4]..5.000000 < darray[5]..6.000000 < sarray[0]..str0 < sarray[1]..str1 < sarray[2]..str2 < sarray[3]..str3 < sarray[4]..str4 < sarray[5]..str5 < sarray[6]..str6 < sarray[7]..str7 < sarray[8]..str8 < sarray[9]..str9 < sarray[0]..1 < sarray[1]..2 < sarray[2]..3 < sarray[3]..4 < null_str..null < abcnull < null < OK < OK < OK < OK < 日本語 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename ------------------vine: sh test.sh ------------------macosx: sh test.sh test 1,279c1 < hoge piyo < \nabc < abccde < 0x123..291 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1 != 3.0..true < 3.0 != 3.0..false < 3.0 >= 1..true < 1 >= 3.0..false < 3.0 > 1..true < 1 > 3.0..false < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1.0 != 3..true < 3 >= 1.0..true < 1.0 >= 3.0..false < 3 > 1.0..true < 1.0 > 3..false < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < int_val..5 < int_val..3 < int_val..9 < int_val..3 < int_val..1 < double_val..5.000000 < double_val..3.000000 < double_val..9.000000 < double_val..3.000000 < double_val..1.000000 < str_val..strhoge3 < int_val..3 < double_val..0.000000 < a..3, b..4.000000 < no_arg < a + b..28 < a + b + c..10.000000 < boolean_func..true < int_func..3 < double_func..3.000000 < string_func..hoge < ********** recursive call ********** < a..10 a..9 a..8 a..7 a..6 a..5 a..4 a..3 a..2 a..1 a..0 < a..0 a..1 a..2 a..3 a..4 a..5 a..6 a..7 a..8 a..9 a..10 < boolean_value..true < !boolean_value..false < true < boolean_value || false < true == true good < true != false good < ! operator good. < true_value == true good < true_value != false good < ! operator good. < true < good < good < good < ********** while statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < ********** for statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < ********** break with label in while ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** break with label in for ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** continue in while ********** < i..5 i..6 i..7 i..8 i..9 i..10 < i..10 < ********** continue in for ********** < i..5 i..6 i..7 i..8 i..9 < i..10 < ********** continue with label in while ********** < i..1 j..0, i..2 j..0, i..3 j..0, < i..3 j..0 < ********** continue with label in for ********** < i..0 j..0, i..1 j..1, i..2 j..2, < i..3 j..3 < *** i..0*** < i == 0 < i != 3 < i != 2 && i != 3 < *** i..1*** < i == 1 < i != 3 < i != 2 && i != 3 < *** i..2*** < i == 2 < i != 3 < i == 2 || i == 3 < i == 2 && j == 3 < *** i..3*** < i == else < i == 2 || i == 3 < *** i..4*** < i == else < i != 3 < i != 2 && i != 3 < i..11 < ii = 10..10 < array[3][0]..10 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < array2[0]..1 < array2[1]..2 < array2[2]..3 < array2[3]..4 < array2[4]..5 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < darray[0]..0.000000 < darray[1]..1.000000 < darray[2]..2.000000 < darray[3]..3.000000 < darray[4]..4.000000 < darray[5]..5.000000 < darray[6]..6.000000 < darray[7]..7.000000 < darray[8]..8.000000 < darray[9]..9.000000 < darray[0]..1.000000 < darray[1]..2.000000 < darray[2]..3.000000 < darray[3]..4.000000 < darray[4]..5.000000 < darray[5]..6.000000 < sarray[0]..str0 < sarray[1]..str1 < sarray[2]..str2 < sarray[3]..str3 < sarray[4]..str4 < sarray[5]..str5 < sarray[6]..str6 < sarray[7]..str7 < sarray[8]..str8 < sarray[9]..str9 < sarray[0]..1 < sarray[1]..2 < sarray[2]..3 < sarray[3]..4 < null_str..null < abcnull < null < OK < OK < OK < OK < 日本語 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 --- > test.dkm:726:文字リテラルが2文字以上あります。 array 6,7c6,7 < len..6 < substr..eほげほ --- > len..8 > substr..eほ&#65533; class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename ------------------macosx: sh test.sh
[この投稿を含むスレッドを表示] [この投稿を削除]
[1186] Re:UTFをEUCへ:実行 Vine
投稿者:(ぱ)こと管理人
2009/01/02 02:42:57

情報ありがとうございます。 >Vine4.2 (EUC-jpな環境)において >(1) EUC-jp->tar zxvf->--------------コンパイル->sh test.sh->の結果 と >(2) UTF-8-->tar zxvf->EUC-jpへ変換->コンパイル->sh test.sh->の結果 は 現在の、EUC/UTF-8の配布パッケージは、プログラムは同じで単に文字コードが 違うだけですから、これが同じ結果になるのはわかります。 しかし、当方では、つよしさんのところと同じ現象は今のところ再現しません。 main/main.cの26行目あたりに setlocale(LC_CTYPE, ""); という行があるはずですが、これを、 setlocale(LC_ALL, "ja_JP.EUC-JP"); に変更し、再コンパイルするとどうなるでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1185] Re:UTFをEUCへ:実行 Vine
投稿者:つよし
2009/01/01 20:50:27

試したことを書きます。 Vine4.2 (EUC-jpな環境)において (1) EUC-jp->tar zxvf->--------------コンパイル->sh test.sh->の結果 と (2) UTF-8-->tar zxvf->EUC-jpへ変換->コンパイル->sh test.sh->の結果 は 1行目のエラーメッセージだけ、一部違いました。 < test.sh: line 1: 17811 セグメンテーション違反です ../diksam test.dkm >test_.result 2>&1 --- > test.sh: line 1: 17754 セグメンテーション違反です ../diksam test.dkm >test_.result 2>&1
[この投稿を含むスレッドを表示] [この投稿を削除]
[1184] UTFをEUCへ:実行 Mac
投稿者:つよし
2009/01/01 20:36:55

前橋さん 試したことを書きます。 MacOSX10.3.9(EUC-jpな環境)において (1) EUC-jp->tar zxvf->--------------コンパイル->sh test.sh->の結果 と (2) UTF-8-->tar zxvf->EUC-jpへ変換->コンパイル->sh test.sh->の結果 は   100% 一致しました。 文字コードは、すべて EUC-jp で実行?しました。 diksam うまくコンパイルできていないのか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1183] Re:EUC環境 Mac Vine
投稿者:(ぱ)こと管理人
2009/01/01 17:51:37

>vine4.2 >test.sh: line 1: 3405 セグメンテーション違反です ../diksam test.dkm こちらは単に死んでしまっているので、ちょっとわからないですが、 >MacOSX10.3.9 >> test.dkm:726:文字リテラルが2文字以上あります。 >array >6,7c6,7 >< len..6 >< substr..eほげほ >--- >> len..8 >> substr..eほ&#65533; こちらを見ると、 ・test.dkmの726行目の'本'という文字リテラルについて、ワイド文字に変換したら  2文字以上と解釈された。 ・array.dkmの46行目の「"hogeほげ".length()」が6を返している。  また、47行目の「"hogeほげほげ".substr(3, 4)」が「eほ&#65533;」を返している。 ということがわかります。マルチバイト文字列の変換に関する問題のようです。 確認ですが、test.dkmやarray.dkmの文字コードは何になっていますか? EUCモードで実行する際は、.dkmファイルもEUCでなければなりません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1182] EUC環境 Mac Vine
投稿者:つよし
2009/01/01 16:23:16

EUCな環境 MacOSX10.3.9 と vine4.2 での $ sh test.sh の結果です。 長いです。 -------------------------------------- vine4.2 test.sh: line 1: 3405 セグメンテーション違反です ../diksam test.dkm >test_.result 2>&1 test 1,279d0 < hoge piyo < \nabc < abccde < 0x123..291 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1 != 3.0..true < 3.0 != 3.0..false < 3.0 >= 1..true < 1 >= 3.0..false < 3.0 > 1..true < 1 > 3.0..false < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1.0 != 3..true < 3 >= 1.0..true < 1.0 >= 3.0..false < 3 > 1.0..true < 1.0 > 3..false < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < int_val..5 < int_val..3 < int_val..9 < int_val..3 < int_val..1 < double_val..5.000000 < double_val..3.000000 < double_val..9.000000 < double_val..3.000000 < double_val..1.000000 < str_val..strhoge3 < int_val..3 < double_val..0.000000 < a..3, b..4.000000 < no_arg < a + b..28 < a + b + c..10.000000 < boolean_func..true < int_func..3 < double_func..3.000000 < string_func..hoge < ********** recursive call ********** < a..10 a..9 a..8 a..7 a..6 a..5 a..4 a..3 a..2 a..1 a..0 < a..0 a..1 a..2 a..3 a..4 a..5 a..6 a..7 a..8 a..9 a..10 < boolean_value..true < !boolean_value..false < true < boolean_value || false < true == true good < true != false good < ! operator good. < true_value == true good < true_value != false good < ! operator good. < true < good < good < good < ********** while statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < ********** for statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < ********** break with label in while ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** break with label in for ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** continue in while ********** < i..5 i..6 i..7 i..8 i..9 i..10 < i..10 < ********** continue in for ********** < i..5 i..6 i..7 i..8 i..9 < i..10 < ********** continue with label in while ********** < i..1 j..0, i..2 j..0, i..3 j..0, < i..3 j..0 < ********** continue with label in for ********** < i..0 j..0, i..1 j..1, i..2 j..2, < i..3 j..3 < *** i..0*** < i == 0 < i != 3 < i != 2 && i != 3 < *** i..1*** < i == 1 < i != 3 < i != 2 && i != 3 < *** i..2*** < i == 2 < i != 3 < i == 2 || i == 3 < i == 2 && j == 3 < *** i..3*** < i == else < i == 2 || i == 3 < *** i..4*** < i == else < i != 3 < i != 2 && i != 3 < i..11 < ii = 10..10 < array[3][0]..10 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < array2[0]..1 < array2[1]..2 < array2[2]..3 < array2[3]..4 < array2[4]..5 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < darray[0]..0.000000 < darray[1]..1.000000 < darray[2]..2.000000 < darray[3]..3.000000 < darray[4]..4.000000 < darray[5]..5.000000 < darray[6]..6.000000 < darray[7]..7.000000 < darray[8]..8.000000 < darray[9]..9.000000 < darray[0]..1.000000 < darray[1]..2.000000 < darray[2]..3.000000 < darray[3]..4.000000 < darray[4]..5.000000 < darray[5]..6.000000 < sarray[0]..str0 < sarray[1]..str1 < sarray[2]..str2 < sarray[3]..str3 < sarray[4]..str4 < sarray[5]..str5 < sarray[6]..str6 < sarray[7]..str7 < sarray[8]..str8 < sarray[9]..str9 < sarray[0]..1 < sarray[1]..2 < sarray[2]..3 < sarray[3]..4 < null_str..null < abcnull < null < OK < OK < OK < OK < 日本語 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename -------------------------------------- MacOSX10.3.9 test 1,279c1 < hoge piyo < \nabc < abccde < 0x123..291 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3 + 5..8 < 3 - 5..-2 < 3 + -5..-2 < 3 * 5..15 < 3 / 5..0 < 10 % 3..1 < 3.0 + 5.0..8.000000 < 3.0 - 5.0..-2.000000 < 3.0 + -5.0..-2.000000 < 3.0 * 5.0..15.000000 < 3.0 / 5.0..0.600000 < 10.0 % 3.0..1.000000 < 3 + 5.0..8.000000 < 3 - 5.0..-2.000000 < 3 + -5.0..-2.000000 < 3 * 5.0..15.000000 < 3 / 5.0..0.600000 < 10 % 3.0..1.000000 < 1 & 3..1 < 1 | 2..3 < 1 ^ 3..2 < ~5..-6 < 3.0 + 5..8.000000 < 3.0 - 5..-2.000000 < 3.0 + -5..-2.000000 < 3.0 * 5..15.000000 < 3.0 / 5..0.600000 < 10.0 % 3..1.000000 < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1 != 3.0..true < 3.0 != 3.0..false < 3.0 >= 1..true < 1 >= 3.0..false < 3.0 > 1..true < 1 > 3.0..false < 1 < 3..true < 3 < 1..false < 1 <= 3..true < 3 <= 1..false < 1 == 1..true < 1 == 3..false < 1 != 3..true < 3 != 3..false < 1 >= 3..false < 3 >= 1..true < 3 > 1..true < 1 > 3..false < 1.0 < 3..true < 3 < 1.0..false < 1.0 <= 3..true < 3 <= 1.0..false < 1.0 == 1.0..true < 1.0 == 3..false < 1.0 != 3..true < 3 >= 1.0..true < 1.0 >= 3.0..false < 3 > 1.0..true < 1.0 > 3..false < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < == good. < != good. < < good. < <= good. < <= good. < >= good. < >= good. < int_val..5 < int_val..3 < int_val..9 < int_val..3 < int_val..1 < double_val..5.000000 < double_val..3.000000 < double_val..9.000000 < double_val..3.000000 < double_val..1.000000 < str_val..strhoge3 < int_val..3 < double_val..0.000000 < a..3, b..4.000000 < no_arg < a + b..28 < a + b + c..10.000000 < boolean_func..true < int_func..3 < double_func..3.000000 < string_func..hoge < ********** recursive call ********** < a..10 a..9 a..8 a..7 a..6 a..5 a..4 a..3 a..2 a..1 a..0 < a..0 a..1 a..2 a..3 a..4 a..5 a..6 a..7 a..8 a..9 a..10 < boolean_value..true < !boolean_value..false < true < boolean_value || false < true == true good < true != false good < ! operator good. < true_value == true good < true_value != false good < ! operator good. < true < good < good < good < ********** while statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < ********** for statement ********** < i..0 i..1 i..2 i..3 i..4 i..5 i..6 < i..0 i..1 i..2 i..3 i..4 i..5 i..6 i..7 i..8 i..9 < ********** break with label in while ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** break with label in for ********** < i..0, j..0 < i..0, j..1 < i..0, j..2 < i..0, j..3 < i..0, j..4 < i..0, j..5 < ********** continue in while ********** < i..5 i..6 i..7 i..8 i..9 i..10 < i..10 < ********** continue in for ********** < i..5 i..6 i..7 i..8 i..9 < i..10 < ********** continue with label in while ********** < i..1 j..0, i..2 j..0, i..3 j..0, < i..3 j..0 < ********** continue with label in for ********** < i..0 j..0, i..1 j..1, i..2 j..2, < i..3 j..3 < *** i..0*** < i == 0 < i != 3 < i != 2 && i != 3 < *** i..1*** < i == 1 < i != 3 < i != 2 && i != 3 < *** i..2*** < i == 2 < i != 3 < i == 2 || i == 3 < i == 2 && j == 3 < *** i..3*** < i == else < i == 2 || i == 3 < *** i..4*** < i == else < i != 3 < i != 2 && i != 3 < i..11 < ii = 10..10 < array[3][0]..10 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < array2[0]..1 < array2[1]..2 < array2[2]..3 < array2[3]..4 < array2[4]..5 < 1 2 3 4 5 6 7 8 9 < 2 4 6 8 10 12 14 16 18 < 3 6 9 12 15 18 21 24 27 < 4 8 12 16 20 24 28 32 36 < 5 10 15 20 25 30 35 40 45 < 6 12 18 24 30 36 42 48 54 < 7 14 21 28 35 42 49 56 63 < 8 16 24 32 40 48 56 64 72 < 9 18 27 36 45 54 63 72 81 < darray[0]..0.000000 < darray[1]..1.000000 < darray[2]..2.000000 < darray[3]..3.000000 < darray[4]..4.000000 < darray[5]..5.000000 < darray[6]..6.000000 < darray[7]..7.000000 < darray[8]..8.000000 < darray[9]..9.000000 < darray[0]..1.000000 < darray[1]..2.000000 < darray[2]..3.000000 < darray[3]..4.000000 < darray[4]..5.000000 < darray[5]..6.000000 < sarray[0]..str0 < sarray[1]..str1 < sarray[2]..str2 < sarray[3]..str3 < sarray[4]..str4 < sarray[5]..str5 < sarray[6]..str6 < sarray[7]..str7 < sarray[8]..str8 < sarray[9]..str9 < sarray[0]..1 < sarray[1]..2 < sarray[2]..3 < sarray[3]..4 < null_str..null < abcnull < null < OK < OK < OK < OK < 日本語 < str[0]..26085 < str[1]..26412 < 本 < str[2]..35486 --- > test.dkm:726:文字リテラルが2文字以上あります。 array 6,7c6,7 < len..6 < substr..eほげほ --- > len..8 > substr..eほ&#65533; class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename --------------------------------------
[この投稿を含むスレッドを表示] [この投稿を削除]
[1181] Re:あけましておめでとうございます!
投稿者:(ぱ)こと管理人
2009/01/01 13:08:26

>EUC な環境をにわかに準備して test.sh を実行しました。 ... >diff が差分を吐き出します。 まず、[1178]につよしさんが貼ってくださった実行結果は、正常に動いています。 UTF-8版は正しく動いたが、EUC版は正しく動かなかった、ということでしょうか? うちではUTF-8版もEUC版も、test.shは流して正常動作を確認しています。 つよしさんのところで動かなかったのだとしたら、そのdiffが吐いた差分を 貼っていただかないと何がおきているのかわからないです。さすがに。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1180] あけましておめでとうございます
投稿者:(ぱ)こと管理人
2009/01/01 13:04:37

あけましておめでとうございます。 今年もよろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1179] あけましておめでとうございます!
投稿者:つよし
2009/01/01 00:53:29

前橋さん 2009年 平成21年 1月 1日 元日 さっそく仕事始めです=嘘です。 EUC な環境をにわかに準備して test.sh を実行しました。 実は、 このパソコンは、メモリテストでエラーが出ますがVine4.2をインストールできました。 なぜかエラーは出ません。見かけはだいじょうぶ? このようなパソコンで test.sh を実行するのは、正常な精神ではありませんが、、笑い。 diff が差分を吐き出します。 前橋さん 追試をお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1178] Re:Linuxコンパイルエラー
投稿者:つよし
2008/12/31 23:14:34

前橋さん 今年もあとわずか!!来年も発展を願います!! アップ試しました。 気持ちよく実行できました。 ありがとうございます。 $ sh test.sh test array class01 class02 class03 method cast classmain downcast instanceof super exception shapemain throws nullpointer array_ex else_ex test switch final do_while enum delegate rename $ ># いまどきEUCは時代錯誤か…… 確かに。 > 個人的には、EUCな環境の方を使っていた時間が長いですが!!
[この投稿を含むスレッドを表示] [この投稿を削除]
[1177] Re:Linuxコンパイルエラー
投稿者:(ぱ)こと管理人
2008/12/31 02:25:31

>というわけで、あわせて修正した版をもうじきUPします。 UPしました。 私のところではこれで動いています。 test.dkm以外のサンプルプログラムは、テスト用シェルスクリプトtest.shを使って、 % sh ./test.sh のようにすればまとめて実行できます。これで、test以下の.dkmのファイル名から 拡張子を除いたものの名前だけがずらずらと出れば成功、diffが相違を検出したら なにか問題が起きてます。 なにかあれば教えてください。 いろいろと報告ありがとうございました > つよしさん # いまどきEUCは時代錯誤か…… 確かに。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1176] Re:Linuxコンパイルエラー
投稿者:(ぱ)こと管理人
2008/12/31 01:45:36

>$ cd test/ >$ echo $LANG >ja_JP.UTF-8 >$ find . -type f -exec nkf -w --overwrite {} \; すみません、見落としていましたが(前回の投稿のコマンドプロンプトのところに 形跡がありました…)、この変換はmain/test以下でやっていたのですね。 Diksamは、エラーメッセージを日本語で出します(これはこれでどうかという 人もいそうですが)。また、そのエラーメッセージは、compilerとdvm以下の error_message.cに埋め込まれています。 現在ダウンロードできるDiksamのソースでは、error_message.cの文字コードが EUCになっています。以下のエラーは、これをDiksamの内部文字コード(wchar_t)に 変換しようとして失敗しているために発生しています。 >$ ../diksam test.dkm >Assertion failure (wc_format != NULL) file..error.c line..92 >wc_format is null. よって、LANGがja_JP.UTF-8な環境で動かすには、コンパイル前に、 error_message.cをUTF-8に変換しなければなりません。 それだけで動くかと思って試してみたところ、share/wchar.cの中に 1文字分のマルチバイト文字列が2文字までであることを想定しているところが あって、UTF-8だと1文字が3バイトになるのでそこでもエラーが出ました。 というわけで、あわせて修正した版をもうじきUPします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1175] Re:Linuxコンパイルエラー
投稿者:つよし
2008/12/30 23:58:09

前橋さん こんばんは 初心者なので最初からやり直しました。 端末のコピーアンドペースとです。 ここから $ tar zxvf diksam_0_4_01_unix.tgz $ cd diksam_unix/main/ $ make <省略> cc ../compiler/compiler.o ../compiler/builtin/builtin.o ../dvm/dvm.o ../share/share.o ../memory/mem.o ../debug/dbg.o ./main.o -o diksam -lm $ cd test/ $ echo $LANG ja_JP.UTF-8 $ find . -type f -exec nkf -w --overwrite {} \; $ ../diksam test.dkm Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. アボートしました $ ここまで。。。 一つ前の前橋さんの書き込みすべて理解できていません。 僕にできるのは、こんな感じです。いじょう~ debian lenny
[この投稿を含むスレッドを表示] [この投稿を削除]
[1174] Re:Linuxコンパイルエラー
投稿者:(ぱ)こと管理人
2008/12/30 22:47:03

>utf-8 なコードを diksam は受け付けない >ということですか?! >utf な環境は、多いです!! Diksamを作り始めた頃は、まだUTF-8が主流ではなかった、ような気がしているの ですが(私が遅れていただけかもしれません)、最近は確かにUTF-8な環境がかなり 多くなっていますね。 >@~/Desktop/diksam_unix/main/test$ find . -exec nkf -w -overwrite {} \; >で utf-8 に変換し実行するとエラーになります。 ところでこれですが、この時、$LANGは何になっていたでしょうか? >Assertion failure (wc_format != NULL) file..error.c line..92 >wc_format is null. これを見る限り、error_message.c内の日本語文字列(UTF-8に変換されている)を ワイド文字列に変換しようとして失敗しているようです。 Diksamは、現在のデフォルトエンコーディングでマルチバイト文字列をワイド文字列に 変換しようとします(main.cに「setlocale(LC_CTYPE, "");」と書いてあります)。 よって、現在の$LANGがja_JP.EUC-JP等になっていれば、正しく変換できません。 >utf-8 なコードを diksam は受け付けない >ということですか?! で、この件ですが、ソースを確認してみたところ、error_message.cをUTF-8に 変換してコンパイルされており、環境も正しくUTF-8になっていれば、UTF-8を 受け付けるのではないかと思います(まだ試せていません)。 先の投稿でUTF-8に未対応、ということを書きましたが、本来、普通に8bitを 通しさえすれば、UTF-8は文字列リテラル等に問題なく使えるはずです(UTF-8という のはそういうことを意図したエンコーディングです)。にも関わらず、crowbarで UTF-8対応がわざわざ必要になったのは、Shift-JIS対応のため特定のバイトの次の バイトを特別扱いする、という対応をしているためで、Diksamをよく見てみたら、 そもそもShift-JISの対応が入っていませんでした… というわけで、現在のWindows版のDiksamは、ソースがShift-JISであることを 期待しているにもかかわらず、「表」等の文字を文字列リテラルに入れると エラーになります(いわゆる0x5C問題)。Diksam on Windowsとか言っときながらこれは さすがにまずいので、早急に対応します。 >他 少し試しましたが セグメンテーションエラーとか いろいろ、、、 さすがの私もtest.shくらいは流してから出してますので、testディレクトリ以下の ものが動かないなら、何らかの環境に依存する問題かと思います。 できれば詳細を教えてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1173] ./test/*
投稿者:つよし
2008/12/30 22:20:22

前橋さん >$ ../diksam rand.dkm は、実行確認できました。 >他 少し試しましたが セグメンテーションエラーとか いろいろ、、、 他、いくつか実行出来ました。 エラーが出るのは、引数とか?与えないといけないのかな? $ ../diksam mathtest.dkm ok!! $ ../diksam downcast.dkm ok!! etc...
[この投稿を含むスレッドを表示] [この投稿を削除]
[1172] Re:Linuxコンパイルエラー
投稿者:つよし
2008/12/30 21:59:16

前橋さん ありがとうございます。 @~/Desktop/diksam_unix/main/test$ find . -exec nkf -w -overwrite {} \; で utf-8 に変換し実行するとエラーになります。 @~/Desktop/diksam_unix/main/test$ ../diksam test.dkm Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. Assertion failure (wc_format != NULL) file..error.c line..92 wc_format is null. アボートしました @~/Desktop/diksam_unix/main/test$ そもそも utf-8 なコードを diksam は受け付けない ということですか?! utf な環境は、多いです!! $ ../diksam rand.dkm は、実行確認できました。 他 少し試しましたが セグメンテーションエラーとか いろいろ、、、
[この投稿を含むスレッドを表示] [この投稿を削除]
[1171] Re:Linuxコンパイルエラー
投稿者:(ぱ)こと管理人
2008/12/30 21:22:01

>../diksam test.dkm > >と実行してみるのはどうでしょうか。 追記ですが、 このtest.dkmは日本語を含みますが、文字コードはEUCです。 現時点のLinux版diksamはEUCのソースしか受け付けないので、UTF-8な環境では 環境の設定を変えるか日本語部分を削ったほうがよいかもしれません。 # crowbarの最新版(未公開)ではUTF-8にも対応しているので、 # 同じ修正をDiksamにも入れようと思いつつ忘れてました…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1170] Re:Linuxコンパイルエラー
投稿者:(ぱ)こと管理人
2008/12/30 15:25:44

>diksam がうまく動くか 試したいのですが? mainディレクトリの下にtestディレクトリがあります。 その下で ../diksam test.dkm と実行してみるのはどうでしょうか。 同じディレクトリにあるシェルスクリプト「test.sh」は、そこにある テストスクリプトを一括実行し、正しい結果とdiffを取ります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1169] Re:Linuxコンパイルエラー
投稿者:つよし
2008/12/30 15:21:44

前橋さん ありがとうございます。 $ sudo aptitude install bison $ sudo aptitude install flex $ pwd /home/tntn/Desktop/diksam_unix/main $ make 以上で diksam を作成できました。 diksam がうまく動くか 試したいのですが?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1168] Re:Linuxコンパイルエラー
投稿者:(ぱ)こと管理人
2008/12/30 13:31:04

つよしさん、はじめまして。 >debian lenny でコンパイルエラーになります。 >何が足りないのでしょうか? >gcc は、4.3 ヴァージョンをインストールしました。 >$ make … >make[1]: yacc: コマンドが見つかりませんでした 見てのとおり、yaccが入っていません。 Debianなら、bisonをパッケージインストールすれば、シンボリックリンクを 勝手に作って、「yacc」で実行できるようになったような気がします。 gccやyaccが標準で入っていない環境なら、おそらくlexも入っていないでしょうから、 flexも入れる必要がありそうです。 もし、bisonやflexは入れたけれど「yacc」や「lex」としては実行できない、 ということなら、compilerディレクトリ以下のMakefileを修正し、 yacc -dv diksam.y となっているところ(2箇所)を、 bison --yacc -dv diksam.y に、 lex diksam.l となっているところを flex diksam.l にしてください。 それはそれとして、 >(Linux版では、Uフォーは、ダメですか?:入門者) 残念ながらダメです……
[この投稿を含むスレッドを表示] [この投稿を削除]
[1167] Linuxコンパイルエラー
投稿者:つよし
2008/12/30 01:33:32

前橋さま debian lenny でコンパイルエラーになります。 何が足りないのでしょうか? gcc は、4.3 ヴァージョンをインストールしました。 (Linux版では、Uフォーは、ダメですか?:入門者) $ make cd ../compiler; make; make[1]: ディレクトリ `/home/tntn/Desktop/diksam_unix/compiler' に入ります yacc -dv diksam.y make[1]: yacc: コマンドが見つかりませんでした make[1]: *** [y.tab.h] エラー 127 make[1]: ディレクトリ `/home/tntn/Desktop/diksam_unix/compiler' から出ます make: *** [../compiler/compiler.o] エラー 2 $
[この投稿を含むスレッドを表示] [この投稿を削除]
[1166] Diksam on Windows
投稿者:つよし
2008/12/30 01:21:04

前橋さま ウィンドウズ版Diksamの公開おめでとうございます。 Uフォーの絵 見ました。それが動いたりするのですか?すごい!! Linuxから書き込んでいますが、Linuxでは、Uフォーは出来ないのかな?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1164] Re:前橋言語:on MacOSX
投稿者:(ぱ)こと管理人
2008/11/12 02:00:49

こんにちは。 >前橋言語の作例は、ありませんか? すみません、今のところサンプルプログラムとしては配布ディレクトリの compiler/test以下にあるものぐらいしかないです。 >パズルとか電卓とか? >前橋さんの電卓ネタを前橋言語で書き換えるとか? Diksam用のyaccはないので、再帰下降パーサを手書きすれば電卓ぐらいは 作れそうではありますが、文字列処理の手段がsubstr()しかなくて、 もちろんそれでもできますけれど効率が悪いので、"abc"[2]で'c'が取れるように したりとか、当然同時に文字リテラルも必要になって、とか、 いずれにしてもライブラリがこれではたいした物は作れないのでライブラリを 補強して、とか、やりたいことはいくつもありますし実現も難しくないのですが、 何をするにも時間が不足しております。 ライブラリの方は現在追加してまして、近々、何かしらちょっとは楽しいプログラムが 作れるようにしようとは思っているのですが。 すみません、Macユーザのたろうさんには大変申し訳ないのですが、今度追加される ライブラリ部分は当面Windows専用になります…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1163] Re:前橋言語:on MacOSX
投稿者:たろう
2008/11/11 15:40:20

管理人(前橋)さま 前橋言語の作例は、ありませんか? パズルとか電卓とか? 前橋さんの電卓ネタを前橋言語で書き換えるとか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1162] Re:前橋言語:on MacOSX
投稿者:(ぱ)こと管理人
2008/11/08 13:23:28

>>$(CC) $(CFLAGS) -o $@ -I../../include builtin_conv.c $(CONV_OBJS) >> ↑ >> >>としてやればうまくいくのではないでしょうか。 > >前橋さん >コンパイル通りました。 情報ありがとうございます。次回リリースからは、Makefileを修正しておきます。 Macでも動いたということで、嬉しいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1161] Re:前橋言語:再帰
投稿者:たろう
2008/11/08 02:24:05

再帰も出来ますね!あたりまえ? 何か使えそうな気配です!! $ vi saiki int fact(int n) { if (n==0) { return 1; } else { return n*fact(n-1); } } println(fact(3)); println(fact(4)); println(fact(5)); println(fact(10)); $ diksam saiki 6 24 120 3628800 $
[この投稿を含むスレッドを表示] [この投稿を削除]
[1160] Re:前橋言語:on MacOSX
投稿者:たろう
2008/11/08 01:21:37

> >ここでこういうエラーが出ているということは、diksamの展開ディレクトリ以下の、 >compiler/builtinディレクトリのMakefileの20行目の > >$(CC) $(CFLAGS) -o$@ -I../../include builtin_conv.c $(CONV_OBJS) > >の「-o$@」の「-o」と「$@」の間に空白を入れ、 > >$(CC) $(CFLAGS) -o $@ -I../../include builtin_conv.c $(CONV_OBJS) > ↑ > >としてやればうまくいくのではないでしょうか。 前橋さん コンパイル通りました。 感謝、感激です。 ありがとうございます。 試してみました。 スキル不足でこんなのでいい? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ $ vi ppp.dk println("hello, たろう."); int s = 0; int i; for (i=1; i<=10; i=i+1) { s += i; print(i); println(" たろう"); } $ diksam ppp.dk hello, たろう. 1 たろう 2 たろう 3 たろう 4 たろう 5 たろう 6 たろう 7 たろう 8 たろう 9 たろう 10 たろう $ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 以上。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1159] Re:前橋言語:on MacOSX
投稿者:(ぱ)こと管理人
2008/11/08 00:41:46

こんにちは。 > マックosx で、コンパイルしたいのですが可能ですか? >powerpc g3 インテルマックでは、ありません。 (略) >ld: unknown flag: -obuiltin_conv MacOS XのCコンパイラがどんなコンパイラなのか私は知らないのですが、 「-obuiltin_conv」というオプションはないよ、というエラーを出しています。 ここは、「-o」というフラグで実行形式の名前を指定しているところで、 私の知っているたいていのコンパイラでは、-oの後ろに空白を入れても入れなくても OKでした。 ここでこういうエラーが出ているということは、diksamの展開ディレクトリ以下の、 compiler/builtinディレクトリのMakefileの20行目の $(CC) $(CFLAGS) -o$@ -I../../include builtin_conv.c $(CONV_OBJS) の「-o$@」の「-o」と「$@」の間に空白を入れ、 $(CC) $(CFLAGS) -o $@ -I../../include builtin_conv.c $(CONV_OBJS) ↑ としてやればうまくいくのではないでしょうか。 確証はありませんが >ld -r -o mem.o memory.o storage.o このへんでは-oオプションがちゃんと効いているところからすると可能性は 高いと思います。 実際に試してくださった方がいらっしゃると励みになります。ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1158] 前橋言語:on MacOSX
投稿者:たろう
2008/11/07 20:04:47

diksam_0_4_unix.tgz 前橋さま  マックosx で、コンパイルしたいのですが可能ですか? powerpc g3 インテルマックでは、ありません。 makeの実行画面を示します。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ $ tar zxf diksam_0_4_unix.tgz $ ls diksam_0_4_unix.tgz diksam_unix/ $ cd diksam_unix/compiler/ $ make yacc -dv diksam.y lex diksam.l cc -c -g lex.yy.c -I/usr/local/include -I../include cc -c -g y.tab.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG main.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG interface.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG create.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG fix_tree.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG generate.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG string.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG wchar.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG util.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG error.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG error_message.c -I/usr/local/include -I../include cc -c -g -Wall -ansi -Wswitch-enum -DDEBUG builtin/builtin.c -I/usr/local/include -I../include cd ../dvm; make; cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include execute.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include load.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include heap.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include native.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include nativeif.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include wchar.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include util.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include error.c cc -c -g -DDEBUG -Wall -ansi -Wswitch-enum -I../include error_message.c ld -r -o dvm.o execute.o load.o heap.o native.o nativeif.o wchar.o util.o error.o error_message.o cd ../share; make; cc -c -g -I../include -DDEBUG -Wall -ansi -Wswitch-enum -I../include dispose.c cc -c -g -I../include -DDEBUG -Wall -ansi -Wswitch-enum -I../include opcode.c cc -c -g -I../include -DDEBUG -Wall -ansi -Wswitch-enum -I../include disassemble.c cc -c -g -I../include -DDEBUG -Wall -ansi -Wswitch-enum -I../include wchar.c cc -c -g -I../include -DDEBUG -Wall -ansi -Wswitch-enum -I../include util.c ld -r -o share.o dispose.o opcode.o disassemble.o wchar.o util.o cd ../memory; make; cc -c -g -DDEBUG -Wall -I../include memory.c cc -c -g -DDEBUG -Wall -I../include storage.c ld -r -o mem.o memory.o storage.o cd ../debug; make; cc -c -g -Wall -DDBG_NO_DEBUG -I../include debug.c ld -r -o dbg.o debug.o cd ./builtin; make; cc -g -DDEBUG -Wall -ansi -Wswitch-enum -obuiltin_conv -I../../include builtin_conv.c ../../memory/memory.o ../../debug/debug.o ld: unknown flag: -obuiltin_conv make[1]: *** [builtin_conv] Error 1 make: *** [diksam] Error 2 $ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[この投稿を含むスレッドを表示] [この投稿を削除]
[1157] Re:業務連絡
投稿者:(ぱ)こと管理人
2008/10/29 01:47:37

ローカルにPHP5の環境を作ったのですが、デフォルトのphp.iniの設定が違いすぎていて、まだ一部動かせていません。 magic_quotes_gpcはOffだわ(これは正しいのですが)、asp_tagsはOffだわ、short_open_tagもOffだわで、これではサーバがPHP5に移行した際、どんな設定になっているかが問題のように思います。 ……と思っていたら、どうもPHPの移行には混在期間があって、当面は今のままで動くようです(PHP5にしたければ拡張子を変えろと)。なので今日はもう寝ます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1156] 業務連絡
投稿者:(ぱ)こと管理人
2008/10/27 02:12:04

この掲示板(を含むうちのWebページ一式)をホスティングしてくれている会社から、 以下の通知が来ました。 >この度、Zend社のPHP4サポート終了の告知を受けまして、サーバーシステムの >保全のため、PHP5へのアップデートを行います。全共用サーバーにおきまして、 >PHP4のご利用ができなくなります。至急設置スクリプトの対応状況をご確認、 >更新をお願いいたします。 この通知が来たのはだいぶ前のことなのですが、いろいろあって放置しているうちに、 変更の期日が10/29に迫ってしまいました。 この掲示板を作った時点の環境は当時のPCが壊れた時点で失われていて、 今現状のLet's Noteの環境にPHPとApacheを入れてみたのですが、まだPHPが 動かせていないようです。 もうちょっといじってみるつもりですが、10/29の時点でこの掲示板が動かなく なっていたら、それが原因とお考えくださいませ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1155] Re:プログラミングコンテスト
投稿者:(ぱ)こと管理人
2008/10/27 01:25:13

>(ぱ)さんが、賞金1万円出して >(ぱ)さんが作ったOSで、プログラミングコンテストをする。 OSを作った覚えはないので、プログラミング言語ですかね。 1万円というと、いにしえのBASICマガジンの原稿料がそれぐらいだったと思います。 ベーマガ相当のプログラムが集まるのなら、最優秀賞に1万円くらい出すのは 惜しくないですが、結局ほとんど集まらず、hello, worldに1万円出すハメに なったりして。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1154] プログラミングコンテスト
投稿者:つんつん
2008/10/26 19:02:23

(ぱ)さんが、賞金1万円出して (ぱ)さんが作ったOSで、プログラミングコンテストをする。 無責任な書き込みでした。本気!
[この投稿を含むスレッドを表示] [この投稿を削除]
[1153] Re:makeファイル中のリダイレクト
投稿者:tos
2008/08/28 17:32:49

今回実行していた「app.exe」が処理が成功しているにもかかわらず、 '1'を返していたため、makeが その戻り値を検出し、処理を停止してしまって いたようです。 ('-'を付加することにより逃げました。) 774RRさんありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1152] Re:makeファイル中のリダイレクト
投稿者:tos
2008/08/28 15:01:40

返信、ありがとうございます。 >なので app.exe target.dat 0<source.dat は本質的に正しい入力であって、 なるほど、そうなんですか。 >なので 0< となるのは「実行できない」の原因ではないと思われまっする。 >「実行できない」の詳細について記載がないのでこれ以上の判断は出来ません。 >本体プログラム側のバグを疑ってください。 今回実行したい「app.exe」が特にエラーメッセージを表示せず、 何故実行できないのかわからなかったため、この'0'が付加することによるのかな と想像してしまいました。 仰るとおり、本体プログラム側を疑って調査してみます。 ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1151] Re:makeファイル中のリダイレクト
投稿者:774RR
2008/08/28 13:29:05

標準入力のリダイレクトは < で行うのですがこれは本来 0< の略記なのです。 http://itpro.nikkeibp.co.jp/article/COLUMN/20060228/231093/ たとえば un*x のコンソール上では $ cat hoge.txt Hoge! $ cat 0<hoge.txt Hoge! $ // と、このように同じ動作をするのが正常な動きでありんす。 んで XP/2000 のコマンドプロンプトである cmd.exe もこの表記を受け付けます。 D:\MYWORK>cat 0<hoge.txt Hoge! D:\MYWORK> なので app.exe target.dat 0<source.dat は本質的に正しい入力であって、 期待したとおりに動くはずです。実際俺のところでは cmd.exe bash.exe の両方で このように0<と手入力しても期待通りの正しい動きをします。 さてここまで納得していただけたでしょうか。この例の場合、バッチファイル中には < としか書いていないリダイレクト記号を、誰かが勝手に (make がやっているのか cmd.exe がやっているのか、他の誰かかは不明) 0< と置換しているわけです(実害ないけど妙なことをやってるよね・・・) 0< となっていても俺んとこでは期待通り動作しています。 なので 0< となるのは「実行できない」の原因ではないと思われまっする。 「実行できない」の詳細について記載がないのでこれ以上の判断は出来ません。 本体プログラム側のバグを疑ってください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1150] Re:makeファイル中のリダイレクト
投稿者:tos
2008/08/28 10:00:12

cygwin をインストールして確認しましたが、 やはり、Borlandのmakeと同じ結果でした。 確認方法は、下記のようなmakefile及び バッチファイルを用意して、 (ダミーの"source.dat"と"app.exe"も用意して) --- makefile -------------------- target.dat : source.dat test.bat --------------------------------- --- test.bat -------------------- app.exe target.dat < source.dat --------------------------------- cygwin上?でmakeを実行しました。 すると、やはり'<'の前に'0'が付加されます。 --------------------------------- $ make test.bat app.exe target.dat 0<source.dat ~ --------------------------------- 何故でしょうか? 環境は、下記です。 GNU make 3.81 Windows XP Professional Version 2002 Service Pack 2
[この投稿を含むスレッドを表示] [この投稿を削除]
[1149] Re:makeファイル中のリダイレクト
投稿者:tos
2008/08/26 14:25:45

>file1.hoge ではなく hoge1.txt みたいに8文字ドット3文字以下の >過去互換性重視なファイル名に変えてみると良いかもしれん、ということぢゃ >直るかもしれんし、直らんかもしれん。どっとはらい。 理解できました。ありがとうございました。 引き続き試してみます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1148] Re:makeファイル中のリダイレクト
投稿者:774RR
2008/08/26 13:51:52

ちなみに GNU make はソースコード提供なので開発環境がないと作れない make 自体は開発環境の一部であり、これがうまく動かないのではコンパイルできない という自己矛盾の状況に陥るわけだ。 cygwin 開発環境一式持ってくるほうが結局面倒が無いかも知れんっす。 そーすると gcc コンパイラ自体も入手できちゃうので某の出番は無い可能性が・・・ 掲示板のスペースで cygwin の解説など不可能っぽいので http://journal.mycom.co.jp/special/2002/cygwin/index.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1147] Re:makeファイル中のリダイレクト
投稿者:774RR
2008/08/26 13:42:30

むかしむかし、あるところに MS-DOS というものがあってのぉ MS-DOS ではファイル名に「8文字以下 ドット 3文字以下」しか使えなかったのぢゃ その関係でなぁ、 Win95 以後のソフトでも8文字ドット3文字のファイル名しか 扱えないような、そーいう過去互換性重視なモノもあったのぢゃよ # 某の make がそういう過去互換重視なものかどうかは知らんがのぉ hoge.exe は4文字ドット3文字だから問題ない file1.txt は5文字ドット3文字だから問題ない のぢゃが file1.hoge や file2.piyo は5文字ドット4文字なのでな、 過去互換性重視なソフトに取っては非互換なファイル名なのぢゃよ file1.hoge ではなく hoge1.txt みたいに8文字ドット3文字以下の 過去互換性重視なファイル名に変えてみると良いかもしれん、ということぢゃ 直るかもしれんし、直らんかもしれん。どっとはらい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1146] Re:makeファイル中のリダイレクト
投稿者:tos
2008/08/26 12:45:39

返信ありがとうございます。 GNU makeで試してみます。 ただ、 >俺の Makefile のように 8.3 コンパチなファイル名で試してみること推奨 この意味がわかりませんので、よろしければ教えてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1145] Re:makeファイル中のリダイレクト
投稿者:774RR
2008/08/26 12:26:34

cat > Makefile <<EOF file1.txt: file2.txt hoge <tab>./hoge file1.txt < file2.txt hoge: hoge.c EOF ということで GNU make で試したけど無問題っす (HPUX11.11 と cygwin) borland の make ではなく GNU make で試してみませう 某の make がどうしてもいい、ってことなら 俺の Makefile のように 8.3 コンパチなファイル名で試してみること推奨
[この投稿を含むスレッドを表示] [この投稿を削除]
[1144] makeファイル中のリダイレクト
投稿者:tos
2008/08/26 10:27:15

皆さんこんにちは、tosです。 makeファイル中で以下のように リダイレクトを要求するexeを実行したいのですが、 正常に実行できません。 ------------------------------------------- FILE1.HOGE : FILE2.PIYO Hoge.exe FILE1.HOGE < FILE2.PIYO ------------------------------------------- 「正常に実行できません」の内容は、最初エラー メッセージのみでわからなかったんですが、 ためしに、上記の2行目をBAT呼び出しにしたところ、 下記のように何故かリダイレクト起動に前に'0'が 付加されていました。 ------------------------------------------- Hoge.exe FILE1.HOGE 0<FILE2.PIYO ------------------------------------------- この'0'は何故付加されるのでしょうか? ちなみに、makeは「BorlandのVersion 5.2」 を使用しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1143] Re:テストBBSが
投稿者:(ぱ)こと管理人
2008/08/02 14:09:00

どうもです。遅くなりましてすみません。 774RRさん: >テストBBSが広告だらけですが、どうせテストだし管理しない方針でしょうか? >ほげほげ認証だけでもつければまた違いそうですが すみません、面倒なので放置しています。 表掲示板とテスト掲示板は同じプログラムで、GETパラメタで動きを変えている だけなので、ほげほげ認証はテスト掲示板にも付いています。 ほげほげ認証導入以後、日本語以外のspamはまったくないようなので、 人力で書いているんですかね。 yuyaさん: >というわけでテスト板見ようとしたんですが、Firefoxでは >>「テスト書き込みの類はテスト用掲示板にどうぞ。」 >のリンクが効いておらず見に行けませんでした。 このメッセージははD/Bに入っていて、掲示板作成用のWeb画面は作ったものの 更新画面がなくて、放置してしまっていました。すみません。 今、手でSQLを書いて更新したのですが… センタリングを忘れました。 これから出かけるのですみませんがひとまずこの状態で。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1142] Re:テストBBSが
投稿者:yuya
2008/08/01 12:17:14

>テストBBSが広告だらけですが、どうせテストだし管理しない方針でしょうか? >ほげほげ認証だけでもつければまた違いそうですが というわけでテスト板見ようとしたんですが、Firefoxでは >「テスト書き込みの類はテスト用掲示板にどうぞ。」 のリンクが効いておらず見に行けませんでした。 ソース見ると、<a>タグに文法ミスがありますね。 IEだと善意に解釈されてリンクしてるんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1141] テストBBSが
投稿者:774RR
2008/08/01 11:37:38

テストBBSが広告だらけですが、どうせテストだし管理しない方針でしょうか? ほげほげ認証だけでもつければまた違いそうですが
[この投稿を含むスレッドを表示] [この投稿を削除]
[1139] Re:電卓:コンパイル出来ません:MacOSX
投稿者:つんつん
2008/07/15 00:00:45

前橋さま コンパイル通りました。 $ ./mycalc >9; >>9 >1+2+3+4+5+6+7+8+9+10; >>55 > mycalc も実行できます。行編集もできます。 ありがとうございます。感謝感謝!!です。 言われますように次ぎの通り修正しました。 $ cat -n Makefile <略> 14 INCLUDES = -I/opt/local/include 15 16 $(TARGET):$(OBJS) 17 $(CC) $(OBJS) -o $@ -L/opt/local/lib -lreadline -lfl -lm <略>
[この投稿を含むスレッドを表示] [この投稿を削除]
[1138] Re:電卓:コンパイル出来ません:MacOSX
投稿者:(ぱ)こと管理人
2008/07/14 23:42:14

>13: CFLAGS = -c -g -Wall -I/opt/local/include >14: INCLUDES = \ >15: >16: $(TARGET):$(OBJS) >17: $(CC) $(OBJS) -o -L/opt/local/include $@ -lreadline -lfl -lm まず、-Lの指定は間違っています。 ・-oオプションはできあがる実行形式の名前を指定するオプションですし、  makeでは、$@がターゲットの名前を指します。よって「-o $@」で組なので  その間に-Lを入れてはいけません。 ・/opt/local/includeは、その名のとおり#includeするファイルを置くところだと  思うので、ライブラリは別のところにあるはずです。  MacOSのディレクトリ構造は知りませんが、おそらく/opt/local/libあたりに、  libreadline.aとかlibreadline.soなんとかというファイルがありませんか?  だとすれば、 >17: $(CC) $(OBJS) -o $@ -L/opt/local/lib -lreadline -lfl -lm でいいと思います。 ただ、エラーメッセージが今でも >cc -c -g lex.yy.c >calc.l:6:31: readline/readline.h: No such file or directory こうだというのなら、-Iも失敗しているようです。 …そう思ってMakefileを見直して気付きました。 CFLAGSはlex.yy.cの規則のところでは使っていませんでした。すみませんこちらのミスです (_o_) 14行目の INCLUDES = \ を、 INCLUDES = -I/opt/local/include としてみてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1137] Re:電卓:コンパイル出来ません:MacOSX
投稿者:つんつん
2008/07/14 19:54:56

すいません 忙しく今bbsを見ました。 積極的にアプローチしてませんが、 電卓を勉強したい人が、スムーズに電卓に入っていけるようになったらなーとも思います。 >とのことなので、もうreadlineを動かしたいとは強くは思っていないように思いますし、 >それなら外野がとやかく言うこともないかな、とも思いますし。 13: CFLAGS = -c -g -Wall -I/opt/local/include 14: INCLUDES = \ 15: 16: $(TARGET):$(OBJS) 17: $(CC) $(OBJS) -o -L/opt/local/include $@ -lreadline -lfl -lm 13: と 17: を変更しました。 ./memory/ と ./debug/ で make は成功します。 mycalc/ で make すると $ make bison --yacc -dv calc.y flex calc.l cc -c -g lex.yy.c calc.l:6:31: readline/readline.h: No such file or directory calc.l: In function `tty_input': calc.l:87: warning: assignment makes pointer from integer without a cast make: *** [lex.yy.o] Error 1 $ お願いします。-Ldir の記述例もお教えください。僕の-Ldirは的を外していると思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1136] Re:電卓:コンパイル出来ません:MacOSX
投稿者:(ぱ)こと管理人
2008/07/13 20:17:03

>まず、どういう指定をしたか、具体的に書きましょう。 一般的にはそうですけど、今回について言えば、つんつんさんは >readline 使っていない方のサイトで 勉強したいと思います。 とのことなので、もうreadlineを動かしたいとは強くは思っていないように思いますし、 それなら外野がとやかく言うこともないかな、とも思いますし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1135] Re:電卓:コンパイル出来ません:MacOSX
投稿者:kit
2008/07/13 19:41:31

>現状:: >readline.h は  /opt/local/include/readline/readline.h です。 >-L も指定したつもりですが、あっているか分かりません。 まず、どういう指定をしたか、具体的に書きましょう。 エスパーじゃないんですから、「-L も指定したつもり」とだけ書かれても、 実際に何をどう指定したのか、つんつんさん以外にはさっぱり分かりません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1134] Re:電卓:コンパイル出来ません:MacOSX
投稿者:つんつん
2008/07/13 09:55:41

前橋さま まだエラーになります。 現状:: readline.h は  /opt/local/include/readline/readline.h です。 -L も指定したつもりですが、あっているか分かりません。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー EasyPackage というパーケージ管理でreafline をインストールすると 標準 /usr/local にインストールされます。 その状態では、mycalcのコンパイル成功します。 しかし、複数のパッケージ管理を使いたくないので EasyPackage の readline は、アンインストールしました。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー パッケージ管理 MacPorts で /opt/local/include/readline/readline.h に インストールした状態で、mycalcをコンパイルすることは、難しいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1133] Re:電卓:コンパイル出来ません:MacOSX
投稿者:(ぱ)こと管理人
2008/07/13 00:23:25

>readline は、/opt/local/include/readline/ にインストールされていました。 … >「コンパイラの-Iオプション」に加えるということが分かりませんので >readline 使っていない方のサイトで 勉強したいと思います。 了解です。 まあ一応書いておくと、今回の例ならトップディレクトリのMakefileに CFLAGS = -c -g -Wall という行がありますが(13行目)、ここに CFLAGS = -c -g -Wall -I/opt/local/include のように-Iを追加すればコンパイルは通るようになると思います。 インクルードのパスが通ってない以上、リンクのパスも通っていない可能性が ありますが、その場合は17行目の $(CC) $(OBJS) -o $@ -lreadline -lfl -lm ここに-Lオプションを加えるとかします。 詳細はこのへんを参照してください。 http://www.asahi-net.or.jp/~wg5k-ickw/html/online/gcc-2.95.2/gcc_2.html#SEC14
[この投稿を含むスレッドを表示] [この投稿を削除]
[1132] Re:リンク切れ
投稿者:(ぱ)こと管理人
2008/07/13 00:12:50

>「C言語 体当たり学習徹底入門」正誤表に載っている「ほげを考えるページ」へのリンクがniftyのURLのままです。 ご指摘ありがとうございます。 ポインタ完全制覇、体当たり学習、Java謎+落とし穴すべてについて 新URLへのリンクを付けておきました。 どの本も移転前だったんだなあ… (遠い目)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1131] Re:電卓:コンパイル出来ません:MacOSX
投稿者:つんつん
2008/07/12 23:56:17

>もし入っているのであれば、コンパイラの-Iオプションにそこを加えれば >よいですし、入っていないのであれば拾ってきて入れることになります。 前橋さま ありがとうございます。 readline は、/opt/local/include/readline/ にインストールされていました。 MacOSX では、readline : いろいろなインストール方法により /opt/local や /sw/local ? や /usr/local にインストールされるみたいです。 「コンパイラの-Iオプション」に加えるということが分かりませんので readline 使っていない方のサイトで 勉強したいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1130] リンク切れ
投稿者:piyo
2008/07/12 23:19:19

「C言語 体当たり学習徹底入門」正誤表に載っている「ほげを考えるページ」へのリンクがniftyのURLのままです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1129] Re:電卓:コンパイル出来ません:MacOSX
投稿者:(ぱ)こと管理人
2008/07/12 13:27:01

こんにちは。 >MacOSX で電卓使いたいとコンパイルしたのですが、エラーになります。 … >cc -c -g lex.yy.c >calc.l:6:31: readline/readline.h: No such file or directory このエラーメッセージは、readline.hというファイルが見つからないと言っている わけですから、GNU readlineがインストールされていないのでしょう。 MacOSはよく知りませんが、デフォルトでは入ってなくても無理ない気がします。 実は入っていて、#includeのパスが通ってないだけかもしれませんが。 もし入っているのであれば、コンパイラの-Iオプションにそこを加えれば よいですし、入っていないのであれば拾ってきて入れることになります。 このページからダウンロードできるようです。 http://tiswww.case.edu/php/chet/readline/rltop.html インストールの方法はここにありました。 http://tiswww.case.edu/php/chet/readline/INSTALL GNUのソフトらしく、 ./configure make make install でインストールできるようです。 ただ、電卓を作るための勉強用なら、こちらの方が簡単でよいかと思います。 GNU readlineも使っていませんし。 http://kmaebashi.com/programmer/devlang/yacclex.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1128] 電卓:コンパイル出来ません:MacOSX
投稿者:つんつん
2008/07/12 05:40:50

その4 「電卓を作ってみよう」 MacOSX で電卓使いたいとコンパイルしたのですが、エラーになります。 前橋さまの電卓試したいのですが、ご教授よろしくお願いします。 $ tar zxvf mycalc.tgz $ cd mycalc $ cd memory/ $ make cc -c -g -Wall memory.c cc -c -g -Wall storage.c ld -r -o mem.o memory.o storage.o $ cd ../debug/ $ make cc -c -g -Wall -I../ debug.c ld -r -o dbg.o debug.o $ cd .. ーーーーーーーーーーーーーーーーここまでは、エラーでませんが $ make bison --yacc -dv calc.y flex calc.l cc -c -g lex.yy.c calc.l:6:31: readline/readline.h: No such file or directory calc.l: In function `tty_input': calc.l:87: warning: assignment makes pointer from integer without a cast make: *** [lex.yy.o] Error 1 $ ーーーーーーーーーーーーーーーーここで、エラーになりました。どうして???
[この投稿を含むスレッドを表示] [この投稿を削除]
[1127] Re:メンバーズホームページ
投稿者:(ぱ)こと管理人
2008/07/11 01:15:43

>以前から告知されていましたが、niftyのメンバーズホームページはリンクのサービスも停止してしまいましたね。 ありがとうございます。まったく気付いていませんでした。変更しておきました。 ずいぶん長いこと転送してくれていましたから、まあ文句は言えませんね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1126] メンバーズホームページ
投稿者:yuya
2008/07/10 13:47:23

トップページ > kmaebashi.comに直接飛ぶように設定できるようになっていたことが判明。今はそのように設定しています。 以前から告知されていましたが、niftyのメンバーズホームページはリンクのサービスも停止してしまいましたね。 トップページの口上が現状と合致しなくなったので、(おせっかいながら)指摘しておきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1122] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:774RR
2008/06/24 08:33:37

もいちど駄レスしておくと オブジェクト指向な設計、というものはあっても 非オブジェクト指向な設計の元にオブジェクト指向なプログラム、ってのはありえない わけで、「基礎設計したことがないプログラマ」ではOOがわからなくて当然。 メタ度が違うっちぅことで。 俺も、基礎設計が気に入らなくなったという理由で、50%くらい作ったプログラムを 全部捨てて最初から再設計したなんて経験が何度もある。 ただ「実装するだけ」のOOでは意味が無いと思うのココロ そーいう人に限って「スーパークラスがごみ置き場」になるわけだ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1121] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:sumim
2008/06/22 14:19:36

>リスコフというと「え、ええと置換原則の人?」程度の私はまだまだ勉強が >必要のようです。 リスコフは「抽象データ型」とか「カプセル化」を考えた(言い出した)人です。 >新しいほうの3系統 >http://d.hatena.ne.jp/sumim/20080415/p1 > >は大変腑に落ちます。 それはよかった。ご紹介痛み入ります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1120] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:(ぱ)こと管理人
2008/06/22 13:43:45

>新人はさしたる仕事もなく、昨日もオブジェクト指向のサイトを転々としておりました。 ああ、それはうらやましい。 戦力として配置されるとだんだん勉強の時間も削られてくるものですし、 さらに年を食うとろくにコードも書かせてもらえなくなるのがこの業界ですので。 > 継承:共通処理(親)をベースとして差分を子に付け加える。ライブラリを > includeするのと逆の発想。 うーん、これはまさに(最近評判があまりよろしくない)実装継承ですよね。 以前、この辺のスレッドで議論したことがあります。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&thread=270 この中で出ているoo-squareのリンクは、現在切れていますがこっちです。 http://www.ogis-ri.co.jp/otc/hiroba/oosquare-ml/Archive/200501.month/thread.html よく使うメソッドをスーパークラスに置いて、なんてことをやっていると、 http://www.ogis-ri.co.jp/otc/hiroba/oosquare-ml/Archive/200501.month/4468.html | 継承は確たる「設計思想」が無い場合、スーパークラスが単なる「ごみ置き場」 | と化していることが多いようです。 なんてことになってしまう。それよりはむしろ、 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=276&range=1 | 「ほらほら、『使うほう』はその実体が具体的に何であるか気にしなくていいんだよ」 のほうが実際の使いどころに合っていると思いますが、こうなるとインタフェースと 一緒になっちゃうんですよね。実際、「継承なんかどうでもよくてインタフェースこそが 本質なのだ」と言う人もいますし。 じゃあ継承なんかなくていいのかというとそうでもなくて、実際私も使うというのが ややこしいところ。「継承とインタフェースのどっちを使えばいいんですか?」というのは FAQですが、私はこれはもう単純に ・データメンバがメインの構造体的なクラスにフィールドを追加するなら継承を、 ・それ以外はインタフェース でいいんじゃないかな、と思っています。 > 隠蔽:見せたくない処理はlocal変数、local関数にて実装する。 これは実態としてまさにそうだと思います。 よく「その『オブジェクト』だけが知っていればよいことはprivateにするんだ」と オブジェクトごとに丸を描いたりして「カプセル化」としている説明がありますが、 言いたいことはよくわかるものの、C++でもJavaでも実はprivateは 「別のクラスから見えない」だけで「別のオブジェクトから見えない」のでは ないんですよね。 これを、単にC++(およびその派生言語)が腐っているとか実用上の妥協だとか 言うことも可能ですが、私はこれを「privateというのは他の『プログラマ』に 対する隠蔽なのだ」と考えてしまってよいと思っています。 > 多態性:引数に基づき、サブルーチン側でif~elseで処理分岐する。 > またはincludeを変える。 「またはincludeを変える」のほうは良くわかりませんが、1行目は、用途としては そのとおりです。よくある図形(Shape)の描画ルーチンの例のように、 ポリモルフィズムを使うことで、プログラムからswitch caseを排除できます。 Cにはそれがないばかりに巨大なswitch caseを書いてる例: http://kmaebashi.com/programmer/devlang/diksam_src_0_2/S/7.html#693 ポリモルフィズムにおいて、一見単なる実装詳細に見えるけど実は結構重要なのは、 サブクラスを追加しても、呼び出し素(switch caseに相当する部分)再コンパイルの 必要がない、ということですね。だからAppletを継承したクラスを作れば すぐにブラウザで実行できるわけで。 > マルチプルインスタンス:サブルーチンをメインの実行状況によって任意に > (動的に)増やせる。 うーん、これはどうなんでしょう。オセロの例で言えば、Boardをいくつnewしても、 put()というルーチンは増えないと思うのですが… 「メソッドはインスタンスに付属している」というイメージからすると、 一緒に増えると考えることもできるのかもしれませんが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1119] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:(ぱ)こと管理人
2008/06/22 13:12:16

こんにちは、sumimさん。(いろいろなところで)いつもお世話になってます。 >すみません(汗)。 いえそんな(大恐縮) >当時はまだリスコフの抽象データ型(カプセル化)について理解があさく、 >ユーザー定義型に手続きを含むか、含まないかで、それぞれを OOP(あるいは、 >手続きによる抽象化。PDA)とするか、ADT(クック独自定義の抽象データ型) >とするかという分類はとてもクールに思えて必要以上に持ち上げてしまいました。 リスコフというと「え、ええと置換原則の人?」程度の私はまだまだ勉強が 必要のようです。 新しいほうの3系統 http://d.hatena.ne.jp/sumim/20080415/p1 は大変腑に落ちます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1118] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:Glory
2008/06/21 16:41:02

返信下さった皆さん、ありがとうございます。興味深く読ませて頂きました。 新人はさしたる仕事もなく、昨日もオブジェクト指向のサイトを転々としておりました。 やはり「猫」の例はヘンですよね。現実世界を模しているならば「鳴けとメッセージを送ると 鳴く」というよりは「腹が減ると鳴く」の方がピッタリでしょう。つまり完全自律型、プログラムで いったら暴走に近いかも・・・。 プログラミングは少々かじったことがあるのですが(学校の実習レベルです)、無理矢理 現実世界に例えるよりはこんな感じの説明の方がイメージに合っていると思います。  継承:共通処理(親)をベースとして差分を子に付け加える。ライブラリをincludeするのと逆の発想。  隠蔽:見せたくない処理はlocal変数、local関数にて実装する。  多態性:引数に基づき、サブルーチン側でif~elseで処理分岐する。またはincludeを変える。  マルチプルインスタンス:サブルーチンをメインの実行状況によって任意に(動的に)増やせる。  オブジェクト指向:これら個々の処理を分離して薄皮でくるみ、モノとして捉える。 わかってないとお叱りを受けそうですが、「犬・猫」よりはそれっぽい(笑)気がします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1117] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:sumim
2008/06/21 15:48:56

># 以前何度か読んで、そのたびに「手続きによる抽象化」について調べようと思いつつ ># 忘れていたらいつの間にか追記がついていた。あれ? すみません(汗)。 当時はまだリスコフの抽象データ型(カプセル化)について理解があさく、 ユーザー定義型に手続きを含むか、含まないかで、それぞれを OOP(あるいは、 手続きによる抽象化。PDA)とするか、ADT(クック独自定義の抽象データ型) とするかという分類はとてもクールに思えて必要以上に持ち上げてしまいました。 その後、リスコフは、手続きを型に含むか含まないかは抽象データ型の実現方法の バリエーションにすぎない(それぞれにメリット・デメリットがある…)と書いてある のを見つけて、追記にように認識を改めた次第です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1116] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:(ぱ)こと管理人
2008/06/21 02:55:11

>オブジェクト指向のごちゃごちゃが気になったら、とりあえずこのページを見ておくと良いと思います。 >http://d.hatena.ne.jp/sumim/20040525/p1 ページの紹介ありがとうございます。 # 以前何度か読んで、そのたびに「手続きによる抽象化」について調べようと思いつつ # 忘れていたらいつの間にか追記がついていた。あれ? というわけで、Javaの勉強をするのなら、「メッセージ」という言葉を多用している 入門書はひとまず避けておけ、と(ぉぃ 逆に言えばうちのページ http://kmaebashi.com/programmer/object/index.html はC++/Java流OO限定ですね。そういうわけで当時の掲示板でのバトルの末 「言語としてはJavaを使用します。」という文言を先頭のページに持ってきた、 という経緯はあるんですが、もうちょっとでかでかと書いてもよかったかも。 まあ当時は依怙地になっていたかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1115] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:(ぱ)こと管理人
2008/06/21 02:48:48

>新人君 (大学では情報技術をやってなかった君) を見ていると >やはり[マルチプルインスタンス]にてつまづいているようだ。 >http://kmaebashi.com/programmer/object/othello.html この「マルチプルインスタンス」という言葉は別に私の造語ではなく、 http://kmaebashi.com/programmer/object/intro.html にも書いたようにC++ FAQにあった言葉を使ったのですが、上のページを私が書いた 時点では、「マルチプルインスタンス オブジェクト指向」でGoogleしても 0件でした。 それが今では258件だか出ます(私のページやそれに対する言及も多いですが)。 うちのページの影響だと思っても、自意識過剰じゃないですよね。きっと。たぶん。 プロトタイプベースまで含めるとまた話がややこしくなりますが、 クラスベースのOOに関する限り、複数のインスタンスが作れるという概念は 基本だと思うんですよね。あまりに基本すぎるせいか、入門書とかでは 飛ばされてしまっていたわけですが。 新人君がなにもかもstaticなプログラムを書いたら「オブジェクト指向的じゃない!」 と怒るくせに。 >マルチプルインスタンスが理解できても static という罠が待ち構えている。 しかもJavaの場合実行がすべてpublic static void main()から始まるために、 本当の入門者がいきなり罠にはまるという…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1114] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:(ぱ)こと管理人
2008/06/21 02:32:07

Gloryさん、こんにちは。 >例題は「車」・・・このサイトの予想通り。ご多分に漏れずなかなか >理解できずにいます。 車ですか…これもよく使われる例かと思いますが、やっぱりたとえ話はよくないと 思います。 >そのうえ更に「よくある○○という説明は間違い、誤解をうむ、 >オブジェクト指向ではない」などと説明されると、卓袱台を引っくり返された >ような感覚すら。 >結局どれが”正”なんだ?と。お互いに自分の説明こそが正しいという立場で主張する >わけですから(当たり前ですが)、初心者は余計に混乱し、根気がないと挫折します。 すみません、一部加担しています。(_o_) >オブジェクト指向に対する根本的なモノの考え方は同じなのかもしれませんが、 >投稿・掲示板でも意見が分かれるように、統一見解がないことこそが >”なぜわからなくなってしまうのか?”の一番の原因なのかもしれません。 [1111]でこくぼさんが挙げておられるページのように、また、 http://practical-scheme.net/trans/reesoo-j.html こちらでも「オブジェクト指向というものが動く標的であるため、オブジェクト指向の 熱心な支持者はこのメニューのうちの適当なサブセットを気まぐれに選んで、 それを以って他の言語はオブジェクト指向ではないと説得しようとする。 」 と言われているように、定義がちゃんと定まったものではないとは思います。 >本当は誰もが認めるバイブル的な教本があるとよいのですがねぇ・・・。 たとえばBertrand MeyerさんのOOSC(Object-Oriented Software Construction)は かなり多くの人がバイブルと認めると思いますが(少なくとも静的型OO支持者であれば)、 それでも「あの本の継承の使い方は…」という留保をつける人が多いんじゃないかと 思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1113] 昨晩は
投稿者:(ぱ)こと管理人
2008/06/20 08:29:06

昨晩はちょっと早めに帰宅して、   ↓ 掲示板を確認し、ゴミ投稿を消して、   ↓ どうお返事しようかなあ、と考えながらベッドにごろんと   ↓ 気付いたら朝 ←いまここ というわけで、今しばらくお待ちくださいませ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1111] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:こくぼ
2008/06/19 19:26:57

オブジェクト指向のごちゃごちゃが気になったら、とりあえずこのページを見ておくと良いと思います。 http://d.hatena.ne.jp/sumim/20040525/p1
[この投稿を含むスレッドを表示] [この投稿を削除]
[1110] Re:なぜわからなくなってしまうのか?の本質(笑)
投稿者:774RR
2008/06/19 16:56:11

新人君 (大学では情報技術をやってなかった君) を見ていると やはり[マルチプルインスタンス]にてつまづいているようだ。 http://kmaebashi.com/programmer/object/othello.html 同じ種類のモノが、複数個!という概念が理解できた後でないと 同じ性質だけど、違う種類! (基底クラス→派生クラス) の理解は危うい。 と思うのであった。 マルチプルインスタンスが理解できても static という罠が待ち構えている。 Java の Double クラスの public static Double valueOf(String s) が ああ、そういうことねーと納得できるかどうか こりゃいったいなにがいいたいんぢゃろと困るか その辺にわかるわからないの境目がありそうな気がする俺ちゃんであった
[この投稿を含むスレッドを表示] [この投稿を削除]
[1109] なぜわからなくなってしまうのか?の本質(笑)
投稿者:Glory
2008/06/19 15:17:39

管理人さん&読者の皆さん、こんにちは。 この前、会社の新人研修でオブジェクト指向(Java)を学びました。 例題は「車」・・・このサイトの予想通り。ご多分に漏れずなかなか理解できずにいます。 いろいろなオブジェクト指向関連のサイトや本を読みあさって勉強していると、筆者それぞれに 思い入れがあって、解説の仕方や考え方が異なることに気付きます。「実は簡単」とか「これだけ 覚えればOK」という内容をよく目にしますが、私のような初心者にとっては、それでさえ 理解できなかったりします。そのうえ更に「よくある○○という説明は間違い、誤解をうむ、 オブジェクト指向ではない」などと説明されると、卓袱台を引っくり返されたような感覚すら。 結局どれが”正”なんだ?と。お互いに自分の説明こそが正しいという立場で主張するわけですから (当たり前ですが)、初心者は余計に混乱し、根気がないと挫折します。 オブジェクト指向に対する根本的なモノの考え方は同じなのかもしれませんが、投稿・掲示板でも 意見が分かれるように、統一見解がないことこそが”なぜわからなくなってしまうのか?”の一番の 原因なのかもしれません。研修の講師の方も仰っていました。「わからないときは先輩に 訊いた方がよい、ただしその相手を間違えるとヘンな設計になる(笑)」。なんとなく分かるような 気がします。どうもベテランのJava開発者=オブジェクト指向を理解している人ではないようです。 本当は誰もが認めるバイブル的な教本があるとよいのですがねぇ・・・。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1108] Re:とあるGのつくプロジェクト
投稿者:こくぼ
2008/06/18 02:14:42

>まあ、仕事のプロジェクトについてここであんまり書くわけにもいきませんから >このへんにしときます。 ですよね。 失礼しましたm(_ _)m
[この投稿を含むスレッドを表示] [この投稿を削除]
[1107] Re:とあるGのつくプロジェクト
投稿者:(ぱ)こと管理人」
2008/06/16 02:45:13

>自分も何の因果か、巡り巡って今はGのつくプロジェクトにどっぶり漬かっています。 >#お客さんとコネのあるベンダーなので面倒がないというか、大変というか…^^; >#(前会社で働いてたときよりも待遇も給料も良いので全然良いんですけどね) あの会社にGのつくプロジェクトはいくつかありますが、あのGであれば、 お会いする機会は今後もあるかもしれません。 まあ、仕事のプロジェクトについてここであんまり書くわけにもいきませんから このへんにしときます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1106] Re:とあるGのつくプロジェクト
投稿者:こくぼ
2008/06/15 16:27:00

>ええと、それならおそらく私です。 やっぱりそうでしたか。お会いできるチャンスを逃してしまって残念です^^; >ただ、現在私は1階にコーヒー屋があるビルの向かいのビルにはいません。 ># 会社自体変わったような変わってないような。 そうなんですか…! >超巨大企業の子会社の、Gのつくプロジェクトの人たちも現在はコーヒー屋がある >ビルではないビルに移っているはずです(全員ではないはずですが)。 今年末くらいに駅近くの新しくできるビルに移るって話は聞いてますが、今はまだ大部分はそこのビルにあると思います。 >月日は過ぎ人は去り状況は刻々と変わっているようです。諸行無常といいますか。 自分も何の因果か、巡り巡って今はGのつくプロジェクトにどっぶり漬かっています。 #お客さんとコネのあるベンダーなので面倒がないというか、大変というか…^^; #(前会社で働いてたときよりも待遇も給料も良いので全然良いんですけどね)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1105] Re:とあるGのつくプロジェクト
投稿者:(ぱ)こと管理人」
2008/06/15 01:18:40

こんにちは。 >自分は名古屋の伏見にある某企業で働いてるのですが、2年ほど前(2006年の3月末) >にとある会社(超巨大企業の子会社)の名簿みたいなやつに前橋さんのお名前を見かけ >ました。 ええと、それならおそらく私です。 >おそらく前橋さんの会社からすぐ近くの1階にコーヒー屋があるビルなのですが、 ただ、現在私は1階にコーヒー屋があるビルの向かいのビルにはいません。 # 会社自体変わったような変わってないような。 超巨大企業の子会社の、Gのつくプロジェクトの人たちも現在はコーヒー屋がある ビルではないビルに移っているはずです(全員ではないはずですが)。 月日は過ぎ人は去り状況は刻々と変わっているようです。諸行無常といいますか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1104] とあるGのつくプロジェクト
投稿者:こくぼ
2008/06/13 18:56:48

はじめまして、こんにちは。 ポインタ本を6年くらい前(?)に読んでから、前橋さんのファンです。 自分は名古屋の伏見にある某企業で働いてるのですが、2年ほど前(2006年の3月末)にとある会社(超巨大企業の子会社)の名簿みたいなやつに前橋さんのお名前を見かけました。 (ちょうど自分が3月末までその会社に派遣されてまして) おそらく前橋さんの会社からすぐ近くの1階にコーヒー屋があるビルなのですが、あのとき見た名前が本当に前橋さんなのか今でも気になっています。 迷惑でなければ、教えてくださいm(_ _)m
[この投稿を含むスレッドを表示] [この投稿を削除]
[1103] Re:本について
投稿者:(ぱ)こと管理人」
2008/05/12 01:24:58

はじめまして。おほめいただきありがとうございます。 >よくわからない宣言は避けて、使わないようにしていたのですが >それが理解できると途端に使えるものが増えて、世界が広がったような気がしました 本にも書いたとおり、あまり複雑な宣言を使うのはおすすめできませんが、読むときには読めないと困りますし、わからないからとvoid*に逃げるのもよろしくないですから、宣言の読み方はわかっているほうがよいですよね。 お役に立てたようで何よりです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1102] 本について
投稿者:sironote
2008/05/11 04:00:43

C言語ポインタ完全制覇の本を読ませていただきました 細部まで説明してくれるこういう本は本当にありがたかったです よくわからない宣言は避けて、使わないようにしていたのですが それが理解できると途端に使えるものが増えて、世界が広がったような気がしました 良い本を出してくれて感謝致します
[この投稿を含むスレッドを表示] [この投稿を削除]
[1101] Re:まだまだ現役ですね!
投稿者:(ぱ)こと管理人
2008/04/03 03:00:44

はじめまして。書き込みありがとうございます。 >で、今回は、面白いページがありましたので、ご紹介致します。(既に知っていらっしゃるかもしれませんが・・・) >http://builder.japan.zdnet.com/sp/c-programming-language/story/0,3800083430,20370255-2,00.htm?p=3&mode=all#block_comment 某筋から聞いて知っていました。4/1にかこつけてこんなのを書いちゃったくらいで (^^; http://d.hatena.ne.jp/kmaebashi/20080401 >しかし、簡単なポインタが分からない人は、表舞台(雑誌とか、本とか)から絶滅したと思っていましたが、まだまだ現役なんですね :-p C自体、うちの会社では使っている部署はどんどん減っているのですが、まだCの記事に需要があるようですね(この記事の出来はさておき)。 「C言語 ポインタ完全制覇」は今度第11刷が出ます(奥付は5月11日)。皆様のおかげです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1100] まだまだ現役ですね!
投稿者:なかなか
2008/04/02 11:52:14

前橋さんのファンです。一度は書き込んでみたいと思っておりました。(^^;) で、今回は、面白いページがありましたので、ご紹介致します。(既に知っていらっしゃるかもしれませんが・・・) http://builder.japan.zdnet.com/sp/c-programming-language/story/0,3800083430,20370255-2,00.htm?p=3&mode=all#block_comment 最初は単純ミスかとも思いましたが、直せば直すほど馬脚を現していく有様を見ていると、これは「真性」だと思います。 しかし、簡単なポインタが分からない人は、表舞台(雑誌とか、本とか)から絶滅したと思っていましたが、まだまだ現役なんですね :-p
[この投稿を含むスレッドを表示] [この投稿を削除]
[1099] Re:オブジェクト指向でないのは
投稿者:(ぱ)こと管理人
2008/03/20 22:11:43

>JAVAを使っていてわざわざ1クラスのなかに全プログラムを記述するような >ことをせず、クラスに分割していけば自動的にオブジェクト指向になっていく >のではないでしょうか。 Javaで1クラスの中に全プログラムを記述するようなことをする人はめったに いないと思いますが、Cで、関数を複数の.cファイルに分類して書いていった ところで、「オブジェクト指向になっている」とは言わないでしょう。普通は。 そういうことを下記ページに書きました。 http://kmaebashi.com/programmer/object/othello.html、 | しかし、現状では、カプセル化は実現できていても、オブジェクト指向に | はなっていません。なぜならここにはオブジェクトがいないからです。 >そこで、JAVAのプログラマーであるのに、オブジェクト指向でない >プログラミングの例を示して解説していただければうれしいです。 >ただし初心者や技術不足が原因のしょうもない例ではなくお願いします。 いまどきJavaといえばWebアプリケーションの開発に使うことが多いと思いますが、 たとえばStrutsとJDBCを使うとして、UIの階層はStrutsが提供するクラスを 継承したりして作るかもしれませんが、そこから呼び出されるビジネスロジックの 階層を「staticメソッドの集合体」にするケースは結構あると思いますよ。 それでもJDBCが提供するinterfaceを使っているからオブジェクト指向だ、とか、 UI層ではActionを継承して作っているからオブジェクト指向だ、と主張する のであれば別に止めませんが。 いわゆる業務アプリケーションの開発において、継承やらインタフェースやらを 多用したクラス階層を自分で設計してプログラムを書いていく場面は実はかなり 少ないです。 以前この掲示板ではこんな議論がありました。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&thread=693 この中で紹介されているhappieさんの意見に、私は大筋で賛成です。 http://happiese.exblog.jp/3127241/
[この投稿を含むスレッドを表示] [この投稿を削除]
[1098] オブジェクト指向でないのは
投稿者:はら
2008/03/19 16:23:20

オブジェクト指向について分かりやすい説明ありがとうございました。CとJAVAの違いで説明されているところで感じたのですが、もともとJAVAでプログラミングしていれば自然にオブジェクト指向になるのではないでしょうか。JAVAを使っていてわざわざ1クラスのなかに全プログラムを記述するようなことをせず、クラスに分割していけば自動的にオブジェクト指向になっていくのではないでしょうか。私の疑問は、JAVAのプログラマーでありながら、オブジェクト指向でないプログラミングをするということの方が難しいのではないかということです。 そこで、JAVAのプログラマーであるのに、オブジェクト指向でないプログラミングの例を示して解説していただければうれしいです。ただし初心者や技術不足が原因のしょうもない例ではなくお願いします。しょうもない例というのは、Newのタイミングを間違えるとかそういう例です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1097] Re:「体当たり学習」について
投稿者:(ぱ)こと管理人
2008/02/25 01:41:53

>結果として、このプログラムは一見正常に動きますが、 >再入力の場合に限り字数チェックが行なわれない、という奇妙な仕様になっています。 ご指摘ありがとうございます。コーディングの方針とかスタイルとか そういう話ではなく、再入力のときBOOK_NAME_LEN等より長い文字列を 入力すると領域破壊を起こしますから、これは致命的ですね。 こういうバグが入った経緯はさすがに思い出せませんが、正誤表に追加しておきました。 えー、他にもまだあるようでしたら(と書くのも怖いのですが、間違いは間違いとして 正誤表に載せておきたいと思いますので)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1096] Re:「体当たり学習」について
投稿者:yuya
2008/02/21 18:14:31

ご確認ありがとうございました。 > (まだあるようでしたらぜひお願いします)。 というお言葉に甘えて、連投ヒンシュク覚悟で……。 【7】 蔵書管理プログラム配列版(p243~のList5-12)において、 「再入力機能」のコード(reinput系統の関数)に納得しかねる点があります。 input_string() と input_number() とは、文字列と数値の違いこそあれ、 ともに「新規入力処理」として並立した存在です。 両者の冒頭には共通の一行入力処理(+α)が fgets() を使って書かれており、 これらはのちに input_line() として切り出されることになります。 そして、この2者に再入力機能(つまり改行だけが入力された場合の処理)を付け加えたものが それぞれ reinput_string() と reinput_number() であるはずですよね。 しかし、再入力に際して input_line() 相当の処理を書くべきところには、ともに input_string(buf, 1024, stdin); と書かれています。これは不合理ではないでしょうか? 配列版での文字列入力は字数制限を伴うため、 新規入力では input_data() が input_string() に上限を渡してチェックさせています。 一方、再入力では reinput_data() がいったん reinput_string() を呼び出し、 その中で上限を1024にして input_string() を呼び出しており、不可解です。 そもそも reinput_string() 自体が上限を引数にとらないので、 reinput_data() から渡せなくなっていますね。 結果として、このプログラムは一見正常に動きますが、 再入力の場合に限り字数チェックが行なわれない、という奇妙な仕様になっています。 全くの憶測ですが、以下のような経緯は考えられないでしょうか? | 配列版を執筆している段階では、まだ再入力機能は無かった。 | 動的メモリ確保版に入り、再入力機能を持たせた。 | この機能を配列版でも使えるように、List5-12(p243~)にさかのぼって、 | reinput_string() 、reinput_number() 、および reinput_data() を付け加えた。 | このとき、配列版特有の字数制限への対応を行なわなかった。 | また、reinput_string() 、reinput_number() では input_line() を呼び出す必要があるが、 | 配列版ではこの関数をまだ切り出していなかったので、関数名だけ reinput_string() に置き換えた。 見当はずれだったら赤っ恥ですが(^^;)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1095] Re:「体当たり学習」について
投稿者:(ぱ)こと管理人
2008/02/19 01:51:20

お返事が大変遅くなりまして申し訳ありません。 >【6】 >3-3の detab.c についてなのですが、p141に (中略) >do{ > putchar(' '); > char_count++; >} while(char_count % TABSTOP != 0); > >で済ませてしまうと思います。 う。これは確かにこれで動きますし、こちらの方がシンプルですね。 「体当たり学習」のサンプルソースがなぜああなっているかについてですが、単純に思いつかなかったのかもしれません。ひょっとすると「出力すべきスペースの数を算出する」→「その数のスペースを出力する」と段階を追って考えたほうがわかりやすいのでは、と思った、という可能性はありますが… いずれにせよすでに記憶の彼方です。すみません。 なお、限りなく手抜きな対応ですみませんが、ここでのやり取りを、下記補足ページに転記させていただきました。 http://kmaebashi.com/taiatari/hosoku.html いろいろとご指摘いただきありがとうございました(まだあるようでしたらぜひお願いします)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1094] 管理者により削除されました
2008/02/19 01:33:56

この2008/02/18 19:16:57の投稿は、 意味不明の投稿だったので削除しました。
[この投稿を含むスレッドを表示]
[1093] Re:「体当たり学習」について
投稿者:yuya
2008/02/16 18:21:13

丁寧にお返事いただき、ありがとうございます。 【2】 > 私は、習慣的にマクロで値を定義するときは括弧で囲んでいます。 > 演算子等を含むと括弧が必要だったりしますから常に入れているというだけで、 > この場合は実用的な意味はあまりないですが。 了解しました。ただ、括弧のない箇所もたくさんあったので(p111など)、 統一性の観点から指摘させていただきました。 【4】 > たしかに対象読者を考えると厳しい気がします。 私自身、初心者に毛が生えた程度なわけですが、 率直に言って、この部分を見たとき、頭がこんがらかっちゃったんですよね。 「何をやっているか」は分かったものの、 「これで万事うまくいく」という確信がすぐには持てませんでした。 なんでスッと頭に入らなかったのか考えてみると、 (ア) ファイルを開く→書き込む→閉じるという順番でしかモノが考えられない(私が) (イ) 「初め」の処理だけ特別扱いされている の2点が原因になっているように思います。 (ア)な初心者としては、下のような手順が素朴に思い浮かびます。 ------------------------------------------------------------------ while(){ 書きかけの出力ファイルがなければ、新しいファイルを開く 文字を書き込む 出力ファイルが一杯になったら、ファイルを閉じる } 最後の出力ファイルが中途半端なサイズで終わっていたら、それを閉じる ------------------------------------------------------------------ つまり、 FILE *out_fp = NULL; while((ch = getc(in_fp)) != EOF){ if(out_fp == NULL){ out_fp = fopen(......); ...... } putc(ch, out_fp); total_size++; if(total_size % OUT_FILE_SIZE == 0){ fclose(out_fp); out_fp = NULL; } } if(out_fp != NULL){ /* ここでは入力ファイルが空の場合だけでなく、 出力ファイルのキリのいいところで終わったときも NULLになる */ fclose(out_fp); } てな構成にすれば、(イ)も自然に解消されるのではないでしょうか。 ……と思って上のソースを見直すと、whileループの末尾と(次の回の)先頭で、 ほとんど同じ条件判断を行っていて非効率ですね(^^;) ほかにも私の気づいていない問題点があるかもしれません。 【5】 > 動くか動かないかという点では動きますし、出力用のファイルポインタと > 読み込み用のファイルポインタを比べると、読み込み用の方がfclose()しなくても > 害が少ないわけですが(書きかけで異常終了すると変なファイルができる可能性が > 高いですが、読み込みならまず大丈夫)行儀としては閉じた方がよいかと思います。 > # ただ、このレベルなら、やっぱり実用上「どっちでもいい」と言ってしまいそうです。 > # 私の場合。 こちらもよく理解できました。ありがとうございます。 風邪をひかれているのに申し訳ないのですが、もう一点、よろしいでしょうか。 【6】 3-3の detab.c についてなのですが、p141に > タブストップが8の時、タブは、「その行の出力文字の総数が8の倍数になるまで」空白を出力します。 とあり、まさにタブの動作はこれで言い尽くされていると思います。 私の場合、単純にこれをそっくりそのままコードに翻訳することを考えてしまうわけですが、 そうすると例えば do{ putchar(' '); char_count++; } while(char_count % TABSTOP != 0); で済ませてしまうと思います。 これも素人ゆえの感想かもしれませんが、「出力すべきスペースの数を算出する」という方法は、 なんだか必要以上に事を複雑にしているように映ってしまうのですが、いかがでしょうか。 どうも勝手なことばかり長々と書き散らしてすみません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1092] Re:「体当たり学習」について
投稿者:(ぱ)こと管理人
2008/02/13 02:18:02

どうもです。いろいろご指摘ありがとうございます。 >【1】第1章の本文に「BMI指数」という表現がありますが、 >body mass indexの「index」は「指数」なので、 >単に「BMI」でいいのではないでしょうか? そうですね。「IT技術」的なことをやってしまっています。 >【2】p105・List2-8(my_sort5.c)・4行目および >p180・List4-2(my_sort6.c)・4行目が > >#define SCORE_ARRAY_SIZE (100) > >となっていますが、この「100」を囲む括弧は意図されたものでしょうか? 私は、習慣的にマクロで値を定義するときは括弧で囲んでいます。 演算子等を含むと括弧が必要だったりしますから常に入れているというだけで、 この場合は実用的な意味はあまりないですが。 >【3】正誤表 >http://kmaebashi.com/taiatari/seigo.html >のp102およびp103に言及している箇所で、ともに >「1手順ごとに『ソートずみの範囲』はひとつづつ増えていきます。」 >という、全く同じ注釈が付いています。 >これは本来p102のほうだけに付けることを意図していた、 という可能性はないでしょうか? これはp102の方のHTMLを書いてから、それをコピペしてp103の方を作って、 消し忘れたようです。 >| 最後に開いた出力ファイルを閉じる。 >| ただし入力ファイルが空で、いきなりEOFに出くわして >| whileループを一度も回さずに脱出したときだけは、閉じるべき出力ファイルがない。 >| このときはout_fpが(10行目の定義によって)NULLに初期化されたままのはず。 >| よって、out_fp != NULL のときのみ、クローズ処理を行う。 > >という解釈でよいのでしょうか? >コメントがないと対象読者には分かりにくいような気もしますが……。 37行の「さっきまでオープンしていたファイルを閉じる」というコメントから、 while () { さっきまでオープンしていたファイルを閉じて、  次のファイルを開く } 最後に開いたファイルを閉じる という構造になっているのはわかってほしいと…あとは、どういう場合に out_fpがNULLでループを抜けるかですが、ループの中(しかもif文の中)で 閉じて開いている以上、NULLでここに落ちてくる可能性には直感で気づいてほしい… という気はしますが、たしかに対象読者を考えると厳しい気がします。 >【5】p148の本文で、「使い終わったファイルはクローズしておいたほうがよい」とあります。 >p158~p159・List3-7(my_split.c)やp168・List3-10(textdump.c)などでは >読み込み用に開いたファイルのクローズ処理が書かれていませんが、別に構わないでしょうか? 動くか動かないかという点では動きますし、出力用のファイルポインタと 読み込み用のファイルポインタを比べると、読み込み用の方がfclose()しなくても 害が少ないわけですが(書きかけで異常終了すると変なファイルができる可能性が 高いですが、読み込みならまず大丈夫)行儀としては閉じた方がよいかと思います。 # ただ、このレベルなら、やっぱり実用上「どっちでもいい」と言ってしまいそうです。 # 私の場合。 今日は遅いですし私は現在風邪ひきですのでアレですが、後日何らかの形で Web上で対応させていただきます。 いろいろご指摘ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1091] 「体当たり学習」について
投稿者:yuya
2008/02/12 18:06:29

こんにちは。 「C言語体当たり学習徹底入門」を読み返しています。 お手数ですが、いくつか確認させてください。 【1】第1章の本文に「BMI指数」という表現がありますが、 body mass indexの「index」は「指数」なので、 単に「BMI」でいいのではないでしょうか? 【2】p105・List2-8(my_sort5.c)・4行目および p180・List4-2(my_sort6.c)・4行目が #define SCORE_ARRAY_SIZE (100) となっていますが、この「100」を囲む括弧は意図されたものでしょうか? 【3】正誤表 http://kmaebashi.com/taiatari/seigo.html のp102およびp103に言及している箇所で、ともに 「1手順ごとに『ソートずみの範囲』はひとつづつ増えていきます。」 という、全く同じ注釈が付いています。 これは本来p102のほうだけに付けることを意図していた、 という可能性はないでしょうか? 【4】p159・List3-7(my_split.c)・55~57行目の if(out_fp != NULL){ fclose(out_fp); } は、 | 最後に開いた出力ファイルを閉じる。 | ただし入力ファイルが空で、いきなりEOFに出くわして | whileループを一度も回さずに脱出したときだけは、閉じるべき出力ファイルがない。 | このときはout_fpが(10行目の定義によって)NULLに初期化されたままのはず。 | よって、out_fp != NULL のときのみ、クローズ処理を行う。 という解釈でよいのでしょうか? コメントがないと対象読者には分かりにくいような気もしますが……。 【5】p148の本文で、「使い終わったファイルはクローズしておいたほうがよい」とあります。 p158~p159・List3-7(my_split.c)やp168・List3-10(textdump.c)などでは 読み込み用に開いたファイルのクローズ処理が書かれていませんが、別に構わないでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1089] はじめまして
投稿者:hrkn
2008/02/10 05:37:23

検索から来ました。参考になります!
[この投稿を含むスレッドを表示] [この投稿を削除]
[1088] Re:変数の宣言
投稿者:(ぱ)こと管理人
2008/02/07 03:36:22

>http://www.atmarkit.co.jp/fjava/rensai2/javaent04/javaent04.html >などを読むと、意識すると理解がより深まるのかなぁ、なんて最近思っています。 おおっ、これはっ! 前後を見ると、「制御構造」もやらないうちからいきなりメモリの話かよ、と思うわけで、説明の方法としては(私の感覚では)同意しかねますが、継承を説明するのにメモリ上の配置から入るのは合理的なんじゃないかと私は思っています。私が継承を理解したのは、Cで無理やり継承を実現したXtがきっかけでしたから。 http://kmaebashi.com/programmer/c_yota/inherit.html yuyaさんもおっしゃるように、具体的な方から攻めていかないと理解できないことは多いと思います。私も「人間、誰だって、低レベルな概念の方が理解が早い」とあちこちに書いています。 と思って今Googleしてみたら http://d.hatena.ne.jp/yaneurao/20060511 | 私はもともとコンパイラやそういう低レベルの実装の話が好きだから | そういう勉強の仕方をするのだが、このへんはあまり共感が得られないかも知れない。 あれ? いやまあコンパイラは置いといて、メモリモデルについては、ちょっとプログラミングをかじった人はなんとなく頭にあって、だからこそ、仮想メモリとかを教えるとびっくりする、という認識があったのですが…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1087] Re:変数の宣言
投稿者:yuya
2008/02/06 00:53:43

>大学生に教える機会が多いのですが、何をどの程度教えればよいか、 >こんなことを気に留めながら、試行錯誤しています。 イマサラな意見で恐縮ですが……。 抽象的なことを理解するには、やっぱり具体的なものを ほんの一部でもいいので徹底的に解剖してみて、 そのあとで再び抽象化する、という過程を踏まないと、 きちんと理解できない(少なくとも私は理解した気になれない)と思います。 「木を見て森を見ず」は確かに良くないけれど、 一本も木を見たことのない人がそれを言っても説得力がないなぁ、というところでしょうか。 具体例を経験した後は、こんどはその経験が足枷にならないように 抽象化(文字通り、対象のエッセンスを抽出する)しないといけないのが難しいところですが。 前橋さんの[1085]の解説は、 Cの規格上は必ずしもそのように実装しなければならないわけではない、ということを承知の上で、 あえて一般的な実装(具体例)の詳細にまで踏み込んでいらっしゃる、 という点に、ひげおやじさんは留意しておかれるとよいと思います。 # あ、今年もよろしくお願いします。 > 皆様
[この投稿を含むスレッドを表示] [この投稿を削除]
[1086] Re:変数の宣言
投稿者:ひげおやじ
2008/02/06 00:19:01

たいへん丁寧なご説明ありがとうございます。感謝しております。 未だ「処理系の実装」を想像できるほど物を知っているわけでは ないのですが、理解を深めるのに意識しながら今後勉強して行きたいと 思います。 ちなみに、メモリを意識せずにプログラミングを自力で作成できるように なるのが良いのかもしれませんが、Javaでの継承がメモリモデルを使って 解説してある記事 http://www.atmarkit.co.jp/fjava/rensai2/javaent04/javaent04.html などを読むと、意識すると理解がより深まるのかなぁ、なんて最近思っています。 大学生に教える機会が多いのですが、何をどの程度教えればよいか、 こんなことを気に留めながら、試行錯誤しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1085] Re:変数の宣言
投稿者:(ぱ)こと管理人
2008/02/04 01:35:25

>>このへんから、 >>・静的型言語 >>・実行時に型を持つ言語 >>・アセンブラみたいな、本当に型のない言語 >>あたりの対比につながると面白いのかな、と思いつつ、 ええと、すみません、そんなたいした話ではないのですが。 たとえばCで、 int a; という(定義を兼ねた)宣言があったとき、これは >(1)変数xの内容を読んだり書いたりするときには、型Tに合った メモリの使い方に従います。 >(2)(1)、かつ、変数xのメモリ領域を型Tに対応するサイズだけ確保する。 この(1), (2)の両方を意味しますが、(1)の意味で効いてくるのはコンパイル時であり、(2)は実行時なんですよね(細かく言えば、staticでないローカル変数なら関数突入時、グローバル変数なら実行開始時)。 もちろんCではintとdoubleとでは普通はサイズが違いますから、「型Tに対応するサイズだけ確保する」ためには型を知らなければならないように思いますが、実際には「intのローカル変数ふたつ」であっても「doubleのローカル変数ひとつ」であっても、実行時の機械語コードは「スタックに領域を8バイト分確保する」となっている(※1)だけで、細かい型までは意識していません。 構造体定義にしても、 typedef struct { double x; double y; } Point; と書いたとして、Cでは、この型定義の情報はコンパイルされた機械語コードには残っていません。Point型の変数pがあったとき、p.yという記述は、「pの先頭アドレスから8バイト(※1)ずれたところを参照する」という機械語コードに変換されるのであって、「メンバyを参照する」ということは実行時には意識していません。 Javaあたりだと微妙に話が違って、リフレクション用にクラスの情報を保持しておく必要はありますし、バイトコード中に「メンバy」という情報は残っていますが、「メンバy」という情報はロード時にオフセット参照に変換されるはずです(JITがなかったとしても)。 静的型言語だとこんな感じですが、型なし言語であるRubyとかcrowbarでは、 a = 10; で変数が宣言されます。JavaScriptなら var a; でしょうか。これはひげおやじさんのおっしゃるところの(2)を、実行時に行っています(※2)。ただし「a = 10;」の実行のあとで「a = "abc";」と書くのも許されます。これは、整数型も文字列型も(変数aのレベルでは)同じサイズで表現されるためです。また、オブジェクトのメンバを参照するためa.yと書いてあったとき、aの型は実行時までわかりません(aにyというメンバがあるかどうかさえも)。よってひげおやじさんがおっしゃるところの(1)は、aという変数が宣言されたさらに後、まさにその変数を使うときに判定されるわけです。 「アセンブラみたいな、本当に型のない言語」は、例としてはたとえば(Cの前身である)Bなんかがそうでしょう。Bでは auto a; で変数が宣言できるようですが(※3)、なにしろBには型がないというか、intとポインタ(アドレス)は同じ型でそれ以外の型はなかったわけですから、「auto a;」は(2)の意味しか持ち得ません。 ……ええと、なんというかあまり面白い話にはならなかった気がしますが、ひげおやじさんもおそらく哲学論議がしたいわけではないと思いますから、ここはひとつ「言語を作ってみる」…とまではいかなくても処理系の実装を想像してみる、というのはいかがでしょうか(と、「プログラミング言語を作る」の宣伝につなげてみる)。 とか言いつつ、静的言語であるDiksamは、いまだにクラス部分が公開できてないわけですが。秋ごろから一応クラスやポリモルフィズムは動いていて、ただいろいろな意味で中身がぐちゃぐちゃで、作業時間が全然(本当に全然)取れないので進んでいないのですが。 ※1)intが4バイト、doubleが8バイトの処理系を想定しています。 ※2)Rubyの変数の宣言は厳密には「代入文が実行されたとき」ではないのですが、ここでは置いておきます。 ※3) http://cm.bell-labs.com/cm/cs/who/dmr/kbman.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1084] Re:変数の宣言
投稿者:ひげおやじ
2008/02/02 15:56:57

ご返答ありがとうございます。 >なんというか、ご質問は、その指すところが曖昧で、(失礼ながら)初心者がワケわかんなくなった上での質問のように一見すると見えて、「774RRさんいきなりそんな話をされても」とか書くべきかと酔っ払った頭で一瞬思ったのですが。 まさにその初心者で、自分で頭の整理ができなくて質問してしまったようなところです。 結局は、変数の「宣言」と「定義」の違いをきちんと認識するのが不足していた と自分では省みています。(質問にもその認識不足がにじみでていたな、とも。) それだけではないのかもしれませんが・・・。 >ヒントになるかもしれないこととしては、 > >typedef struct { > double x; > double y; >} Point; > >と書いたとき、これだけでは単なる型宣言なのでメモリはまったく確保しませんが、上記(1)で言うところの型Tを定義する意味は持っているわけですよね。 これって、Javaのabstract class や interfaceなどでも同じことが当てはまるんでしょうか。浅はかな知識だけで、この質問も曖昧かもしれなく、すいません。 >このへんから、 >・静的型言語 >・実行時に型を持つ言語 >・アセンブラみたいな、本当に型のない言語 >あたりの対比につながると面白いのかな、と思いつつ、 可能ならば、この続きを教えていただければと存じます、触りだけでも。 宜しくお願い致します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1083] Re:変数の宣言
投稿者:(ぱ)こと管理人
2008/02/02 05:43:38

どうもです。 >プログラムで、変数を宣言する文は、プログラムを実行した >ときのパソコンのどんな動作に対応するのでしょうか。 なんというか、ご質問は、その指すところが曖昧で、(失礼ながら)初心者がワケわかんなくなった上での質問のように一見すると見えて、「774RRさんいきなりそんな話をされても」とか書くべきかと酔っ払った頭で一瞬思ったのですが。 >(1)変数xの内容を読んだり書いたりするときには、型Tに合った >メモリの使い方に従います。 >(2)(1)、かつ、変数xのメモリ領域を型Tに対応するサイズだけ確保する。 この(1)と(2)は、変数の宣言の二面性をかなり明確に意識しているように思います(だからこそ774RRさんのご回答がこの区分にきっちり一致しているわけで)。 今は酔っ払っているので頭回ってませんが、ヒントになるかもしれないこととしては、 typedef struct { double x; double y; } Point; と書いたとき、これだけでは単なる型宣言なのでメモリはまったく確保しませんが、上記(1)で言うところの型Tを定義する意味は持っているわけですよね。 このへんから、 ・静的型言語 ・実行時に型を持つ言語 ・アセンブラみたいな、本当に型のない言語 あたりの対比につながると面白いのかな、と思いつつ、すみませんもう寝ますおやすみなさい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1082] Re:変数の宣言
投稿者:774RR
2008/02/01 22:20:46

>また、言語によって違ったりするんでしょうか。 世の中にはプログラミング言語など星の数ほどあるので、違ったりするだろうな それだと答えに困るので、とりあえず C C++ の類に限定すると メモリ という言葉をより広義の「記憶域」と読み替えて (1) Yes (2) 宣言が同時に定義となる場合には Yes 変数は狭義の「メモリ」つまり、俗に言う RAM に置かれるとは限らなくて もっと高速にアクセスできる「レジスタ」に置かれる場合もあるわけだ。 レジスタとメモリ(とその他変数に使えそうなもの)を称して記憶域という (1)(2)のあわせ技から以下のようなバグが発生することがあるので注意だな 「定義にならない宣言」と「定義になる宣言」が矛盾する場合におかしなことになる ---a.c--- extern int wrong_declared_variable; // declaration without definition ... wrong_declared_variable=0; // may destroy other variables ---b.c--- char wrong_declared_variable; // declaration with definition
[この投稿を含むスレッドを表示] [この投稿を削除]
[1081] 変数の宣言
投稿者:ひげおやじ
2008/01/31 20:39:14

お世話になります。 プログラムで、変数を宣言する文は、プログラムを実行した ときのパソコンのどんな動作に対応するのでしょうか。 変数xをある型Tで宣言するのは、次のいずれかなんじゃないかなぁ、 なんて自分では推測しているのですが。 (1)変数xの内容を読んだり書いたりするときには、型Tに合った メモリの使い方に従います。 (2)(1)、かつ、変数xのメモリ領域を型Tに対応するサイズだけ確保する。 (3)(1)、(2)以外。 どれが正解なんでしょう。それとも正解はないんですかね(^_^; また、言語によって違ったりするんでしょうか。 どなたかご教授いただければ幸いです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1079] Re:「ほげほげ認証」てすと
投稿者:(ぱ)こと管理人
2008/01/11 01:16:12

>本日は晴天なり すみません、純粋なテスト投稿であればできるだけテスト用掲示板 http://kmaebashi.com/bbs/list.php?boardid=testbbs の方にお願いします。テスト用掲示板にもほげほげ認証は付いています。 …が、今見てみたら、テスト用掲示板にはspamが来てるじゃないですか! 人間がアルバイトで投稿しているのかなあ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1078] 「ほげほげ認証」てすと
投稿者:
2008/01/10 19:09:28

本日は晴天なり
[この投稿を含むスレッドを表示] [この投稿を削除]
[1077] Re:業務連絡:「ほげほげ認証」を実装しました
投稿者:(ぱ)こと管理人
2008/01/03 09:35:50

>では早速テスト投稿などしてみませう どうも、おひさしぶりです。 # おひさしぶりになってしまったのは掲示板が壊れていたためですね…すみません。 >はたして cgi 君はうまくうごくのであろうか PHPだからcgiではないです、というツッコミはありでしょうか。 ところで、昨日は一晩で14通のspamが来たことを考えると、「ほげほげ認証」は それなりに効果があると思ってよさそうです。もうちょっと続けてみないと なんとも言えませんが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1076] Re:業務連絡:「ほげほげ認証」を実装しました
投稿者:774RR
2008/01/02 18:56:17

では早速テスト投稿などしてみませう はたして cgi 君はうまくうごくのであろうか
[この投稿を含むスレッドを表示] [この投稿を削除]
[1075] 業務連絡:「ほげほげ認証」を実装しました
投稿者:(ぱ)こと管理人
2008/01/02 16:37:11

掲示板を直したところspamがひどいので、 以下のページで紹介されている「ほげほげ認証」を導入しました。 http://diary.noasobi.net/2006/07/diary_060728a.html お手数をおかけしますが、今後投稿する際は、投稿欄の下のテキストボックスに 「ほげほげ」と入力してください。 こんなのは固定パスワードですし、画面に堂々と出るわけですし、 本来であればCAPTCHAか何かを導入すべきかもしれませんが、 ロボット相手ならそれなりに効果があるんじゃないかなあ、ということで 手抜き実装です。 投稿される方にはひと手間増えて申し訳ありませんが、よろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1074] Re:あけましておめでとうございます(兼業務連絡)
投稿者:(ぱ)こと管理人
2008/01/02 07:33:44

>max(serialid)に置き換えて修復しました。 > >どうりで長いこと投稿がなかったわけだ… で、直したとたんスパム14連発かよ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1073] あけましておめでとうございます(兼業務連絡)
投稿者:(ぱ)こと管理人
2008/01/01 16:37:06

今年もよろしくお願いいたします。 ……と投稿しようと思ったら、SQLがエラーを吐きました。 スクリプトを見直したら、掲示板ごとの連番を取得するところでcount(*)を使っており、 少し前の広告削除で空き番ができるような物理削除をしていたのでcount(*)で取得した 連番が重複エラーを出していました。センスの悪いSQLを書いてましたね。 max(serialid)に置き換えて修復しました。 どうりで長いこと投稿がなかったわけだ…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1072] Re:ソースコードの単純な誤植
投稿者:(ぱ)こと管理人
2007/10/08 17:32:28

>以下のような文章が出てきます。 >(下2行はいらないでしょうが、一応載せておきますね。) >----- >i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367) >Copyright (C) 2005 Free Software Foundation, Inc. >This is free software; see the source for copying conditions. There is NO >warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 情報ありがとうございます。 うちのUbuntu Linuxの gcc (GCC) 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5) とやらではこの警告は出ないので、4.x系なら出るのかというとそういうわけでも なさそうですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1069] Re:ソースコードの単純な誤植
投稿者:cocoatomo
2007/10/08 12:03:36

>gcc --versionで表示されるgccのバージョンは何でしょうか? 以下のような文章が出てきます。 (下2行はいらないでしょうが、一応載せておきますね。) ----- i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367) Copyright (C) 2005 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -----
[この投稿を含むスレッドを表示] [この投稿を削除]
[1067] Re:ソースコードの単純な誤植
投稿者:(ぱ)こと管理人
2007/10/08 04:08:04

>----- >mycalc.y:64: warning: incompatible implicit declaration of built-in function 'exit' >----- >と警告が出てしまいます。 「of built-in function 'exit'」つまりexit()を組み込み関数とした上で 警告を出してくれるわけですね。 すみません、よろしければ教えていただきたいのですが、 gcc --versionで表示されるgccのバージョンは何でしょうか? うちのMinGW(gcc (GCC) 3.4.2 (mingw-special))ではこの警告は 出ないようです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1065] Re:ソースコードの単純な誤植
投稿者:cocoatomo
2007/10/07 06:42:35

はじめまして。 前回の投稿で挨拶をしていなくて、すみませんでした。 >>8行目 >>"}" → "};" >>"union" の宣言の終わりのセミコロンが無い。 > >これですが、ここはもともとセミコロンは不要ではないでしょうか >(bisonで試したところあってもなくても通りましたが)。 はい、自分のところで試してみたところ、セミコロン無しでも通りました。 エラーメッセージを読み間違えたのだと思います。 >>64行目 >>"exit()" を使用しているのに、"stdlib.h" が include されていない。 > >こちらは修正いたしました。 >gccだとexit()は組み込み関数になっていて、-Wallを付けても、stdlib.hをinclude >していない状態でコンパイルエラーにならなくて… というのは言い訳ですね。 私の環境(MacOSX v10.4.10 Darwin 8.10.1?)で gcc -o mycalc y.tab.c lex.yy.c を実行すると ----- mycalc.y:64: warning: incompatible implicit declaration of built-in function 'exit' ----- と警告が出てしまいます。 なので、一応神経質になって include してみた次第です。 # こういう仔細な状況を書き忘れないようにしようとは思うのですが、 # 忘れてしまいます。すみません。 お早い返信ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1064] Re:ソースコードの単純な誤植
投稿者:(ぱ)こと管理人
2007/10/07 01:26:20

はじめまして。ご報告ありがとうございます。 >8行目 >"}" → "};" >"union" の宣言の終わりのセミコロンが無い。 これですが、ここはもともとセミコロンは不要ではないでしょうか (bisonで試したところあってもなくても通りましたが)。 NUTSHELLの本でも、以下のサンプルでもセミコロンは付いていませんし。 http://www.linux.or.jp/JF/JFdocs/Lex-YACC-HOWTO-6.html#ss6.3 >64行目 >"exit()" を使用しているのに、"stdlib.h" が include されていない。 こちらは修正いたしました。 gccだとexit()は組み込み関数になっていて、-Wallを付けても、stdlib.hをinclude していない状態でコンパイルエラーにならなくて… というのは言い訳ですね。 実は現在公開しているcrowbarやDikamでも同様の問題があり、最近ようやく -ansiオプションを付けました。次バージョンから修正します。 >私は2行目と3行目の間に "#include <stdlib.h>" という行を挿入したのですが、 >これでいいのでしょうか? それでOKです。 ご報告いただきありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1063] ソースコードの単純な誤植
投稿者:cocoatomo
2007/10/06 02:25:44

リンクされているページのソースコード"mycalc.y"に誤りがありましたので、報告いたします。 8行目 "}" → "};" "union" の宣言の終わりのセミコロンが無い。 64行目 "exit()" を使用しているのに、"stdlib.h" が include されていない。 私は2行目と3行目の間に "#include <stdlib.h>" という行を挿入したのですが、これでいいのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1062] 管理者により削除されました
2007/10/04 12:46:19

広告なので削除。 管理者削除がたまってきたのでそろそろDBから物理削除します。
[この投稿を含むスレッドを表示]
[1061] 管理者により削除されました
2007/10/04 12:45:20

意味不明の投稿につき削除
[この投稿を含むスレッドを表示]
[1060] 管理者により削除されました
2007/09/24 04:57:51

エロ系SPAMにつき削除
[この投稿を含むスレッドを表示]
[1059] 管理者により削除されました
2007/09/24 04:57:25

エロ系SPAMにつき削除
[この投稿を含むスレッドを表示]
[1058] 管理者により削除されました
2007/09/19 08:08:21

広告なので削除しました
[この投稿を含むスレッドを表示]
[1056] 管理者により削除されました
2007/09/12 23:12:53

エロ系SPAMだったので削除しました。
[この投稿を含むスレッドを表示]
[1055] Re:externと「外部結合」
投稿者:yuya
2007/09/06 15:20:34

> Rationaleを見ても、このへんに関する記述は以下の箇所くらいのようです。 > http://www.lysator.liu.se/c/rat/c1.html#3-1-2-2 rationaleにこんな記述があったのですね。ありがとうございます。 > extern int i3 = 3; > これも不可解ですが、これはcommonモデルの方を引き継いだのでしょうかね。 該当箇所をよく読んでみると、列挙されたモデルの4つ目にinitializionモデルというのがあり、 「定義になるかどうか」を初期化子の有無だけで判断するものがあったようですね。 さらにその後には、 (訳) >規格で採用されたモデルは、strict ref/defモデルとinitializationモデルの特徴を組み合わせたものとなっている。 >(略) >しかし、外部定義として働くのは、「初期化」あるいは「記憶域クラス指定子のない特定の宣言」のいずれでもよい。 >このような混合アプローチが選択されたのは、さまざまな環境と既存の実装に可能な限り広範囲に適応するためである。 とあります。これを読む限り、 extern int i3 = 3; の挙動はinitializationモデルを引き継いだ可能性もありそうです。 同モデルの説明のところにはexternの扱いは明記されていないので、少し話がずれているかもしれませんが。 有用な資料の箇所を指し示してくださってありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1054] Re:externと「外部結合」
投稿者:774RR
2007/09/03 15:52:21

C/C++ の予約語に関しては D&E で Stroustrup も書いているんだけど 「新しいキーワードを増やすことは激論を招く」pp.191 C/C++ では同じ予約語を文脈によって異なる意味に使うことで、増やさない選択をした。 違和感の原因はこの辺にありそう。 > 特に「紹介状」は使わせてもらっていいでしょうか。 どーぞご自由に。 <前橋様>すんません、勝手に盛り上がってしまっております。 本来こー言う[俺はこう思う]論は自分で blog 等立てるのが筋なんですが 小心者ですので web は「使う側」に回らせてもらっております。 もう少し掲示板スペースをお貸しください</前橋様>
[この投稿を含むスレッドを表示] [この投稿を削除]
[1053] Re:externと「外部結合」
投稿者:yuya
2007/09/03 14:29:41

▼ > 要するに言語仕様上の extern と、英語の単語 external の不一致に違和感がある > っつーことでっか そうです。すでに決まっちゃったものに文句を言っても仕方ないですが、 「説明するときに名前との関連を前面に出すか、抑えるか」という選択肢は残されています。 そもそも結合は定義サマが決めるのが筋なのであって、 定義でない宣言がいくら結合を声高に主張しても、 「定義との食い違いを処理系に見つけてもらおう」というのでない限り無意味ですよね。 int hoge = 1; static int hoge; でエラーを出してくれるならまだしも、未定義動作ですし。 それならば、「参照に(ほぼ)特化した、結合に関してはオールマイティな」 externのようなキーワードが用意されているのは合理的だと思いますが、 なにもそんな名前じゃなくても良かろう、と思うわけです。 # externは実は外部宣言(external declaration)から来ているのかも、というオチは……。 ▼ > プログラム言語のキーワードをいちいち英語とつき合わせていると違和感ありですな。 > 俺的に一番違和感があるのは const であります。 > const ではなく readonly にしてくれると **俺的には** 解消です。 私もまったく同じように思います。というか、 「文字通りではないことに気付いているかどうか」によって、 理解度が測れてしまうこと自体(Cはこんなのばっかり)、なんて不健全な状況なんだ(^^;) #define INTERN static #define READONLY const ... ▼レベル別教授法はとても参考になりました。 特に「紹介状」は使わせてもらっていいでしょうか。 「エキスパートCプログラミング」には「(定義でない宣言は)税関の申告のようなものだ」とあり、 初めて読んだときは???でしたが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1052] Re:externと「外部結合」
投稿者:774RR
2007/09/03 11:26:05

ふむー 要するに言語仕様上の extern と、英語の単語 external の不一致に違和感がある っつーことでっか プログラム言語のキーワードをいちいち英語とつき合わせていると違和感ありですな。 俺的に一番違和感があるのは const であります。 const ではなく readonly にしてくれると **俺的には** 解消です。 言語規格書は古い非推奨な書き方してる既存のコードが invalid にならないように 過去との互換性維持のためだけの文言・機能も含んでいるので、そーいうところは 初心者・中級者むけクラスでは一切教えない。教える必要も無い。隠しておくべし。 たとえばいまさら「関数原型宣言にならない関数宣言」など教える必要は一切無い。 「extern があると先行する宣言に従う」はまさにこの黒歴史の部分。初心者に教えるな! # 知っておいて隠しておくのと知らないままでいるのとでは大きく違うのだがね。 extern に関して俺が後輩諸氏に説明するならばレベルに応じ 初心者向け(厳密に宣言を必ず先行させる新しいスタイルのみ教える) ・ヘッダファイル中において変数を宣言する場合には必ず extern を書くべし  →宣言とは他人/自分が [その名前] を使えるようにするものである  →他人の作った未知の関数や変数は使いたくないだろ。だから最低限素性がわからないと困るんだ   だから、ヘッダファイル中には[名前]と「紹介状」を書くべし(=これが宣言) ・他人/自分がその変数を使えるようにするために、定義を1つ .c 中に書くべし  →定義とは [その名前] の変数や関数を作って提供することである  →「紹介状」と実際の人物像が異なると困るだろ、だから紹介状を書く側には責任がある   人間の目でなくコンパイラでチェックできるよう、自作ヘッダは自作ソース中で #include しろ   そーすれば機械が不一致を検出してくれる  →紹介状は複数人で回覧することができる (宣言は複数回あっていい) が、   実際の人物は1人しかいないわけだから定義は1つ。 宣言と定義の簡易解説は必要。詳細解説までは不要。 結合や記憶域期間や可視性、等の詳細については説明不要 (消化不良になるだけ) 中級者向け(旧式の非推奨な書き方してるソースコードには触らせない) ・宣言と定義の詳細解説 ・内部結合と外部結合と無結合の違い  →「原則として」と前置きして extern は外部結合・定義にならない宣言となると解説  (変数宣言に extern があっても定義になりうると話しても混乱を招くだけなので説明しない)  →「原則以外は?」と問われたら上級者向け解説を実施 関数の場合の話を問われたら ・関数宣言と関数定義はソースコード上の記述形式が明確に異なるので区別できるから  extern/static は結合の決定にのみ使われるとフォローし ・static が明記されていない場合は extern が省略されていると解説 (X3010:1993 に準拠) ・これは変数の場合と挙動が異なるぞ、ともフォロー 上級者向け(既存のソースコードのダークサイドまで全部面倒見る人向け) ・言語規格書の章番号+解説 ・相手に興味がありそうで時間もあれば既に書いた俺妄想による Rationale をフォロー
[この投稿を含むスレッドを表示] [この投稿を削除]
[1051] Re:externと「外部結合」
投稿者:yuya
2007/09/02 16:34:38

774RRさん、(ぱ)さん、ありがとうございます。 たくさんコメントをいただいたので、[1045]~[1050]へのリプライは こちらにまとめさせていただきます。 [1048]774RRさん; > ながながと書いたけど結局のところ yuya さんの疑問点は > extern 記憶域指定子はなぜに (6.2.2) のようなヘンな振る舞いをするのか、その根拠やいかに > ということでよろしいのだろうか? [1049](ぱ)さん; >>static int i2 = 2; // 定義,内部結合 >>extern int i2 ; // 内部結合をもつ前の定義を参照する > > この「extern int i2;」の挙動が不可解だということですよね。 > 私にも不可解に見えます。そもそもキーワードの名前が「extern(al)」なのに! 6.2.2のexternの振る舞いが奇妙に映るのは、(ぱ)さんのおっしゃるとおり、 `extern'という、外部結合(external linkage)を想起させる名前によるところが大きいと思います。 いったん名前のことを忘れて、単に 「(翻訳単位内外にかかわらず)どこかで定義されている(かもしれない)変数・関数を参照する」 という機能が主眼だと考えれば、6.2.2の結合の定まり方は、 「可能な限り状況に合わせて結合を決定する」という、ある意味ではきわめて合理的な、 悪く言えば御都合主義的な仕様になっています。 その背景には[1048]・[1050]で774RRさんが書いてくださったような事情があった可能性が高いと思います。 現在の目から見て、初心者に「結局のところexternって何をするんですか?」と聞かれたとき、 最も正しい答えは[1046]でまとめていただいたように規格書の該当箇所を指し示すことだと思いますし、 最終的には本人にそこまで行き着いてもらわないといけないわけですが、 やはり(自分自身の頭を整理するためにも)「何が原則で、何が例外か」という観点で整理したくなり、 できるだけ普遍的な原則・少ない例外で理解できる方法はないだろうか、と思ってしまうわけです。 その過程の中で、歴史的経緯を知ることが原則を抽出する助けになることも多いと思います。 もちろん規格書には「これが原則、これが例外」などということは書かれていませんから、 注意しないと私が陥ったように勝手な行間解釈や俺俺用語を生んでしまうわけですが……。 で、実際にexternに対してそのような整理を試みたとき、ポイントとなる切り口は [1047]でご指摘のとおり「結合は何か」「定義になるかどうか」です。 ここでexternという名前を尊重して、「結合指定」を原則に据えると、 内部結合になるケースを例外と捉え、「定義になるかどうか」は別途論じることになります。 これに対して、「定義にならない」ことを原則に据えると、 (a); 結合は上記のように状況に合わせて定まる。 (b); 何も付けなくても初めから外部結合のブロック外定義になっているもの (関数定義や初期化子つきのブロック外変数定義)だけは、externをつけても定義とみなされる。 extern int hoge = 1; /* 外部結合のブロック外定義 */ と整理することができ、(b)が昔はコンパイルエラーになっていたとなれば、 例外として扱うことへの抵抗が小さくなります。 結局のところ、Cの振る舞いを統一的に理解することなど追求すべきでないのかも知れず、 [1045]774RRさんの > なんか難しく考えすぎなのではないかと思ってきた・・・ が最も正しいような気がしてきました。自覚はあるんですけど(^^;)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1050] Re:externと「外部結合」
投稿者:774RR
2007/09/02 08:31:11

>最初期のCではexternはあってもなくても同じだったらしい 「最初期」をどのくらいまで遡るか次第、だけど 俺妄想だと Kerningham/Ritchie が作った直後のCには、たぶん extern はまったく無かったのだろうと思う。 なおかつリンカーが bss combine を勝手に行ってしまう都合上 ODR は実装したくても実装するすべが無かった。 ----aaa.c---- static int i1; // internal linkage, definition int i2; // external linkage, definition ----bbb.c---- static int i1; // internal linkage, definition, another instance of aaa.c!i1 double i2; // external linkage, definition, different decl of aaa.c!i2 ----bss in a.out--- aaa.c!i1; bbb.c!i1; common!i2; // combined together, uses maximum size bss combine 機能が無いリンカーをもつ処理系に移植する際に困ったので 後付で extern を追加したが、そのときにはすでに extern を持たないCで書かれた ソースコードがたくさんあったので、互換性を維持するには?と考えた結果が今の仕様 あと初期化子の有無で挙動が異なるのも、リンカーの都合 (非0の)初期化子がある=bss に置けない=bss combine が効かない って、これも妄想 歴史家なら、黒歴史を追及するのもまあお仕事ですし、実際面白そうだけど 1ユーザとしては今ある仕様を理解するほうが建設的かなーって思うのであった
[この投稿を含むスレッドを表示] [この投稿を削除]
[1049] Re:externと「外部結合」
投稿者:(ぱ)こと管理人
2007/09/02 00:26:07

えー、一応管理人としては何か言うべきところなんでしょうが、正直、 私にはわかりません。 >6.9.2 外部オブジェクト定義 例1(抜粋) > >static int i2 = 2; // 定義,内部結合 > int i2 ; // 前に内部結合をもつ定義があるため、 > // 結合の不一致が生じ、6.2.2によって > // 動作は未定義となる >extern int i2 ; // 内部結合をもつ前の定義を参照する この「extern int i2;」の挙動が不可解だということですよね。 私にも不可解に見えます。そもそもキーワードの名前が「extern(al)」なのに! Rationaleを見ても、このへんに関する記述は以下の箇所くらいのようです。 http://www.lysator.liu.se/c/rat/c1.html#3-1-2-2 これはこれで興味深いのですが(最初期のCではexternはあってもなくても同じだった らしい)、yuyaさんの疑問の回答にはならないように思います。 Relaxed Ref/Defモデルのところには、 | The appearance of the keyword extern (whether it is used outside of the | scope of a function or not) in a declaration indicates a pure reference | (ref), which does not define storage. (超訳) >externはどっかの定義の参照を意味し、記憶領域の定義ではない。 とあるので、そのモデル(UNIX Cのモデル)を引き継ぐとそういう考え方になるのかなあ、 と思いましたが… UNIX Cにおいてexternが内部結合の定義を参照するような 実装があったのでしょうか。 externは定義にはならない、と考えると extern int i3 = 3; これも不可解ですが、これはcommonモデルの方を引き継いだのでしょうかね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1048] Re:externと「外部結合」
投稿者:774RR
2007/09/01 23:18:11

ながながと書いたけど結局のところ yuya さんの疑問点は extern 記憶域指定子はなぜに (6.2.2) のようなヘンな振る舞いをするのか、その根拠やいかに ということでよろしいのだろうか? 根拠 (Rationale) は規格書採択の際の委員会議事録などをさがせば出てくるんだろう。 でも俺は規格策定委員でもなんでもないただの1ユーザなのですだ。 そういう議事録みたいなのが公開されていれば誰か探してみてほしい。 まずは検証可能な事実を指摘: この「結合」の振る舞いは JIS X3010:1993 (ISO/IEC 9899:1990) の時点から ほとんど変わっていない。(一部些細な変更があるが今の議論には関係ないところ) 言語規格書ってのは、理想を追求するあまりに今あるユーザー・処理系を無視する わけにはいかない代物なわけだ。 したがって当時1990年頃に書かれていた「一般的なソースコードがすべて不適合」に なるような文言てのは採用するわけには行かない。理想と現実の落としどころが重要になる。 以下は俺の妄想: ヘッダファイルを多重に #include していて include-guard がうまく効いていない、 あるいは、同一大域変数の宣言を複数の別ヘッダファイルが行っている、 そんなソースコードでできたプログラムがあるとして。 #include の結果として、 翻訳単位中に extern の無い大域変数宣言 (要するに外部定義) が先に現れ、 後から extern のある大域変数宣言 (いわゆる変数宣言) が現れる、ような場合であっても うまいことコンパイル&リンクができるようにする必要があった。 すなわち extern 記憶域指定子の振る舞いは JIS X3010:1993 なら 6.1.2.2 JIS X3010:2003 なら 6.2.2 のように定めると都合がよかった。 そーいう話だと思って勝手にコメントしてみたけど、 いや、ずれてる!ということならまたよろしく。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1047] Re:externと「外部結合」
投稿者:774RR
2007/09/01 22:50:45

> そもそもリンケージが翻訳単位外に及ぶ(つまり外部結合)、というのと、 > 宣言が定義を探しに行く範囲が翻訳単位外に及ぶ(extern宣言)、というのは > 分けて考えるべきだと思うのですが、皆様のご意見はいかがでしょうか? この文章の意味が俺には解釈が難しいんだけど、つまるところ規格書が主張してるのは ・extern があれば外部結合になる (6.2.2) ・extern があっても外部結合であるとは限らない(6.2.2) ・extern があれば外部定義にならない(6.7+6.9.2) ・extern があっても外部定義になりうる場合がある(6.9.2) ・プログラム全体の中で現れる、外部結合をもつ同一識別子は、  そのすべての宣言において、同じものを表す (6.2.2) ということ。それ以上でも以下でもなくて、勝手に行間を読んではいけない。 extern 宣言なんて用語は言語規格書には無いわけで、あえて言うなら 「宣言に extern 指定子がある場合」と呼ぶべき。そして、解釈すべきは 「その宣言が同時に定義になるか否か」「その宣言の持つ結合は何か」 だけ。余計なことを考えずに素直に規格書通りにプログラムを読むだけでいい。 俺俺用語を勝手に作ってはいかん。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1046] Re:externと「外部結合」
投稿者:774RR
2007/09/01 22:25:46

このコメントは yuya さんむけというわけではなくて、第三者読者様の参考分として <結合の規則> 6.2.2 識別子の結合 オブジェクトの宣言の場合 (関数には適用されない) ・記憶域クラス指定なし=外部結合 ・static 指定あり=内部結合 ・extern 指定あり  「すでに宣言があって、その宣言で外部結合または内部結合が指定されている」   →その既存の宣言と同じ結合をもつ  「すでに宣言があって、その宣言で無結合が指定されている」または「宣言が無い」   →外部結合 </結合の規則> <宣言> ・無結合の識別子の宣言が同一スコープ内に2つ以上あってはならない </宣言> ということは、外部結合の宣言が2つあってもよいということ。 6.9.2 の例 int i4; // 宣言、外部結合の仮定義 int i4; // 宣言、外部結合の仮定義 extern int i4; // 宣言、既出の結合を採用、この場合は外部結合 static int i5; // 宣言、内部結合の仮定義 extern int i5; // 宣言、既出の結合を採用、この場合は内部結合 6.9.2 に出てない例 (外部定義にならないのでわざと出していない) extern int i6; // 宣言、既出の宣言が無いので外部結合、外部定義にならない (*136) 脚注のとおり、識別子を使わなければ定義は無くてよい
[この投稿を含むスレッドを表示] [この投稿を削除]
[1045] Re:externと「外部結合」
投稿者:774RR
2007/09/01 22:03:00

なんか難しく考えすぎなのではないかと思ってきた・・・ 言語規格書は書いてあるとおりに読めばよくて、勝手に行間を解釈しては誤るよ。 <[外部定義かそうでないか]の解釈> JISX3010:2003 6.9.2 外部オブジェクト定義、で述べられている内容は要約すると ・オブジェクトの外部定義=ファイル有効範囲と初期化子をもつ場合 ・初期化子がなく、記憶域クラスなしか static があるとき=仮定義 ・仮定義が1つ以上あって外部定義が無い場合は、翻訳単位の終了時点で  仮定義を =0 という初期化子を持つ外部定義と読み替える。 以上。 よってここに書いてないものは外部定義ではないっつーことだ。 記憶域クラス指定 extern をもつ宣言についてはここ 6.9.2 では記載が無いので、 外部オブジェクト定義ではない。 > 私は定義ではなく、ただの宣言である。 ここまでは正しい。というか「外部定義にならない宣言である」というべきかな。 > 定義はほかにある そんな勝手な行間を読んではいけない。これに関しては別に規定がきっちりある。 6.9 外部定義、において ・外部結合で宣言した識別子を使用している場合、プログラム全体の中でその識別子に  対する外部定義がちょうど1つなければならない。 ・使用していない場合、1つ以下でなければならない (*136) (*136) 外部結合で宣言した識別子を使用しない場合、その外部定義は必要ない </[外部定義かそうでないか]の解釈>
[この投稿を含むスレッドを表示] [この投稿を削除]
[1044] Re:externと「外部結合」
投稿者:yuya
2007/08/31 10:38:45

774RRさん、ありがとうございます。 0. C限定の話です。 1. はい、ご紹介くださったものと同じものを入手しています(保存も……)。 2. 変数のextern宣言について[1043]で成り立つことは、 関数原型宣言(externをつけてもつけなくても同じですが)についても成り立つと思うので、関数も含む話です。 3. 処理系準拠限定の話です。[1043]の末尾の非準拠の話は、歴史的経緯の手がかりになるかも、と思って付け加えました。 で、この議論に関係する条項は JISX3010:2003 6.2.2 識別子の結合 6.9 外部定義(とくに 6.9.2 外部オブジェクト定義) になると思います。 [1043]の投稿は、[1025]に774RRさんが書かれた > extern の意味するところは[1020]で書いたとおり、結合指定 > (略) > 厳密なところは自分で JIS 言語規格書を参照してもらうとして、簡単に言うなら > extern:外部結合を指定、static:内部結合を指定 というところを読んで、その意味を考えたのがきっかけです。 確かに6.2.2にはextern宣言された識別子の結合が場合分けされて書かれていますが、 よく読むと回りの定義状況に合わせた定まり方になっており、私には(ごく自然な) *結果* と映ります。 だとすると、extern宣言はどんな「結合指定」を担っているのだろう?と疑問に思ったのです。 特に、初期化子のない外部(ブロック外)変数定義・宣言の場合、 externをつけないほうがむしろ積極的に「外部結合」を指定しているように思います。 内容は前回の繰り返しになりますが、規格書で言えば 6.9.2 外部オブジェクト定義 例1(抜粋) static int i2 = 2; // 定義,内部結合 int i2 ; // 前に内部結合をもつ定義があるため、 // 結合の不一致が生じ、6.2.2によって // 動作は未定義となる extern int i2 ; // 内部結合をもつ前の定義を参照する が該当します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1043] Re:externと「外部結合」
投稿者:774RR
2007/08/30 20:56:28

詳しい議論(重箱の隅ともいう)に入る前に確認事項をいくつか 0.この話は C 限定か?それとも C++ 限定か? 1.言語規格書は読みましたか?今手元にありますか? (C89 なら JIS X3010:1993 ないし ISO/IEC 9899:1990) (C99 なら JIS X3010:2003 ないし ISO/IEC 9899:1999) (C++ なら JIS X3014:2003 ないし ISO/IEC 14882:2003) 2.変数の話限定か?それとも関数も含むか? 3.規格非準拠の処理系の話も含むか?規格書採択前を含むか? 規格非準拠の処理系の話ならパスします(きりがないので) C/C++ 言語規格書が無いのであればお話にならないです。げっちゅしてください。 http://www.jisc.go.jp/ から*閲覧*が可能です (小細工すれば保存もゲフゲフ) 検索が効かないので役に立ちませんが、無いよりは無限大にマシです。 んで、疑問に思われる/わからないところを具体的に条項番号を挙げて話してください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1042] externと「外部結合」
投稿者:yuya
2007/08/30 16:42:41

別スレッドを立てました。 externと「外部結合」については以前から私の悩みの種で、 現時点で以下のように理解しているのですが、問題がないかどうか、よろしければご意見をお聞かせください。 以下、すべてブロック外の話で、「宣言」とは「定義でない宣言」を指すとします。 extern宣言は、同一翻訳単位内にすでに定義があれば、その結合に従った宣言となります。 定義がなければ他の翻訳単位に定義があるだろうと仮定して、 それに対応する宣言になろうとします(この場合には、状況から外部結合しかあり得ません)。 このようにextern宣言の振る舞いを見ると、externは 「近いところから順に定義を探し、状況に合わせて(きわめて自然に)結合が定まる」 宣言であると考えられます。 もちろん、実際にはほとんどのケースで外部結合になり、 内部結合になるのは同一翻訳単位内にstatic定義がある場合だけですが、 これを「例外」と捉えるよりも、上記のように結合が定まると考えたほうが良いように思います。 初期化子のない変数定義・宣言を考えたとき、記憶クラス指定子をつけなければ外部結合の仮定義になりますが、 これが(他に定義があるために)宣言に成り下がった場合でも、外部結合であることは動きません。 したがって、 static int hoge = 1; /* 定義(内部結合) */ int hoge; /* 仮定義(外部結合)、ここでは宣言になるが、結合指定が定義と矛盾する */ は未定義動作になります。これに対し、2行目にexternをつけた static int hoge = 1; /* 定義(内部結合) */ extern int hoge; /* 宣言(結合は状況に応じる)、ここでは定義に従い内部結合となる */ は問題ありません(ソースを比較すると、後者のほうが「問題あり」に見えてしまいますが)。 これを「結合」という観点から見ると、「絶対に外部結合」だったものが、 externを付けることで「結合は状況に合わせる」に変わっています。 ではexternの実際の機能は何かというと、 「私は定義ではなく、ただの宣言である。定義はほかにある」ことを明示することにあります。 [1024]ひげおやじさんの > 「別のところにあるのを宣言する」ってのはexternの本質を表していないのですね。 において、「別のところ」というのが「翻訳単位外」を指しているならば、確かに誤りです。 しかし、その「誤りである理由」は、「外部結合が『翻訳単位内も含む』概念だから」ではなく、 「externが(結合とは無関係に)翻訳単位内外両方に定義を探しに行くから」ではないでしょうか。 そもそもリンケージが翻訳単位外に及ぶ(つまり外部結合)、というのと、 宣言が定義を探しに行く範囲が翻訳単位外に及ぶ(extern宣言)、というのは 分けて考えるべきだと思うのですが、皆様のご意見はいかがでしょうか? なお、ブロック外において明らかに定義と分かるもの(関数定義や、初期化子の付いた変数定義)に externが付いた場合、外部結合になりますね(付けなくても同じですが)。 この場合はexternが文字通り「外部結合」を意味していると考えられますが、 ANSI以前はコンパイルエラーになっていたと聞いたことがあります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1041] 管理者により削除されました
2007/08/30 03:03:40

引用のみの投稿だったため削除しました。
[この投稿を含むスレッドを表示]
[1040] 管理者により削除されました
2007/08/30 03:04:15

引用のみの投稿だったため削除しました。 …ていうか何の嫌がらせよ。
[この投稿を含むスレッドを表示]
[1039] Re:externについて
投稿者:(ぱ)こと管理人
2007/08/29 00:34:30

>この小細工を施したヘッダを『すでに定義を書いてあるファイル』に >インクルードしているようなソースが世の中に(けっこう)存在する > >という大前提がありますよね。 えっ? …と読み返したら、yuyaさんの[1034]には確かにそう書いてありました。 (すみません、よく読んでませんでした) この小細工を使うときには、.cにはそもそも定義を書かないと思います。 .cに定義を書いたらメリットがまったくありませんので。 >>・この小細工は、(1)の問題の解決には役に立たない >えーと、これは「小細工を施してもコンパイラはチェックしてくれない」と >いう意味ではなく、「チェックしてくれるのは小細工のおかげではない」と >いう意味ですよね? そうです。 小細工を行わないとき、方法はふたつあって、[1037]で言うところの a)defvar.cに定義を書き、extern.hに宣言を書く。  defvar.cではextern.hを#includeする。 b)defvar.cに定義を書き、extern.hに宣言を書く。  defvar.cではextern.hを#includeしない。 a)なら型チェックが効きますが、b)では効きません。 774RRさんがおっしゃるような、 >この小細工はexternとは同一翻訳単位外のものを取り扱うものだと >「誤解したプログラマ なら、a)はそもそも書けないと思い込んでいるから、型チェックのため 小細工を行った、というのが、私が書いた 「(1)を問題視したプログラマがこの小細工を使った」 の意図です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1038] Re:externについて
投稿者:yuya
2007/08/28 07:16:42

どうも自分が議論について行っているつもりで 実は勘違いしているような気がしてきて不安なのですが……。 まず、この議論には この小細工を施したヘッダを『すでに定義を書いてあるファイル』に インクルードしているようなソースが世の中に(けっこう)存在する という大前提がありますよね。その上での話ですが、 > 774RRさんの説は、(1)を問題視したプログラマがこの小細工を使った、 > というものですよね。(2)はいずれにせよ問題になるんですから。 確かに宣言自体を削らずにわざわざexternだけ削っているということは コンパイラのチェックを気にしているとも考えられますが、 単に「ここではまずいから、externを削っとこう」くらいの人もいるような気がします。 誰かが(2)の目的で書いたものを見て、 主旨を誤解して使っている(で、同じことをばっちり2回書いている)というのは あり得そうですね。 >・この小細工は、(1)の問題の解決には役に立たない えーと、これは「小細工を施してもコンパイラはチェックしてくれない」という意味ではなく、 「チェックしてくれるのは小細工のおかげではない」という意味ですよね?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1037] Re:externについて
投稿者:(ぱ)こと管理人
2007/08/28 01:38:14

山奥に旅に出ているうちに掲示板が進んでました。 >この小細工はexternとは同一翻訳単位外のものを取り扱うものだと >「誤解したプログラマが」書いてたもので >言語仕様を理解していたプログラマなら書かない代物。 どうでしょうか。私が最初にコレ↓を書いた時点では、 http://kmaebashi.com/programmer/pointer.html 細かい仕様を理解していたかどうかはともかく、extern付きのとそうでないのを 同一コンパイル単位に書いてよい、ということは経験から知っていたと思いますよ (昔のことですし、証拠を出せといわれても困りますが)。 ていうか、変数定義を入れたdefvar.cとextern宣言を入れたextern.hがあったとして、 defvar.cだけextern.hを#includeしないことは容易です。 その場合嬉しくないこととしては以下の2点があって、 (1)defvar.cとextern.hの間でコンパイラのチェックが働かなくなる。 (2)似たようなことを2箇所に書かなければならない。 774RRさんの説は、(1)を問題視したプログラマがこの小細工を使った、 というものですよね。(2)はいずれにせよ問題になるんですから。 (1)の問題は、int hoge[100];とint *hoge;みたいな問題を起こすので 確かに恐ろしいんですが、(2)の問題も存在するわけですから、 (1)の問題のため「だけ」にこの小細工が使われた、というのは無理があるように 思います。 ・この小細工は、(1)の問題の解決には役に立たない(役に立つと思っている  人がいるとしたら、Cの仕様を知らないだけ)。 ・(2)の問題の解決にはなるが、初期化子が書けなくなるしパーサ通らなくなる  マクロの使い方なのであまり薦められたもんではない。 ということであれば同意します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1036] Re:externについて
投稿者:yuya
2007/08/27 17:08:34

> [結合]を理解していないプログラマが[仮定義]を理解していて、 > 意識してこういうコードを書いたかという点については、俺はきわめて疑問に思う。 > たまたま実害が無かったとしても「間違っているが結果オーライ」なだけだろう。 全面的に同意します。前回もそういうつもりで書きました。 実害が出てくれりゃ勉強する機会も生まれただろうに、と。 > [1020]と[1033]のサンプルは変えてあるのだけど、ちゃんと見てるよね。 はい、ちゃんと見てますです(コメントしておらず失敬しました)。 複数のヘッダファイルをインクルードする状況では、 [1020]だと#undefしとかないと重複定義になっちゃいますね。 でもって、[1035]のようにEXTERNの名前を使い分けるなら、 わざわざHOGE_DEFINITIONだのPIYO_DEFINITIONだのを別に用意する必要はないわけですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1035] Re:externについて
投稿者:774RR
2007/08/27 08:32:29

[結合]を理解していないプログラマが[仮定義]を理解していて、 意識してこういうコードを書いたかという点については、俺はきわめて疑問に思う。 たまたま実害が無かったとしても「間違っているが結果オーライ」なだけだろう。 繰り返すが C++ には[仮定義]は無いのでこーいう書き方はダメ。 [1020]と[1033]のサンプルは変えてあるのだけど、ちゃんと見てるよね。 [1020]は実際には一行抜けてて #undef EXTERN が #ifdef の前に必要 [1033]は EXTERNHOGE と EXTERNPIYO と使い分けて名前がかぶらない 両者ともいちおう正しく使えば[仮定義]も重複しないようになってるつもり。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1034] Re:externについて
投稿者:yuya
2007/08/26 16:41:01

774RRさん、ありがとうございます。 「現代 C/C++ では不要」とあったので、 古い処理系でも通るようにするための小細工なのかな、 と思ったんですが、「誤解の産物」だったんですね。 誤解されたままで、このヘッダが 外部定義か仮定義のあるファイルにインクルードされてEXTERNが消えても、 それに続く部分は仮定義になるので (つまり、外部定義 + 仮定義になるか、仮定義 + 仮定義になり、 どちらにしても「外部定義がただひとつ」と等価になる) 実害はなかった、ということになるのでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1033] Re:externについて
投稿者:774RR
2007/08/25 21:38:09

>かつてはexternが「同一翻訳単位外のみ」を意味していたのでしょうか? かつてというのがどのくらい昔の話を意図してるのかわからないけど、 少なくともC89 (ISO/IEC 9899:1990) の文書には今と同じ[結合]の記述がある。 規格採択前の独自仕様の処理系については、もう知る必要も無いと思う。 俺は採択前の処理系も複数個実用してたけど、「外のみ」は無かったと追記しとく。 この小細工はexternとは同一翻訳単位外のものを取り扱うものだと 「誤解したプログラマが」書いてたもので 言語仕様を理解していたプログラマなら書かない代物。 あるいは[1022]前橋さんのコメントのように 宣言部と定義部で類似の記述を分散させるのを嫌ったプログラマが行っていたかもしれない。 ----hoge.h---- extern int hoge; ----hoge.c---- #include "hoge.h" int hoge; // これならここに初期値を書ける -------------- hoge の記述がヘッダとソースで2回出てくるのはミスの元という人がいる 以下のように書いておけば記述が2回必要ないというわけで ----piyo.h---- #ifndef EXTERNPIYO #define EXTERNPIYO extern #endif EXTERNPIYO int piyo; ----piyo.c---- #define EXTERNPIYO #include "piyo.h" // piyo の初期値を与える手段が無い -------------- んで [1022] に既述のごとく初期化子がうまく書けないとか問題があるんで俺はやらない。 ちなみにC++ではODRがあるので「定義にならない宣言」と「定義」は分離するのが定石。 類似の既述が2回でてくるのは仕方ない。類似は同一ではないのだから。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1032] 管理者により削除されました
2007/08/30 03:03:18

引用のみの投稿だったため削除しました。
[この投稿を含むスレッドを表示]
[1031] Re:自動変数を返すこと
投稿者:ひげおやじ
2007/08/25 12:53:42

ご回答ありがとうございますm(_ _)m >returnで変数の値を返すときは、それがポインタかどうかに関わらず、別の場所へ中身がコピーされます。 この「returnの動作」の理解が足りませんでした。おかげさまでモヤモヤが取れました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1030] Re:externについて
投稿者:yuya
2007/08/25 08:46:08

>以下のような小細工コードをいまだに見るけど、現代 C/C++ であれば不要 >#ifdef HOGE_DEFINITION >#define EXTERN >#else >#define EXTERN extern >#endif 昔のCを知らないので、教えていただきたいのですが、 かつてはexternが「同一翻訳単位外のみ」を意味していたのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1029] Re:自動変数を返すこと
投稿者:トル
2007/08/25 01:49:50

日本語がまずかったので訂正。 >呼び出し側で返されたポインタを使って、自動変数(のあった所)にアクセスしているからまずいのです。 呼び出した関数から返されたポインタを使って、自動変数(のあった所)にアクセスしているからまずいのです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1028] Re:自動変数を返すこと
投稿者:トル
2007/08/25 01:46:46

はじめまして。 >そこに載っている関数int_to_strではポインタを返しているからまずいの >でしょうか?それとも、ポインタでなく整数値を返す場合でも、関数の >中で宣言した自動変数の値を返すことはやめた方がよいのでしょうか。 呼び出し側で返されたポインタを使って、自動変数(のあった所)にアクセスしているからまずいのです。 >たとえば、次のような関数は(int_to_strと同じ観点から見て)まずいのでしょうか。 > >int keep(int int_value) >{ > int i; > i = int_value * int_value; > return i; >} この場合は問題ありません。 returnで変数の値を返すときは、それがポインタかどうかに関わらず、別の場所へ中身がコピーされます。 自動変数のポインタを返すとまずいのは、そのポインタが指す領域がなくなってしまうからです。 int *f(void) { int a = 0; return &a; } と言う関数があったとき、 int *p = f(); printf("%p", p); /* pの値を表示する */ のようにすることは何の問題もありません。しかし、ポインタが指している領域はすでに開放されているので、 int *p = f(); printf("%d", *p); /* pが指している領域の値を表示する */ のような事はできない、と言うことです。 こんな感じでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1027] 自動変数を返すこと
投稿者:ひげおやじ
2007/08/24 23:24:01

お世話になっております。 「C言語ポインタ完全制覇」の97ページの補足「自動変数の領域は、 関数を抜けたら開放される!」のつながりで質問させてください。 そこに載っている関数int_to_strではポインタを返しているからまずいの でしょうか?それとも、ポインタでなく整数値を返す場合でも、関数の 中で宣言した自動変数の値を返すことはやめた方がよいのでしょうか。 たとえば、次のような関数は(int_to_strと同じ観点から見て)まずいのでしょうか。 int keep(int int_value) { int i; i = int_value * int_value; return i; } ご返答いただけると幸いです。 (なにぶん継ぎ接ぎの知識なもんで、この質問自体がまずいかもしれませんが・・・)
[この投稿を含むスレッドを表示] [この投稿を削除]
[1026] Re:体当たり学習について質問
投稿者:ちょいち
2007/08/22 02:02:52

>トルさん、(ぱ)さん 返信遅くなってすみません。 大変分かりやすく説明していただき、ありがとうございました! よくわかりました。 「なぜこの関数から??」 →まさにこの疑問でした・・・。 本当にありがとうございました!!
[この投稿を含むスレッドを表示] [この投稿を削除]
[1025] Re:externについて
投稿者:774RR
2007/08/21 08:37:50

>「別のところにあるのを宣言する」ってのはexternの本質を表していないのですね。 こういう疑問が出てくるということは、言語規格書を読んでみていいレベルということだ 初心者向け解説書は厳密さよりもわかりやすさを優先せざるを得ないので びみょーに不正確だったりすることがある extern の意味するところは[1020]で書いたとおり、結合指定 C なら JIS X 3010:2003 6.2.2 C++ なら JIS X 3014:2003 3.5 厳密なところは自分で JIS 言語規格書を参照してもらうとして、簡単に言うなら extern:外部結合を指定、static:内部結合を指定 外部結合=その名前が表す実体は、他の翻訳単位または同じ翻訳単位で使うことができる 内部結合=その名前が示す実体は、同じ翻訳単位で使うことができる ということだ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1024] Re:externについて
投稿者:ひげおやじ
2007/08/21 03:24:05

ご回答ありがとうございますm(_ _)m 変数と関数の宣言・定義の違いでの説明がしっくり来ました。 >初心者向け解説として「 extern は別のところにあるものを使う宣言」と書いてある書籍を見かけるけど >言語規格書的には大きく間違い (同一翻訳単位中にあってもかまわないので) まさにこれがもう一つ質問したかったことでした。 「別のところにあるのを宣言する」ってのはexternの本質を表していないのですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1023] Re:externについて
投稿者:774RR
2007/08/21 00:03:20

>グローバル変数の名前が偶然かち合ってしまう可能性があります。 (snip) >と書いてもエラーにならないと困ってしまいます。 C++ においては ODR (One Definition Rule) により、これは必ずエラーになる C ではエラーにならない (仮定義の重複を認める) という違いがあるですな。 初心者向け解説として「 extern は別のところにあるものを使う宣言」と書いてある書籍を見かけるけど 言語規格書的には大きく間違い (同一翻訳単位中にあってもかまわないので) 俺も後輩君にそういう説明したことあるし反省っすな。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1022] Re:externについて
投稿者:(ぱ)こと管理人
2007/08/20 22:56:45

>ヘッダ中で宣言+ソースファイル中で定義することは完璧に正しい これはもちろんそうなのですが、 >以下のような小細工コードをいまだに見るけど、現代 C/C++ であれば不要 >#ifdef HOGE_DEFINITION >#define EXTERN >#else >#define EXTERN extern >#endif この小細工は、ヘッダとソースファイルに似たようなものを分散させたくないという面からは有効だと思いますよ。初期化子がうまく書けないとか、文法的にCのパーサを通らんようなマクロを作るなとか、そもそもそんなにグローバル変数使うなよとか、批判があるのはわかりますが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1021] Re:externについて
投稿者:(ぱ)こと管理人
2007/08/20 22:51:43

>分割コンパイルなどで、外部で定義している変数を参照するにはexternを使う、と >よく本に書いてあると思いますが、外部の関数を参照するにはexternを >付ける必要がないように見受けられるのです。これはなぜなんでしょうか。 774RRさんのおっしゃるようにそういう約束だから…なのですが(X3010の6.1.2.2)それを言ってしまうとつまらないので、理由を考えますと。 大規模なプログラムを何人もの人で書いている場合、グローバル変数の名前が偶然かち合ってしまう可能性があります。たとえば a.c: int hoge; b.c: int hoge; と書いてもエラーにならないと困ってしまいます。この場合、それぞれの担当プログラマには、「グローバル変数の値がいつの間にか変わっている」という得体の知れないバグとして見えるはずです。 その点、「externなしで定義できるのは必ず1箇所のみ、それ以外の箇所では必ずexternを書け」という規則にしておけば、リンク時にエラーになるのでこの問題を回避することができます。 では関数の場合はどうかというと、関数名が偶然かち合ったとして、 a.c: int hoge(void) {...} b.c: int hoge(void) {...} とか書いたらどうせエラーです。 つまり、関数の場合、関数の処理を書くブロックの有無で定義と宣言の区別がつくため、わざわざexternをつける必要はない、というのが私の理解です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1020] Re:externについて
投稿者:774RR
2007/08/20 20:09:49

そういう約束だから 関数(原型)宣言に extern も static もない場合は extern が補われると考えよう void myfunc(int); // これには extern も static も明示されてないので extern void myfunc(int); // と解釈される規則 この規則は関数の場合にのみ適用されるので、変数宣言には適用されない 以下は、言語規格書の厳密解釈なので、一読してわからなかったらスキップしてね ・関数宣言で指定できる linkage は static か extern かどちらかだけ (無指定も OK) ・ static が明示されている関数宣言は internal linkage ・ internal linkage でない関数宣言は external linkage ヘッダ中で宣言+ソースファイル中で定義することは完璧に正しい ----hoge.h---- void hogefunc(double); // This declaration has external linkage ----hoge.c---- #include "hoge.h" void hogefunc(double d) { ... } // This definition also has external linkage 以下のような小細工コードをいまだに見るけど、現代 C/C++ であれば不要 #ifdef HOGE_DEFINITION #define EXTERN #else #define EXTERN extern #endif
[この投稿を含むスレッドを表示] [この投稿を削除]
[1019] externについて
投稿者:ひげおやじ
2007/08/20 15:07:24

「C言語ポインタ完全制覇」を読ませてもらっております。 その本の本筋とは外れるのかしれませんが、第5章のヘッダファイルの作成と関連 してexternでわからない点がいくつかあるので質問させてください。 ご回答いただけると幸いです。 とりあえず、ひとつお聞きします。 分割コンパイルなどで、外部で定義している変数を参照するにはexternを使う、と よく本に書いてあると思いますが、外部の関数を参照するにはexternを 付ける必要がないように見受けられるのです。これはなぜなんでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1018] Re:体当たり学習について質問
投稿者:(ぱ)こと管理人
2007/08/16 22:04:45

ちょいちさん、はじめまして。 >fgets(buf, 1024, stdin) >と書いていたのを、なぜ急に >fget(buf, 1024, fp) >と変えたのですか?? もちろんこれはトルさんから回答があったように入力元を変えるためなのですが、 「なぜこのプログラムから?」というのが疑問であるわけですよね。 確かに説明不足だったかもしれません。 理由は、ここで作っている関数input_string()は、汎用の関数を目指している ためです。 このinput_string()は、扱える行の最大長に制限があるとはいえおおむね現実的な 入力においては、長さチェックを行って長すぎる場合にはエラーまで出してくれる、 という便利な関数です。実際、蔵書管理プログラムの中でもあちこちで使われて いますし、今後別のプログラムで使うこともあるかもしれません。 今後別のプログラムで使うことがあるのなら、入力元をstdinに限定して しまったのでは汎用性が薄れます。そこで、input_string()に引数として 入力元を渡せるようにしているわけです。 これで回答になっていますでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[1017] Re:体当たり学習について質問
投稿者:トル
2007/08/16 13:24:20

はじめまして。私は『C言語 体当たり学習徹底入門』はもってないんですが・・・ちょっとだけ。 fgetsの第三引数の型はFILE *で、入力先を指定します。 stdinは標準入力と結びついていますので、stdinを渡せば標準入力から入力します。 fpの方は、どこぞのファイルに結びついていますので、fpを渡せばそのファイルから入力します。 要するに、stdinをfpに変えたのは、読み込み先を変えたという事です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1016] Re:体当たり学習について質問
投稿者:ちょいち
2007/08/16 02:56:05

すいません。 自分の文章が自分でも理解できなかったので 何が分からないかを言い直しますw えぇと、「FILE *fpを引数に渡しているのはなぜか」というよりも、 fgets(buf, 1024, stdin) と書いていたのを、なぜ急に fget(buf, 1024, fp) と変えたのですか?? ってことがわからないってことです・・・。 すんません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1015] 体当たり学習について質問
投稿者:ちょいち
2007/08/16 02:47:02

はじめまして。ちょいちというC言語初心者です。 C言語体当たり学習徹底入門で勉強しています。 お世話になってます。 で、早速質問を・・・。 既出でしたら大変申し訳ないのですが、 p225のlist5-6やp227のlist5-8において、関数の引数に 『FILE *fp』があるのはなぜですか? よろしくお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1014] 管理者により削除されました
2007/08/11 13:56:30

広告なので削除しました。
[この投稿を含むスレッドを表示]
[1013] 管理者により削除されました
2007/08/08 01:27:43

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[1012] 管理者により削除されました
2007/08/03 19:59:13

広告なので削除しました。
[この投稿を含むスレッドを表示]
[1011] Re:前橋和弥さんへの謝罪
投稿者:(ぱ)こと管理人
2007/08/03 03:26:31

>お父さんには今夜じゅうにでも謝っておこうかと思います。 それはよかった… ですが。 >後、気になることがあるのですが、以前、掲示板を覗かせてもらったときに、 >前橋さんが僕に対して「前言撤回。こういう馬鹿は一度死ななきゃわからないのかも >しれない。」とおっしゃっていたのを記憶しております。 a) まず、私はそのような発言をした覚えはありません。念のため「前言撤回」や  「馬鹿」でkmaebashi.comをGoogleサイト内検索してみましたがみつかりません。 b) それ以前の問題として、そもそも吉田さんは、この掲示板に書き込んだのは  2007年8月1日の[1008]が最初ではないのですか? 「初めまして」と書いてあるし。  ほんの1~2日前にこの掲示板に登場した人に、過去罵声を浴びせることが  できるはずがありません。 c) 仮に、吉田さんがかつては別のハンドルネームでうちの掲示板に書き込んでいて  私から何らかの罵声を浴びせられたとして、だったらその過去のハンドルネームなりを  教えてもらわなければ、私には、何の話だかわかるはずもありません。  >これは何に対する憤怒なのでしょうか。 >僕はずっとbrainfuckインタプリタを自分の物として父親に発表されたことによる >憤怒かと思っておりました。 d) 「brainfuckインタプリタを自分の物として父親に発表された」ということを  吉田さんがこの掲示板に報告したのは、これもつい1~2日前の[1008]の投稿です。  吉田さんがお父さんに何を発表しようと、その内容を私が知ることは不可能です。  よって、それによって私が憤怒するなどということがあるはずもありません。 a)だけなら、別の掲示板と勘違いしてたとか、前橋の方が過去に罵声を浴びせた ことを忘れてる、ということもあり得るでしょうが、b), c), d)は、そういうことでは 説明がつきません。 煽りでもなんでもなく思うのですが、吉田さん、統合失調かなにかのケがありませんか。 もちろん私のような素人が勝手に診断を下してよいはずはないわけで、だからこそ、 (現在未受診であれば)精神科の診察を受けられたほうがよいのではないでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1010] Re:前橋和弥さんへの謝罪
投稿者:吉田祥彰(本名)
2007/08/02 11:50:03

前橋さん、ご返信ありがとうございます。 brainfuckインタプリタの件に関して前橋さんが「問題ない」とおっしゃってくれてホッとしております(NYSLの簡単な概要に関しては理解しました)。 お父さんには今夜じゅうにでも謝っておこうかと思います。 後、気になることがあるのですが、以前、掲示板を覗かせてもらったときに、前橋さんが僕に対して「前言撤回。こういう馬鹿は一度死ななきゃわからないのかもしれない。」とおっしゃっていたのを記憶しております。これは何に対する憤怒なのでしょうか。僕はずっとbrainfuckインタプリタを自分の物として父親に発表されたことによる憤怒かと思っておりました。もし、違う理由があるのであれば、その理由を教えていただけないでしょうか。よろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1009] Re:前橋和弥さんへの謝罪
投稿者:(ぱ)こと管理人
2007/08/01 23:16:32

>僕が前橋和弥さんの作った宝であるbrainfuckインタプリタをさも自分が >作ったかのように自分の父親に発表してしまったことです。これは >ソースファイルの盗用にあたるかと思います。 Brainfuck自体は、私が考えた言語ではないですし、実装もそこかしこに 転がっていますがそれはさておき。 BF-BASIC'nのソースについて言えば、ライセンスはNYSLであり、これは http://www.kmonos.net/nysl/ | ご自分の作ったものを扱うのと同じように、自由に利用することが出来ます。 と明記してあるとおり、BF-BASIC'nのソースを「さも自分が作ったかのように」 扱うことはまったく問題がありません。 よって、私からすればまったく問題ないわけですが、吉田さんが謝罪すべき 相手はお父様の方ではないでしょうか。嘘をついたわけですから。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1008] 前橋和弥さんへの謝罪
投稿者:吉田祥彰(本名)
2007/08/01 11:53:44

初めまして。吉田祥彰という者です。今回は前橋和弥さんへ謝罪いたしたく投稿させていただきました。謝りたい件というのは、僕が前橋和弥さんの作った宝であるbrainfuckインタプリタをさも自分が作ったかのように自分の父親に発表してしまったことです。これはソースファイルの盗用にあたるかと思います。ここで前橋さんにお願いがあります。どうか前橋さんの寛大な心で、僕の愚行を許していただけないでしょうか?今後、このようなことはしないように最大限の注意を払って努力していくつもりです。どうかよろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1007] Re:すぽぽーーん
投稿者:(ぱ)こと管理人
2007/07/29 01:32:04

>BF-BASIC…前フリで「逆にいま BASIC 回帰もありなんだな」とか妙に納得しちゃったんですがすぽぽーんでコーヒー吹きました どうもです。ウケたようで何よりです。 いまさらですが、BF-BASIC'nは日付を見ればわかるように2006年のエイプリルフールに書いたものです。 ところで、前フリ部分は、私にとってはあれはあれで一面の本音ではあります(ぼそっ)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1006] すぽぽーーん
投稿者:通りすがったり
2007/07/28 14:30:08

BF-BASIC…前フリで「逆にいま BASIC 回帰もありなんだな」とか妙に納得しちゃったんですがすぽぽーんでコーヒー吹きましたBF で気づくべきだったのだな
[この投稿を含むスレッドを表示] [この投稿を削除]
[1005] Re:Python 関数電卓
投稿者:nao
2007/07/23 23:49:52

>>コードが美しく、短く、分かりやすいです。 > >うーん、ざっと見ただけですが、なんか効率悪いパーサのような… > 許容範囲のコードかなぁー
[この投稿を含むスレッドを表示] [この投稿を削除]
[1004] Re:Python 関数電卓
投稿者:(ぱ)こと管理人
2007/07/22 14:51:44

>つんつんが時々 訪れている「紫藤さんのページ」のPython関数電卓です。 >http://www.shido.info/py/python_calc.html 情報ありがとうございます。 「Perl, Python, Rubyの比較」 http://www.shido.info/py/python1.html は以前に読んだことがあるのですが、その方のページだったんですね。 >コードが美しく、短く、分かりやすいです。 うーん、ざっと見ただけですが、なんか効率悪いパーサのような…
[この投稿を含むスレッドを表示] [この投稿を削除]
[1003] Python 関数電卓
投稿者:つんつん
2007/07/21 08:08:11

つんつんが時々 訪れている「紫藤さんのページ」のPython関数電卓です。 http://www.shido.info/py/python_calc.html コードが美しく、短く、分かりやすいです。 (つんつんの関数電卓は、引退しました。) 「紫藤さんのページ」には、scheme の関数電卓もあります。 http://www.shido.info/lisp/scheme_calc.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1002] 管理者により削除されました
2007/07/21 01:14:25

意味不明の投稿なので削除しました。 テスト投稿であればテスト用掲示板にお願いします。
[この投稿を含むスレッドを表示]
[1001] Re:「プログラミング言語を作る」が面白い
投稿者:(ぱ)こと管理人
2007/07/19 00:42:24

>>あ、それすごく面白そうです。何度か書いてますが、私自身車輪の再発明が趣味ですし。 > >私も全く同様なのですが、どうも肩身が狭いですね。 >サイトが稼動し始めたらお知らせします。 や、よろしくお願いします。 エディタとかメーラとか、普段使っているツールは、プログラマにとってもっとも自作 したくなる道具であるはずで、だったらプログラミング言語は最優先のはずではないか、 とも思うのですが。 前提からして間違っているのかなあ… # かくいう私自身、クライアントアプリとしてのメーラを書いたことはないですが # (Webメーラなら書いたことある) >解説とか研修を行なうときは「無駄を省いた自作コース」を提供するのが強力であることが多いと思います。 その意味で、以前書いたように「本当の基礎からのWebアプリケーション入門―― Webサーバを作ってみよう」というのを考えてはいるのですが、Diksamができるまでは お預けです。ていうか私自身読みたいネタなので、誰か書いてくれないかしらん。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1000] Re:「プログラミング言語を作る」が面白い
投稿者:yuya
2007/07/18 12:34:35

>>「車輪の再発明工場(仮称)」なんていうサイトを立ち上げようとしている私としては、 > >あ、それすごく面白そうです。何度か書いてますが、私自身車輪の再発明が趣味ですし。 私も全く同様なのですが、どうも肩身が狭いですね。 サイトが稼動し始めたらお知らせします。 > 言語処理系だけでなく、普段使っている何かを自作するというのは、それを理解する > 一番の方法でもありますし(時間はかかるので効率は悪いですが…)。 そうですよね。何にもない状態から発明した人よりははるかに短時間で作れるわけですから、 解説とか研修を行なうときは「無駄を省いた自作コース」を提供するのが強力であることが多いと思います。 # 「何でも自作してみないと本当に分かった気がしないのは、損なのか得なのか??」と悩んじゃうことはありますが(^^;)
[この投稿を含むスレッドを表示] [この投稿を削除]
[998] Re:「プログラミング言語を作る」が面白い
投稿者:(ぱ)こと管理人
2007/07/15 04:17:07

>「車輪の再発明工場(仮称)」なんていうサイトを立ち上げようとしている私としては、 あ、それすごく面白そうです。何度か書いてますが、私自身車輪の再発明が趣味ですし。 言語処理系だけでなく、普段使っている何かを自作するというのは、それを理解する 一番の方法でもありますし(時間はかかるので効率は悪いですが…)。 >素朴な疑問なんですが、(ぱ)さん自身はCrowbarやDiksamを普段どれくらい使われているのでしょうか? これはもう正直なところを言ってしまうと、ほぼまったく使っていません。 Diksamなんか現状でprint()しか組み込み関数がないので実用になりませんし、 crowbarならAWK程度の役には立ちそうですが、そもそもAWKとかPerlとかRubyとかの 言語でさくっとテキスト処理、という機会も、今の私にはあまりないですし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[997] Re:「プログラミング言語を作る」が面白い
投稿者:yuya
2007/07/14 00:38:53

久々にお邪魔します。 >まあ、あの文章が面白いのだとすればそれは別に私の手柄ではなく、 >「プログラミング言語を作る」という行為自体が非常に面白いためなんだろうと >思いますが。 ># でも、同意してくれる人はあまり多くない気がします。残念ながら。 「(ぱ)さんの手柄ではない」という点は同意しませんが、 「言語を作るという行為自体が面白い」という点は同意します(そんなに少数なんですかね?)。 「車輪の再発明工場(仮称)」なんていうサイトを立ち上げようとしている私としては、 「面白そうだからやってみる。それだけ」というノリに共感を覚えてしまうんですが(^^;) 素朴な疑問なんですが、(ぱ)さん自身はCrowbarやDiksamを普段どれくらい使われているのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[996] 管理者により削除されました
2007/07/14 07:55:43

広告なので削除しました
[この投稿を含むスレッドを表示]
[994] Re:「プログラミング言語を作る」が面白い
投稿者:(ぱ)こと管理人
2007/07/13 00:54:52

はじめまして。おほめいただきありがとうございます。 まあ、あの文章が面白いのだとすればそれは別に私の手柄ではなく、 「プログラミング言語を作る」という行為自体が非常に面白いためなんだろうと 思いますが。 # でも、同意してくれる人はあまり多くない気がします。残念ながら。 >「プログラミング言語を作る」を体裁を整えて本にしてください。 >5000円未満なら買います。 えー、どうなるかはわかりませんが、精進いたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[993] Re:bc より高機能な関数電卓
投稿者:(ぱ)こと管理人
2007/07/13 00:53:00

>あれ、Cにはありますよ。少なくともC89では既にありました。 ありゃ、本当だ。Cの構文規則は何度も見ているしパーサを書いたことも複数回あるし、 知らなかったはずはないのですがなぜか「ない」と思い込んでいたようです。 >Java は知りません。:) ありました。 http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.15.3 毎度のことながらご指摘ありがとうございます。 嘘を書きましてすみませんでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[992] 「プログラミング言語を作る」が面白い
投稿者:なぞ
2007/07/12 18:49:18

「プログラミング言語を作る」を体裁を整えて本にしてください。 5000円未満なら買います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[991] Re:bc より高機能な関数電卓
投稿者:kit
2007/07/11 22:58:34

> CでもJavaでも単項の+演算子は用意されていませんよね あれ、Cにはありますよ。少なくともC89では既にありました。 Java は知りません。:)
[この投稿を含むスレッドを表示] [この投稿を削除]
[990] Re:bc より高機能な関数電卓
投稿者:(ぱ)こと管理人@自宅環境復活
2007/07/11 02:15:46

 再投稿ありがとうございます。  電卓の大親分であるはずのPCが目の前にあるのに電卓叩いてたり、あろうことか電卓内蔵のマウスパッドなんかが普通に商品の1ジャンルを占めていたりする現状を見るにつけ、こういう(bcのような)電卓には価値があると思います。  私はすぐにyaccを使ってしまいますが、つんつんさんのは手書きの再帰下降パーサですね。RubyならRaccという手もあるかと思いますが。 >bc では、+1+1+1 がエラーで、-1-1-1 が成功します。 >動作が変です。  これは実際そのとおりだと思いますが、CでもJavaでも(ついでに言うとcrowbarでもDiksamでも)単項の+演算子は用意されていませんよね(Rubyにはあるようですが)。  単項+演算子を付けるのは容易なはずなのに付けてないのは、crowbarやDiksamについて言えば単にCをまねたからなのですが、冗長な表現を嫌ったという理由もあるのかもしれません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[989] bc より高機能な関数電卓
投稿者:つんつん
2007/07/10 23:25:19

bc では、+1+1+1 がエラーで、-1-1-1 が成功します。 動作が変です。 ruby スクリプト:正規表現が厳密に合っていないのですが 電卓として機能します。 'q' で終了です。 試してください。   http://www.otc.ne.jp/~mugenkai/keisan.rb tntn@otc.ne.jp
[この投稿を含むスレッドを表示] [この投稿を削除]
[988] 管理者により削除されました
2007/07/10 23:11:58

ここにあった投稿は広告なので削除するんですけど、 この投稿の前に、Rubyで作った電卓プログラムを投稿された方が いらっしゃったはずなんですが… 削除しちゃったのかなあ。残念です。
[この投稿を含むスレッドを表示]
[985] Re:関数の型の宣言構文について
投稿者:みずしま
2007/06/27 15:15:02

>ASTや中間表現は共通で、コード複製はコード生成部で行うことになるのだと >思いますけれども、それをいつやるか、という問題がありますよね。 >Javaのような実行形態を考えると、Listクラスはきっと事前にコンパイルされて >いるはずですし、List<int>を使うクラスがあっちにもこっちにもあるとすると、 >コンパイルの時点で複製すると悲惨なことに。 分割コンパイルを行うときの問題ですか。基本型を対象とするなら個数が あらかじめ決まっているので、Listクラスのコンパイル時に List_int.class, List_long.class, ... を生成しておけば済みそうですが、実体型をユーザが宣言できる言語だと、 同じ手は使えないわけで、考えどころですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[984] Re:関数の型の宣言構文について
投稿者:(ぱ)こと管理人@自宅環境復活
2007/06/27 01:44:54

>PCは新しいのを買ったんでしょうか? >いまどきなら Core 2 Duo とか? はてなの方に書いてますが、こんな感じです。 http://d.hatena.ne.jp/kmaebashi/20070620#p1 http://d.hatena.ne.jp/kmaebashi/20070627 ブツ自体はこれです。Core 2 Duoです。 http://panasonic.jp/pc/products/w5a/index.html 久々にはりこみました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[983] Re:関数の型の宣言構文について
投稿者:(ぱ)こと管理人@自宅環境復活
2007/06/27 01:38:31

>はい。ただ、それは全ての型について同一のバイトコードで扱えなければならないという方針の場合の話であって、例えば、基本型は型ごとにコード複製、参照型はErasureによって同一のバイトコードに変換するなどの方針であればコンパイラだけでごまかせると思います。 それはそうです。実際C#だと、値型はコード複製、参照型は同一コードということに なっているようですし。 http://ja.wikipedia.org/wiki/C_Sharp%E3%81%A8Java%E3%81%AE%E6%AF%94%E8%BC%83 >確かに。ただ、ASTや中間表現の段階で実体型ごとにコードを複製しておけば、 >「何バイトコピーするか」などの詳細はコード生成部に任せられるのでは? ASTや中間表現は共通で、コード複製はコード生成部で行うことになるのだと 思いますけれども、それをいつやるか、という問題がありますよね。 Javaのような実行形態を考えると、Listクラスはきっと事前にコンパイルされて いるはずですし、List<int>を使うクラスがあっちにもこっちにもあるとすると、 コンパイルの時点で複製すると悲惨なことに。
[この投稿を含むスレッドを表示] [この投稿を削除]
[982] Re:関数の型の宣言構文について
投稿者:kit
2007/06/26 01:03:04

> 現在のDiksamについてであれば、実体に対する代入等の操作ができるように > するつもりはありません。 なるほど。 > それがどれぐらい仕様上も実装上も難しいものであるか、 たぶんユーザにも優しくないですよねえ。 > @自宅環境復活 PCは新しいのを買ったんでしょうか? いまどきなら Core 2 Duo とか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[981] Re:関数の型の宣言構文について
投稿者:みずしま
2007/06/26 00:51:15

>どこまでVMに実行時情報を持たせるかにもよりますが、たとえばJVMでは、 >T型の変数 a, b があるとき、 >Tがintのときの a = b; と、Tがdoubleのときの a = b;を同一のバイトコードでは >表現できないのでは? >Javaはクラスに関する限りポインタ(参照)しかない言語ですし、 >Genericsで対象にできるのは結局Objectだけなので、コンパイラだけで >ごまかしきれてますけれども。 はい。ただ、それは全ての型について同一のバイトコードで扱えなければならないという方針の場合の話であって、例えば、基本型は型ごとにコード複製、参照型はErasureによって同一のバイトコードに変換するなどの方針であればコンパイラだけでごまかせると思います。 >基本型は対象にしないとしても、クラスの(ポインタでなく)実体を扱えるように >した場合、C++のように機械語を吐くコンパイラでは、「何バイトコピーするか」が >型ごとに違ってきます。このへんVMだと工夫のしようはありそうですが。 確かに。ただ、ASTや中間表現の段階で実体型ごとにコードを複製しておけば、「何バイトコピーするか」などの詳細はコード生成部に任せられるのでは?
[この投稿を含むスレッドを表示] [この投稿を削除]
[980] Re:関数の型の宣言構文について
投稿者:(ぱ)こと管理人@自宅環境復活
2007/06/26 00:31:08

>あれ、インスタンスに対して参照だけではなく、実体に対する代入等の操作ができる >ようにするんでしょうか? それはやめた方が良いような。 ええと、みずしまさんの独自言語についてはわかりませんが、 現在のDiksamについてであれば、実体に対する代入等の操作ができるように するつもりはありません。 [975]で >当時は、Javaのような「ポインタしかない言語」が嫌で、クラスは実体でも >宣言できるようにしようとしていましたし、 と書いたように、(ふたつめくらいのDiksamを作っていた)「当時は」、そういう 仕様を考えていた、ということです。 それがどれぐらい仕様上も実装上も難しいものであるか、ということを 知らなかっただけですはい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[979] Re:関数の型の宣言構文について
投稿者:kit
2007/06/25 21:02:11

> クラスの(ポインタでなく)実体を扱えるようにした場合 あれ、インスタンスに対して参照だけではなく、実体に対する代入等の操作ができる ようにするんでしょうか? それはやめた方が良いような。 継承のあるクラスのインスタンスではなく、単なる構造体のようなものに対してのみ 許すなら問題ないかもしれませんけど...
[この投稿を含むスレッドを表示] [この投稿を削除]
[978] Re:関数の型の宣言構文について
投稿者:(ぱ)こと管理人@自宅環境復活
2007/06/25 01:47:14

>普段使っていないと、久しぶりに使ってみたときに、つい括弧つけちゃった >という経験があります。結局、自分が普段使っている言語に合わせるのが一番 >なのかなとも思います。 それもひとつの手ですし、なまじ似てるから混乱するというのなら、 いっそ中括弧でなくendで終わる構文にするとか、根本的に変えてしまう というのもありかもしれませんね。 >>当時は、Javaのような「ポインタしかない言語」が嫌で、クラスは実体でも >>宣言できるようにしようとしていましたし、そうなるとtemplateも、Javaのように >>コンパイラだけでごまかしきることはできなくなります。 > >(C++風の)templateなら、コンパイラだけでなんとかなるのではと思ったのですが、 >何か見落としがあるんでしょうか?あるいは、 どこまでVMに実行時情報を持たせるかにもよりますが、たとえばJVMでは、 T型の変数 a, b があるとき、 Tがintのときの a = b; と、Tがdoubleのときの a = b;を同一のバイトコードでは 表現できないのでは? Javaはクラスに関する限りポインタ(参照)しかない言語ですし、 Genericsで対象にできるのは結局Objectだけなので、コンパイラだけで ごまかしきれてますけれども。 基本型は対象にしないとしても、クラスの(ポインタでなく)実体を扱えるように した場合、C++のように機械語を吐くコンパイラでは、「何バイトコピーするか」が 型ごとに違ってきます。このへんVMだと工夫のしようはありそうですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[977] Re:関数の型の宣言構文について
投稿者:みずしま
2007/06/24 20:55:34

みずしまです。返事が遅くなりましてすみません。 >どうもcrowbar ver.0.1で「ifの後ろの()をなくす」という文法にしたものの >(これも以前のDiksamではすべてそうなっていました)、自分自身すら慣れることが >できなかった、というのがトラウマになっている気もします。 >本当にバリバリに使えば、すぐ慣れることなのかもしれませんけれども。 私の作った言語でも、if、whileなどの後ろの()が無い文法になっているのですが、 普段使っていないと、久しぶりに使ってみたときに、つい括弧つけちゃった という経験があります。結局、自分が普段使っている言語に合わせるのが一番 なのかなとも思います。 >以前の3つくらいのバージョンのDiksamのふたつめくらいまではtemplateを >付けようとしていました。が、結局そのあたりを作っている間に(複雑に >なりすぎて)挫折してしまったわけでして。 >私は今でもgeneric programmingの知識や経験が豊富なわけではありませんが、 >当時はもっと知らなかったにも関わらずそんなところに手を出したら >挫折するのも当然です。 templateの実装は結構複雑そうですね。かく言う自分も、Java generics相当の 機能(JVMで動作するので、仕様はJavaと互換にしたい)を俺言語に搭載しようと 思いつつ、Java genericsの型システムがかなり複雑なので、なかなか 挑めないでいます。 >当時は、Javaのような「ポインタしかない言語」が嫌で、クラスは実体でも >宣言できるようにしようとしていましたし、そうなるとtemplateも、Javaのように >コンパイラだけでごまかしきることはできなくなります。 >型ごとにコード複製やむなし、という考えで作っていたように思いますが、 >結局、その部分の実装まですら行き着けなかったような。 (C++風の)templateなら、コンパイラだけでなんとかなるのではと思ったのですが、 何か見落としがあるんでしょうか?あるいは、 > 型ごとにコード複製やむなし というのが、型ごとにコード複製すれば、コンパイラだけでなんとかなるという 意図でしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[976] 管理者により削除されました
2007/06/17 19:38:29

思わず投稿ボタンをダブルクリックして二重投稿した上に、 パスワードを入れていなかったので管理者権限削除。 ちゃんとこの辺の対策もしなければいけませんねえ。
[この投稿を含むスレッドを表示]
[975] Re:関数の型の宣言構文について
投稿者:(ぱ)こと管理人@ネットカフェ
2007/06/17 19:36:57

>C言語ポインタ完全制覇の記述などを見ても、後置の型宣言の方がお好みなのかな >と思っていたので、ちょっと意外な気がしました。 私自身も「後置の型宣言の方が好み」と思っています。 現在のDiksamは「4つ目くらいの作り直し中」で、以前のバージョンでは すべて後置にしていました。 どうもcrowbar ver.0.1で「ifの後ろの()をなくす」という文法にしたものの (これも以前のDiksamではすべてそうなっていました)、自分自身すら慣れることが できなかった、というのがトラウマになっている気もします。 本当にバリバリに使えば、すぐ慣れることなのかもしれませんけれども。 >あと、質問なんですが、将来的にDiksamを拡張して、多相型(JavaのGenerics >相当の機能)を付け加える予定はあるでしょうか?多相型のセマンティクスは >言語によってかなりバリエーションがあり、一応俺言語を作っている者として、 >前橋さんがどのようなセマンティクスが良いと考えておられるかについて興味が >あります。 以前の3つくらいのバージョンのDiksamのふたつめくらいまではtemplateを 付けようとしていました。が、結局そのあたりを作っている間に(複雑に なりすぎて)挫折してしまったわけでして。 私は今でもgeneric programmingの知識や経験が豊富なわけではありませんが、 当時はもっと知らなかったにも関わらずそんなところに手を出したら 挫折するのも当然です。 当時は、Javaのような「ポインタしかない言語」が嫌で、クラスは実体でも 宣言できるようにしようとしていましたし、そうなるとtemplateも、Javaのように コンパイラだけでごまかしきることはできなくなります。 型ごとにコード複製やむなし、という考えで作っていたように思いますが、 結局、その部分の実装まですら行き着けなかったような。
[この投稿を含むスレッドを表示] [この投稿を削除]
[974] Re:関数の型の宣言構文について
投稿者:みずしま
2007/06/16 02:09:55

>>案としてJava 7風に >> B foo(A); > >Java 7で関数を代入できる変数の宣言は > >B(A) foo; > >では? >http://journal.mycom.co.jp/articles/2006/08/23/java7closuer/002.html あ、そうですね。うろ覚えで書いたので間違ってしまったようです。 >>というわけで、静的型付け関数型言語(MLとかHaskellなど)でよくあるように、 >> foo : int -> int; >>と書くのはいかがでしょう? > >ご提案ありがとうございます。ちょっと調べてみます。 >ただDiksamは、 >「floatなんか付けるつもりもないくせに浮動小数点数はdouble」 >というくらいC/Javaにひよった言語ですので、Java 7風かなあ、とは思っています。 >と言いつつ、「なぜかBだけ先頭」という規則が美しくないとは思っているんですけどねえ。 C言語ポインタ完全制覇の記述などを見ても、後置の型宣言の方がお好みなのかな と思っていたので、ちょっと意外な気がしました。とはいえ、この程度の細かい シンタックスの違いはある意味どうでもいい話なので、C/Javaにひよるのも一つ なのかもしれません。 あと、質問なんですが、将来的にDiksamを拡張して、多相型(JavaのGenerics 相当の機能)を付け加える予定はあるでしょうか?多相型のセマンティクスは 言語によってかなりバリエーションがあり、一応俺言語を作っている者として、 前橋さんがどのようなセマンティクスが良いと考えておられるかについて興味が あります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[973] Re:関数の型の宣言構文について
投稿者:(ぱ)こと管理人
2007/06/15 12:29:55

>こんにちは。みずしまです。 こんにちは。 はてなの方でちょっと書いたのですが、自宅PCが不調で、昨夜からついに起動もできなくなりました。今は昼飯がてらネットカフェで書いています。 というわけでしばらく反応が遅くなると思います。ご了承ください。 >案としてJava 7風に > B foo(A); Java 7で関数を代入できる変数の宣言は B(A) foo; では? http://journal.mycom.co.jp/articles/2006/08/23/java7closuer/002.html つまり、 > var foo:(A) B; この形式から、末尾のBを先頭に持ってきて、それ以外の部分をBの後ろにつないだ形式になります(と、私は解釈しています)。 > B foo(A); Diksamには関数のプロトタイプ宣言があるので、この構文はバッティングしますね。 >というわけで、静的型付け関数型言語(MLとかHaskellなど)でよくあるように、 > foo : int -> int; >と書くのはいかがでしょう? ご提案ありがとうございます。ちょっと調べてみます。 ただDiksamは、 「floatなんか付けるつもりもないくせに浮動小数点数はdouble」 というくらいC/Javaにひよった言語ですので、Java 7風かなあ、とは思っています。 と言いつつ、「なぜかBだけ先頭」という規則が美しくないとは思っているんですけどねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[972] 関数の型の宣言構文について
投稿者:みずしま
2007/06/14 21:02:39

こんにちは。みずしまです。 以前から前橋さんのページの特にプログラミング言語関係のネタをwatchして いましたが、今年になってから「プログラミング言語を作る」の 「静的型・バイトコード実行型言語を作る」編を開始されたということで、 静的型言語好きな自分としては、Diksamがどんな言語になっていくのか 楽しみにしております。 さて、本題なのですが、Diksamでは将来的に関数型の変数を扱う機能の実装を 予定されているようですが、構文に関してはまだ決定されていないようです。 案としてJava 7風に B foo(A); と書く方法と var foo:(A) B; と書く方法の2つを考えておられるようですが、どちらも関数を返す関数などの 複雑な型を書く場合にイマイチな気がします。 C(B) foo(A); //Aを受け取り、「Bを受け取りCを返す関数」を返す関数 var foo:(A) (B) C; //引数と返り値の型が区切られて無いせいで、読みにくい気がする というわけで、静的型付け関数型言語(MLとかHaskellなど)でよくあるように、 foo : int -> int; と書くのはいかがでしょう?
[この投稿を含むスレッドを表示] [この投稿を削除]
[971] Re:無題
投稿者:(ぱ)こと管理人
2007/06/08 08:22:22

えー、補足で一応書いておくと、 これが私の書いたものに対する正当な批判のつもりなら、 ・そもそもどの文章についてなのか。 ・そこで使われている「バカ」の具体例 くらい出さなきゃ話にならんでしょう。 まあ、こんな書き捨て野郎には何も期待してませんけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[970] Re:無題
投稿者:(ぱ)こと管理人
2007/06/08 08:02:23

なんなんすかね、これ。 匿名書き捨て野郎の相手をするほどヒマではないので放置しときますが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[969] 無題
投稿者:unko
2007/06/07 22:52:51

何かアレだな 文章に頻繁に出てくる「バカ」ってのがウザい 人をバカにする文章を書くことで優越感に浸れるのかもしれないけど 読んでる方は不快なだけだから。
[この投稿を含むスレッドを表示] [この投稿を削除]
[968] 管理者により削除されました
2007/05/27 12:00:10

[この投稿を含むスレッドを表示]
[966] 管理者により削除されました
2007/04/23 00:36:06

なんなんだ最近連投されているラグナロクオンライン関連らしいぶっ壊れた日本語のしかもリンク先すら読めないこのSPAMは。
[この投稿を含むスレッドを表示]
[965] 断酒宣言
投稿者:(ぱ)こと管理人
2007/04/04 00:11:48

ページ直すのが面倒なので今年はこっちでやります。 3/22より例によって断酒しています。 今回の期間はゴールデンウイーク開始まで。 ・飲み会では飲んでもいい。 ・それ以外でどうしても飲んじゃった場合には、その旨をここで報告する。 というふたつの例外条件はいつものとおり。 年度の変わり目は飲み会が多いので、そのへんを狙うのがコツ(ぉぃ)
[この投稿を含むスレッドを表示] [この投稿を削除]
[964] 時間切れ
投稿者:(ぱ)こと管理人
2007/04/02 02:32:41

昨年のBF-BASIC'nに続き、今年も何かエイプリルフールネタをやろうとして、「S式を箇条書きで表現するLispもどき言語」というのを考えてたんですが時間切れでした… あーあ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[963] 広告を削除しました
投稿者:(ぱ)こと管理人
2007/03/30 20:46:00

 広告が連投されていて、この掲示板では管理者削除で消しても形跡が残るので、鬱陶しいので物理削除しました。  spam向けの削除機能とspamよけの何らかの機能を考えないといかんかなあ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[962] Re:めちゃめちゃ勉強になりました
投稿者:(ぱ)こと管理人
2007/03/23 00:19:12

はじめまして。お役に立てたのなら幸いです。 >仕事に、「構文解析」の needsが出て、 目的のアプリケーションがCで、yacc/lexが使える状況であれば、 うちのサイトの記述が役に立つかと思います。なお、yaccのコンフリクト 解消については、「プログラミング言語を作る」よりも 「電卓を作ってみよう」 http://kmaebashi.com/programmer/c_yota/calc.html の方に記述がありますのでよろしければそちらもどうぞ(今見返すと、 我ながらアレな文章書いてますが…)。 目的のアプリケーションがC++なら、(yacc/lexも使えますが)Boostの spiritの方がよいかもしれません。 外部ツールやライブラリを使うのが難しいなら、再帰下降で手書きの パーサを書くという方法もありますよね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[961] めちゃめちゃ勉強になりました
投稿者:巨大怪獣
2007/03/21 19:47:13

仕事に、「構文解析」の needsが出て、 困っているところに、 前橋さんのこのサイトを見つけました。 「あっ!これで、なんとなく、助かるじゃん!」という感じなんです。 本当に、感謝します。 (まったく私の勝手ですが。。。)これから、よろしくお願いします。^_^ さって、「電卓作成」の勉強に入ります。。。
[この投稿を含むスレッドを表示] [この投稿を削除]
[960] 管理者により削除されました
2007/03/10 22:19:56

投稿者の記載も新しい追記もなく、単に古い投稿に返信しただけの記事だったので削除しました。 テスト投稿はテスト用掲示板 http://kmaebashi.com/bbs/list.php?boardid=testbbs にお願いします。
[この投稿を含むスレッドを表示]
[959] 無題
投稿者:(ぱ)こと管理人
2007/02/25 20:36:21

レンタルサーバ業者さんから下記の通りサービス停止の連絡が来ています。 サーバ停止中は、kmaebashi.comの閲覧や掲示板の使用ができません。 ただしメールは届きます。 > メンテナンス作業実施のお知らせ > ネットワーク機器のメンテナンス作業を実施いたします。 > 作業日時:3/5(月)午前1時~ > 作業対象:国内全サーバー > 作業内容:ネットワーク機器のメンテナンス > 作業時間は4時間程度を予定しております。 > 作業中、数回程度断続的にネットワークが遮断されます。 > 一回の遮断は30秒から3分程度となっております。
[この投稿を含むスレッドを表示] [この投稿を削除]
[958] Re:リンク
投稿者:(ぱ)こと管理人
2007/02/23 02:01:46

>http://kmaebashi.com/bbs/  なるほど… 報告ありがとうございます。掲示板のスクリプトがhttp://kmaebashi.com/bbs/以下においてあるくせに、Niftyの過去ログがhttp://kmaebashi.com/bbs/index.htmlである、ということがまずいように思えます。  Niftyの過去ログは、Niftyでは500件で投稿が流れてしまうという制限があったため、せっかくの投稿が消えてしまわないように作ったものです。当時はレンタルサーバ借りて自分で掲示板を設置するとは思いもよらず/bbs/直下にしたわけですが、その後、いざ掲示板を作るにあたっても、別に悪いこともないだろうと/bbs/直下に置いたのが仇になったようです。  どっちかのURLを変えればよいわけですが、既にNifty掲示板の過去ログも現行掲示板も結構Google等に拾われているようなので、当面このままにしようかと思います。あしからずご了承くださいませ。  この現象のせいですごく困っている、という方はご報告ください。私は携帯は使わないので、状況を把握していない可能性があります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[957] Re:リンク
投稿者:yuya
2007/02/21 12:47:29

> お気になさらず。 ありがとうございます。 テスト板の方で勝手に実験させてもらったのですが、再現しませんでした。 [952]で「Niftyの過去ログに飛んだ」と書きながら OTDの過去ログのURLを書いてしまっていましたが、正しくは http://kmaebashi.com/bbs/index.html でした。おそらく携帯ブラウザの制限から、本来のURLが破棄されて、 /../ すなわち http://kmaebashi.com/bbs/ として解釈されてしまい、index.html が表示されたのだろうと推測しています。 もちろんこのファイル名は「Niftyの過去ログのインデックス」という意味でしょうけれど、 デフォルトインデックスとして扱われてしまったのでしょうね。 # お騒がせしました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[956] Re:リンク
投稿者:(ぱ)こと管理人
2007/02/20 23:47:03

>ありゃ、お役に立とうと思ったら裏目に出てしまった。 >すみませんです。 や、これはもう完璧に私のポカですからお気になさらず。 # SQLの文法の問題だと言い張りたい気はなきにしもあらずですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[955] Re:リンク
投稿者:(ぱ)こと管理人
2007/02/20 23:47:00

>ありゃ、お役に立とうと思ったら裏目に出てしまった。 >すみませんです。 や、これはもう完璧に私のポカですからお気になさらず。 # SQLの文法の問題だと言い張りたい気はなきにしもあらずですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[954] Re:リンク
投稿者:yuya
2007/02/20 12:50:07

ありゃ、お役に立とうと思ったら裏目に出てしまった。 すみませんです。 前橋さんのサイトは携帯電話のブラウザでも ほとんど問題なく読めるので、よく携帯(au)からアクセスするのですが そのときに起きた現象だったので、 キャッシュは残ってましたがソースが見られない。 うー、気持ち悪い。
[この投稿を含むスレッドを表示] [この投稿を削除]
[953] Re:リンク
投稿者:(ぱ)こと管理人
2007/02/20 02:28:22

>このspammerの書いていたリンク先を、削除される前にクリックしちゃったんですが、 >なぜか旧掲示板(Nifty)の過去ログのページに飛んだんですよ。 >たぶんここに↓↓ >http://kmaebashi.com/bbs/otdindex.html うーん、D/Bをいじってフラグを戻し、投稿を復活させてクリックしてみたのですが、 再現しないようです。 それはさておきその時update文にwhereを付け忘れてしまい… 広告が全部復活してしまいました (;_;) 途中までは消したのですが、今日はもう眠いので後日ぼちぼち消していきます。 とほほ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[952] リンク
投稿者:yuya
2007/02/20 02:13:25

このspammerの書いていたリンク先を、削除される前にクリックしちゃったんですが、 なぜか旧掲示板(Nifty)の過去ログのページに飛んだんですよ。 たぶんここに↓↓ http://kmaebashi.com/bbs/otdindex.html 再現されるかどうか分かりませんけど、 何かバグがあるなら修正の機会になるかと思い、一応指摘させていただきました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[951] 管理者により削除されました
2007/02/20 02:29:45

広告なので削除しました。 聖書のお言葉に従う人がspamをばらまいているらしい。へー。 # てなことを書いたような気が。
[この投稿を含むスレッドを表示]
[948] Re:コピペの痕跡が・・・
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>「プログラミング言語を作る」の『サンプル言語「Diksam」』 >http://kmaebashi.com/programmer/devlang/index.html > >の一番下の注釈を消し忘れているみたいです。 ご指摘ありがとうございます。修正しました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[947] コピペの痕跡が・・・
投稿者:トル
2007/02/20 02:13:25

「プログラミング言語を作る」の『サンプル言語「Diksam」』 http://kmaebashi.com/programmer/devlang/index.html の一番下の注釈を消し忘れているみたいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[946] Re:ヘルプ
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>毎度こまかな指摘で恐縮ですが、掲示板のヘルプのページのOTD関係の記述って、 >もう要らないんではないでしょうか? ご指摘ありがとうございます。気にはしていたのですが、放置したままn年過ぎてしまいました。 ひとまず直しました。不備等ありましたらまた明日以降直します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[945] ヘルプ
投稿者:yuya
2007/02/20 02:13:25

毎度こまかな指摘で恐縮ですが、掲示板のヘルプのページのOTD関係の記述って、 もう要らないんではないでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[944] Re:トラックバックURLをまた変更しました
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

「trackback.php」を「aaa.php」に変えるという対策は功を奏さなかったので、トラックバックURLをJavaScriptで生成するようにしてみました。 さてどうなるか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[943] Re:774RRさん、お返事ありがとうございます。
投稿者:undo
2007/02/20 02:13:25

>> その場でエラーにならなければ参照しているだけですから、通常その後にはクラッシュしません。 > >例えばbufが関数へのポインタの配列だったりすると、 >誤って取得しちゃったbuf[10]の値に従って関数を呼び出すかもしれないわけですよね。 そうですね。 初期化していないデータをポインタとして参照したら、不正なアドレスですから、いつクラッシュしてもおかしくないですね(^_^) # 無謀なキャストも同様ですね。 書き方が少し変でした。 「(参照しているだけですから)その場でエラーにならなければ、通常その後にはクラッシュしません。」 というつもりでした(_ _)
[この投稿を含むスレッドを表示] [この投稿を削除]
[942] Re:774RRさん、お返事ありがとうございます。
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>例えばbufが関数へのポインタの配列だったりすると、 >誤って取得しちゃったbuf[10]の値に従って関数を呼び出すかもしれないわけですよね。 他にもポインタの配列だったり、intの配列でもそれが別の配列の添字になっていたりとか。 >たけさんが初めに出した例(要素の値を表示するだけ)であれば たけさんの最初の例だと、ひとつだけ超えたところですからたぶん書き込んでも死なないんですよね。 この辺の「不定」さがCの難しさではありますが、たとえばJavaでもマルチスレッドなら結果が予測できないことはいくらでもあるので、「ダメなコードは何をしでかすかわからない」ことは結局理解しなければいけないことだよなあ、と思ったり。
[この投稿を含むスレッドを表示] [この投稿を削除]
[941] Re:トラックバックURLを変更しました
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>弾いても良いと思いますが (そもそもそういうトラックバックってあります?)、 のまネコ関連でひとつリンクなしが来てますね。この人は正直あまり友達になりたくないタイプではありますが、この手のトラックバックの使い方は全面的に否定はできないような気がします。 もっとも、私はこういうことはしませんし、自分のページは自分のポリシーで運営すればよいので、言及なしトラックバックを禁じてもよいとは思うのですが、「技術的に面倒くさい」というのが結局のところ最大の理由です。 >まあでも今や spam 対策なしのサイト運営は厳しい時代なんじゃないかと。 そう思います。 で、「トラックバックスパム対策」とかでGoogleすると、言及なしリンクをはじいたりフィルタをかけたりする(面倒な)方法ばかりなんですよね。spammerがトラックバックURLを検出する方法を推測すればもっと手軽にいけないかなあ、と思ったのですが、外したようです。そりゃまあ簡単に対策できるならみんなそうするわけで、この結果は必然だったのかもしれませんが、自分で失敗して見えてくるものもありますし。 だから、 >この推測が合っているかどうかは知りませんし、知っている人は知っていることのような気もしますが、ひとまずこの方法で対策します。 と書いたわけです。 spammerが「trackback.php」に反応していたわけではないらしい(少なくとも一部のspammerは)ということがわかっただけでもそこそこ面白かったです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[940] Re:774RRさん、お返事ありがとうございます。
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

ああ、確かにちょっと不正確な書き方でしたね。 >>Cでは、配列の範囲を超えたところをアクセスしても、普通はエラー等にはならず、ずっと離れたところでプログラムがクラッシュしたりします。 Cでは、配列の範囲をちょっと越えたところに書き込んでも、普通はエラー等にはならず、ずっと離れたところでプログラムがクラッシュしたりします。 と訂正します。 >無関係なところを参照してアドレスエラーや境界チェックエラーなどになれば、その場でクラッシュするでしょう。 >その場でエラーにならなければ参照しているだけですから、通常その後にはクラッシュしません。 わかって書いておられるとは思いますが、「その場でエラーにならなければ参照しているだけ」とは限りませんよね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[939] Re:774RRさん、お返事ありがとうございます。
投稿者:yuya
2007/02/20 02:13:25

> その場でエラーにならなければ参照しているだけですから、通常その後にはクラッシュしません。 例えばbufが関数へのポインタの配列だったりすると、 誤って取得しちゃったbuf[10]の値に従って関数を呼び出すかもしれないわけですよね。 こういう場合、 「参照だけして、ずっと先でクラッシュしてしまう(or してくれる)」という事態は、 そんなに珍しいことではないように思うのですが。 そういう話をしているのではない!?ならゴメンナサイ。 たけさんが初めに出した例(要素の値を表示するだけ)であれば きっとクラッシュしないでしょうけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[938] Re:774RRさん、お返事ありがとうございます。
投稿者:undo
2007/02/20 02:13:25

>Cでは、配列の範囲を超えたところをアクセスしても、普通はエラー等にはならず、ずっと離れたところでプログラムがクラッシュしたりします。 この記述の「アクセス」というのは書き換えを意図しているんだと思います。 コンパイラ、ランタイム、参照アドレスによっても違うでしょうが、 無関係なところを参照してアドレスエラーや境界チェックエラーなどになれば、その場でクラッシュするでしょう。 その場でエラーにならなければ参照しているだけですから、通常その後にはクラッシュしません。 buf[10]を参照することに意味があるとは思いませんが(^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[937] Re:トラックバックURLを変更しました
投稿者:kit
2007/02/20 02:13:25

> いつものkitさんですよね? あ、そうです。すいません。 > ここ↓で言われている関連仲間文化圏的なものをすべて弾いて良いか、 > という点で迷うところもあるのですけど、 弾いても良いと思いますが (そもそもそういうトラックバックってあります?)、 気になるなら、承認制にして、一度承認したサイトはホワイトリストに登録とか ですかね。 > これを実現するにはトラックバックのURLを見て相手側のページを取得し、URL > が含まれているかどうかをチェックする必要がありますよね。そこまでやらな > きゃいかんのかなあ… こっちの方が面倒そうですよね。 まあでも今や spam 対策なしのサイト運営は厳しい時代なんじゃないかと。
[この投稿を含むスレッドを表示] [この投稿を削除]
[936] Re:トラックバックURLを変更しました
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

ええと、ハンドル名が「kit1」になっているのは、 [715] http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=715&range=1 の時に間違って入力してしまったものがcookieに残っていたとかで、いつものkitさんですよね? >よくある、先方のページから逆リンクがない限りトラックバックを >認めないor要承認にするって奴はどうでしょうか? ひとつには、ここ↓で言われている関連仲間文化圏的なものをすべて弾いて良いか、という点で迷うところもあるのですけど、 http://www.kotono8.com/2006/01/06trackback.html それよりも、トラックバックで飛んでくるPOSTには、先方のページの要約しか含まれないので、これを実現するにはトラックバックのURLを見て相手側のページを取得し、URLが含まれているかどうかをチェックする必要がありますよね。そこまでやらなきゃいかんのかなあ… と思いつつ、もうふたつspamが届いている。うへぇ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[935] Re:トラックバックURLを変更しました
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

ええと、ハンドル名が「kit1」になっているのは、 [715] http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=715&range=1 の時に間違って入力してしまったものがcookieに残っていたとかで、いつものkitさんですよね? >よくある、先方のページから逆リンクがない限りトラックバックを >認めないor要承認にするって奴はどうでしょうか? ひとつには、ここ↓で言われている関連仲間文化圏的なものをすべて弾いて良いか、という点で迷うところもあるのですけど、 http://www.kotono8.com/2006/01/06trackback.html それよりも、トラックバックで飛んでくるPOSTには、先方のページの要約しか含まれないので、これを実現するにはトラックバックのURLを見て相手側のページを取得し、URLが含まれているかどうかをチェックする必要がありますよね。そこまでやらなきゃいかんのかなあ… と思いつつ、もうふたつspamが届いている。うへぇ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[934] Re:トラックバックURLを変更しました
投稿者:kit1
2007/02/20 02:13:25

よくある、先方のページから逆リンクがない限りトラックバックを 認めないor要承認にするって奴はどうでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[933] トラックバックURLを変更しました
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

 うちの雑記帳にはトラックバック機能があるのですが、トラックバックspamが毎日数十来ます。  削除の際は、そのトラックバックのURLのドメインを禁止ドメインに登録し、以後そのドメインのURLのトラックバックはすべてはじく、というフィルタを仕込んでなおこの有様です。  こんな僻地の自作トラックバックをspammerはどうやって見つけるんだろう、と考えたのですが、 ・うちの雑記帳には自動トラックバック用のRDFは入ってない。 ・「この記事のトラックバックURL」という文言を見つけて、その近辺のURLを…  とも思ったけれどこんな日本語文言を見つけて英文spamを打ってくるのも変では。 ・トラックバック受信スクリプトが「trackback.php」という名前なのが  まずいのかなあ。 と考えて、phpの名前を変更しました。  この推測が合っているかどうかは知りませんし、知っている人は知っていることのような気もしますが、ひとまずこの方法で対策します。  これでしばらくたってまたspamが来るようになったら、「この記事のトラックバックURL」という文言を画像にしてみるとか、それでも来るようならトラックバックURLの一部(http://kmaebashi.comまで、とか)を画像にしてみるとか、いろいろ試してみようと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[932] Re:774RRさん、お返事ありがとうございます。
投稿者:774RR
2007/02/20 02:13:25

御意。およそ何がしたいのか意図がつかめないので、あの程度のコメントとなった次第。 あえてもっと詳しくコメントしてみるテスト char buf[10]; は char が 10 個の配列、の意味。10個の内訳は buf[0] .. buf[9] の10個 // 0から開始するので ということは buf[10] は存在しないので、その中身を使ってはならない。 もちろん buf[-1] や buf[-2] や buf[11] や buf[498914] 等も全部ダメ。 char *cp=buf; は char *cp=&buf[0]; の短縮形であるため cp は buf[0] を指す。 んでそもそも buf[1] ってのは *(&buf[0]+1) のこと。 cp[1] も *(cp+1) のこと。 だからこの場合 cp[1] と buf[1] は同じところを意味する。 cp=&buf[1]; とか cp=buf+1; とかすれば cp は1つずれるわけだ。 なのでこうすると、 cp がずれてる分 cp[2] と buf[3] が同じところを意味する。 当然 cp[9] は buf[10] に相当するので前述のごとくこれも使っちゃダメ。 あと配列外をアクセスするとダメってことの解説。 多くの場合配列外に相当するメモリ/アドレス表現は存在していたりする。 存在するけど、そこは他の変数だったり、他の重要な情報だったりする。 ということで配列外をアクセスすると他の変数を壊す=遠くでクラッシュしたりする。 エラーを OS/CPU が検出してくれる場合もあるが、多くは検出なしにメモリを壊すだけ。 OS/CPU が検出をサボってよい代わりにプログラマが細心の注意を払え、ってのが C/C++ その分、正常に動いている限りにおいては他言語より高速なプログラムが書けたりする。 これとは別に 配列外のオブジェクトの中身を見てはならない (buf[10] はダメ) んだけど 配列直後に限りアドレスを計算しても良い (&buf[10] はOK) という決まりがある。 for (i=0; i<10; ++i) buf[i]=0; と書いてよいごとくに for (cp=&buf[0]; cp<&buf[10]; ++cp) *cp=0; と書いてよいということ。 直後以外はダメ。なので &buf[11] や &buf[-1] は計算しちゃダメ。 計算したらエラーになるかもしれないし、 エラーにならずにおかしな値が得られるかもしれない。 C/C++ は「やっちゃだめ」なことをしたときに「何が起こるかわからない」のだ。 これを「鼻から悪魔が飛び出してもかまわない」と表現したりする。 何が起こるかわからない=エラー発生、ならまだ良かったりする。 何が起こるかわからない=一見、プログラマの期待通りに動いたりする、こともある。 後者は怖いよー。
[この投稿を含むスレッドを表示] [この投稿を削除]
[931] 管理者により削除されました
2007/02/20 02:14:51

広告なので削除。
[この投稿を含むスレッドを表示]
[930] 管理者により削除されました
2007/02/20 02:15:28

広告なので削除。
[この投稿を含むスレッドを表示]
[929] Re:774RRさん、お返事ありがとうございます。
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

昨晩は「寒いから暖房が効くまで布団の中で本でも読んでよう」と思いつつ気が付いたら朝でした。こんなのばっか。 >>buf[10] で、無いオブジェクトの中を見に行っている時点で許されない。 >>*(cp+10) も同様。 >>ただし &buf[10] や cp+10 は許されるというあたりが微妙なところであったりする。 > >明日試してみます。 ええと、試してみたところで「動いてしまう」可能性がそれなりにあります。 Cでは、配列の範囲を超えたところをアクセスしても、普通はエラー等にはならず、ずっと離れたところでプログラムがクラッシュしたりします。 それはさておき、「たけ」さんのサンプルプログラムでは、代入もしていない「buf[10]」の中身をいきなり参照していますが、それで「'1'」が入っていることを期待しているわけではないですよね? そもそも本当は何を聞きたかったのかが疑問です。 774RRさんのご指摘どおり、char buf[10];で宣言した配列のbuf[10]は参照できませんが、 char buf[10]; char *cp; cp = buf; として、*(cp + 3)とかを参照するのは合法です。buf[3]と同じものが見えます。 ただし、「*(cp + 3)」のようなわかりにくい書き方をするよりは、cp[3]と書いたほうがよいでしょう。これもbuf[3]と同じものが見えます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[928] 774RRさん、お返事ありがとうございます。
投稿者:たけ
2007/02/20 02:13:25

>buf[10] で、無いオブジェクトの中を見に行っている時点で許されない。 >*(cp+10) も同様。 >ただし &buf[10] や cp+10 は許されるというあたりが微妙なところであったりする。 明日試してみます。 私は去年の4月から、プログラマーとして、仕事をしています。 配列やポインタの勉強は大変ですが、C言語が面白くなってきたところです。 たまには、酒でも飲みたいのですが、みんな忙しくて、機嫌が悪いです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[927] Re:質問してもよろしいでしょうか?
投稿者:774RR
2007/02/20 02:13:25

buf[10] で、無いオブジェクトの中を見に行っている時点で許されない。 *(cp+10) も同様。 ただし &buf[10] や cp+10 は許されるというあたりが微妙なところであったりする。
[この投稿を含むスレッドを表示] [この投稿を削除]
[926] 質問してもよろしいでしょうか?
投稿者:たけ
2007/02/20 02:13:25

初心者で変な質問をしているかもしれませんが、 教えていただけると助かります。 以下のコードはC言語で許されますか? char buf[10]; char *cp; if (buf[10] != '1'){ printf("array[10]=%c",buf[10]); } cp = buf; if (*(cp + 10) != '1'){ printf("pointer[10]=%c",*(cp + 10)); }
[この投稿を含むスレッドを表示] [この投稿を削除]
[924] Re:さっそくのお返事ありがとうございました
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

 掲示板で人生相談されても困るんですが。 >お金のため(生きるため)に働くのはいやです。 >60のしらが親父になってから世界旅行して何が楽しいのかわからないです。 >生きてるか分かりませんが、60になって自分の残りの人生を考えるたときに >愕然としそうなのがこわい。死ぬまでに悟りたいことがあるんです。 >そんなひまがなく日々の仕事におわれて、いつのまにか年をとっているのが >こわいんです。  ということは「ゆう」さん的には、35過ぎてもまだあくせく働いている私なんぞは、悟りとやらも一生得られない人生の敗北者なのでしょうから、成功者のところで教えを乞うほうがよいのでは?  うちの両親は60過ぎてからあちこち旅行行ってますが、そこそこ楽しそうですけども。  「OB」さんは私の大学の先輩なのですが、一緒に酒を飲んだりすると時々、 「学生の頃は、『世間はそんなに甘くない』ということをよく聞くけれど、  いざ社会人になってみると結構甘いもんだな」  という話をしてます。  世間はもちろん甘くないところもありますが、まっとうにやっていればそうそう理不尽な目に遭うことは少ないし、何となれば転職の自由だってある。努力が常に報われるとは限らないけれども常に報われないわけでもない。特にサラリーマンなんてのは今でも何だかんだで手厚く守られているのであって、サラリーマンが勤まらないような人に起業ができるはずもない。  就職が決まっているのなら、まずはそこでがんばってみることでしょうに。何もしないうちからいったい何を言っているのかと。
[この投稿を含むスレッドを表示] [この投稿を削除]
[922] Re:システム屋さんは儲かるか?
投稿者:たまに口出しするOB
2007/02/20 02:13:25

>>技術者として前橋さんのように会社でコツコツがんばっても35歳くらいまでに、 >>金持ちになるのは不可能ですか?前橋さんの経験でよいので話してくれませんか? >>金持ちの定義は難しいですが、一生働かなくてもよいくらいお金を持っている人の >>こととします。 一生働かなくてもよいくらいのお金がいったい幾らなのかも問題ですが、 一般的にはどんな大きな会社でも、サラリーマンをしていて、そうなれることは まず無いと思います。 35歳と言わず、40歳でも50歳でもそこまでの稼ぎでリタイアできるだけの 金持ちになるためには自分で会社をやる側(経営陣、でなく会社オーナー)に ならないと無理でしょう。 また一般に会社を自分で興すとそれが楽しくて、金が問題では無くなる様に見えます。 人間の欲望は簡単にインフレーションします。今のあなたの金銭感覚でリタイヤ できるだけのお金を稼ぐ頃には、あなたの金銭感覚もインフレーションしていて その金額では満足出来なるなってることでしょう。 世間でたまに居る若くしてリタイヤするIT長者は金銭感覚のインフレーション よりも、所得の伸びが上回った大変珍しい例だと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[921] システム屋さんは儲かるか?
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>技術者として前橋さんのように会社でコツコツがんばっても35歳くらいまでに、 >金持ちになるのは不可能ですか?前橋さんの経験でよいので話してくれませんか? >金持ちの定義は難しいですが、一生働かなくてもよいくらいお金を持っている人の >こととします。  私は35は超えているわけですが、結論から言えば、「一生働かなくてもよいくらいお金を持って」はいませんねえ。持ってたら私だって仕事してません。サラリーマンやってる限りどの会社に行ってもそうじゃないでしょうか。  ただし、この業界は、仕事がどんどん下請け孫受けに回されて、(仕事内容に関わらず)この階層が下がるほど収入が下がっていくので、腐っても大企業に入っておけ、というのはあります。「一生働かなくてよい」というのは土台無理としても、生活のゆとりに大きく差が出ます。  本を出したら何もしなくても印税で儲かるのでは、実のところ周りからもよく言われるのですが、それなりに売れる本を出したとしても、出した年だけのことです。私の著書の中では、「ポインタ完全制覇」などはこの業界では結構なロングセラーだと思いますが、今年に関して言えば、飲み代が賄えているかどうか、というところです。 # おまえの飲み代は月にいくらなのか? というツッコミは却下。
[この投稿を含むスレッドを表示] [この投稿を削除]
[920] C言語体当たりを読んで
投稿者:ゆう
2007/02/20 02:13:25

はじめまして、私は22歳学生です。前橋さんの本は、わかりやすくて、新たな発見がたくさんありました。私は、情報学部の生徒で、来年の春からシステム系の企業に就職します。プログラムは苦手で、不安で、最近本を読みまくっています…。独習C 柴田望洋さん ポインタが理解できない理由などなど…。前橋さんの本は、他にはない説明の仕方でとてもわかりやすいです。センスオブプログラミングも途中ですけど、読んでます。わかりやすくて、ためになる知識がつきます。例えば、変数の名前の付け方などです。あげたらキリないのでやめます。ところで、前橋さんは、本を書くくらいですから、かなりの技術力をもち収入もかなりありそうですが…HPなどを拝見してると、そんなことはないみたいな感じがします。私は、金持ちになりたいです。働きたくないからです。技術者として前橋さんのように会社でコツコツがんばっても35歳くらいまでに、金持ちになるのは不可能ですか?前橋さんの経験でよいので話してくれませんか?金持ちの定義は難しいですが、一生働かなくてもよいくらいお金を持っている人のこととします。変な質問をしてすみません。答えるのがめんどければ、答えてくれなくて結構です。忙しそうなので…。
[この投稿を含むスレッドを表示] [この投稿を削除]
[919] Re:新しいプログラミング言語
投稿者:阿部
2007/02/20 02:13:25

> 掲示板での宣伝行為については、私はよその掲示板管理人より多少は寛大なつもりです。うちの趣旨に合っていて、話題投下としての書き込みであれば、たとえ宣伝が含まれていてもとやかく言うつもりはありません。ただ、アクセスログを見てみると、阿部さんの場合、 > >(1)Googleで「プログラミング言語」を検索 >(2)「プログラミング言語を作る」のトップページを参照 >(3)そこから直接掲示板に来る >(4)リスト表示から一度だけスレッド表示に切り替えた後、 >(5)いきなり投稿フォームへ > >という遷移で来ているようなので、これはかなり「無差別宣伝書き込み」に近いものだと思いますが。 > すばらしい解析能力ですね。うちに財力があれば、来ていただきたいぐらいです。 しかし、考えてみてください。僕がどうしてこのサイトを始めて訪れたとわかるのでしょうか(実際、僕は以前にもここを訪れています)。 そして、この掲示板がプログラミング言語と無縁の掲示板だったら、書き込みをしなかったでしょう。実際、僕がこのような形で書き込んだのは、ここ以外、ありませんから。それは、僕が書いたことの内容を見れば、判断できることだと思います。 さらに言えば、みなをサイトにひっぱてきて、直接の経済活動に結びつけようというものではありません。ただただ、プログラミング言語を作っている人であれば、また、そのサイトを訪れる人であれば、KI言語にも興味を持たれるかもしれない、そう思っただけなのです。何しろ、今の僕には、何の財力もなく、こうした方法で、少しでも、人に関心を持ってもらうことぐらいしか、やれることがないのです。 結局、無差別宣伝かどうかというのは、内容で判断するしかないのではありませんか? 前橋さんが無差別的書き込みに対して怒る気持ちは、よく分かります。無差別宣伝や嫌がらせに近い書き込みのために、議論やコミュニケーションの場であるはずの掲示板が機能しない。だからこそ、最近は、MIXIがはやるのでしょう(僕も、MIXIなら、まともな議論ができるのかなと思い、少し試してみましたが、残念ながら、あそこは社交の場でしかないようですね)。 ---------------------- カテナスのホームページもリニューアルして、まだ、2ヶ月足らずで、ご指摘の通り、まだまだ不十分です。ただ、少しずつ、更新していますから、「興味があれば」、見にきてください。 最後に、KI言語が何なのかよく分からないというご指摘に関して、こう答えればいいでしょうか。ページを分割して得られる領域(領域に置かれる文字列や図を含む)、自由に配置できる領域、線や曲線などの図形、スタイル情報、プログラム文、データ、メタ情報をすべてキーという名のインスタンスとしてキー構造に配置し、かつ、動的に扱える(生成、挿入、削除ができる)言語。う~む、よけいにわかりにくなったかしら。
[この投稿を含むスレッドを表示] [この投稿を削除]
[918] Re:新しいプログラミング言語
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>> SaLAというのがKI言語の実行系のようですが、SaLAはHTMLの代わりにKI言語を解釈するWebブラウザのいとこようなものなのでしょうか。そして、それを使うと「KSCS Labo」に接続できて、お絵かきコンテストに参加できる? > >その通りです。 それを読みとるのに、少なくとも私はえらく苦労したんですけど。 >SaLAは、Vectorにも登録していますが、あなたの言うことに従えば、 >Vectorにある無名の人たちのソフトウェアは、インストールできないと >いうことでしょうか。  Vectorに登録しているということ自体初耳なわけですが、Vectorの場合、 ・Vector側で最低限の動作確認はしているだろう。 ・もし悪さをするようなソフトなら、ダウンロードしたユーザからVectorに  通報が行き、しかるべき処置がなされるだろう。  という期待があるから、そのへんの無名のページからダウンロードするよりは安心感が多少増すでしょうね。もちろんそれはVectorという会社の実績と知名度によるものです。  まあ実際には、Vectorも「分類目的で内容をチェックすること」しか行ってないようですし、考えてみればMan-in-the-middle攻撃くらってファイルを途中で差し替えられる可能性もゼロとは言えなさそうですが(でも一度でもそれが表面化すれば、Vectorは何らかの対策をしてくれるだろうという期待はあります)。  このへんの線引きは人によっていろいろあるでしょうが、少なくとも私は、「掲示板への宣伝書き込みからリンクされてるページ」にあるものをうかうかとダウンロードして実行することはできません。これは普通の感覚ではないでしょうか。  掲示板での宣伝行為については、私はよその掲示板管理人より多少は寛大なつもりです。うちの趣旨に合っていて、話題投下としての書き込みであれば、たとえ宣伝が含まれていてもとやかく言うつもりはありません。ただ、アクセスログを見てみると、阿部さんの場合、 (1)Googleで「プログラミング言語」を検索 (2)「プログラミング言語を作る」のトップページを参照 (3)そこから直接掲示板に来る (4)リスト表示から一度だけスレッド表示に切り替えた後、 (5)いきなり投稿フォームへ という遷移で来ているようなので、これはかなり「無差別宣伝書き込み」に近いものだと思いますが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[917] Re:新しいプログラミング言語
投稿者:阿部
2007/02/20 02:13:25

>ソフトウェアが使われるのは、ユーザが望む機能がそこにあるからだと思います。知名度が高くても、使ってみようと思わない限りは使われません。 僕が書いたのは、「知名度ないと、ユーザの望む機能があったとしても、使われない」ということです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[916] Re:新しいプログラミング言語
投稿者:トル
2007/02/20 02:13:25

>会社名でソフトウェアの信用性が決まるとしたら、悲しいことですね。 >正直のところ、私は、今、肩書きや知名度で判断されるこの社会の中で、それっとどうなの?と叫んではみるものの、いやと言うほどその厳しさを感じています。 ソフトウェアが使われるのは、ユーザが望む機能がそこにあるからだと思います。知名度が高くても、使ってみようと思わない限りは使われません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[915] Re:新しいプログラミング言語
投稿者:阿部
2007/02/20 02:13:25

> SaLAというのがKI言語の実行系のようですが、SaLAはHTMLの代わりにKI言語を解釈するWebブラウザのいとこようなものなのでしょうか。そして、それを使うと「KSCS Labo」に接続できて、お絵かきコンテストに参加できる? その通りです。お絵かきコンテストは、少しでも実際に試してもらえればと、考えた企画です。KI言語では、ドロー系の描画を描画命令を順次実行するのではなく、一種のオブジェクトとして、定義しているため、描画ツールの作成が簡単に行えます。 > それはそれで面白そうではありますが、失礼ながら私は「有限会社カテナス」という会社を存じ上げているわけではないですから、「出処不明のソフトウェア」をそうそう軽々しくインストールするわけにも行きませんし。 SaLAの開発にようやく終わりが見えてきた今、多くの人に使ってもらって、反応を知りたいと考えています。それで、こちらにも投稿したのですが、もし、会社名でソフトウェアの信用性が決まるとしたら、悲しいことですね。SaLAは、Vectorにも登録していますが、あなたの言うことに従えば、Vectorにある無名の人たちのソフトウェアは、インストールできないということでしょうか。 正直のところ、私は、今、肩書きや知名度で判断されるこの社会の中で、それっとどうなの?と叫んではみるものの、いやと言うほどその厳しさを感じています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[914] Re:C言語体当たり学習
投稿者:めがね
2007/02/20 02:13:25

丁寧な解説ありがとうございます。 確かに、前橋さんのおっしゃるとおり、 >・sorted_countは「ソートされた要素の数」である。 >・すべての要素がソートされた要素になればよいのだから、sorted_countが  score_countになるまで回せばよい。 と考えるのは直感的で分かりやすいと思います。 > 単純選択ソートにおいて、未ソート範囲から最小値を選ぶとき、たまたま未ソート範囲内の左端が最小値であれば、事実上交換は発生しません(同じ変数同士の交換になる)。、「sorted_count < score_count」としたとき最後に起きる無駄な交換も、現象としてはこれと同じです。 確かに、言われてみればそのとおりですね。 なんだか重箱の隅をつつくような質問ですいませんでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[913] Re:C言語体当たり学習
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>もう一つ質問なのですが、36行目から始まる外側のforループの判定条件を >「i < score_count - 1」としなかったのは何か訳があってのことでしょうか? >もし何か訳があれば補足をお願い致します。 特に理由があるわけではないですし、こっちがよいとか主張したいわけでもないですが。 ・sorted_countは「ソートされた要素の数」である。 ・すべての要素がソートされた要素になればよいのだから、sorted_countが  score_countになるまで回せばよい。 ということで、直感的であるかとは思います。  107ページの図(Fig.2-7)に、「ソートずみの範囲」と「未ソートの範囲」を色分けし、間に線を引いた図がありますが、ソートが進むにつれ、この境界線がだんだん右に移動し、ついに右端に至ったときがソートの終了と考えれば、「sorted_count < score_count」になるように思います。境界線の右から左に、ぽいぽい要素を放り込んでいくイメージです。  単純選択ソートにおいて、未ソート範囲から最小値を選ぶとき、たまたま未ソート範囲内の左端が最小値であれば、事実上交換は発生しません(同じ変数同士の交換になる)。、「sorted_count < score_count」としたとき最後に起きる無駄な交換も、現象としてはこれと同じです。単純選択ソートであれば、確かに言われてみれば最後に残った要素は最大値に決まってますから「境界線の右から左に放り込む」必要はないわけなのですが、コメントでも書いておかないと、私の場合「あれっ」とか思ってしまいそうです。  挿入ソート(List 4-6)でも、「境界線の右から左に、ぽいぽい要素を放り込んでいく」操作を行いますが、こちらでは、最後に残るのが最大値とは限りません。単純選択ソートにおいて最後に最大値が残るのは、あくまでこのソート方法の特性なので、そこを理解して効率のよいコードを書くのもよいですが、必ずしもそこまでやらなくてもバチはあたらないのではないでしょうか。 # とか言いつつ挿入ソートのサンプルソースでは、sorted_countを1から始めてるな…(^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[912] Re:C言語体当たり学習
投稿者:kit
2007/02/20 02:13:25

> 36行目から始まる外側のforループの判定条件を > 「i < score_count - 1」としなかったのは何か訳があってのことでしょうか? > もし何か訳があれば補足をお願い致します。 C言語のfor文の判定条件は毎回評価されるので、年寄りとしては ループ内で不変な値を条件式に書くのは躊躇しちゃいますね。 たいてい lim = score_count - 1; for (sorted_count = 0; sorted_count < lim; sorted_count++) { としちゃいます。 まあ score_count が auto 変数でかつアドレス参照されてなければ、 あるいはループ内に関数呼びだしがなければ、いまどきのコンパイラは 自動的に同等な機械語に変換してくれるんでしょうけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[911] Re:C言語体当たり学習
投稿者:yuya
2007/02/20 02:13:25

面白い話題ですね。 私だったら、実行時の無駄を承知の上で判定条件を sorted_count < score_count; /* (-1)は付けない */ とします。 最小値を表す記号を min{x, y, z, ...} と書いたとき、 min{5, 3, 8} = 3 min{2, 2} = 2 min{6} = 6 などとなりますが、このminを定義(あるいは実装)するときに、 ・要素数が2個以上のとき……最小の要素を選ぶ ・要素数が1個  のとき……その要素そのもの と場合分けするのが良いと考える人は少ないと思います。 そんな話はこの判定条件の問題とは違うのかもしれませんが、 大局的には同じようなセンスの問題をはらんでいると私には感じられます。 経験上は(って、アマチュアですけど)、このようなスタンスで臨むほうが 仕様変更や拡張に強いコーディングになるような気がします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[910] Re:C言語体当たり学習
投稿者:めがね
2007/02/20 02:13:25

>my_sort5.cは挿入ソートではなく、単純選択ソートですね。 間違えました。 >(1)条件は「<」なのですから、sorted_countのループ内での最大値は > score_count-1です。よって、score[sorted_count]で参照する限り、 > 範囲外を参照することはありません。 >(2)38行目からのループは、 > for (i = sorted_count + 1; i < score_count; i++) { > で始まっています。iがsorted_count + 1から始まりますが、 > sorted_countが最大のとき、このループは1回も回らないので、score[i]で > 範囲外が参照されることもありません。 こちらから指摘しておいてすいません。その通りのようです。私が勘違いしていました。 もう一つ質問なのですが、36行目から始まる外側のforループの判定条件を 「i < score_count - 1」としなかったのは何か訳があってのことでしょうか?もし何か訳があれば補足をお願い致します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[909] Re:C言語体当たり学習
投稿者:(ぱ)こと管理人
2007/02/20 02:13:25

>p106のmy_sort5.cのソースコード36行目から始まる単純挿入ソートなのですが、 >誤:for(sorted_count = 0; sorted_count < score_count; sorted_count++) { >正:for(sorted_count = 0; sorted_count < score_count - 1; sorted_count++) { >ではないでしょうか(判定条件の-1が抜けてる)。 >誤りと思われるコードでは、配列の範囲外を(配列の要素数より1つ分多く) >参照してしまうと思います。 my_sort5.cは挿入ソートではなく、単純選択ソートですね。 ソースを確認しましたが、 (1)条件は「<」なのですから、sorted_countのループ内での最大値は  score_count-1です。よって、score[sorted_count]で参照する限り、  範囲外を参照することはありません。 (2)38行目からのループは、  for (i = sorted_count + 1; i < score_count; i++) {  で始まっています。iがsorted_count + 1から始まりますが、  sorted_countが最大のとき、このループは1回も回らないので、score[i]で  範囲外が参照されることもありません。 ただ、単純選択ソートの原理は「未ソート部分から最小値を探してきて左端に持ってくる」というものですから、最後にひとつ残された未ソートの要素は最大値に決まっているので、無駄といえば無駄ではあります。現状のソースだと43~45行目のスワップで、必ず同じ変数をひっくり返します。 これはバグとは思いませんが、補足かなにかで書いておいた方がよいかもしれませんね(今日は時間が時間なのでアレですが)。 ご意見ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[908] C言語体当たり学習
投稿者:めがね
2007/02/20 02:13:25

前橋さんの「C言語体当たり学習」の読者です。 正誤表に反映されてない誤りと思われる記述を見つけたので報告させていただきます。 p106のmy_sort5.cのソースコード36行目から始まる単純挿入ソートなのですが、 誤:for(sorted_count = 0; sorted_count < score_count; sorted_count++) { 正:for(sorted_count = 0; sorted_count < score_count - 1; sorted_count++) { ではないでしょうか(判定条件の-1が抜けてる)。 誤りと思われるコードでは、配列の範囲外を(配列の要素数より1つ分多く)参照してしまうと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[907] Re:新しいプログラミング言語
投稿者:(ぱ)
2007/02/20 02:13:25

>僕も新しいプログラミング言語を開発しました。言語名はKIです。 … >ぜひ、試してみてください。できる限り、オープンな形で今後も >開発を進めたいと思っていますので。  すみません、ページを拝見したのですが、どういうソフトでどういう言語なのか、よくわかりませんでした。  SaLAというのがKI言語の実行系のようですが、SaLAはHTMLの代わりにKI言語を解釈するWebブラウザのいとこようなものなのでしょうか。そして、それを使うと「KSCS Labo」に接続できて、お絵かきコンテストに参加できる?  それはそれで面白そうではありますが、失礼ながら私は「有限会社カテナス」という会社を存じ上げているわけではないですから、「出処不明のソフトウェア」をそうそう軽々しくインストールするわけにも行きませんし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[906] Re:教えてください
投稿者:(ぱ)
2007/02/20 02:13:25

>オブジェクト指向初心者です。 こんにちは。 >最終行の"こちら"の部分がリンク切れのようですが、どこへのリンクでしょうか?  すみません、以前にも指摘があって、掲示板には書いたのですが、HTMLの方は直していませんでした。  書いたのはずいぶん前なので記憶が曖昧なところはありますが、ここのリンク先は↓です。  http://kmaebashi.com/programmer/object/shigoto.html  strtok()のように同時に2箇所で使えない「関数」では再利用性が高いとはいえないが、StringTokenizerのようにオブジェクトにすることで、より広く、どこでも自由に使えるようになった、という意図で書いています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[905] 教えてください
投稿者:オブジェクト指向初心者
2007/02/20 02:13:25

オブジェクト指向初心者です。 「疑り深いあなたのためのオブジェクト指向再入門」を拝見しましたが、 一部リンク切れがあり、内容が非常に気になりますので教えていただければ幸いです。 2. なぜわからなくなってしまうのか? オブジェクト指向で再利用性は高まるか? ~この点についてはこちらで後述します。 最終行の"こちら"の部分がリンク切れのようですが、どこへのリンクでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[904] 新しいプログラミング言語
投稿者:阿部
2007/02/20 02:13:25

僕も新しいプログラミング言語を開発しました。言語名はKIです。 いわゆる手続き型のプログラミング言語ではありません。 HTMLにJavaSctiptとCSSを加えたようなものと言えばいいでしょうか。 僕は、レイアウト言語と呼んでいます。HTMLは、巻物のようなもの、 つまり、終わりのない文書を整形するための言語ですが、KI言語は ページ内に文字列や図をレイアウトするための言語になっています。 僕自身も、プログラミング言語に関しては、全くの素人ですが、 いつの間にか、結構、大規模なものになりました。 ぜひ、試してみてください。できる限り、オープンな形で今後も 開発を進めたいと思っていますので。 http://www.kathenas.com/
[この投稿を含むスレッドを表示] [この投稿を削除]
[903] Re:サニタイズ
投稿者:(ぱ)
2007/02/20 02:13:25

>…と思ったら、 >http://b.hatena.ne.jp/HiromitsuTakagi/  高木さんのブックマークに取り上げられたおかげか、はてなでずいぶんブックマークされているようです。 http://b.hatena.ne.jp/entry/http://kmaebashi.com/zakki/zakki0042.html  「反論」というほどではないにせよ「異論」的なものはあるようですのでコメントしたいのですが、いまちょっと時間が…
[この投稿を含むスレッドを表示] [この投稿を削除]
[902] Re:サニタイズ
投稿者:kit
2007/02/20 02:13:25

>高木さんによるサニタイズに関する記事に対する解釈は、僕も全く同じです。 …と思ったら、 http://b.hatena.ne.jp/HiromitsuTakagi/ で、高木さんご本人からお墨つきがあったんですね。 まあ当然ですなあ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[901] サニタイズ
投稿者:kit
2007/02/20 02:13:25

お、mmasudaさんのリンクをたどると見なれたページが… :-) 高木さんによるサニタイズに関する記事に対する解釈は、僕も全く同じです。 普段読んでる日記だと、 http://www.coins.tsukuba.ac.jp/~hdk/diary/d200602b.html#10-4 でも、本質的には同じ解釈がされてたし(日記の著者は筑波の院生さん)、 そう解釈している人はたくさんいるのではないかと思います。 ただし、それが多数派かどうかは断言できないかもしれないところが、 ちょっと怖い…
[この投稿を含むスレッドを表示] [この投稿を削除]
[900] Re:感謝&訂正の訂正
投稿者:(ぱ)
2007/02/20 02:13:25

>8行目の >>違いが分かるようになりました。 >という書き込みは、本を全て読んだのではなく、まだまだ読むところがあるので >>違いが分かるようになってきました。 >に訂正です。 >小さなことで悪いですが・・・気になって夜も眠れないので訂正させてもらいます。  や、190ページとのことなので3章の終盤程度ですか。  3章のラストが「頭に叩き込んでおくべきこと――配列とポインタは別物だ!」なので、配列とポインタの違いに関して言えば、そこでひとまず終了、のつもりです。もちろん4章以降も読んでいただきたいですけれど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[899] Re:トラックバックSPAM
投稿者:(ぱ)
2007/02/20 02:13:25

>[895]のComroさんの誤植指摘を見て、なんとなく該当ページを久々に覗いてみたら…… >なんかSPAMトラックバックがえらいことになっていますね。  ご指摘ありがとうございます。  実はトラックバックSPAMは定期的に消しています(消すためのページを作りました。1件ずつチェックボックスで選んで削除するUIにしてしまったので数が多いと大変です)。  ここ数日、出張してたりとかいろいろあって溜め込んでしまいました。放っておくと1日数十とかのオーダーでSPAMが来ます。  あんまりひどいので、トラックバックのリンク先URLをドメイン単位ではじく機能を追加し、削除する際そのテーブルにドメインを追加しているのですが、それでもこの有様です。  ちなみに現在禁止ドメインは1315件あります。はじいたトラックバックについては現在特に記録を残していないのですが、そのうち修正して、どれくらいの比率でSPAMをはじいているのかを見てみようと思っています。  それにしてもなんでまたこんなWebの片隅にある手作りトラックバックにまでSPAMがやってくるのやら…  「Brainfuckのせいか?」と思ったこともあるのですが、SPAMが来るのはあそこばかりでもないですし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[898] Re:感謝&訂正
投稿者:(ぱ)
2007/02/20 02:13:25

>前橋さんの書いた本(C言語ポインタ完全制覇)を入門書の次の次に読み、 お読みいただきありがとうございます。 >僕はPerlしか知りませんが、Perlはelsifです。 こちらもご指摘ありがとうございます。 elseifがふたつありましたね… typoでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[897] Re:感謝&訂正の訂正
投稿者:Comro
2007/02/20 02:13:25

8行目の >違いが分かるようになりました。 という書き込みは、本を全て読んだのではなく、まだまだ読むところがあるので >違いが分かるようになってきました。 に訂正です。 小さなことで悪いですが・・・気になって夜も眠れないので訂正させてもらいます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[896] トラックバックSPAM
投稿者:yuya
2007/02/20 02:13:25

[895]のComroさんの誤植指摘を見て、なんとなく該当ページを久々に覗いてみたら…… なんかSPAMトラックバックがえらいことになっていますね。 雑記帳のインデックスのページでは一番下の過去記事リンクにたどり着くまで ぐぉぉぉーっとスクロールしなきゃいけなくなってます。 http://kmaebashi.com/zakki/index.html 余計なお世話かと思いましたが、もし前橋さんがご存知でなければと思い、 指摘させていただきました。 個人的には閲覧の妨げとして無視できない量になりつつあるので、 できれば削除して欲しいなぁ、と思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[895] 感謝&訂正
投稿者:Comro
2007/02/20 02:13:25

前橋さんの書いた本(C言語ポインタ完全制覇)を入門書の次の次に読み、 分かりやすいし、補足も面白くて、良い本だと思い、作者をYAHOOで検索したら、このページに着きました。 ちなみに、入門書の次に読んだ本は、よく分からず途中で止めて、C言語ポインタ完全制覇を読みはじめました。 今までに僕の買ったC言語関係の本にはこんなこと書いてなく、 この本を読むまでいつも、配列とポインタの違いが分からず混乱していましたが、 違いが分かるようになりました。 まだ、190Pぐらいまでしか読んでいませんが、早くこの本を全部読んで、 途中で読むのを止めていた入門書の次の本を読破したいです。 この本と早めに出合えて本当に良かったです。 そして、訂正ですが、 「プログラミング言語を作る」の「見た目の問題(2005/6/25)」の Perl, Ruby, MODULA-2, Ada, Eiffel elseifについて、 僕はPerlしか知りませんが、Perlはelsifです。 それでは。
[この投稿を含むスレッドを表示] [この投稿を削除]
[894] Re:Brainfuck
投稿者:マスタング
2007/02/20 02:13:25

>うーん、私が想定していたのは、内部形式をふたつ作るのではなく、 >「読み込んで内部形式に変換するところ」でまとめて変換する、というものでした。 >内部形式をふたつ作ってもよいでしょうが、ストロークを少なくするという >code golfの趣旨に反するような気がします。 ここでおっしゃっている内部形式が私の考えているものとずれているかもしれないですが、例えば、入力(文字列)を内部形式(メモリ上の変数)、例えば、リストなどに変換するのは、Pythonでは、sが入力文字列だとすると、list(s)とするだけですし、forなどに文字列(シーケンス)を直接渡しても、1文字ずつ処理してくれるので文字列が内部形式としても良いですし、どのタイミングで変換するかは問題ではないように思えますがどうでしょう? 文字列を1文字ずつ処理するのは、例えば、以下のような感じ。 >>> s = 'test' >>> for c in s: ... print c, ... t e s t >Perlはたまに使いますがたまにしか使わないので身に付かず、 >PHPはここの掲示板を作った程度、 >Rubyはちょこちょこ見ては試しにプログラムを動かしたりはしてますが、 >Rubyのソースを書くのに費やした時間よりRubyの実装のソースを読んだ時間の方が >長いくらい、 >PythonはRubyについてよりも浅学ですねえ。 なるほどです。しかし、crowbarみたいなスクリプト言語を作れるというのはすごいと思います。PythonがRubyよりも浅学というのはPythonファンの私としては残念です。 >「Rubyソースコード完全解説」をWebで読んじゃって本を購入しなかったので、 >罪滅ぼしに「ふつうのHaskellプログラミング」を読んでたり。 私も「ふつける」は購入しましたが、最近、MYCOMから出た「入門Common Lisp」という本も買ってしまいました。最近、(ぱ)さんが本を出さないのは残念です。何か書く予定があったら教えてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[893] Re:Brainfuck
投稿者:(ぱ)
2007/02/20 02:13:25

>>それをすべきタイミングは >>Brainfuckソースを読み込んで内部形式に変換するところでしょうから、 >>「文字列変換」ではないですよね。 > >リスト(内部形式)に変換してから別のリスト(内部形式)に変換しても >良いかもしれません。 うーん、私が想定していたのは、内部形式をふたつ作るのではなく、 「読み込んで内部形式に変換するところ」でまとめて変換する、というものでした。 内部形式をふたつ作ってもよいでしょうが、ストロークを少なくするという code golfの趣旨に反するような気がします。 >Perl、PHP、Ruby、Pythonなどを想定していました。 Perlはたまに使いますがたまにしか使わないので身に付かず、 PHPはここの掲示板を作った程度、 Rubyはちょこちょこ見ては試しにプログラムを動かしたりはしてますが、 Rubyのソースを書くのに費やした時間よりRubyの実装のソースを読んだ時間の方が 長いくらい、 PythonはRubyについてよりも浅学ですねえ。 「Rubyソースコード完全解説」をWebで読んじゃって本を購入しなかったので、 罪滅ぼしに「ふつうのHaskellプログラミング」を読んでたり。
[この投稿を含むスレッドを表示] [この投稿を削除]
[892] Re:Brainfuck
投稿者:マスタング
2007/02/20 02:13:25

すいません(汗)。先ほどの返信で、 >さすがに(ぱ)も手を出しているのかなと思いました。 「(ぱ)さんも」と書こうとして、「(ぱ)も」と書いてしまいました…。大変失礼致しました…<_O_>
[この投稿を含むスレッドを表示] [この投稿を削除]
[891] Re:Brainfuck
投稿者:マスタング
2007/02/20 02:13:25

ご回答ありがとうございます。 >Code Golf自体は以前「Matzにっき」からリンクを辿って、ページの構成が >わかりにくいのもあってちょっと眺めただけでしたが。 ルールがどこに明記されているのか分かりにくいのは私も感じました。 >ええと、Brainfuck問題というのは > > ... > >で、課題は、 >・マスタングさんがPythonで書いたBrainfuckの処理系に、 >・課題のページで与えられているBrainfuckのコードを食わせて、 >・正しい解答が、4秒以内に得られること > >ですよね? (「4秒以内」という制限がどこに書いてあるのか、見つけられていませんが) その通りです。4秒以内というのは問題によってたまに書いてるのですが、Code Golfでのルールみたいです。 >うちの処理系をベースにしたのであれば、実行部分は、アルゴリズム的に小手先で >最適化できる余地はあんまりないのではないでしょうか(Brainfuck処理系には、 >「]」が来たとき実行時に「[」を検索しているようなものもありますが、うちの >処理系はそのへんは読み込み時に済ませていますし)。 >Pythonの実装に依存するチューニングの余地はあるかもしれません。読み込んだ >Brainfuckプログラムをどのような内部形式で保持するか、とか。 Pythonの実装に依存するチューニングは確かにありそうですが、残念ながら思いつきません。内部形式もリストを使用しているのですが、dict(辞書)も値として式しか書けないので使えなさそうですし他には分かっていません。 >5秒を4秒にする程度のことであれば、「++++」を「+4」のようなひとつのコードに >するというアイディアで十分かとは思いますが、それをすべきタイミングは >Brainfuckソースを読み込んで内部形式に変換するところでしょうから、 >「文字列変換」ではないですよね。 6秒を4秒かもしれません。文字列変換というのは、例えば、'>+++++[<+++]<.'という入力(文字列)が与えられたときに、'>+5[<+3]<.'という文字列に変換してからリスト(内部形式)に変換することを想定していました。リスト(内部形式)に変換してから別のリスト(内部形式)に変換しても良いかもしれません。 文字列変換を考えていたのは、正規表現で簡単にできないかなと考えていました。 >(「スクリプト」が何なのかが不明ですが)いろいろな言語の本やら解説ページやら >読んではいますが、簡単なチュートリアルの例題とかではなく、実際に日頃から >自分の問題を解くために使っていないと、「身に付く」ことにはならないようですね。 スクリプトは、最近、LL言語と言われているもの、例えば、Perl、PHP、Ruby、Pythonなどを想定していました。普段使ってないと身に付くことにならないというのは同感です。私もC++やJavaは本読んでいただけなので全く身についていません。 Ruby、Pythonは世間で今流行っているというイメージがあったので、さすがに(ぱ)も手を出しているのかなと思いました。Haskellとか関数型言語などを勉強しているのかなとか。 悩んでいても進まないのでとりあえず、Brainfuck問題はPendingしておくことにしました。ありがとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[890] Re:Brainfuck
投稿者:(ぱ)
2007/02/20 02:13:25

Code Golf自体は以前「Matzにっき」からリンクを辿って、ページの構成が わかりにくいのもあってちょっと眺めただけでしたが。 >最近Pythonを覚えて、Code Golf(http://codegolf.com/) >というコンペにはまっているのですが、Brainfuck問題というのがあり、(ぱ)さんのソースを参考にさせて頂いたのですが、最後の問題が4秒以内という制限にTime outでパスしません。恐らくあと1秒くらい短縮しないとダメみたいです。 ええと、Brainfuck問題というのは http://codegolf.com/brainfuck ここのことで、「最後の問題」というのは、このページの一番下のところにある Rot-13の問題のことですか? WikipediaのRot-13のページ: http://ja.wikipedia.org/wiki/ROT13 で、課題は、 ・マスタングさんがPythonで書いたBrainfuckの処理系に、 ・課題のページで与えられているBrainfuckのコードを食わせて、 ・正しい解答が、4秒以内に得られること ですよね? (「4秒以内」という制限がどこに書いてあるのか、見つけられていませんが) >ネックは、入力の1文字1文字をループで回しているところだと思うのですが、3百万回のループが問題になっていそうです。スクリプトはループに弱いので。 うちの処理系をベースにしたのであれば、実行部分は、アルゴリズム的に小手先で 最適化できる余地はあんまりないのではないでしょうか(Brainfuck処理系には、 「]」が来たとき実行時に「[」を検索しているようなものもありますが、うちの 処理系はそのへんは読み込み時に済ませていますし)。 Pythonの実装に依存するチューニングの余地はあるかもしれません。読み込んだ Brainfuckプログラムをどのような内部形式で保持するか、とか。 >何か一般的に早くアウトプットを得る方法はあるのですか?とりあえず、'++++'などを'+4'のようにすればループ回数が劇的に減るかなと思っているのですが、まだ試していません。うまい文字列変換が思いつかないので。 5秒を4秒にする程度のことであれば、「++++」を「+4」のようなひとつのコードに するというアイディアで十分かとは思いますが、それをすべきタイミングは Brainfuckソースを読み込んで内部形式に変換するところでしょうから、 「文字列変換」ではないですよね。 >あと(ぱ)さんはスクリプトは勉強とかされていますか? (「スクリプト」が何なのかが不明ですが)いろいろな言語の本やら解説ページやら 読んではいますが、簡単なチュートリアルの例題とかではなく、実際に日頃から 自分の問題を解くために使っていないと、「身に付く」ことにはならないようですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[889] Brainfuck
投稿者:マスタング
2007/02/20 02:13:25

お久しぶりです、マスタングです。もし分かれば教えて欲しいです。 最近Pythonを覚えて、Code Golf(http://codegolf.com/) というコンペにはまっているのですが、Brainfuck問題というのがあり、(ぱ)さんのソースを参考にさせて頂いたのですが、最後の問題が4秒以内という制限にTime outでパスしません。恐らくあと1秒くらい短縮しないとダメみたいです。 ネックは、入力の1文字1文字をループで回しているところだと思うのですが、3百万回のループが問題になっていそうです。スクリプトはループに弱いので。 何か一般的に早くアウトプットを得る方法はあるのですか?とりあえず、'++++'などを'+4'のようにすればループ回数が劇的に減るかなと思っているのですが、まだ試していません。うまい文字列変換が思いつかないので。他に何かうまい方法ありますか? あと(ぱ)さんはスクリプトは勉強とかされていますか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[888] Re:大感激です
投稿者:(ぱ)
2007/02/20 02:13:25

>プログラミング(超)初心者です。 はじめまして。ほめていただきありがとうございます。 最近仕事に追われておりまして、Webページの更新もすっかり滞り、 この掲示板も放置状態でしたが、久々に投稿いただきその点でもありがとうございます。 >前橋先生の他の本を購入しようと思っています。 それはもう是非(商魂モード)
[この投稿を含むスレッドを表示] [この投稿を削除]
[887] 大感激です
投稿者:White_Star_Cat
2007/02/20 02:13:25

プログラミング(超)初心者です。 「C言語体当たり学習 徹底入門」を図書館で借りました。 あまりのわかりやすさに大感激です。 (^o^)/ 前橋先生の他の本を購入しようと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[886] 管理者により削除されました
2007/02/20 02:17:27

広告なので削除しました。
[この投稿を含むスレッドを表示]
[885] 管理者により削除されました
2007/02/20 02:19:26

広告なので削除。
[この投稿を含むスレッドを表示]
[884] Re:crowbar ver.0.4.02
投稿者:kit
2007/02/20 02:13:25

>そういえばLGPLはスタティックリンクはだめでしたっけ。すっかり忘れてました。 必ずしもスタティックリンクが駄目というわけじゃないですが、 スタティックリンクすると、 LGPL http://www.gnu.org/licenses/lgpl.html の第6項 a) みたいな制約を満たさないといけなくなります。 すなわち、LGPL なライブラリを再リンクできるようにするため、 アプリケーションの側のオブジェクトコードか、ソースコードを 提供する必要が生じます。 それよりはダイナミックリンクして、第6項 b) の適用を選んだ方が 楽なことが多いんじゃないかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[883] 本当の基礎からのWebアプリケーション入門 ―Webサーバを作ってみよう―
投稿者:(ぱ)
2007/02/20 02:13:25

Subject変えました。 >>「本当の基礎からのWebアプリケーション入門 ―Webサーバを作ってみよう―」 > > ネットワークに関してはほとんど無知なので何とも言えませんが、Webサーバの >作成は原点に戻りすぎではありませんか?随分と役に立つとは思いますけど。 昔、「インターネットを256倍使うための本」というのがあって、その中に、 「シェルによるhttpdの実装」というのがありました。 …今探したらソースが公開されていました。こちらです。 http://www.ascii.co.jp/books/support/4-7561-1663-9/supplement/0001/shttpd こちらによれば、 http://www.ascii.co.jp/books/support/4-7561-1663-9/supplement/ 「筆者が偉いんではなく、shが偉いんでもなく、ズバリinetdが偉い」そうですが、 その部分をJavaかなんかでちょろっと書いてしまえば、Webサーバとしての機能は すぐに実装できそうですし、それをベースにいろいろ拡張すれば勉強になるんじゃ ないかなあ、と思うわけです。ブラウザが何を送ってきてるのか目で見えますし、 どう対応すればいいかもわかるので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[882] Re:crowbar ver.0.4.02
投稿者:(ぱ)
2007/02/20 02:13:25

>SDL は LGPL なので、スタティックリンクするよりは、Windows の場合なら >実行ファイルと同じディレクトリに展開されるようにアーカイブを作る方が >いいでしょうね。 そういえばLGPLはスタティックリンクはだめでしたっけ。すっかり忘れてました。 >LGPL よりライセンスの緩いライブラリとしては Allegro というのがあるよう >です。http://www.talula.demon.co.uk/allegro/ こちらも情報ありがとうございます。 >行数については、大学時代には、1日1000行、6日で6000行書いちゃう先輩が >いました。まあ、この人は特別で、絶対真似できんと当時から言ってましたが。 現在なら、1日1000行はやれないこともないのですが…あくまで「非常時」だけですね。 後で読みたくないコードになることが多いので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[881] Re:『センス・オブ・プログラミング!』誤植
投稿者:トル
2007/02/20 02:13:25

>Cで掲示板というのは別の意味ですごいというか、ずいぶん手間がかかったのでは >ないでしょうか。PHPを覚えるほうが手っ取り早いような。  PHPの$_POSTの代わりの物をせっせと作っていたりした辺りを手間と言えば確かにPHPより はずいぶん手間がかかりました。  一番時間がかかったのはデータベースを使わなかったので、保存や読み込みの辺りです。 ちょうどその頃「プログラミング言語を作る」でyaccとlexが使われていたので、興味本位で 使ってみたりしました。楽ができたかと聞かれますと微妙ですが。 >「本当の基礎からのWebアプリケーション入門 ―Webサーバを作ってみよう―」  ネットワークに関してはほとんど無知なので何とも言えませんが、Webサーバの作成は原点に 戻りすぎではありませんか?随分と役に立つとは思いますけど。 >掲示板のプログラムを公開することは、Webページのひとつも立てれば可能では >ないでしょうか。お金もかかりませんし。  それは可能ですが、見てくれる相手が未だにいないのが悩みの種です。メーリングリストなどに 参加してみたいとは思うのですが、今は色々とありますのでまだ先の事になると思いますし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[880] Re:『センス・オブ・プログラミング!』誤植
投稿者:(ぱ)
2007/02/20 02:13:25

>P.198 L.3 (4-6-1) >Line polyline_array[LINE_MAX]; 確認しました。ご指摘ありがとうございました。正誤表に入れておきます。 > 話が変わりますが、「PHPとMySQLで掲示板を作る」を前に読ませていただき、 >私も作ってみたいな~、と思い、前橋さんの掲示板を参考にして作ってみました。 >まともに使える言語がCしかなく、練習の意味合いも込めてCで作ったのですが、 >あまり上手くは作れませんでした。 Cで掲示板というのは別の意味ですごいというか、ずいぶん手間がかかったのでは ないでしょうか。PHPを覚えるほうが手っ取り早いような。 とはいえ、CGIはWebアプリケーションの基本ですから、(Perlでもよいので)一度は 作っておくべきものかとは思います。最近は、PHPやらJSPやらStrutsやら、果ては ASP.NET等いろいろ便利な道具があって、もちろんそれはそれでよいのですが、 結局下回りを知らないと困ることもありますから。 「本当の基礎からのWebアプリケーション入門 ―Webサーバを作ってみよう―」 なんての、誰か書いてくれませんかね… > 独学で、周りにプログラミングのできる知り合いがおらず、評価したりして >もらえないので寂しいです。 掲示板のプログラムを公開することは、Webページのひとつも立てれば可能では ないでしょうか。お金もかかりませんし。 > あと、「プログラミング言語を作る」も楽しく読ませていただいています。 ありがとうございます。停滞しておりましてすみません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[879] Re:crowbar ver.0.4.02
投稿者:kit
2007/02/20 02:13:25

SDL は LGPL なので、スタティックリンクするよりは、Windows の場合なら 実行ファイルと同じディレクトリに展開されるようにアーカイブを作る方が いいでしょうね。 Linux の場合は、ディストリビューションに最初からついてきて、デフォルト でインストールされることが多いので、特に考慮の必要はないと思います。 LGPL よりライセンスの緩いライブラリとしては Allegro というのがあるよう です。http://www.talula.demon.co.uk/allegro/ 行数については、大学時代には、1日1000行、6日で6000行書いちゃう先輩が いました。まあ、この人は特別で、絶対真似できんと当時から言ってましたが。 大学祭の展示が素晴らしいってのは同感です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[878] 『センス・オブ・プログラミング!』誤植
投稿者:トル
2007/02/20 02:13:25

正誤表に載っていませんでしたので、お知らせします。(初版第一刷) P.198 L.3 (4-6-1) Line polyline_array[LINE_MAX]; とありますが、 PolyLine polyline_array[LINE_MAX]; ではないでしょうか?  話が変わりますが、「PHPとMySQLで掲示板を作る」を前に読ませていただき、 私も作ってみたいな~、と思い、前橋さんの掲示板を参考にして作ってみました。 まともに使える言語がCしかなく、練習の意味合いも込めてCで作ったのですが、 あまり上手くは作れませんでした。  独学で、周りにプログラミングのできる知り合いがおらず、評価したりしてもらえないの で寂しいです。  あと、「プログラミング言語を作る」も楽しく読ませていただいています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[877] Re:crowbar ver.0.4.02
投稿者:(ぱ)
2007/02/20 02:13:25

どうもです。返答が遅くなりましてすみません。 >> そろそろWindowsに特化してもいいんじゃないかと思っていたり(謎)。 >これって昔聞いたあの話の関連ですかね。  この文言はcrowbar 0.4の時のToDoリストに入ってまして、この時は そういうこともそれなりに考えていたのですが、今はちょっと別方面に 手を出しつつあって、どうしようかなあ、という状態です。 >だとすると、SDL をライブラリとして使えば、Windows に特化しなくても >いいのではないかって気もします。  毎度アドバイスありがとうございます。  ちょっと調べてみましたが、このへんを見る限り、使い方はそんなに 難しくなさそうです。 http://lazyfooproductions.com/SDL_tutorials/index.php  ただ、あっち方面を目指す場合、「.EXEファイル単体で動く」というのは それなりに重要な用件であるように思います。crowbarもそっち方面を目指すなら、 HSPやひまわりがそうであるように、インタプリタとスクリプトをひとつの .EXEにまとめられなきゃな、と思っていました。そこに別のDLLが必要に なるというのはちょっと…(Windows限定なら、staticに固めてしまえばよいのかも しれませんが) >大学祭で見たアレも SDL で作ってた >そうです。たかだか千数百行であれくらいできてしまうってのも驚き >でしたが。  そう思います。  でも、自分が大学生だった頃のことを考えると、「千数百行」は「たかだか」では なかったわけで、その意味でもびっくりです。今の現役生はがんばってるなあ、と。  
[この投稿を含むスレッドを表示] [この投稿を削除]
[876] crowbar ver.0.4.02
投稿者:kit
2007/02/20 02:13:25

> そろそろWindowsに特化してもいいんじゃないかと思っていたり(謎)。 これって昔聞いたあの話の関連ですかね。 だとすると、SDL をライブラリとして使えば、Windows に特化しなくても いいのではないかって気もします。大学祭で見たアレも SDL で作ってた そうです。たかだか千数百行であれくらいできてしまうってのも驚き でしたが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[874] 管理者により削除されました
2007/02/20 02:18:23

広告なので削除しました。
[この投稿を含むスレッドを表示]
[872] Re:List 4-6
投稿者:(ぱ)
2007/02/20 02:13:25

> たとえ話は好きじゃないですが、材木屋さんになったと想像してください。 >材木がコンベアーに(縦方向に)乗って流れてくるのですが、材木の長さはまちまちです。 >あなたはそれを箱詰めして発送しなければなりません。 1点補足します。 あなたが立っている場所からはコンベアーの端しか見えず、材木はとても長いので、 材木が最後まで流れてこないと材木の長さがわからない、と思ってください。 …やっぱり、このたとえ話もはずしたかな?
[この投稿を含むスレッドを表示] [この投稿を削除]
[871] Re:List 4-6
投稿者:(ぱ)
2007/02/20 02:13:25

>お世話になります。プログラミング初心者です。 > >「ポインタ完全制覇」のp218のList 4-6のプログラムで質問させてください。 > >76--79行目でmallocを使っているのは何故なのでしょうか。 > >代わりに、 > >return st_line_buffer; > >では駄目なのでしょうか。  マスタングさんが書いておられるように、この書き方では、2行目が読み込まれたときに1行目の領域が上書きされてしまいます。st_line_bufferが指す先の領域はひとつしかないからです。  ただし、たとえば以下のように書けば、 temp = st_line_buffer; st_line_buffer = NULL; st_current_buffer_size = NULL; return temp;  次のread_line()の呼び出しでは新たな領域が割り当てられますから、正しく動作することでしょう。ただし、st_line_bufferはALLOC_SIZE(256バイト)ずつまとめて伸びていきますから、行の長さによってはメモリが無駄になります。  256バイトずつではなく、1バイトずつrealloc()していけばこの無駄はなくせますが、p.221で説明しているようにrealloc()はそれなりに重い関数なので、あまり頻繁にrealloc()しないため、こうしているわけです。  List 4-6では、以下の戦略をとっています。 (1)ファイルから文字を1文字ずつ読み込み、いったん「一時置き場」に蓄える。 (2)「一時置き場」はひとつしかない。 (3)行が「一時置き場」に入りきらない場合、「一時置き場」は256バイトを単位に  まとめて拡張される。一時置き場が縮むことはない。 (4)行を最後まで読み終わり、行の長さが確定した時点で、その行の長さに  ぴったり合わせたサイズの領域を新たに確保し、そこにコピーして、  利用者に返す。  たとえ話は好きじゃないですが、材木屋さんになったと想像してください。材木がコンベアーに(縦方向に)乗って流れてくるのですが、材木の長さはまちまちです。あなたはそれを箱詰めして発送しなければなりません。  コンベアーの端に広めの作業領域を作り、いったん材木をそこに置いて、正確な長さを測ってから、ぴったりの大きさの箱を作るという方法が無駄がないと思いませんか? このプログラムではそういう方針をとっているわけです。  
[この投稿を含むスレッドを表示] [この投稿を削除]
[870] Re:定義
投稿者:(ぱ)
2007/02/20 02:13:25

>僕が混乱したのは、きっと、1次式の定義に「式」という1次式を含む未定義の >クラスが登場したと受け止めたからだと思います。 その受け止め方は正解です。そして再帰的定義というのはそういうものです。 ちょうどうちのページにこんな文書がありまして、簡易的な電卓の構文規則を載せています。 http://kmaebashi.com/programmer/devlang/yacclex.html 7: expression /* 「式」とは… */ 8: : term /* 「項」、 */ 9: | expression ADD term /* または、「式」 + 「項」 */ 10: | expression SUB term /* または、「式」 - 「項」 */ 11: ; 12: term /* 「項」とは、 */ 13: : primary_expression /* 「一次式」、 */ 14: | term MUL primary_expression /* または、「項」 * 「一次式」 */ 15: | term DIV primary_expression /* または、「項」 / 「一次式」 */ 16: ; 17: primary_expression /* 「一次式」とは… */ 18: : DOUBLE_LITERAL /* 実数のリテラル */ 19: ; この電卓は括弧が使えないのでprimary_expressionの定義は異なりますが、 この電卓でも、式の定義にはやっぱり式が登場します。 K&Rをお持ちであれば、巻末の構文規則(p.298あたり)でCの式の構文が定義されています。 >式は1次式から構成されるものなのでしょうが、どのように構成されるものをそう言うのか、 >そこでの記述では不明だと思います。定義になっていないのでは。 ポインタ完全制覇における式の定義に関する説明は、 ・「式には1次式と呼ばれるものがあります」 ・「式に対して演算子を適用したり、演算子でもって式と式をつなぎ合わせたもののことも、   また式と呼びます」  となっています。  Cには関数呼び出し等を含めたくさんの演算子がありますし、sizeof(型)はどうなるのか等、この定義では曖昧すぎるというご意見はあるかと思いますが、この場所でそれを延々と書くのもよろしくないと判断した、のだと思います。ずいぶん前の話なので記憶が曖昧ですが。  
[この投稿を含むスレッドを表示] [この投稿を削除]
[869] Re:List 4-6
投稿者:マスタング
2007/02/20 02:13:25

一部、間違えました。 (誤) >char s1, s2; (正) char *s1, *s2;
[この投稿を含むスレッドを表示] [この投稿を削除]
[868] Re:List 4-6
投稿者:マスタング
2007/02/20 02:13:25

>「ポインタ完全制覇」のp218のList 4-6のプログラムで質問させてください。 > >76--79行目でmallocを使っているのは何故なのでしょうか。 > >代わりに、 > >return st_line_buffer; > >では駄目なのでしょうか。違いがわからないのですが。 これは、オブジェクト指向の防御的コピーに近いですが、 read_line()が、st_line_bufferを素直に返している訳ではないので ちょっと違うかもしれません。 read_line.cファイルが1つのオブジェクト、st_line_bufferがprivateな メンバと考えると、実装詳細を直接戻すと、カプセル化が崩れるという 考え方も可能だと思います。 違いは以下です。 // もし、read_line()で、st_line_bufferを返す場合 char s1, s2; s1 = read_line(fp); // 例えば、s1が、"abc" s2 = read_line(fp); // 例えば、s2が、"def" // ここで、s1もs2も、"def"となる! // もし、read_line()で、コピーを返せば、 // s1は"abc"、s2は"def"となる。
[この投稿を含むスレッドを表示] [この投稿を削除]
[867] List 4-6
投稿者:黒霧お湯割
2007/02/20 02:13:25

お世話になります。プログラミング初心者です。 「ポインタ完全制覇」のp218のList 4-6のプログラムで質問させてください。 76--79行目でmallocを使っているのは何故なのでしょうか。 代わりに、 return st_line_buffer; では駄目なのでしょうか。違いがわからないのですが。 ご教授いただけると幸いです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[866] Re:定義
投稿者:黒霧お湯割
2007/02/20 02:13:25

ご回答ありがとうございました。 > 説明不足でしたでしょうか。 > 「定義するもの自身をその定義で書いた」もののことを「再帰的定義」と言いまして、プログラミングの世界ではさほど珍しいものではありません。 僕が混乱したのは、きっと、1次式の定義に「式」という1次式を含む未定義のクラスが登場したと受け止めたからだと思います。 式は1次式から構成されるものなのでしょうが、どのように構成されるものをそう言うのか、そこでの記述では不明だと思います。定義になっていないのでは。
[この投稿を含むスレッドを表示] [この投稿を削除]
[865] Re:定義
投稿者:774RR
2007/02/20 02:13:25

>そのため 「部分式 1+2*3 」に括弧をつけて (1+2*3) と書くと、これが部分式になるという規則が必要なのです。 typo これぢゃ意味判らん orz 部分式 1+2*3 に括弧をつけて (1+2*3) と書くと、これが一次式になる ですな。
[この投稿を含むスレッドを表示] [この投稿を削除]
[864] Re:定義
投稿者:774RR
2007/02/20 02:13:25

もっとあえて蛇足するなら (1+2*3)+4*5 とかを考えるといいかもしれません この例では括弧内を先に、括弧外の + を後に評価してもらわなければなりません。 もっというなら + より先に 4*5 を評価してもらわなければなりません。 そのため 「部分式 1+2*3 」に括弧をつけて (1+2*3) と書くと、これが部分式になるという規則が必要なのです。 実際のプログラムも再帰を使います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[863] Re:定義
投稿者:(ぱ)
2007/02/20 02:13:25

>1次式の定義の中で、「式を()で囲んだもの.」とあるのですが、 >定義するもの自身をその定義で書いたらいけないと思うのですが。  説明不足でしたでしょうか。  「定義するもの自身をその定義で書いた」もののことを「再帰的定義」と言いまして、プログラミングの世界ではさほど珍しいものではありません。 「再帰的定義」でGoogle: http://www.google.co.jp/search?hl=ja&q=%E5%86%8D%E5%B8%B0%E7%9A%84%E5%AE%9A%E7%BE%A9&lr= >きっと、その上3つを指しているんだと思うのですが・・・。 ポインタ完全制覇p.165より引用します。 | 1次式とは以下のものを指します。 | ・識別子(変数名、関数名のこと) | ・定数(整数定数と浮動小数点定数を含む) | ・文字列リテラル(""で囲まれた文字列) | ・式を()で囲んだもの  「その上3つ」と解釈すると、「(hoge)」とか「(0.5)」とか「("abc")」とかになりますが、「(hoge + 5)」と書いても1次式なので、その解釈ではまずいです。「その上3つ」は「1次式」の定義ですが、4つ目では「『式』を()で囲んだもの」と書いています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[862] 定義
投稿者:黒霧お湯割
2007/02/20 02:13:25

「C言語ポインタ完全制覇」の165ページなのですが。1次式の定義の中で、「式を()で囲んだもの.」とあるのですが、定義するもの自身をその定義で書いたらいけないと思うのですが。きっと、その上3つを指しているんだと思うのですが・・・。僕には精神衛生上きついっす。
[この投稿を含むスレッドを表示] [この投稿を削除]
[861] Re:「疑り深いあなたのためのオブジェクト指向再入門」読みました
投稿者:(ぱ)
2007/02/20 02:13:25

>これは、オブジェクト指向とは言わないのではないでしょうか? >あえて言うなら、オブジェクト指向の特徴の一つである『データ抽象化』でしか >ないと思います。オブジェクト指向というには、『継承』の概念が実装されている >必要もあると思います。  まあそうなのかもしれませんけど、「どこまでやってるとオブジェクト指向であるか」といった用語の定義的な議論は、既にずいぶん曖昧な定義で使われている「オブジェクト指向」という言葉については、不毛だと思います。 前にもあげたページだと思いますが http://www.shiro.dreamhost.com/scheme/trans/reesoo-j.html | オブジェクト指向というものが動く標的であるため、オブジェクト指向の熱心な | 支持者はこのメニューのうちの適当なサブセットを気まぐれに選んで、それを以って | 他の言語はオブジェクト指向ではないと説得しようとする。 私も以下のように書きました。 http://kmaebashi.com/programmer/object/intro.html | ※2 「それは抽象データ型だ」という意見もあるかもしれませんが、抽象データ型は | オブジェクト指向に至るためには必須の概念です。 Matzにっきより。 http://www.rubyist.net/~matz/20030729.html#p01 |「オブジェクト指向」のもっとも重要な概念は通常のプログラミングにも登場して | いる。たとえば、Cで | FILE *f = fopen(path, "r"); | という呼び出しは「pathにあるファイルをオープンして、ファイルオブジェクトを | 得る」という処理そのものだ。別にオブジェクト指向は必要ない。CのFILE*には | fprintf()やfclose()などのいくつかの「メソッド」がある。 >(ただし、Xtも単なる抽象データ型だったかも。継承を実装していたか記憶が > 定かではありません。 継承は実現していましたね。たとえばMotifのRowColumnはManagerのサブクラスです。 # んで、JavaのレイアウトマネージャがComponentクラス階層の中になく、 # プラグイン的に突っ込むようになっているのを見て衝撃を受けましたとも。
[この投稿を含むスレッドを表示] [この投稿を削除]
[860] Re:「疑り深いあなたのためのオブジェクト指向再入門」読みました
投稿者:ytanaka
2007/02/20 02:13:25

>オブジェクト指向の標準関数がありますね。FILE * を介して行なうファイル入出力です これは、オブジェクト指向とは言わないのではないでしょうか? あえて言うなら、オブジェクト指向の特徴の一つである『データ抽象化』でしかないと思います。オブジェクト指向というには、『継承』の概念が実装されている必要もあると思います。 >その他、X Window System の Xlib やそのツールキットもオブジェクト指向です。 私は、学生の頃、Xtのソースを読んで、『なんだこのコーデイングは?なんで構造体に関数のポインタぶち込んでるんや?』『おお!そういうことか!すげー!』と凄い衝撃を覚えました。 このころは、まだオブジェクト指向という言葉を知らなかったのですが、あとからC++を勉強したときには、C言語のテクニックを駆使して無理やりオブジェクト指向に仕上げたXtはやっぱり凄かったんだと再認識しましたね。(ただし、Xtも単なる抽象データ型だったかも。継承を実装していたか記憶が定かではありません。でも、構造体に関数をぶち込んでいる時点でFILEとfopen等よりも高度ですね。関数のポインタを書き換えて振る舞いを変えさせることもできましたしね。)
[この投稿を含むスレッドを表示] [この投稿を削除]
[859] Re:JAVA VMエラー
投稿者:aaa
2007/02/20 02:13:25

>本屋でJAVA謎+落とし穴徹底解明を見つけました。 >あまりにも難しい内容ですが今困っていますので教えてください。 >WIN XPSP2で証券会社のHPにアクセスすると下記ERRで強制終了します。 >またSUN JAVAコンソールをクイックしても同じERRになります。 > > ># ># An unexpected error has been detected by HotSpot Virtual Machine: ># ># EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d6c20e6, pid=1228, tid=2324 ># ># Java VM: Java HotSpot(TM) Client VM (1.5.0_02-b09 mixed mode) ># Problematic frame: ># V [jvm.dll+0x820e6] ># > >--------------- T H R E A D --------------- > >Current thread (0x0562a6a8): JavaThread "main" [_thread_in_vm, id=2324] > >siginfo: ExceptionCode=0xc0000005, reading address 0x00000008 > >Registers: >EAX=0x00000000, EBX=0x00000000, ECX=0x00000008, EDX=0x00000000 >ESP=0x069f5f74, EBP=0x069f5fac, ESI=0x0562a6a8, EDI=0x00000000 >EIP=0x6d6c20e6, EFLAGS=0x00010246 > >Top of Stack: (sp=0x069f5f74) >0x069f5f74: 6d6c494b 00000000 00000000 0562a764 >0x069f5f84: 6d317763 0000000c 09352923 00000000 >0x069f5f94: 100f38a0 00000000 00000000 056cf3a8 >0x069f5fa4: 0562a6a8 00000000 069f5fd0 6d304c3a >0x069f5fb4: 0562a764 6d317774 00000000 0562a764 >0x069f5fc4: 00000000 00000000 0562a764 069f5ff8 >0x069f5fd4: 6d30543a 0562a764 069f6003 6d317774 >0x069f5fe4: 6d317768 6d317750 055f5684 0562a764 > >Instructions: (pc=0x6d6c20e6) >0x6d6c20d6: e8 0c 2a ff ff c3 8b 44 24 04 8b 0d b0 64 7a 6d >0x6d6c20e6: 8b 04 01 c3 8b 44 24 04 8b 0d ac 64 7a 6d 8b 04 > > >Stack: [0x06900000,0x06a00000), sp=0x069f5f74, free space=983k >Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) >V [jvm.dll+0x820e6] >C [java.dll+0x4c3a] >C [java.dll+0x543a] >C [java.dll+0x54d3] >C [java.dll+0x18ba] >j java.lang.ClassLoader$NativeLibrary.load(Ljava/lang/String;)V+0 >j java.lang.ClassLoader.loadLibrary0(Ljava/lang/Class;Ljava/io/File;)Z+300 >j java.lang.ClassLoader.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)V+48 >j java.lang.Runtime.load0(Ljava/lang/Class;Ljava/lang/String;)V+57 >j java.lang.System.load(Ljava/lang/String;)V+7 >v ~StubRoutines::call_stub >V [jvm.dll+0x818e8] >V [jvm.dll+0xd4989] >V [jvm.dll+0x817b9] >V [jvm.dll+0x887ae] >C [jpishare.dll+0x4380] >C [jpishare.dll+0x1eb2] >C [jpiexp32.dll+0x5744] >C [npjpi150_02.dll+0x1abf] >C [ole32.dll+0x2206a] >C [ole32.dll+0x40a03] >C [ole32.dll+0x4071d] >C [ole32.dll+0x27b76] >C [ole32.dll+0x27a62] >C [ole32.dll+0x27c48] >C [ole32.dll+0x27bf4] >C [ole32.dll+0x4112b] >C [ole32.dll+0x410e2] >C [ole32.dll+0x27c9b] >C [ole32.dll+0x27a62] >C [ole32.dll+0x27a7c] >C [ole32.dll+0x27a62] >C [ole32.dll+0x278f6] >C [ole32.dll+0x277af] >C [ole32.dll+0x27731] >C [urlmon.dll+0x3c5c7] >C [urlmon.dll+0x3cb1e] >C [urlmon.dll+0x3ce5a] >C [mshtml.dll+0x273785] >C [mshtml.dll+0x273afa] >C [mshtml.dll+0x26e889] >C [mshtml.dll+0x275cfe] > >Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) >j java.lang.ClassLoader$NativeLibrary.load(Ljava/lang/String;)V+0 >j java.lang.ClassLoader.loadLibrary0(Ljava/lang/Class;Ljava/io/File;)Z+300 >j java.lang.ClassLoader.loadLibrary(Ljava/lang/Class;Ljava/lang/String;Z)V+48 >j java.lang.Runtime.load0(Ljava/lang/Class;Ljava/lang/String;)V+57 >j java.lang.System.load(Ljava/lang/String;)V+7 >v ~StubRoutines::call_stub > >--------------- P R O C E S S --------------- > >Java Threads: ( => current thread ) > 0x066f0878 JavaThread "traceMsgQueueThread" daemon [_thread_blocked, id=2540] > 0x066decc0 JavaThread "AWT-Windows" daemon [_thread_in_native, id=560] > 0x066de8d8 JavaThread "AWT-Shutdown" [_thread_blocked, id=460] > 0x066dab40 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=1336] > 0x06657588 JavaThread "Low Memory Detector" daemon [_thread_blocked, id=2148] > 0x0659d750 JavaThread "CompilerThread0" daemon [_thread_blocked, id=292] > 0x06554df8 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=2536] > 0x06592a50 JavaThread "Finalizer" daemon [_thread_blocked, id=2532] > 0x0563a580 JavaThread "Reference Handler" daemon [_thread_blocked, id=2528] >=>0x0562a6a8 JavaThread "main" [_thread_in_vm, id=2324] > >Other Threads: > 0x06581580 VMThread [id=2496] > 0x05659768 WatcherThread [id=744] > >VM state:not at safepoint (normal execution) > >VM Mutex/Monitor currently owned by a thread: None > >Heap > def new generation total 576K, used 334K [0x100b0000, 0x10150000, 0x10810000) > eden space 512K, 52% used [0x100b0000, 0x100f3a80, 0x10130000) > from space 64K, 100% used [0x10140000, 0x10150000, 0x10150000) > to space 64K, 0% used [0x10130000, 0x10130000, 0x10140000) > tenured generation total 1408K, used 201K [0x10810000, 0x10970000, 0x160b0000) > the space 1408K, 14% used [0x10810000, 0x10842500, 0x10842600, 0x10970000) > compacting perm gen total 8192K, used 3930K [0x160b0000, 0x168b0000, 0x1a0b0000) > the space 8192K, 47% used [0x160b0000, 0x16486a20, 0x16486c00, 0x168b0000) >No shared spaces configured. > >Dynamic libraries: >0x00400000 - 0x00419000 C:\Program Files\Internet Explorer\iexplore.exe >0x7c940000 - 0x7c9dd000 C:\WINDOWS\system32\ntdll.dll >0x7c800000 - 0x7c931000 C:\WINDOWS\system32\kernel32.dll >0x77bc0000 - 0x77c18000 C:\WINDOWS\system32\msvcrt.dll >0x77cf0000 - 0x77d7f000 C:\WINDOWS\system32\USER32.dll >0x77ed0000 - 0x77f16000 C:\WINDOWS\system32\GDI32.dll >0x77f20000 - 0x77f96000 C:\WINDOWS\system32\SHLWAPI.dll >0x77d80000 - 0x77e29000 C:\WINDOWS\system32\ADVAPI32.dll >0x77e30000 - 0x77ec1000 C:\WINDOWS\system32\RPCRT4.dll >0x76350000 - 0x764bc000 C:\WINDOWS\system32\SHDOCVW.dll >0x765c0000 - 0x76653000 C:\WINDOWS\system32\CRYPT32.dll >0x77c40000 - 0x77c52000 C:\WINDOWS\system32\MSASN1.dll >0x75410000 - 0x75485000 C:\WINDOWS\system32\CRYPTUI.dll >0x76be0000 - 0x76c0e000 C:\WINDOWS\system32\WINTRUST.dll >0x76c40000 - 0x76c68000 C:\WINDOWS\system32\IMAGEHLP.dll >0x770d0000 - 0x7715c000 C:\WINDOWS\system32\OLEAUT32.dll >0x76970000 - 0x76aad000 C:\WINDOWS\system32\ole32.dll >0x59250000 - 0x592a4000 C:\WINDOWS\system32\NETAPI32.dll >0x76660000 - 0x76704000 C:\WINDOWS\system32\WININET.dll >0x76f10000 - 0x76f3c000 C:\WINDOWS\system32\WLDAP32.dll >0x77bb0000 - 0x77bb8000 C:\WINDOWS\system32\VERSION.dll >0x762e0000 - 0x762fd000 C:\WINDOWS\system32\IMM32.DLL >0x60740000 - 0x60749000 C:\WINDOWS\system32\LPK.DLL >0x73f80000 - 0x73feb000 C:\WINDOWS\system32\USP10.dll >0x77160000 - 0x77262000 C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll >0x7d5b0000 - 0x7ddad000 C:\WINDOWS\system32\SHELL32.dll >0x5ab60000 - 0x5abf7000 C:\WINDOWS\system32\comctl32.dll >0x58730000 - 0x58768000 C:\WINDOWS\system32\uxtheme.dll >0x74660000 - 0x746ab000 C:\WINDOWS\system32\MSCTF.dll >0x75ed0000 - 0x75fcd000 C:\WINDOWS\system32\BROWSEUI.dll >0x20000000 - 0x20010000 C:\WINDOWS\system32\browselc.dll >0x76d90000 - 0x76db2000 C:\WINDOWS\system32\appHelp.dll >0x76f80000 - 0x76fff000 C:\WINDOWS\system32\CLBCATQ.DLL >0x77000000 - 0x770ab000 C:\WINDOWS\system32\COMRes.dll >0x73620000 - 0x7364e000 C:\WINDOWS\system32\msctfime.ime >0x4edc0000 - 0x4ee16000 C:\WINDOWS\system32\imjp81.ime >0x648f0000 - 0x649c0000 C:\WINDOWS\system32\imjp81k.dll >0x3b100000 - 0x3b11b000 C:\WINDOWS\IME\IMJP8_1\Dicts\IMJPCD.DIC >0x75c40000 - 0x75cdc000 C:\WINDOWS\system32\urlmon.dll >0x77fa0000 - 0x77fb1000 C:\WINDOWS\system32\Secur32.dll >0x76570000 - 0x765c0000 C:\WINDOWS\System32\cscui.dll >0x76550000 - 0x7656c000 C:\WINDOWS\System32\CSCDLL.dll >0x76040000 - 0x76199000 C:\WINDOWS\system32\SETUPAPI.dll >0x10000000 - 0x100af000 c:\program files\google\googletoolbar1.dll >0x71a00000 - 0x71a0b000 C:\WINDOWS\system32\WSOCK32.dll >0x719e0000 - 0x719f7000 C:\WINDOWS\system32\WS2_32.dll >0x719d0000 - 0x719d8000 C:\WINDOWS\system32\WS2HELP.dll >0x76af0000 - 0x76b1b000 C:\WINDOWS\system32\WINMM.dll >0x5a820000 - 0x5a827000 C:\WINDOWS\system32\serwvdrv.dll >0x58a60000 - 0x58a67000 C:\WINDOWS\system32\umdmxfrm.dll >0x74cd0000 - 0x74d61000 C:\WINDOWS\system32\MLANG.dll >0x76940000 - 0x76964000 C:\WINDOWS\system32\ntshrui.dll >0x76ad0000 - 0x76ae1000 C:\WINDOWS\system32\ATL.DLL >0x759b0000 - 0x75a60000 C:\WINDOWS\system32\USERENV.dll >0x71a50000 - 0x71a62000 C:\WINDOWS\system32\MPR.dll >0x75eb0000 - 0x75eb7000 C:\WINDOWS\System32\drprov.dll >0x71b60000 - 0x71b6e000 C:\WINDOWS\System32\ntlanman.dll >0x71c20000 - 0x71c35000 C:\WINDOWS\System32\NETUI0.dll >0x71be0000 - 0x71c20000 C:\WINDOWS\System32\NETUI1.dll >0x71bd0000 - 0x71bd7000 C:\WINDOWS\System32\NETRAP.dll >0x71b40000 - 0x71b53000 C:\WINDOWS\System32\SAMLIB.dll >0x75ec0000 - 0x75ec9000 C:\WINDOWS\System32\davclnt.dll >0x73cc0000 - 0x73cd3000 C:\WINDOWS\system32\shgina.dll >0x758b0000 - 0x759a3000 C:\WINDOWS\system32\MSGINA.dll >0x762b0000 - 0x762c0000 C:\WINDOWS\system32\WINSTA.dll >0x73520000 - 0x7355d000 C:\WINDOWS\system32\ODBC32.dll >0x76300000 - 0x76348000 C:\WINDOWS\system32\comdlg32.dll >0x03aa0000 - 0x03ab7000 C:\WINDOWS\system32\odbcint.dll >0x092d0000 - 0x09349000 C:\WINDOWS\system32\Audiodev.dll >0x086c0000 - 0x08904000 C:\WINDOWS\system32\WMVCore.DLL >0x070d0000 - 0x0710b000 C:\WINDOWS\system32\WMASF.DLL >0x67930000 - 0x679d1000 C:\WINDOWS\system32\DBGHELP.DLL >0x76e90000 - 0x76ecc000 C:\WINDOWS\system32\RASAPI32.DLL >0x76e40000 - 0x76e52000 C:\WINDOWS\system32\rasman.dll >0x76e60000 - 0x76e8f000 C:\WINDOWS\system32\TAPI32.dll >0x76e30000 - 0x76e3e000 C:\WINDOWS\system32\rtutils.dll >0x72220000 - 0x72225000 C:\WINDOWS\system32\sensapi.dll >0x03dd0000 - 0x03e52000 C:\WINDOWS\system32\shdoclc.dll >0x04060000 - 0x0406e000 C:\Program Files\Adobe\Acrobat 7.0\ActiveX\AcroIEHelper.dll >0x7c340000 - 0x7c396000 C:\WINDOWS\system32\MSVCR71.dll >0x75de0000 - 0x75e8f000 C:\WINDOWS\system32\SXS.DLL >0x040c0000 - 0x04620000 C:\WINDOWS\system32\xpsp2res.dll >0x71980000 - 0x719bf000 C:\WINDOWS\system32\mswsock.dll >0x607c0000 - 0x60816000 C:\WINDOWS\system32\hnetcfg.dll >0x719c0000 - 0x719c8000 C:\WINDOWS\System32\wshtcpip.dll >0x04b20000 - 0x04b3c000 c:\progra~1\mcafee.com\vso\McVSSkt.dll >0x76ed0000 - 0x76ef7000 C:\WINDOWS\system32\DNSAPI.dll >0x76930000 - 0x76938000 C:\WINDOWS\system32\LINKINFO.dll >0x76f70000 - 0x76f76000 C:\WINDOWS\system32\rasadhlp.dll >0x03d80000 - 0x03d9c000 C:\Program Files\Adobe\Acrobat 7.0\ActiveX\PDFShell.dll >0x7cca0000 - 0x7cf85000 C:\WINDOWS\system32\mshtml.dll >0x74600000 - 0x74627000 C:\WINDOWS\system32\msls31.dll >0x74630000 - 0x7465a000 C:\WINDOWS\system32\msimtf.dll >0x64890000 - 0x648eb000 C:\WINDOWS\IME\imjp8_1\IMJPCIC.DLL >0x75ba0000 - 0x75c0e000 C:\WINDOWS\system32\jscript.dll >0x75390000 - 0x75401000 C:\WINDOWS\system32\mshtmled.dll >0x72c70000 - 0x72c79000 C:\WINDOWS\system32\wdmaud.drv >0x72c60000 - 0x72c68000 C:\WINDOWS\system32\msacm32.drv >0x77b90000 - 0x77ba5000 C:\WINDOWS\system32\MSACM32.dll >0x77b80000 - 0x77b87000 C:\WINDOWS\system32\midimap.dll >0x71c90000 - 0x71cac000 C:\WINDOWS\system32\ACTXPRXY.DLL >0x6bf50000 - 0x6bf85000 C:\WINDOWS\system32\dxtrans.dll >0x6d5d0000 - 0x6d5da000 C:\WINDOWS\system32\ddrawex.dll >0x736b0000 - 0x736f9000 C:\WINDOWS\system32\DDRAW.dll >0x73b10000 - 0x73b16000 C:\WINDOWS\system32\DCIMAN32.dll >0x6bf90000 - 0x6bfea000 C:\WINDOWS\system32\dxtmsft.dll >0x1c000000 - 0x1c006000 C:\WINDOWS\HKNTDLL.dll >0x5ec50000 - 0x5ec89000 C:\WINDOWS\ime\mscandui.dll >0x6d590000 - 0x6d5a1000 C:\Program Files\Java\jre1.5.0_02\bin\npjpi150_02.dll >0x5c9a0000 - 0x5c9b7000 C:\WINDOWS\system32\OLEPRO32.DLL >0x6d400000 - 0x6d417000 C:\Program Files\Java\jre1.5.0_02\bin\jpiexp32.dll >0x76f60000 - 0x76f68000 C:\WINDOWS\System32\winrnr.dll >0x6d450000 - 0x6d468000 C:\Program Files\Java\jre1.5.0_02\bin\jpishare.dll >0x6d640000 - 0x6d7c5000 C:\PROGRA~1\Java\JRE15~1.0_0\bin\client\jvm.dll >0x6d280000 - 0x6d288000 C:\PROGRA~1\Java\JRE15~1.0_0\bin\hpi.dll >0x76ba0000 - 0x76bab000 C:\WINDOWS\system32\PSAPI.DLL >0x6d610000 - 0x6d61c000 C:\PROGRA~1\Java\JRE15~1.0_0\bin\verify.dll >0x6d300000 - 0x6d31d000 C:\PROGRA~1\Java\JRE15~1.0_0\bin\java.dll >0x6d630000 - 0x6d63f000 C:\PROGRA~1\Java\JRE15~1.0_0\bin\zip.dll >0x6d000000 - 0x6d166000 C:\Program Files\Java\jre1.5.0_02\bin\awt.dll >0x72f50000 - 0x72f76000 C:\WINDOWS\system32\WINSPOOL.DRV >0x73890000 - 0x73960000 C:\WINDOWS\system32\D3DIM700.DLL >0x6d240000 - 0x6d27d000 C:\Program Files\Java\jre1.5.0_02\bin\fontmanager.dll >0x6d1f0000 - 0x6d203000 C:\Program Files\Java\jre1.5.0_02\bin\deploy.dll >0x049c0000 - 0x049dd000 C:\Program Files\Java\jre1.5.0_02\bin\RegUtils.dll >0x08910000 - 0x08bd6000 C:\WINDOWS\system32\msi.dll > >VM Arguments: >jvm_args: -Xbootclasspath/a:C:\PROGRA~1\Java\JRE15~1.0_0\lib\deploy.jar;C:\PROGRA~1\Java\JRE15~1.0_0\lib\plugin.jar -Xmx96m -Djavaplugin.maxHeapSize=96m -Xverify:remote -Djavaplugin.version=1.5.0_02 -Djavaplugin.nodotversion=150_02 -Dbrowser=sun.plugin -DtrustProxy=true -Dapplication.home=C:\PROGRA~1\Java\JRE15~1.0_0 -Djava.protocol.handler.pkgs=sun.plugin.net.protocol -Djavaplugin.vm.options=-Djava.class.path=C:\PROGRA~1\Java\JRE15~1.0_0\classes -Xbootclasspath/a:C:\PROGRA~1\Java\JRE15~1.0_0\lib\deploy.jar;C:\PROGRA~1\Java\JRE15~1.0_0\lib\plugin.jar -Xmx96m -Djavaplugin.maxHeapSize=96m -Xverify:remote -Djavaplugin.version=1.5.0_02 -Djavaplugin.nodotversion=150_02 -Dbrowser=sun.plugin -DtrustProxy=true -Dapplication.home=C:\PROGRA~1\Java\JRE15~1.0_0 -Djava.protocol.handler.pkgs=sun.plugin.net.protocol vfprintf >java_command: <unknown> > >Environment Variables: >PATH=C:\PROGRA~1\Java\JRE15~1.0_0\bin;C:\Program Files\Internet Explorer;;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;. >USERNAME=管理人室 >OS=Windows_NT >PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 1, GenuineIntel > > >--------------- S Y S T E M --------------- > >OS: Windows XP Build 2600 Service Pack 2 > >CPU:total 1 family 15, cmov, cx8, fxsr, mmx, sse, sse2, ht > >Memory: 4k page, physical 244464k(55328k free), swap 598668k(323724k free) > >vm_info: Java HotSpot(TM) Client VM (1.5.0_02-b09) for windows-x86, built on Mar 4 2005 01:53:53 by "java_re" with MS VC++ 6.0 > >
[この投稿を含むスレッドを表示] [この投稿を削除]
[858] 管理者により削除されました
2007/02/20 02:20:08

広告なので削除
[この投稿を含むスレッドを表示]
[857] 管理者により削除されました
2007/02/25 19:28:21

広告なので削除しました。
[この投稿を含むスレッドを表示]
[856] Re:BF-BASIC'n
投稿者:(ぱ)
2007/02/20 02:13:25

>えーっと、GPLかNYSLを適用しておいてもらえますでしょうか? そうでした。ライセンスの規定を忘れていました。ご指摘ありがとうございます。 NYSLにさせていただきました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[855] BF-BASIC'n
投稿者:yuya
2007/02/20 02:13:25

こんな言語を探してました。 えーっと、GPLかNYSLを適用しておいてもらえますでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[854] Re:インデント
投稿者:(ぱ)
2007/02/20 02:13:25

>なるほど。めったにプリントアウトしないため気づきませんでした。 私も今はプリントアウトはしませんが、25行のテキスト端末でvi使ってた時代は そういうわけにもいきませんでした。 >あ、ひょっとして勘違いだったかもしれません。申し訳ありません。 うーん、やはりそちらに書き込んだことはないようです。 >40代のオヤジ技術者です。これを機にお見知りおきを。 了解しました。こちらこそよろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[853] Re:インデント
投稿者:酔漢
2007/02/20 02:13:25

>と書くわけです。でも、当時ソースをプリントアウトしたとき、紙の切れ目で「}」が来ると、 >そこでif文が終わりなのか判定しにくいと思いやめました。 なるほど。めったにプリントアウトしないため気づきませんでした。 >す、すみません、「酔漢」さんがどなたかわかりませんです。 >私が定期的に書き込んでいる掲示板等は、そんなにないと思うのですが… あ、ひょっとして勘違いだったかもしれません。申し訳ありません。 40代のオヤジ技術者です。これを機にお見知りおきを。
[この投稿を含むスレッドを表示] [この投稿を削除]
[852] Re:インデント
投稿者:(ぱ)
2007/02/20 02:13:25

はじめまして。 >ちなみに私は >if() { > ... >} >else { > ... >} >と、そうとう変則的です。 でも、この書き方はたまに見かけると思います。 私も当初、else ifごとにコメントを入れたくて、そういう書き方にしていた頃があります。 if () { ... } /* ほにゃららの場合 */ else if (ほにゃらら) { ... } と書くわけです。でも、当時ソースをプリントアウトしたとき、紙の切れ目で「}」が来ると、 そこでif文が終わりなのか判定しにくいと思いやめました。 >ご挨拶が遅れました。はじめまして。私のところにいらっしゃるときと雰囲気が違うので驚きました。 す、すみません、「酔漢」さんがどなたかわかりませんです。 私が定期的に書き込んでいる掲示板等は、そんなにないと思うのですが…
[この投稿を含むスレッドを表示] [この投稿を削除]
[851] インデント
投稿者:酔漢
2007/02/20 02:13:25

begin/endか{/}かというページを読んで、昔読んだインデント論争を思い出しました。こちらもbit誌の連載で、その後単行本に収録されたはずですが、実家の両親に捨てられました。 SIGPLAN NOTICEの読者投稿で行われた「インデントはいかにあるべきや」という論争で、今で言えば、C言語のifに続く{はifの行末か、ifの次の行で同じ深さか、はたまた一段落とすかという話です。最後は編集者が「もういい」と打ち切ったそうです。 ちなみに私は if() { ... } else { ... } と、そうとう変則的です。最近は誰も「宙ぶらりんのelse」の話をしないので寂しいです。 ご挨拶が遅れました。はじめまして。私のところにいらっしゃるときと雰囲気が違うので驚きました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[850] Re:「疑り深いあなたのためのオブジェクト指向再入門」読みました
投稿者:(ぱ)
2007/02/20 02:13:25

このところどたばたしてまして返事が遅くなりましてすみません。 >で、思ったんですが、よくよく考えてみればC言語には昔からオブジェクト指向の標準関数がありますね。FILE * を介して行なうファイル入出力です そう思います。以下のページにそんなことを書きました。 http://kmaebashi.com/programmer/c_yota/inherit.html >その他、X Window System の Xlib やそのツールキットもオブジェクト指向です。 それも上記のページに書いています。 「疑り深い~」に書き足すかどうかはちょっと保留にさせてください。 # ていうか今は無理です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[849] 「疑り深いあなたのためのオブジェクト指向再入門」読みました
投稿者:NOBORU
2007/02/20 02:13:25

で、思ったんですが、よくよく考えてみればC言語には昔からオブジェクト指向の標準関数がありますね。FILE * を介して行なうファイル入出力です (これだけでもう分かると思いますが、fopen() が新しいインスタンスを作る new のようなもの。fclose() が C++ の delete のようなもの。fprintf()やfgets()などの入出力関数は全て最初に作った FILE 型領域へのポインタを介して行なって、違う FILE * だと違うファイルが対象になります)。 解説にその辺のことも付け加えるといいんじゃないでしょうか。これならよほどの初心者か特殊な環境のプログラマでない限りは使ったことあるでしょうから理解され易いと思います。 p.s. その他、X Window System の Xlib やそのツールキットもオブジェクト指向です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[848] ハッシュは何を使うか
投稿者:マスタング
2007/02/20 02:13:25

最近STLを勉強していて、C++の標準にはハッシュはないので 何で実現するかに迷っています。 もちろんアプリや目的が何かが重要ですが、実行速度優先で 考えていて、mapは遅いので使えないです。 ハッシュ関数はint値をテーブルサイズで割った余りを 返すという単純なものを考えています。 候補としては、以下のものを考えているのですが、 もっとうまい方法や常套手段はあるのでしょうか? 1) VC++のhash_map 2) SGIのhash_map 3) STLportのhash_map 4) templateで自作する .NET2003のVC++を使っているので1)か4)で考えているのですが、 良いサンプルがなかなかなくて、標準に入ってないだけで 結構苦労してます。慣れの問題かもしれないですが。 MSDNにも簡単なサンプルしかないし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[847] Re:マスタングさんへ
投稿者:kit
2007/02/20 02:13:25

> 私もそう思いますが、「センス・オブ~」でそう書いたところ査読して > くださった方からの反論があり、多少表現を変更した、という経緯も (^^; (^^; Cで単方向リストを書く場合、私も先頭のダミー要素は使いません。 リンクポインタへのポインタを使えば、不要になるからです。 でも、Lisp 文化圏あたりでは、ダミー要素も割と当たり前に使うんじゃ ないでしょうか? というか、C と C++ 以外の(リンクポインタへの ポインタを使えない) 言語では、わりと使うことが多いような。 あと私は、Cでも双方向リストを書く場合には、ほとんどの場合、環状にして ダミー要素を使います。結構そういう人は多いと思うんですけど、そうでも ないですかねえ。 試しに Java の標準ライブラリ jdk-1_5_0-src-scsl/j2se/src/share/classes/java/util/LinkedList.java を確認してみましたが、やはりダミー要素を使っているようですよ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[846] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

>listのsortとアルゴリズムのsortやqsortなら後者の方が速いような気がしますが(気がするだけですが)、 >その話ではないのです。紛らわしくてすみません。 >連結リストを自分で実装した場合の話です。 > >↓の最後の方法のことを言いたかったのです。 >http://www.kouno.jp/home/c_faq/c13.html#10 了解しました。 ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[845] Re:マスタングさんへ
投稿者:(ぱ)
2007/02/20 02:13:25

>先頭に置くなら番兵とは呼ばずにダミー要素と呼ぶべき。  私自身そう呼びますが(センス・オブ~ではダミーノードと呼んでいた)、774RRさん自身が「それとも最初に作ってる sta は番兵?」と書いておられるので、先頭のダミーノードを番兵と呼ぶ文化圏というのもありなのかなあ、と私は解釈しましたが。 >1方向リンクリストでも使わないほうが自然でしょう。  私もそう思いますが、「センス・オブ~」でそう書いたところ査読してくださった方からの反論があり、多少表現を変更した、という経緯も (^^;
[この投稿を含むスレッドを表示] [この投稿を削除]
[844] Re:マスタングさんへ
投稿者:(ぱ)
2007/02/20 02:13:25

>自分自身、リストの有用性自体をはっきりわかってないと思っています。  crowbarのcrowbar.hを見ると、連結リストをかなり使っていますね。 http://kmaebashi.com/programmer/devlang/crowbar_src_0_4/S/6.html  動的に追加される要素は、ランダムアクセスの必要がない限り、たいてい連結リストにしている、という感じです。  途中への追加とかがなくても連結リストを使っているのは、単にrealloc()で配列を伸ばすのが面倒だとか、型Tの配列をrealloc()で伸ばすとTのポインタが変わってしまって誰かが指していたときに困るとか(Tへのポインタの配列にすればいいんだけど)、create.cでの解析木の構築はrealloc()できないMEM_storage_malloc()を使っているとか、事情はいろいろありますが、単なる私の「癖」のような気もしないでもないです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[843] Re:elsif と else if
投稿者:(ぱ)
2007/02/20 02:13:25

いろいろどたばたしておりまして、返信がずいぶん遅くなりましてすみません。 >私が初めて買ったCの入門書には「if文は入れ子を避けるために二分岐処理に限定してswitch文の使用を検討しろ」というようなことが書いてありました。  以前の同僚で、「昔はelse ifという書き方が大嫌いだった」というのがいました。  「昔は」と言っていたのでその後改宗したわけですが、「if~elseは二分岐処理に限定して使うべき」と昔は思っていた、ということでしょう。私には理由がよくわかりませんが、そう思う人はいるらしい、ということで。
[この投稿を含むスレッドを表示] [この投稿を削除]
[842] Re:マスタングさんへ
投稿者:NykR
2007/02/20 02:13:25

>># リストの最も簡単で速いソート方法は配列にコピーしてqso(略 > >配列へのコピー時間はなしにしても、list#sortよりも早いのですか? >qsoってqsort()のことですか? listのsortとアルゴリズムのsortやqsortなら後者の方が速いような気がしますが(気がするだけですが)、 その話ではないのです。紛らわしくてすみません。 連結リストを自分で実装した場合の話です。 ↓の最後の方法のことを言いたかったのです。 http://www.kouno.jp/home/c_faq/c13.html#10
[この投稿を含むスレッドを表示] [この投稿を削除]
[841] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

>う、確かに難しかったかも知れません(書くのはともかく読むのは)。 > > 1.最初の要素をピボットにして、 >  残りの部分をピボット未満の要素のリスト(left)とピボット以上の要素のリスト(right)に分割する > 2.それぞれをソートする > 3.leftと最初の要素とrightをこの順に繋げる > >ということをやっています。 ># それぞれを関数化すべきでしたね。 ># ちなみに簡単だと思った理由は(ループが1重は冗談として)分割した後の領域の境界について考える必要がないからです 解説ありがとうございます。 簡単かどうかは置いといて、結局やっていることは アルゴリズム的には、配列と同様なことをやっているようですね。 但し、配列とリンクリストは要素へのアクセス方法(の実装)は 違いますが。 >まあ、クイックソートは最悪の場合 O(n^2) になってしまうわけで、 >ランダムアクセスできないとどうしても、 >それを避けるために書いたコードのせいで定数項が大きくなってしまいそうです。 ># gccのSTLの実装ではランダムアクセスイテレータにしかできないことばっかりやってたり > >リンクリストの場合はデータ構造を直接いじってマージソートしてしまった方が速いでしょうしね(std::listは実際にそうなっていますが)。 確かに、std::listは、ソート用の自前のメンバ関数を持っていましたね。 ># ちなみに上で説明した方法もデータ構造を直接いじっています ># ですから、std::sortでは同じことは出来ません > > >>NykRさんのサンプルの計算量はいまいち良く分かりませんでした。 > >平均(のオーダー)は O(n log n) ですが最悪だと O(n^2)です。 結局、std::listで、std::sortが使えないのは、実装がstd::listだけ 特殊扱いになってしまうのでできないということですね。 containerによって場合分けするなら、配列と同様な計算量で 実装できるから問題ない訳で、std::sortは、 汎用的な実装をしているというだけですね。 汎用的と言っても、配列(系)の実装を想定しているだけだと思いますが。 ># リストの最も簡単で速いソート方法は配列にコピーしてqso(略 配列へのコピー時間はなしにしても、list#sortよりも早いのですか? qsoってqsort()のことですか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[840] Re:マスタングさんへ
投稿者:NykR
2007/02/20 02:13:25

勘違いがあったので訂正します。 >>ただ、ピボットを選ぶときにランダムアクセスできないとワーストケースに対応できないので、その意味では配列の方が良いと言えるかもしれません。 ピボットを選ぶのは関数呼び出し1回につき1度だけなので、頭から順にアクセスしていってもオーダーは変わりませんね。 という訳で「ワーストケースに対応できない」というのはこの意味では嘘でした。 >>実装はリンクリストの方がむしろ簡単だと思います。 > >クイックソートがリンクリストで実装できるのは知りませんでしたが、 >私はNykRさんの実装が難しくて理解できませんでした う、確かに難しかったかも知れません(書くのはともかく読むのは)。  1.最初の要素をピボットにして、   残りの部分をピボット未満の要素のリスト(left)とピボット以上の要素のリスト(right)に分割する  2.それぞれをソートする  3.leftと最初の要素とrightをこの順に繋げる ということをやっています。 # それぞれを関数化すべきでしたね。 # ちなみに簡単だと思った理由は(ループが1重は冗談として)分割した後の領域の境界について考える必要がないからです >STLのsort()はランダムアクセスイテレータが必要ですが、 >私のイメージは、listはクイックソートに対して、 >実行効率の面で現実的ではないからできないのだと思っています。 >実装が簡単だというのも重要だと思いますが、 >(STLは)ライブラリなのであくまでもパフォーマンスが問題で、 >やはりリンクリストでは配列と同等のパフォーマンスが >でないのではないでしょうか? まあ、クイックソートは最悪の場合 O(n^2) になってしまうわけで、 ランダムアクセスできないとどうしても、 それを避けるために書いたコードのせいで定数項が大きくなってしまいそうです。 # gccのSTLの実装ではランダムアクセスイテレータにしかできないことばっかりやってたり リンクリストの場合はデータ構造を直接いじってマージソートしてしまった方が速いでしょうしね(std::listは実際にそうなっていますが)。 # ちなみに上で説明した方法もデータ構造を直接いじっています # ですから、std::sortでは同じことは出来ません >NykRさんのサンプルの計算量はいまいち良く分かりませんでした。 平均(のオーダー)は O(n log n) ですが最悪だと O(n^2)です。 # リストの最も簡単で速いソート方法は配列にコピーしてqso(略
[この投稿を含むスレッドを表示] [この投稿を削除]
[839] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

>クイックソートは、アルゴリズムそのものにはランダムアクセスは不要です。 >ただ、ピボットを選ぶときにランダムアクセスできないとワーストケースに対応できないので、その意味では配列の方が良いと言えるかもしれません。 >実装はリンクリストの方がむしろ簡単だと思います。 クイックソートがリンクリストで実装できるのは知りませんでしたが、 私はNykRさんの実装が難しくて理解できませんでした (いやみではありません。能力的な問題です)。 STLのsort()はランダムアクセスイテレータが必要ですが、 私のイメージは、listはクイックソートに対して、 実行効率の面で現実的ではないからできないのだと思っています。 実装が簡単だというのも重要だと思いますが、 (STLは)ライブラリなのであくまでもパフォーマンスが問題で、 やはりリンクリストでは配列と同等のパフォーマンスが でないのではないでしょうか? NykRさんのサンプルの計算量はいまいち良く分かりませんでした。 クイックソートのアルゴリズムにランダムアクセスがなくても 実装可能だと言うのは了解しました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[838] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

>>startは、staをさしている訳で、エラーの原因はstaは >>動的に確保されたオブジェクトではないからです。 >御意なのですが、だからといって最初を除外して free するというのも間違いと思う。 間違いではないと思います(逆に正解だとも言えません)。 ある意味どっちでも良いと思います。 サンプルの例ではauto変数であるstaがリンクリストの先頭な訳で、 これをそのまま(あるいはアドレスを)渡した方が分かりやすいと思った訳です。 free_list(sta.next);やfree_list(start->next);は分かりにくい気がします。 何でリンクリストの先頭(あるいはリンクリストそのものを表すもの)を 渡さないで、nextの要素を渡さないといけないのかという気がします。 確かに関数の汎用性を考えれば最初を除外するのは良くないと思います。 しかし、そういう次元の議論ではありません。 また、そもそもマルチプルインスタンスを考えた実装にはなっていないので マルチプルインスタンスに対応しようとすると破綻するのはしょうがないと 思います。 私ならlist(は名前を変えたい)の上にラッパーの構造体 (仮にllistとしましょう)を作成し、その中にlistの先頭を入れてあげます。 こうすれば、llistの中にダミーのstaも持たせることできますし、 どうにでも実装できます。free用の関数も以下で問題ないです。 free_llist(llist *head); マルチプルインスタンスだって当然できます。 問題は、どこまで実装を抽象化するかであり、今の負け組一号さんの 実装を踏襲するならば774RRさんのご指摘通り、問題点は多いです。 >リンクリストで番兵を使うというのが根底の発想として間違っている気がします。 また、これも間違っているとは断言できないと思います。 あくまで実装の問題で、実装を分かりやすくするために 番兵を入れるのであって、番兵を使うのが間違いではないと思います。 但し、負け組一号さんの番兵(ダミー?)の使い方が適切だとは 私も思っていません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[837] Re:マスタングさんへ
投稿者:NykR
2007/02/20 02:13:25

話の腰を揉んでみるテスト。ふにふに >リンクリストは、要素(サンプルの場合、list)を削除する処理が >配列に比べて早いというのが一般的に言われています。 リストを使う理由としては、配列だと削除された要素の後ろの要素を指すイテレータの扱いに困る、というのもありますね。 STLではそういうイテレータは無効になります。 >また、ソートに関しては基本的にリンクリストより配列の方が早いと思います。 >と言うのも、例えばクイックソートを使うならランダムアクセスが必要になるので >そもそもリンクリストでは(クイックソートは)無理です。 クイックソートは、アルゴリズムそのものにはランダムアクセスは不要です。 ただ、ピボットを選ぶときにランダムアクセスできないとワーストケースに対応できないので、その意味では配列の方が良いと言えるかもしれません。 実装はリンクリストの方がむしろ簡単だと思います。 void quick_sort(Node ** head_p) { if (*head_p != NULL && (*head_p)->next != NULL) { Node *p; Node *left = NULL, *right = NULL; Node **left_p = &left, **right_p = &right; for (p = (*head_p)->next; p != NULL; p = p->next) { if (p->value < (*head_p)->value) { *left_p = p; left_p = &(*left_p)->next; } else { *right_p = p; right_p = &(*right_p)->next; } } *left_p = *right_p = NULL; quick_sort(&left); quick_sort(&right); for (; *left_p != NULL; left_p = &(*left_p)->next) ; *left_p = *head_p, (*head_p)->next = right; *head_p = left; } } # いや、ループが1重で済んでるし<簡単
[この投稿を含むスレッドを表示] [この投稿を削除]
[836] Re:マスタングさんへ
投稿者:774RR
2007/02/20 02:13:25

話の腰を折りまくります。 >774RRさんがおっしゃっていたようにstaは番兵ですね。 リンクリストで番兵を使うというのが根底の発想として間違っている気がします。 >startは、staをさしている訳で、エラーの原因はstaは >動的に確保されたオブジェクトではないからです。 御意なのですが、だからといって最初を除外して free するというのも間違いと思う。 tree や環状リストで番兵を使ったりはしません。 1方向リンクリストでも使わないほうが自然でしょう。 もし仮に番兵を配置するならリンクリストの末尾に置くのが適切です。 先頭に置くなら番兵とは呼ばずにダミー要素と呼ぶべき。 そして、仮に番兵/ダミー要素を使うのであれば、その番兵/ダミーも malloc() でとっておくべきです。 [813] で書いたとおり auto な番兵/ダミーを用意するのは大きな間違いです。 マルチプルインスタンスを実現しようとして list* root1=create_list(...); list* root2=create_list(...); 等と直したくなった場合に破綻します。 んで、この程度の話は [813] で紹介した先にて述べられ済みなのですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[835] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

>なるほど!! >ありがとうございます >void free_list(list *start)の内容を見て、なっとくっす。 >チェーンをたぐりよせてmalloc()で取った領域を開放を繰り返し >NULLが来て、解放終わりって感じですね。 >すっごいわかりました。本当にありがとうございました。 void free_list(list *start) { list *curr, *temp; for (curr = start->next; curr != NULL;) { temp = curr->next; free(curr); curr = temp; } start->next = NULL; } あとで気がついたのですが、最後の行 start->next = NULL; という一行も入れておいた方が良いです。 これをしておかないと、freeした後に間違えて staのnextの参照や書き込みを行った場合問題となります。 参照をしたタイミングではオブジェクトはなくても ポインタの値は残っていて(ダングリングポインタと言います) 不正なアクセスとなります。 これは、問題の原因があるところと問題の発生位置 (別のところでアクセスバイオレーションになったりする) がずれる可能性があるため、気づきにくいバグとなります。 ここら辺の知識はポインタ関係ですので、(ぱ)さんの 「C言語ポインタ完全制覇」はかなりお勧めです。 私もこの本に早く出会っていればもっと早くレベルアップ できたのにと思っています。 http://www.amazon.co.jp/exec/obidos/ASIN/4774111422/qid=1141917620/br=3-1/br_lfncs_b_1/249-0186723-6715515
[この投稿を含むスレッドを表示] [この投稿を削除]
[834] Re:マスタングさんへ
投稿者:負け組一号
2007/02/20 02:13:25

> >void free_list(list *start) { > list *curr, *temp; > > for (curr = start->next; curr != NULL;) { > temp = curr->next; > free(curr); > curr = temp; > } >} > >これで、以下のように呼び出せます。 >free_list(start); > >先ほどの例だと、以下のように呼び出さないといけません。 >free_list(start->next); >もしくは、 >free_list(sta.next); なるほど!! ありがとうございます void free_list(list *start)の内容を見て、なっとくっす。 チェーンをたぐりよせてmalloc()で取った領域を開放を繰り返し NULLが来て、解放終わりって感じですね。 すっごいわかりました。本当にありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[833] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

すいません。見落としてました。 free(start)はエラーになったということで、 startは、staをさしている訳で、エラーの原因はstaは 動的に確保されたオブジェクトではないからです。 774RRさんがおっしゃっていたようにstaは番兵ですね。 ですので、以下が正解です。 void free_list(list *start) { list *curr, *temp; for (curr = start->next; curr != NULL;) { temp = curr->next; free(curr); curr = temp; } } これで、以下のように呼び出せます。 free_list(start); 先ほどの例だと、以下のように呼び出さないといけません。 free_list(start->next); もしくは、 free_list(sta.next);
[この投稿を含むスレッドを表示] [この投稿を削除]
[832] Re:マスタングさんへ
投稿者:マスタング
2007/02/20 02:13:25

>自分自身、リストの有用性自体をはっきりわかってないと思っています。 >せいぜい「線形リストなら、文字を打ち込んで行ってもチェーンのつなぎ換えで >ソートできて便利だな~」という程度の知識です。 リンクリストは、要素(サンプルの場合、list)を削除する処理が 配列に比べて早いというのが一般的に言われています。 ですので、要素の追加や削除を頻繁に行う場合は有用かもしれないですが、 実のところ、データ構造は配列が一番便利ですし、ツリーやキューなど の方が良いケースもありますので、リンクリストが有用な場面は少ない かもしれないです。 私は、Cで動的に要素を追加するのにリンクリストを使ってたり しましたが、C++ならvectorで動的な追加ができるので C++ならlist(リンクリスト)を使う場面は少ないかもしれません。 あとCでハッシュの実装をする場合は、リンクリストはよく使います。 また、ソートに関しては基本的にリンクリストより配列の方が早いと思います。 と言うのも、例えばクイックソートを使うならランダムアクセスが必要になるので そもそもリンクリストでは(クイックソートは)無理です。 ソートする必要があるなら、配列を使うべきだと思います。 >>関数でfreeするなら、引数でstartを渡してあげればOKです >で、free(start)してみたら、エラーになってしまい、ただ >free(start->next)としたら通りました。 >まぁ、free(start)が通らないのは、僕の理解不足からくる見当違いな事をしてるせい >だと思いますが、free(start->next)としたとき、チェーンで繋がった先のNULLに至るまで >にmalloc()で割り当てたそれぞれのメモリ領域も解放してくれるのかが僕の理解不足の >点です。free(start->next)したとき、next側のメモリだけ解放され、後に続く >NULLまでのmalloc()で取った領域は動かされず、残ったままなら これは私の言葉足らずでしたが、例えば、以下のような関数を作成してやれば OKです(テストしてないですが多分OKだと思います)。 void free_list(list *start) { list *curr, *temp; for (curr = start; curr != NULL;) { temp = curr->next; free(curr); curr = temp; } } で、呼び出し側は、free_list(start)とやれば良いので、 startという変数(の管理)が大事だと言った訳です。 >まだ、ちゃんと理解できてないと自分自身思いますので、まだまだ精進精進だと思って >います。 アルゴリズムとデータ構造は奥が深いですが、このぐらいはまだまだ入門です。 C言語でのアルゴリズムの専門的な本を購入されて読むことをお勧めします。 C++では標準ライブラリで基本的なデータ構造は用意されているのですが、 データ構造の基本的な知識がないときちんとした理解ができないので プログラミングの知識と経験はこつこつと積み上げていくしかないと思っています。 仕事レベルですと、「基本」を押さえておくことが非常に重要になりますし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[831] マスタングさんへ
投稿者:負け組一号
2007/02/20 02:13:25

レスありがとうございます 返信遅くてすいませんでした。 自分自身、リストの有用性自体をはっきりわかってないと思っています。 せいぜい「線形リストなら、文字を打ち込んで行ってもチェーンのつなぎ換えで ソートできて便利だな~」という程度の知識です。 ところで >負け組一号さんのサンプルで、startという変数が重要になります。 >どこかで(例えば関数で)free処理をするのでしょうが、 >start変数は、listの先頭を表していますので、これさえあれば >listにつながっているデータは全てfreeできます。 >関数でfreeするなら、引数でstartを渡してあげればOKです で、free(start)してみたら、エラーになってしまい、ただ free(start->next)としたら通りました。 まぁ、free(start)が通らないのは、僕の理解不足からくる見当違いな事をしてるせい だと思いますが、free(start->next)としたとき、チェーンで繋がった先のNULLに至るまで にmalloc()で割り当てたそれぞれのメモリ領域も解放してくれるのかが僕の理解不足の 点です。free(start->next)したとき、next側のメモリだけ解放され、後に続く NULLまでのmalloc()で取った領域は動かされず、残ったままなら マスタングさんの言う >現在のlistのnextの情報を先にとっておきます。 >そして、現在のlistをfree()します。 >その処理を現在のカーソルがNULLになるまで繰り返します。 >つまり、nextがNULLになるまで繰り返すのです。 という方法になるのか。と納得を得たしだいです。 まだ、ちゃんと理解できてないと自分自身思いますので、まだまだ精進精進だと思って います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[830] Re:elsif と else if
投稿者:奈々氏
2007/02/20 02:13:25

XSLTという言語では、if文にelse節はありません。 以下のようにあくまでif文しか書けないような言語仕様になっています。 <xsl:if test="...."> <!-- 何らかの処理 --> </xsl:if> 多分岐には、choose文(Cで言うところのswitch文)を使えという言語仕様になってますね。 <xsl:choose> <xsl:when test="...."> <!-- 何らかの処理 --> </xsl:when> <xsl:otherwise> <!-- 何らかの処理 --> </xsl:otherwise> </xsl:choose> これはこれですっきりしていて、キレイだと思います。 >>>then節とelse節で書けるものが違う、とか、if文だけ特別扱い、とか >> >>やっぱりこれを汚いと思う人が多いからではないでしょうか。 >> >>汚いかどうかは主観の問題ですけど、私なら、if文だけ特別扱いするくらいなら、 >>elsifを導入します。 > >なるほど。参考になります。 > > >>確かに、Cプログラマで、Cにはelse ifという特別な構文があると思っている人は >>少なくなかったですから、 > >私が初めて買ったCの入門書には「if文は入れ子を避けるために二分岐処理に限定してswitch文の使用を検討しろ」というようなことが書いてありました。 >「else節にif文を直接書く」という発想は知らなければ出てこないものなのかもしれませんね。 > > > >#つか金返せやゴルァ
[この投稿を含むスレッドを表示] [この投稿を削除]
[829] ありがとうございます。
投稿者:初心者
2007/02/20 02:13:25

奈々氏 さん、(ぱ) さん、マスタング さん へ ご返信ありがとうございます。 頂いた情報がかなり参考になりそうです。 とにかく感謝します、これから徹夜でサイトや資料を読みます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[828] Re:elsif と else if
投稿者:NykR
2007/02/20 02:13:25

>>then節とelse節で書けるものが違う、とか、if文だけ特別扱い、とか > >やっぱりこれを汚いと思う人が多いからではないでしょうか。 > >汚いかどうかは主観の問題ですけど、私なら、if文だけ特別扱いするくらいなら、 >elsifを導入します。 なるほど。参考になります。 >確かに、Cプログラマで、Cにはelse ifという特別な構文があると思っている人は >少なくなかったですから、 私が初めて買ったCの入門書には「if文は入れ子を避けるために二分岐処理に限定してswitch文の使用を検討しろ」というようなことが書いてありました。 「else節にif文を直接書く」という発想は知らなければ出てこないものなのかもしれませんね。 #つか金返せやゴルァ
[この投稿を含むスレッドを表示] [この投稿を削除]
[827] Re:C言語サブセットについて
投稿者:奈々氏
2007/02/20 02:13:25

『UNIXプログラミング環境』という本の第8章にhocという簡易プログラミング言語を yaccとlexを用いて徐々に機能を追加して開発する過程が解説されています。 本書の著者の一人はBrian W. Kernighan、あの『プログラミング言語C』の著者なので、 かなり信用のおける内容だと思います。 ただし、yaccとlexそのものについてはあまり詳しく解説していません。 あと、『コンパイラの理論と実現』という本には、C-というC言語からいくつかの 機能を取り除いた言語のコンパイラの作成方法が解説されていたと思います。 どちらもソースコード付きなので、オススメです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[826] Re:C言語サブセットについて
投稿者:(ぱ)
2007/02/20 02:13:25

訂正(?) >昔、「yacc/lex―プログラムジェネレータonUNIX」という本があって、この本には >・変数はA-Zだけ。配列なし。 >・バイトコードコンパイル方式。 >という簡易言語のサンプルが載っていました。 この本は、昔、啓学出版から出てたと思うんですが(小さめの版形で、半透明の カバーがかかってた奴)、今ぐぐるとテクノプレスから出ています。著者は同じだし、 内容も同じじゃないかと思うんですが。 ついでにこんなのも見つかりました。 http://www.watalab.cs.uec.ac.jp/tinyCabs.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[825] Re:C言語サブセットについて
投稿者:(ぱ)
2007/02/20 02:13:25

>flexとbissonで言語を作ってみようと思った人ですが。このページを読むと本当に勉強になりました。 どうもです。 >今、crowbarのソースを読んでますが、初心者なので、これよりもっとシンプルのソースあるでしょうか。 単にcrowbarより簡単なソースなら、うちのページにある(マスタングさんも挙げられた) 「電卓を作ってみよう」のcalcなんかがよいかもしれませんけれども。 ただし、作りたいものが「外面がCっぽい言語」なのか、「中の動きがCっぽい言語」で あるかによって、作り方は相当変わってきます。たとえばcrowbarは配列をヒープに 確保しますけど、内部的な動作を含めてCっぽい言語を作りたいのなら、配列もスタックに 確保すべきでしょう。内部的な動作を含めてCっぽい言語を作ったほうが、Cの理解が 深まる、という利点もあります。 >例え、データ型 intしかない、論理演算 if else while for <>= +-* /しかできるC言語サブセットのソース例はあるでしょうか。教えてください。よろしくお願いいたします。^^ 昔、「yacc/lex―プログラムジェネレータonUNIX」という本があって、この本には ・変数はA-Zだけ。配列なし。 ・バイトコードコンパイル方式。 という簡易言語のサンプルが載っていました。 また、「yaccによるCコンパイラプログラミング」 http://www.context.co.jp/~cond/books/yacc-book.html には、8086で動作する簡単なCコンパイラのソースが載っていました(構造体がない くらいで、ほぼCコンパチだったような気がします)。 でも、今はどちらも入手できないと思います。図書館とか会社の書庫とかで 探してみるのがよいのではないでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[824] Re:elsif と else if
投稿者:(ぱ)
2007/02/20 02:13:25

>if文のぶら下がり文に関してふと思いついたんですが、 >本体にブロックを強制する場合でも >else節にだけ、if文も書けるようにすればelsif(elif, elseif)というようなキーワードを導入しなくても困りませんよね? なるほど。確かに構文規則を以下のようにいじってbisonにかましてみましたが、 特にconflictは起きませんでした。 if_statement: IF LP expression RP block | IF LP expression RP block ELSE block | IF LP expression RP block ELSE if_statement | IF LP expression RP block elsif_list | IF LP expression RP block elsif_list ELSE block | IF LP expression RP block elsif_list ELSE if_statement >文法が微妙に汚くなるからでしょうか >then節とelse節で書けるものが違う、とか、if文だけ特別扱い、とか やっぱりこれを汚いと思う人が多いからではないでしょうか。 汚いかどうかは主観の問題ですけど、私なら、if文だけ特別扱いするくらいなら、 elsifを導入します。 確かに、Cプログラマで、Cにはelse ifという特別な構文があると思っている人は 少なくなかったですから、elseの後のif文だけ特別扱いしてもさほど混乱はないのかも しれませんけど、「Cにはelse ifという特別な構文があると思っている人」が 周囲にたくさんいた私としては、そういう人への啓蒙もこめてelsifを導入した、 という意図もあったようななかったような。
[この投稿を含むスレッドを表示] [この投稿を削除]
[823] Re:C言語サブセットについて
投稿者:マスタング
2007/02/20 02:13:25

>flexとbissonで言語を作ってみようと思った人ですが。このページを読むと本当に勉強になりました。 >今、crowbarのソースを読んでますが、初心者なので、これよりもっとシンプルのソースあるでしょうか。 >例え、データ型 intしかない、論理演算 if else while for <>= +-* /しかできるC言語サブセットのソース例はあるでしょうか。教えてください。よろしくお願いいたします。^^ crowbar 0.1のソースや「プログラミング言語を作る」の"電卓を作ってみよう"は 参考にならないでしょうか? また、初心者さんが求めている内容とは少し違いますが、 以下のものはどうでしょうか? 1) yacc入門講座(簡単な説明) http://www.tokumaru.org/yacc/index.htm 2) Bison入門(リファレンス) http://guppy.eng.kagawa-u.ac.jp/~kagawa/2000/SysProg/bison-1.2.8/bison-ja_toc.html 3) Flex(リファレンス) http://www.asahi-net.or.jp/~wg5k-ickw/html/online/flex-2.5.4/flex_toc.html 4) lex&yaccプログラミング(残念ながら日本語版は売り切れなようです) http://www.amazon.co.jp/exec/obidos/ASIN/4756102972/qid=1141565795/br=3-2/br_lfncs_b_2/249-0186723-6715515 5) いまどきのプログラム言語の作り方(Javaで再帰下降型パーサの実装です) http://www.amazon.co.jp/exec/obidos/ASIN/4839919232/qid=1141567196/br=3-1/br_lfncs_b_1/249-0186723-6715515 私も興味ありますので、何か良いサイトや参考書などあれば 逆に教えてください。 あくまでもflexやbison(yaccやlex)にこだわるなら 私は、ドラゴンブックやタイガーブックなどより先に、 yaccやlexをある程度理解しておくことが重要だと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[822] C言語サブセットについて
投稿者:初心者
2007/02/20 02:13:25

flexとbissonで言語を作ってみようと思った人ですが。このページを読むと本当に勉強になりました。 今、crowbarのソースを読んでますが、初心者なので、これよりもっとシンプルのソースあるでしょうか。 例え、データ型 intしかない、論理演算 if else while for <>= +-* /しかできるC言語サブセットのソース例はあるでしょうか。教えてください。よろしくお願いいたします。^^
[この投稿を含むスレッドを表示] [この投稿を削除]
[821] Re:elsif と else if
投稿者:NykR
2007/02/20 02:13:25

># elseというキーワードはあるのにthen節であることを示すキーワードはない訳で 何を言ってるんだろ? ええと、ブロックを中括弧で表現する言語でelsifのようなものを使う言語の中には、elseはあるのにthen節を示すキーワードは存在しない、というようなものもある訳で、 と言いたかったんですね。多分(ぉ
[この投稿を含むスレッドを表示] [この投稿を削除]
[820] elsif と else if
投稿者:NykR
2007/02/20 02:13:25

if文のぶら下がり文に関してふと思いついたんですが、 本体にブロックを強制する場合でも else節にだけ、if文も書けるようにすればelsif(elif, elseif)というようなキーワードを導入しなくても困りませんよね? 何で世の中の多くの言語はそうなってないんでしょう? 文法が微妙に汚くなるからでしょうか then節とelse節で書けるものが違う、とか、if文だけ特別扱い、とか でも、then節とelse節を全く同じにする必要はないと思いますし、 # elseというキーワードはあるのにthen節であることを示すキーワードはない訳で # というのはちょっと苦しいか if文の中でif文を特別扱いするのもそんなに変なこととは思いません # うーん、気付いてないだけで何か他に問題があるんだろうか? # そこまでして else if と書けるようにするより、elsifを導入した方が簡単・・・でもないよなぁ。 どう思います?
[この投稿を含むスレッドを表示] [この投稿を削除]
[819] Re:長文すみません
投稿者:マスタング
2007/02/20 02:13:25

タイガー改めマスタングです。 私なりに思ったことを書いてみます。 まず思ったのは、自分が少しでも複雑だなと感じる処理を考える場合は、 図を書いてみると理解しやすいです。 掲示板では少々書きづらいので自分なりに紙にでも書いてみてください。 >線形リストif(sagyou->num < fo->next->num)が、他の参考書を見ながら打ってた時 >next->next->...->numという感じで全部比較して見てるのか?となぜか思い >それで、逐一アドレス表示させるようにしたりして、自分なりに疑問を解消しつつ >本当に、fo->next->numは、nextだけを見てるのかとまだ疑問だったんですが >実は言いますと、この投稿フォームに、その疑問を考えながら書いてる間に >「あれ、これって、for文で回して、単に比較してチェーン変えてるだけだ」 >と、なぜか、その場で気づいたのですが、やはり確認しておこうと思い書きました。 listが数珠つなぎになっていて、forループの中でのfo変数は、 イメージとして、カーソルを表しています。 カーソルが先頭から末尾まで1つずつ各listを指しながら動く感じです。 これは、例えば、for (i = 0; i < num; i++)の、「i」と似ています。 iは、0から(num - 1)まで値を変えながら進んで行きます。 これは、「処理」としては、同じなので抽象化(同じ扱い)ができ、 一般的に、こういったカーソルをiteratorと言います (若干厳密性はないかもしれないですが、イメージはそんな感じだと思います)。 >free()に関しては、リストでmalloc()を使うのは解るが、それらをfree()にする >タイミングがよくわからなかったんですが、リストにして結果をはき出したら >またチェーンでたどってfree()にするのかなとか、まぁ、その、まだまだ >例題をみながら打ち込みながら理解しつつ、昨日覚えた事を今日忘れるような >日々つれづれとおくっておりまして、、、 負け組一号さんのサンプルで、startという変数が重要になります。 どこかで(例えば関数で)free処理をするのでしょうが、 start変数は、listの先頭を表していますので、これさえあれば listにつながっているデータは全てfreeできます。 関数でfreeするなら、引数でstartを渡してあげればOKです。 つまり、どこでfreeするかはユーザの自由ですが、freeするタイミングまで start変数を管理できていればOKな訳です。 start変数を管理(保持)する方法としては、ある関数内(ローカル)に持ち歩くか、 static変数(あるいは、グローバル変数)などで持っておくかの どちらかになると思います。 もちろん、別のデータ(構造)内に保持していても同じです。 freeするタイミングは重要ではないと思うのですが、 言えることがあるとすれば、いらなくなった時です。 >ただ、nextポインタがNULLになってるポインタを順次free()していけば出来るのかな >と思い、試してみます。 これは、違います。 nextポインタがNULLであろうが、NULLでなかろうが、 現在、カーソルが指しているlistをfree()します。 しかし、現在指しているlistをfree()してしまうと、 listに入っているnextの(ポインタの)情報がとれなくなってしまうので、 現在のlistのnextの情報を先にとっておきます。 そして、現在のlistをfree()します。 その処理を現在のカーソルがNULLになるまで繰り返します。 つまり、nextがNULLになるまで繰り返すのです。 まだ不明な点があればいくらでも聞いてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[818] Re:長文すみません
投稿者:負け組一号
2007/02/20 02:13:25

確かに、おっしゃるとおりっす。 自分の文章は、論理的に書けてないですね。 とにかく、もっとソースを体当たりで打ち込んで理解を深めます。 その上で、ポインタ関連で疑問が生じたら書き込みささしてもらいます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[817] Re:長文すみません
投稿者:本多
2007/02/20 02:13:25

あまり本質的な議論には参加してないくせに言うのもおかしいかもしれませんが少しだけ。 負け組一号さんは、一つの文章を短く切った方が文章の意味がわかりやすくなると思います。 「それが私の文章の味」とか言われちゃうと、それまでなのですが、 技術的な文章は、わかりやすさ重視でしょう。 なんとなく古文の授業を思い出してしまいます。 さて(ぱ)さんへのコメント中に 「どうfree()して行けば良いのかが解らない」とおっしゃってますが、 「どこでfree()というやつで解放してやれば良いのでしょうか」という質問では 求める答えが得られないのはお解かりでしょうか。 「方法」がわからないときに「記述する位置」を質問しても求める答えは得られないのは自明でしょう。 わからないことが「考え方や根拠」「概念」「方法」「動作原理」の どれなのかを分類するといいと思います。 少々きつい言葉で批判めいたことを書きましたが 自分自身の経験から「わからないことが何か」を理解した段階で 自然に「理解できる」場合が多いように思えます。 その一助として 「自分がわからない事柄は『方法』なのか?『考え方』なのか?『動作原理』なのか?」 と自問することは重要だと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[815] 長文すみません
投稿者:負け組一号
2007/02/20 02:13:25

774RRさん、(ぱ)さん、返信ありがとうございます。 線形リストif(sagyou->num < fo->next->num)が、他の参考書を見ながら打ってた時 next->next->...->numという感じで全部比較して見てるのか?となぜか思い それで、逐一アドレス表示させるようにしたりして、自分なりに疑問を解消しつつ 本当に、fo->next->numは、nextだけを見てるのかとまだ疑問だったんですが 実は言いますと、この投稿フォームに、その疑問を考えながら書いてる間に 「あれ、これって、for文で回して、単に比較してチェーン変えてるだけだ」 と、なぜか、その場で気づいたのですが、やはり確認しておこうと思い書きました。 free()に関しては、リストでmalloc()を使うのは解るが、それらをfree()にする タイミングがよくわからなかったんですが、リストにして結果をはき出したら またチェーンでたどってfree()にするのかなとか、まぁ、その、まだまだ 例題をみながら打ち込みながら理解しつつ、昨日覚えた事を今日忘れるような 日々つれづれとおくっておりまして、、、 とりあえず、まだまだ、打ち込んで、理解を深め、この劣化した脳に新たなメモリを 加えたく(脳の細胞は再生しないが、新生はするらしいので)思いつつ、今度は ちゃんと何が解らないのかが解らない状態で質問せず、何が解らないか解るよう 質問(甘え)さしてもらいたいです。 上記の文を書いて、ポインタ完全制覇を読み直した結果、駄目じゃん俺と再認識 >>774Rさん >提示コードは先頭に追加される必要がある場合にうまくない。 >それとも最初に作ってる sta は番兵? 番兵の意味を聞かれて、持ってる書籍を見て初めて意味を知りました。番兵って奴です。 >一番最初の1個目を作る場合と、末尾に追加する場合とが特殊なわけだ。 >でも、実際には特殊ではなくて、ロジック上真ん中に挿入の場合と同じに扱える >ということが理解できるかどうかが肝 まだまだ、理解は出来るが、「さぁ作れ」と言われたら悩んでしまうレベルです。 >>(ぱ)さん >「どうわからないのか」をもう少し具体的に書いていただけませんか。 わからない部分は線形リストでmalloc()で割り当てて行った領域をどうfree()して行け ば良いのかが解らないといった感じです。 ただ、nextポインタがNULLになってるポインタを順次free()していけば出来るのかな と思い、試してみます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[814] Re:(ぱ)さんに甘えさして頂きます
投稿者:(ぱ)
2007/02/20 02:13:25

どうも、(いつものことですが)「何がわからないのか」がわからないので 答えようにも困ってしまうわけですが。 >    if(sagyou->num < fo->next->num ) >の、fo->next->numは、その時点でのfoのnext側のnumを見てる >と捉えて良いのでしょうか。 この質問にYesかNoかで答えれば、(774RRさんが書いておられるように)「Yes」と 答えるしかないわけですが、疑問に思ったからには、何か引っかかるところが あるわけでしょう。 ->は所詮演算子なので、 p = fo->next->num; として「foのnext側のnumを見」る代わりに、 temp = fo->next; p = temp->num; と書いてもよいし、 fo->next->numの代わりに(fo->next)->numと書いても構わないわけですが、 こうやって書き換えると感覚的にわかりやすくなったりしますかね。 >ついで、malloc()で得たメモリは >どこでfree()というやつで解放してやれば良いのでしょうか。 これも、「要らなくなったとき」としか答えようがないのですが、 そんなことは入門書にも書いてあるはずで、それでわからなかったから 質問しているわけでしょう。 「どうわからないのか」をもう少し具体的に書いていただけませんか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[813] Re:線形リスト
投稿者:774RR
2007/02/20 02:13:25

リスト構造自体はそんなに難しいものではなくて、単に数珠つなぎになってるだけ。 例えば http://www9.plala.or.jp/sgwr-t/c/sec15-5.html 演習のほうも見てみませう。 提示コードは先頭に追加される必要がある場合にうまくない。 それとも最初に作ってる sta は番兵? 番兵にせよなんにせよ今のままでは sta が auto なのでまずいけど。 >fo->next->numは、その時点でのfoのnext側のnumを見てる もちろん >どこでfree()というやつで解放してやれば良いのでしょうか。 要らなくなったとき。 malloc() するってことは、当座しばらくは必要だから保持しとけ、ということ。 例えばワード等で文章を開いたときなんかにこうやって文書データを保持してるわけだ。 free() するのは文章を閉じたときとかワードを終了するときとか。 提示コードであればリストを破棄するのは main 終了直前でしょうな。 こういうのはポインタに関する「文法理解」ではなくてむしろ「アルゴリズム理解」の話。 線形リストの場合「真ん中に挿入」する場合がいちばん簡単で、紹介先の図のとおり。 一番最初の1個目を作る場合と、末尾に追加する場合とが特殊なわけだ。 でも、実際には特殊ではなくて、ロジック上真ん中に挿入の場合と同じに扱える ということが理解できるかどうかが肝。
[この投稿を含むスレッドを表示] [この投稿を削除]
[812] (ぱ)さんに甘えさして頂きます
投稿者:負け組一号
2007/02/20 02:13:25

レス頂き、ありがとうございました。 そんで、(ぱ)さんに、甘えた質問さしていただきます。 ソースなんで長いですが自分でリストを理解しようと改造した線形リストです。 typedef struct list {     int num;     struct list *next; }list; int main() {     list sta ={0,NULL};     list *start = &sta; /*先頭*/     list *sagyou; /*作業領域*/     list *fo; /*for用*/     char str[16]; /*入力用*/     while(1) {         printf("整数を入力(Eで終了)-->");         gets(str);         if(strcmp(str,"E") != 0){//strcmpは文字列の比較             sagyou = (list *)malloc(sizeof(list));             if(sagyou == NULL ){                 printf("メモリ確保できず\n");                 exit(1);             }         }         else break;         sagyou->num = atoi(str);//atoiは文字列をint型に変換する         for(fo = start; fo->next != NULL; fo = fo->next){             if(sagyou->num < fo->next->num ){                 sagyou->next = fo->next;                 fo->next = sagyou;                 break;             }         }         if(fo->next == NULL){             fo->next = sagyou;             sagyou->next = NULL;         }     } で、上のリストで、数字を大きい順にしようとするとき for(fo = start; fo->next != NULL; fo = fo->next){     if(sagyou->num < fo->next->num ) の、fo->next->numは、その時点でのfoのnext側のnumを見てる と捉えて良いのでしょうか。ついで、malloc()で得たメモリは どこでfree()というやつで解放してやれば良いのでしょうか。 線形リスト、双方向リスト等、及び二分木探索などの例ばかりが 載ってる書籍を探しても、あるのは入門書ばかりで、初心者 から脱皮できない自分に負い目を感じる今日このごろです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[811] Re:カナダで「ほげ通り(HOGE ST.)」を見つけました
投稿者:マモル
2007/02/20 02:13:25

>情報ありがとうございます。後ほど「ほげを考えるページ」に追加情報として >挙げさせていただきます。 ありがとうございます。リンクにスペースが入ってリンク切れのようになっていました。もう一度リンクを書き込ませて頂きます。スイマセン…。 http://ameblo.jp/mamoru/entry-10009422221.html >リンクはどのページにもご自由にどうぞ。 勝手な書き込みでしたが、丁寧に対応して頂いてありがとうございました。 ではっ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[810] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

なんとなくネタ的に面白いので追加検証。gcc ならソースコードがあるので読んでみた。 gcc-3.4.5 を追っかけ。 gcc-4 では大幅な変更が入っているので変わっているかもしれない。 int array[1]; array=0; なるソースコードに対する挙動 C の場合 gcc/c-typeck.c Line 3677 でエラーメッセージを出力 これは convert_for_assignment() 関数の末尾である。この関数の先頭部分で if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE) rhs = default_conversion (rhs); なるコードが実行されている(すなわち右辺はデフォルト変換が実施されている) のに対して左辺のデフォルト変換を行うコードは見当たらない。 =代入式の左辺においては「配列名を先頭へのポインタに読み替える」変換は実施していない C++ の場合 gcc/cp/typeck.c Line 5295 でエラーメッセージを出力 これは build_modify_expr() 関数の一部であり if (TREE_CODE (lhstype) == ARRAY_TYPE) の内側にある。この例では右辺左辺の型が異なるのでこのエラー。 もし array=array; であるなら、型一致なのでこの行ではなく先に進んで ISO C++ forbids assignment of arrays エラーが発生。 いずれにせよ左辺のデフォルト変換を行う関数は呼ばれていない。
[この投稿を含むスレッドを表示] [この投稿を削除]
[809] Re:カナダで「ほげ通り(HOGE ST.)」を見つけました
投稿者:(ぱ)
2007/02/20 02:13:25

>はじめまして。マモルと申します。 はじめまして。 >カナダのホワイトホースという町で「ほげ通り(HOGE ST.)」を見つけました↓。 > >http://ameblo.jp/mamoru/entry-10009422221.html 情報ありがとうございます。後ほど「ほげを考えるページ」に追加情報として 挙げさせていただきます。 >hoge研究の参考になれば嬉しく思います。また、誠に勝手ながら「ほげを考えるページ 」に無断でリンクを張らして頂きました。もし不都合があればリンクを削除いたします。 リンクはどのページにもご自由にどうぞ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[808] Re:左辺値としての配列名
投稿者:(ぱ)
2007/02/20 02:13:25

774RRさん: >ところで JIS X 3010 は 2003 版が発行済で 2003 版には 6.2.2.1 が無かったです。 >引用元は 1990 版でしょうか? そうです。 NykRさん: >私自身は「変換する」と書いてあるんだから変換するんだろうと思ってますが、 >例えばこんなコードをgccでコンパイルすると コンパイラがそう実装するのは当然なので、特定の3つのケースを除き「変換する」と 書いてありそれに含まれないのだから(文法上は)変換すると解釈するのが自然だろうと 私は思いますが、変換するかどうかはさておき、代入できない理由としては、 「変更可能な左辺値ではないから」という理由も挙げておくべきであるように 思います。今は無理ですが、近々Web上で対応します。 >ついでに、K&Rの附録Aでは制約が書き加えられて変換しないことになっています。 日本語版p.245ですね。規格と違う説明をするのはいかがなものかと思いますが… ポインタ完全制覇を書いているとき、これに気付いてなかったのかなあ… 今となってはすっかり忘れています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[807] カナダで「ほげ通り(HOGE ST.)」を見つけました
投稿者:マモル
2007/02/20 02:13:25

はじめまして。マモルと申します。 カナダのホワイトホースという町で「ほげ通り(HOGE ST.)」を見つけました↓。 http://ameblo.jp/mamoru/entry-10009422221.html hoge研究の参考になれば嬉しく思います。また、誠に勝手ながら「ほげを考えるページ 」に無断でリンクを張らして頂きました。もし不都合があればリンクを削除いたします。 ではっ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[806] 管理者により削除されました
2007/02/20 02:22:36

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[805] Re:左辺値としての配列名
投稿者:NykR
2007/02/20 02:13:25

私自身は「変換する」と書いてあるんだから変換するんだろうと思ってますが、例えばこんなコードをgccでコンパイルすると int main(void) { int a[1]; a++; return 0; } array_inc_test.c: In function `main': array_inc_test.c:4: wrong type argument to increment と、型に問題がある、というメッセージが表示されます。 a++を(&a)++と、ポインタ値のインクリメントに置き換えると array_inc_test.c:4: invalid lvalue in increment と表示されますからgccではaはポインタではないみたいです。 ついでに、K&Rの附録Aでは制約が書き加えられて変換しないことになっています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[804] 管理者により削除されました
2007/02/20 02:22:56

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[803] 管理者により削除されました
2007/02/20 02:23:12

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[802] 管理者により削除されました
2007/02/20 02:23:48

意味不明の投稿なので削除しました。
[この投稿を含むスレッドを表示]
[801] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

あう sizeof は右辺値でもいいのか。 だったら「sizeof の係る式が左辺値の場合には右辺値変換するな」って旨を コンパイラ作者に通知する条文でもあるわけだな。 結論は変わらん。
[この投稿を含むスレッドを表示] [この投稿を削除]
[800] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

規格書の一部はコンパイラ作者向けに、一部はユーザ向けに書かれている。 で、当該項はユーザ向けだと、俺は思う。 俺がコンパイラ作るなら、左辺値が必要とされる文脈で右辺値変換するなんて無駄なことはしない。 単項 & や sizeof はまさに左辺値が必要とされるところであるから、そこで 無駄な右辺値変換を行わなければ規格書どおりの動作となるわけだ。 同じことが代入式の左辺でもいえる。 だから、俺的には配列名が代入式の左辺に現れたときに右辺値変換されるとは思わない。 「変更不可能」だから左辺におくとエラーと考えるほうが自然。 まあどう解釈しても結果は同じだからどうでもいいけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[799] Re:左辺値としての配列名
投稿者:yuya
2007/02/20 02:13:25

前橋さん、774RRさん、ありがとうございます。 > 配列に代入できないのは変更可能な左辺値ではないから なるほど、 「配列に代入できないのは、配列は左辺値だが変更不可能だから」 と考える必要はないんですね。 「『変更可能な左辺値』ではないもの」には、 「変更不可能な左辺値」だけでなく「右辺値」も含まれますから。 (a)変更可能な左辺値 (b)変更不可能な左辺値 (c)右辺値 (d)その他 に分けたとして、 ・「ポインタ完全制覇」での説明:    「配列に代入できないのは、(c)だから」 ・私が[796]で書いた説明:    「配列に代入できないのは、(b)だから」 ・おそらく最も正確な説明:    「配列に代入できないのは、(a)でないから」 「(a)でない」を満たしさえすれば 配列に代入ができないことには変わりなく、 その実態が(b)なのか(c)なのか、あるいは(d)なのかは 別問題である、ということですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[798] Re:左辺値としての配列名
投稿者:774RR
2007/02/20 02:13:25

char a[10]; char (*p)[10]=&a; // である場合に *p=0; あるいは *p={0}; であれなんであれ *p は代入式の左辺に置けません。 JIS X 3010:2003 6.5.16 代入演算子 [制約] 変更可能な左辺値でなければならない。 JIS X 3010:2003 6.3.2.1 変更可能な左辺値とは...[配列を含まない] なので >配列に代入できないのは変更可能な左辺値ではないから であり、それ以上でも以下でもないです。 ただしこの話はスレ題の「左辺値が要求される場所においても読み替えが起こるか」とは無関係。 無関係ではありますが、やはり同じく JIS X 3010:2003 6.3.2.1 型"~の配列"を持つ式は、型"~へのポインタ"の式に型変換する。 それは配列オブジェクトの先頭の要素を指し、左辺値ではない。 とありますから、スレ題に関して言えば「どちらでもいい」となります。 起こると解釈しても起こらないと解釈しても、いずれにせよ代入式の左辺に置けないことに違いは無い。 ところで JIS X 3010 は 2003 版が発行済で 2003 版には 6.2.2.1 が無かったです。 引用元は 1990 版でしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[797] Re:左辺値としての配列名
投稿者:(ぱ)
2007/02/20 02:13:25

>配列名は式の中では先頭要素へのポインタ(右辺値)に読み替えられる、 >という規則は、代入演算子の左側のような、 >「左辺値が要求される場所」においてもそうなのでしょうか? JIS X3010の6.2.2.1によれば、 | 左辺値がsizeof演算子のオペランド、単項&演算子のオペランド、文字配列を初期化 | するのに使われる単純文字列リテラルまたはwchar_tに適合する要素型をもつ配列を | 初期化するのに使われる文字列リテラルである場合を除いて、型"~型の配列"をもつ | 左辺値は、型"~型へのポインタ"を持つ式に型変換する。 とあります。 もし、代入演算子の左側のような「左辺値が要求される場所」においては配列から ポインタへの読み替えが行われないのだ、とするのなら、上記の3つの条件の中に 単項&演算子のオペランドを含める必要はないはずです。&演算子のオペランドは もともと左辺値が要求される場所だからです。 ということで、上記3つの箇所を除いて、(左辺値が要求されようがされまいが) 式の中では配列はポインタに読みかえられる、と解釈するのが自然ではないでしょうか。 # とはいうものの、「変更可能な左辺値」の定義からわざわざ配列が除かれている # ところからすると、配列に代入できないのは変更可能な左辺値ではないからだ、 # という解釈もできるような気が…
[この投稿を含むスレッドを表示] [この投稿を削除]
[796] 左辺値としての配列名
投稿者:yuya
2007/02/20 02:13:25

こんにちは。Cの「配列名」について、質問があります。 「ポインタ完全制覇」には、 char hoge[5]; hoge = "abcd"; がダメな理由は、hogeが右辺値だから、とあります。 配列名は式の中では先頭要素へのポインタ(右辺値)に読み替えられる、 という規則は、代入演算子の左側のような、 「左辺値が要求される場所」においてもそうなのでしょうか? 配列名は、右辺値(先頭要素へのポインタ)に読み替えられる前は、 配列オブジェクトそのものを表す変更不可能な左辺値なので、 「hoge = "abcd";がダメなのは、hogeは左辺値だけど変更不可能だから」 という説明であれば納得できるのですが、 どちらの説明が正しいのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[795] Re:ポインタってそんなに難しいか?
投稿者:774RR
2007/02/20 02:13:25

>ところで、ポインタの概念は難しくないですが、使いこなすのは大変だ 禿げ上がるほど御意。 むかーーーーしの自分のソースを見ると良くわかったりします。 >実行時に型情報を持っていると誤解する人が出そうです。 今までに扱ったCPU/コンパイラ全てで「実行時型情報をもつポインタ」って無いですね。 無駄っぽなので。ただ、規格書は何も言及してないので「あっても違反ぢゃない」です。 # CPU 何種類使っただろう? 両手ぢゃ足らんくらいだな。 メモリアドレスをどう扱うか、ソースレベルで指定してる。と言うべきだったかな。 C++ の dynamic_cast/typeid 系が扱う型情報は、ポインタ自体にではなく、 その指す先のオブジェクトにあるワケで、やはりポインタには型情報は無いな。
[この投稿を含むスレッドを表示] [この投稿を削除]
[794] Re:ポインタってそんなに難しいか?
投稿者:(ぱ)
2007/02/20 02:13:25

>タイトルのとおりなのですが、ポインタってそんなに難しいですか? 難しいのでは。少なくとも難しいと思う人がいるからこそポインタ本の需要が生まれ、 私が日々の酒代を稼ぐ余地が生まれたというものです。ありがたいことです(ぉぃ) >正確には「ポインタの概念が」難しいと思ったこと無いというべきかな。 >ポインタ関連の表記が難しいとは思ったけど。 これはそう思います。私のそのへんに関する認識は、以下のページの冒頭に書きました。 http://kmaebashi.com/programmer/pointer.html だからこそ、ポインタ完全制覇では、宣言の構文やら配列とポインタの関係やらに 力を入れたつもりなのでして、「負け組一号」さんがまだわからないところがあるのなら、 具体的にどこがどうわからないと言っていただければ、アドバイスできるかもしれませんし、 私にとっても参考になるわけなのですが。 ところで、ポインタの概念は難しくないですが、使いこなすのは大変だ、というのも ありますね。同じオブジェクトを複数箇所から指して思わぬ書き換えをしてしまったり、 Cだと、free()しすぎや領域破壊の危険も高いです。 >メモリアドレスに、その扱い方の情報を付帯してるだけぢゃん。 774RRさんは当然わかって書いていると思うのですが、この言い方だと、ポインタが 実行時に型情報を持っていると誤解する人が出そうです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[793] ポインタってそんなに難しいか?
投稿者:774RR
2007/02/20 02:13:25

タイトルのとおりなのですが、ポインタってそんなに難しいですか? 俺なんかは Z80 のアセンブラから入った口なので、ポインタが難しいと思ったこと無いです。 正確には「ポインタの概念が」難しいと思ったこと無いというべきかな。 ポインタ関連の表記が難しいとは思ったけど。 難攻不落なんて言うほどのものぢゃ糸色文寸無い。 メモリアドレスに、その扱い方の情報を付帯してるだけぢゃん。
[この投稿を含むスレッドを表示] [この投稿を削除]
[792] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

>もしsetjmp/longjmpがcreate_jmp()してから使うような形であったら、&なしがきれいですよね。 御意。 > 今まで考えなしに付けてなかったですけど、概念的には付けるべきだったのかしら。 俺なんかはその昔の &array が規定されてなかった頃からCをやってる人ですから 「配列名が先頭要素へのポインタに変換される」仕様が本能レベルで染み付いているので memset 等のポインタが必要な関数が使われてて引数に & が無い場合にはむしろ 「& がないから、これって配列なんだ」と解釈しがちな傾向がありますな。 # よく読んだら、ポインタ変数だったりすると後からびっくり。 概念的には & があるべきなのだと思う。ただ歴史的事情により 配列であることが明確な場合には & を書かないソースのほうが圧倒的多数だと思います。 > 例えば「配列へのポインタ」と「配列の先頭要素へのポインタ」の > 表現方法が異なるような処理系において > ...では、やっぱりmemset()の使用は推奨されないのかなぁ? void* は、内部表現が最大サイズとなるポインタを保持できなければならず、なおかつ、 必要な時には内部表現を失わずに元の型に戻せることが必須とされていますから、 問題ないです(問題あったら大変だ) # テスト略
[この投稿を含むスレッドを表示] [この投稿を削除]
[791] Re:ポインタ完全制覇
投稿者:本多
2007/02/20 02:13:25

#テストの(略) >>jmp_buf の場合は「set/longjmp で使うハンドル」と考えれば & なしにも違和感なし >handle = CreateWindow(...); >みたいなのだと思うので、戻り値ではなく引数で返すならやっぱり&が付くのではないかと。 もしsetjmp/longjmpがcreate_jmp()してから使うような形であったら、&なしがきれいですよね。 jmp_buf myjmp = create_jmp(); if ( (ret = setjmp(myjmp)) == 0 ) { ... } else { ... } ~略~ longjmp(myjmp, ret); >memset()の場合でも、&を付けない人のほうが多いんじゃないかなあ。 今まで考えなしに付けてなかったですけど、概念的には付けるべきだったのかしら。 例えば「配列へのポインタ」と「配列の先頭要素へのポインタ」の 表現方法が異なるような処理系において ...では、やっぱりmemset()の使用は推奨されないのかなぁ?
[この投稿を含むスレッドを表示] [この投稿を削除]
[790] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

# テストに反応してみるテスト >jmp_buf の場合は「set/longjmp で使うハンドル」と考えれば & なしにも違和感なし ハンドルといえば、 handle = CreateWindow(...); みたいなのだと思うので、戻り値ではなく引数で返すならやっぱり&が付くのではないかと。 >memset の場合は要求されるのが void* だから &array のほうが適切な場合多し >strcpy の場合は要求されるのが char* だから array と書かなきゃいけない >scanf+%s の場合も同様 memset()の場合でも、&を付けない人のほうが多いんじゃないかなあ。 適当にぐぐって見たけど付いてない例が多いようです。 http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_CRT_memset.asp http://www.cppreference.com/stdstring/memset.html >C/C++ はエラーメッセージの読み方が難しいのが減点ポイント (馬から落馬) まあ、エラーメッセージの良し悪しはコンパイラによるところもあるとは思いますが、 C言語自体が多様な書き方を許すためにエラーメッセージがわかりにくくなるところは ありますね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[789] Re:難解不落のポインタ すべてはプログラマにゆだねられ プログラマはポインタに揺らされる
投稿者:(ぱ)
2007/02/20 02:13:25

>char* p,p2; >とするとp2は >char p2;となってしまうと理解させていただいています。 この問題だけであれば、一度に複数の変数を宣言するなゴルアで回避できるのですが、 Cではたとえば配列なども型の一部ですから、どっちみち 型 変数名; の形では変数宣言を解読できないんですね。CESさんが出した問題がそうであるように。
[この投稿を含むスレッドを表示] [この投稿を削除]
[788] Re:面白い本を探しているのですが……
投稿者:(ぱ)
2007/02/20 02:13:25

>前橋さんの本やこのホームページは、 >扱っている技術の内容が高く、 >現場のプログラミングにおいても、 >ものすごく役に立つのでよく見ています。 ありがとうございます。 >さて、私も「Java謎+落とし穴」を最近読んだのですが、 >少し内容が古くなってきたように感じます。 これは確かにそう思います。 >特に進化のスピードが速いJavaでは、 >本書で前橋さんが苦言を呈している >ジェネリックやenumなどの機能については、 >現在、ほとんど盛り込まれています。 そうですね。 >そこで、ここ最近、話題になっている? >「疑い深いあなたのためのオブジェクト指向再入門」 >の内容に加筆したものを新規に書き起こして、 >加筆修正した改訂版を出してはどうでしょうか。 >(単に私が読みたいだけですが。) 「疑い深いあなたのためのオブジェクト指向再入門」にあることは、言いっぷりは ともかくとして「謎+落とし穴」にも書いたつもりですから、J2SE5.0対応の改訂版、 ということになるのだと思いますけれど。 書いてみたいネタではあります。ただ、J2SE5.0は仕事で使っていないので、 本が書けるところまで私自身わかっているか、という問題はありますね。 # 仕事じゃまだまだJDK1.3が現役だったりします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[787] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

# あれこれ言ってみるテスト jmp_buf の場合は「set/longjmp で使うハンドル」と考えれば & なしにも違和感なし なまじ buf という文字列が見えてしまっているのが名前付けに失敗した例と思う memset の場合は要求されるのが void* だから &array のほうが適切な場合多し strcpy の場合は要求されるのが char* だから array と書かなきゃいけない scanf+%s の場合も同様 GCC はフォーマット文字列がリテラルな場合に警告してくれます。 scanf("%s", &buf); に対して gcc -Wformat hoge.c で piyo.c:4: warning: char format, different type arg (arg 2) みたいに。 C/C++ はエラーメッセージの読み方が難しいのが減点ポイント (馬から落馬) たいていの原因はエラー表示のある行の直前にあったりするし。 template 多用時は俺でもエラー判別がめんどくさかったりするですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[786] 難解不落のポインタ すべてはプログラマにゆだねられ プログラマはポインタに揺らされる
投稿者:負け組一号
2007/02/20 02:13:25

Thank you for res. >char *p; > >よりも > >char* p; > >と書くほうがわかりやすい、という意味でしょうか? >それはそれで否定しませんが、それで問題は解決しない、ということもポインタ完全制覇は これについては、著書で理解しております。 char* p,p2; とするとp2は char p2;となってしまうと理解させていただいています。 あと、char *p;としてprintf("%p",p);としたとき参照されてない というエラーがでましたが、まぁ、ただ、もう理解してますので、蛇足です。 あと、他の言語では、配列とポインタは、”ほぼ別格”というのは、新たな知識として ありがとうございます。 とりあえず、今は構造体のリストを理解するために、脳をこねくりまわしている状態です。 しっかし、まぁ、I study hard and more hard to purogramming-Cってなことですな~ ついでの蛇足で int dt = (a = 20,b=10);とすると dt=10となるなんていう、たぶん一生必要ない知識ですが、まぁ、なんというか・・・ 色々あるな~・・・と思う、日々。 年々歳々花相似たり、年々歳々人同じからず
[この投稿を含むスレッドを表示] [この投稿を削除]
[785] Re:面白い本を探しているのですが……
投稿者:七氏
2007/02/20 02:13:25

>>こんにちは。はじめまして。 >>Java謎+落とし穴を読ませていただきました。 > >どうもです。 > >>他の著者の方や他の言語でもこういう「面白い」本はあるのでしょうか。 > >分野がわからないとアレですが、アスキーの256倍シリーズとかですかねえ。 はじめまして。 前橋さんの本やこのホームページは、 扱っている技術の内容が高く、 現場のプログラミングにおいても、 ものすごく役に立つのでよく見ています。 さて、私も「Java謎+落とし穴」を最近読んだのですが、 少し内容が古くなってきたように感じます。 特に進化のスピードが速いJavaでは、 本書で前橋さんが苦言を呈している ジェネリックやenumなどの機能については、 現在、ほとんど盛り込まれています。 そこで、ここ最近、話題になっている? 「疑い深いあなたのためのオブジェクト指向再入門」 の内容に加筆したものを新規に書き起こして、 加筆修正した改訂版を出してはどうでしょうか。 (単に私が読みたいだけですが。) 結構、売れると思いますw(余計なお世話ですか?)
[この投稿を含むスレッドを表示] [この投稿を削除]
[784] Re:ポインタ完全制覇
投稿者:CES
2007/02/20 02:13:25

>ポインタの読み方から頑張って導こうとしなくても、こんなのを書いちゃうと一発だと、散々悩んでから気がついた。 > >template< typename ReturnType > >ReturnType Test(); > >std::cout << typeid( Test< char(*)[10] > ) << std::endl; マチガヘタ。 std::cout << typeid( Test< char(*)[10] > ).name() << std::endl; が正しい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[783] Re:ポインタ完全制覇
投稿者:CES
2007/02/20 02:13:25

>>問: >>char 型の配列へのポインタを返す関数の宣言を記述しなさい。 >>関数名、引数、戻り値の要素数は任意とする。 > >用途としては、「\0込みで30文字以内の文字列を可変の個数返す関数」とかですかね。 ポインタの読み方から頑張って導こうとしなくても、こんなのを書いちゃうと一発だと、散々悩んでから気がついた。 template< typename ReturnType > ReturnType Test(); std::cout << typeid( Test< char(*)[10] > ) << std::endl; ちなみに、皆さんご存知だと思うけれど、正解はこう(N は要素数)。 char ( * f() )[ N ]; なんでこんなもので悩んでいたかというと、VC++ に奇怪なソースを発見したから。 配列の要素数を数えるコード。 template< typename _TypeOfArray, size_t _SizeOfArray > char ( * __countof_helper( _TypeOfArray ( & )[ _SizeOfArray ] ) )[ _SizeOfArray ]; #define _countof( _Array ) sizeof( * __countof_helper( _Array ) ) __countof_helper は、日本語で言うと「_TypeOfArray 型の配列(要素数は _SizeOfArray 個)の参照を引数に取り、char 型の配列(要素数は _SizeOfArray 個)のポインタを返す関数」の宣言。 返ってきたポインタを間接参照して sizeof すれば、引数に渡した配列と同じ要素数の char 型の配列のサイズ、すなわち引数の要素数が手に入るというカラクリ。 テンプレートに引数配列の要素数まで推測させているのにビックリ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[782] Re:ポインタ完全制覇へはまだ遠し
投稿者:(ぱ)
2007/02/20 02:13:25

>これなら、配列に書き込む時オーバーフローしてもしかたがないと思う反面 >過去にどっかで、誰か偉い人が、配列というものをポインタとはまた別の物として >規定をなぜしてくれなかったのかと思います。 配列とポインタがこんなふうにこんがらがった変な言語はC/C++くらいなものであり、 たいがいの言語では、明確に別なものとして定義されています(ポインタではなく 参照と呼んでいるかも知れないけれど)。 ポインタ完全制覇にも書いたように、Cはもともと現場の要求を満たすために でっちあげられた言語なので、「ベストな言語」どころか「ベストを目指した言語」 でもないように思います。でも、そこそこよくできていたため広く使われてしまった、 というのが世の常であるわけで。 デザインの「悪い方がよい」原則 http://chasen.org/~daiti-m/text/worse-is-better-ja.html >ついでに、初期化で >char array[] = "abcd"; >char *p = array; >の意味が最初僕はわかりませんでした。「*pの内容にarray?どういうこと?」と思いました >これもchar* p = array;とすれば意味がすんなりわかりました。 これは、 char *p; よりも char* p; と書くほうがわかりやすい、という意味でしょうか? それはそれで否定しませんが、それで問題は解決しない、ということもポインタ完全制覇には 書きました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[781] Re:面白い本を探しているのですが……
投稿者:(ぱ)
2007/02/20 02:13:25

>こんにちは。はじめまして。 >Java謎+落とし穴を読ませていただきました。 どうもです。 >他の著者の方や他の言語でもこういう「面白い」本はあるのでしょうか。 分野がわからないとアレですが、アスキーの256倍シリーズとかですかねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[780] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

本多さん: >「&a」で取得できる「配列へのポインタ」って使い道ってあります? 私の認識は、こっちに書いた通り。 http://kmaebashi.com/programmer/pointer.html | 配列から読み換えられたポインタは左辺値を持たないため、 & 演算子の | オペランドにはならないはずであるが、この例外規則のため、 & でアドレス | (配列の先頭要素のアドレスではなく、配列全体のアドレス)が 取得できる。 | この規則は初心者を混乱させることがある (例えば scanf("%s", buf) でなく、 | scanf("%s", &buf)と書いても 正常に動いてしまう(正常に動いたように見えて | しまう)が、 メリットは今ひとつわからない。 774RRさん: >int a[10]; >memset(&a, 0, sizeof a); >配列だから &a にせずとも a とだけ書けば事足りるのだが、配列の場合だけ & 不要ってのは >(単なる表記の問題ではあるが)初心者を惑わすもととなりうるんで。 strcpy(dest, src)とかでもdestに&は付きませんから、これは付けないほうが むしろ統一が取れるのではないでしょうか。 >typedef int i10[10]; // これは .h ファイルにあって >i10 a; memset(&a, 0, sizeof a); // こっちは .c ファイルにある >の場合には & ありのほうが自然で、ないのは不自然。 MinGWのsetjmp.hより: typedef _JBTYPE jmp_buf[_JBLEN]; でも、setjmp()を使うときは、 jmp_buf buf; if (setjmp(buf) == 0) { ... なのであって、&は付けません。 まあ、前から書いているように、私もこれって不自然だと思うんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[779] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

>問: >char 型の配列へのポインタを返す関数の宣言を記述しなさい。 >関数名、引数、戻り値の要素数は任意とする。 用途としては、「\0込みで30文字以内の文字列を可変の個数返す関数」とかですかね。 CADやってたころは、たとえば3次元ポリラインなどで、「double3つの可変長配列」を よく受け渡ししたものです。また、4×4の行列もしょっちゅう引数で受け渡ししました。 配列を引数で渡すとき、 void func(double a[]) のように書けるシンタックスシュガーは、私は混乱を招くだけだと思うのですが、 やっぱりこれを使ったほうが読みやすい、という主張もわからなくはないです。 特に多次元配列では。 でも、仮引数の宣言でしか使えない(戻り値とか、一時変数に代入する時には使えない) んじゃやっぱ中途半端だよなあ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[778] ポインタ完全制覇へはまだ遠し
投稿者:負け組一号
2007/02/20 02:13:25

レスありがとうございます 私は 技術評論社の入門本物志向が身に付く本(浅井 淳さん 著)とウェブの初心者ページ で初心者としての知識を身につけ 初心者用問題集(確か~望洋さん 著)の本を一通り解いて C言語ポインタ完全制覇(前橋 和弥さん 著)と C言語文字列操作+ファイル入出力完全制覇(山地 秀美さん 著)を買い C言語文字列操作+ファイル入出力完全制覇の構造体を使ったリストの所で 頭がこんがらがり、今は、C言語入門シニア編(林 晴比古さん 著)by ソフトバンク で勉強中で、かつ、プログラムはなぜ動くのか(矢沢 久雄さん 著)by 日系BPを読み アセンブラを勉強した方が良いのか?と思いつつ、とにかくC言語をという感じで 勉強中です。 以上駄文ですが、なにかお勧めの本はありますか?あれば教えて頂きたいです。 このBBSにふさわしくない内容でしたら削除します。駄文もうしわけない。 ちなみに、ポインタに関しては、さし棒と考える事にしてます そんで、array[index]=*((array)+(index))だし これなら、配列に書き込む時オーバーフローしてもしかたがないと思う反面 過去にどっかで、誰か偉い人が、配列というものをポインタとはまた別の物として 規定をなぜしてくれなかったのかと思います。 ついでに、初期化で char array[] = "abcd"; char *p = array; の意味が最初僕はわかりませんでした。「*pの内容にarray?どういうこと?」と思いました これもchar* p = array;とすれば意味がすんなりわかりました。 で、勉強すればするほど、シンタックスシュガーなるもの、プログラミング言語に 存在してはいけないのじゃないのか?と初心者ながらに思いつつ 「まぁ、偉い人がこう決めたんだから、必要性もあるんだろう」と思っています。 以上、失礼します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[777] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

たとえばこんなのとか int a[10]; memset(&a, 0, sizeof a); 配列だから &a にせずとも a とだけ書けば事足りるのだが、配列の場合だけ & 不要ってのは (単なる表記の問題ではあるが)初心者を惑わすもととなりうるんで。 typedef int i10[10]; // これは .h ファイルにあって i10 a; memset(&a, 0, sizeof a); // こっちは .c ファイルにある の場合には & ありのほうが自然で、ないのは不自然。 個人的には char (*)[N] を単体で使うってのは他ではナイなぁ。 二次元(以上)配列を使うときに現れるだけだと思う。
[この投稿を含むスレッドを表示] [この投稿を削除]
[776] 面白い本を探しているのですが……
投稿者:もつ
2007/02/20 02:13:25

こんにちは。はじめまして。 Java謎+落とし穴を読ませていただきました。 難しい話がなぜか面白い文章になっていて読むのがとても楽しかったのですが、他の著者の方や他の言語でもこういう「面白い」本はあるのでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[775] Re:ポインタ完全制覇
投稿者:本多
2007/02/20 02:13:25

>「配列へのポインタ」の存在価値がわからんという人も居たな。 >多次元配列(より正確には配列の配列)を考えれば存在価値がわかるだろう。 「配列へのポインタ」という型はもちろん存在価値があるのですが、 読んでてふと思ったことがあります。 「int a[10];」という配列に対して、 「&a」で取得できる「配列へのポインタ」って使い道ってあります? っていうか実務で使った経験ってありますか? int a[10][20]を受け取る関数の引数とかでなく、 配列自身に「&」をつけて、それを使うプログラムを使ったことが、です。 言語仕様を確認しようとしたチョイプロとかじゃなくて 何か明確な意図を持って、それを使わなくちゃいけない または使うほうが適切と判断するような場面ってありましたか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[774] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

カンペキだ... もう何も言うことは無い。俺が書かなかった内容まで指摘済み。以下蛇足。 > ポイント先は「50バイト分のヒトカタマリ」であって、 これが理解できない人がいる、ってのが理解に苦しむというかなんというか。 int* だって 2byte なり 4byte なりの塊を指すワケだし、何一つ違わないと思うのだが。 もっと言うなら char* だって 8bit の塊 (もっと大きいこともあるが) を指すのだし。 「配列へのポインタ」の存在価値がわからんという人も居たな。 多次元配列(より正確には配列の配列)を考えれば存在価値がわかるだろう。 char a[10]; char (*p)[10]=a; なとき *p=0; と書けないから理解できんのだろうか。そりゃ無謀ってもんだが... っと、先の [772] は yuya さん宛てに書いたのではなくって ROM 者のための課題だったので そこの ROM なあなた、自分で一度考察してみると理解が深まって吉ですぜ。 # 774 げっと
[この投稿を含むスレッドを表示] [この投稿を削除]
[773] Re:ポインタ完全制覇
投稿者:yuya
2007/02/20 02:13:25

頭の整理のために、ということで。 A1'. char(*)[10] はchar配列(要素数10)へのポインタ。 char*[10] はcharへのポインタの配列(要素数10)。 A1". char (*hoge)[10]; Q3. 暗黙の変換前は 「charの配列(要素数10)の配列(要素数5)」型であり、 b[0]~b[4]の5つ(配列が5つ)のこと。 暗黙の変換後はその先頭要素へのポインタになるので、 「charの配列(要素数10)へのポインタ」型の右辺値となり、 そのポイント先はb[0]です。 「b + 1」はb[1]を、つまり10バイト離れたところをポイントします。 Q4. &bの「b」は暗黙の変換が行なわれないので、 配列そのもの(この場合は「配列の配列」という配列そのもの)になり、 それに「&」を付けた「&b」は「charの配列の配列へのポインタ」型の右辺値です。 「&b」のポイント先は「50バイト分のヒトカタマリ」であって、 「&b + 1」はもはや配列外をポイントするので、 ここを書き換えると何が起こるか分かりません。それこそ >「配列へのポインタ」で示される先に実体が1つあるだけ という状態ですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[772] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

こたえ書いちゃうのは簡単なので、書かずに盛り上げるテスト # この辺、ポインタ中級レベルになるのでしょうか?それとも上級? ここはまず「配列へのポインタ」っつーものがあることを理解しなければならない。 char a[10]; という配列があるとき &a[0] = 配列先頭要素へのポインタ右辺値 (char*) &a = char [10] 配列へのポインタ右辺値 (Q1. この型の表記を行え) である。これも概念レベルの問題なので理解できない人は一生理解しないままだったりする。 # A1.char(*)[10] 型。 Q1'. char(*)[10] と char *[10] の違いを述べよ Q1". char(*)[10] 型の変数を作るにはどう記述するといい? 先の例は「配列へのポインタ」で示される先に実体が1つあるだけ。つまりよくある char c; char* p=&c; と同じレベルの些細でつまらない例に該当する。だからより実用的な例に変えよう。 Q2.char b[5][10]; とするとき &b[0] の型を述べよ (答えは char[10] へのポインタ右辺値) Q3.では b とだけ書いたら何型で何を指す? (暗黙の変換前と変換後の両者を答えよ) Q4.では &b と書いたら何型で何を指す? このへんがすらすら答えられるようになるなら CES さんの問題も簡単。
[この投稿を含むスレッドを表示] [この投稿を削除]
[771] Re:ポインタ完全制覇
投稿者:yuya
2007/02/20 02:13:25

こんにちは、CESさん。面白くてためになる問題ですね。 >関数名、引数、戻り値の要素数は任意とする。 戻り値はポインタなんですよね。 戻り値の要素数というのは? 戻り値であるポインタが指す先のchar型配列の要素数ということでしょうか? それとも、戻り値がポインタの配列になるかも知れないということでしょうか? いや、ポインタの配列を返したくても、その先頭要素へのポインタ(ポインタへのポインタ)を返すしかないわけですけれど(^^;)
[この投稿を含むスレッドを表示] [この投稿を削除]
[770] Re:ポインタ完全制覇
投稿者:CES
2007/02/20 02:13:25

この前、読み方で思いっきり躓いた。 せっかくだからクイズにしてみよう。 問: char 型の配列へのポインタを返す関数の宣言を記述しなさい。 関数名、引数、戻り値の要素数は任意とする。
[この投稿を含むスレッドを表示] [この投稿を削除]
[769] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

>うーん。なぜ皆「ポインタのポインタ」というのだろうか。すごく不思議。 >「ポインタへのポインタ」というほうがわかりやすくて正確だと思うのだが。 同意します。なので「ポインタ完全制覇」では、ある型Tを指すポインタは、 原則「Tへのポインタ」と言っているはずで…と思い、「ポインタのポインタ」で Googleしたらうちのページがトップに来た Σ(゚д゚lll)ガーン >ポインタで躓いている人の半分くらいはポインタ左辺値と右辺値の違いがわかってない。 一応そのつもりで、ポインタ完全制覇では、ポインタはまず型であり、ポインタ型が あるのだから、ポインタ型の変数もポインタ型の値もある、と書いているつもりです。 K&Rに「ポインタはアドレスを格納する変数である」と書いてあるのがやっぱり 諸悪の根源ではないかと。 今は(例によって)酔っ払っているので続きはまた考えます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[768] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

うーん。なぜ皆「ポインタのポインタ」というのだろうか。すごく不思議。 「ポインタへのポインタ」というほうがわかりやすくて正確だと思うのだが。 ポインタで躓いている人の半分くらいはポインタ左辺値と右辺値の違いがわかってない。 判ってるほうはわざわざ区別する気にならないのであえて明言しないし。 これは概念理解の問題なので、噛み砕いて説明しても無駄な場合が多くて泣きそう。 残り半分は宣言の読み方が判らないだけで、こっちは技術的問題なので慣れでなんとかなる。 int (*pf)(); と int func(int*); は C++ では明確に非互換なので無問題。 C では JIS X 3010:2003 6.7.5.3 関数宣言子にて「関数型が適合とは」の解説があり、 俺的解釈では pf=func; は適合であるため、「警告が出ないのがあたりまえ」 「もし警告が出るとしたら、それはコンパイラが親切なだけ」であると思われる。 int (*pf2)(void*); と int func(int*); は非互換でなきゃならない。 # 元発言者様の発言が質問になっていないので単なる感想。
[この投稿を含むスレッドを表示] [この投稿を削除]
[767] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

はじめまして。 >はじめまして、プログラミングを勉強するには遅すぎる年齢(28)で >C言語を勉強している者です。それも再就職を目指し今は病気療養で傷病手当 お大事に。無理せずがんばってください。 >そこで、本の内容で、ポインタのポインタについて一切触れられてない点が気になり >ました。(そんなに、使う物では無いのかな?と勝手に思ってもいますが) ご意見ありがとうございます。 うーん、ポインタのポインタ(型)、というのは、単にポインタから派生したポインタ型に 過ぎませんから、宣言の読み方からすれば3章の記述で足りそうですし、 実際の使い方としては、4-2-2の「可変長配列の可変長配列」および4-2-4の 「引数経由でポインタを返してもらう」で扱っているつもりです。 また、実際にプログラムを書くときの用途もそんなところです。 もちろん、ポインタのポインタを引数で返してもらうときにはポインタのポインタのポインタを 使いますし、ポインタのポインタの可変長配列を作りたければやっぱりポインタのポインタの ポインタを… いやこっちはさすがに構造体を導入すると思いますが。 まあ、「ポインタのポインタって何だ?」と疑問を持った人が、ポインタ完全制覇で その説明を探すときのことを考えれば、章タイトルに「ポインタのポインタ」が 入っていたほうがよかったかもしれません。 >例えば >int (*func)(); >int func2(int*); >とプロトタイプ宣言し、mainブロック内で >func = func2; >とした時僕としては、プロトタイプ宣言時に >int (*func)(void*); なぜ、 int (*func)(int*); ではだめなのでしょうか。 ひょっとして、funcに代入される実際の関数は、 int func2(int*); int func3(char*); int func4(double*); のうちのどれだかわからない、ということでしょうか。 もしそうであれば、これはちょっと邪悪な書き方だと思います。 # 厳密に言うと規格上もまずいです。int*とvoid*が同じ形式とは限らないので。 どうしてもこういうことをしたければ、私なら、 int (*func)(void*); としておいて、関数側で、受け取った後でキャストします。 int func2(void *a) { int *int_p = (int*)a; ... }
[この投稿を含むスレッドを表示] [この投稿を削除]
[766] ポインタ完全制覇
投稿者:負け組一号
2007/02/20 02:13:25

はじめまして、プログラミングを勉強するには遅すぎる年齢(28)で C言語を勉強している者です。それも再就職を目指し今は病気療養で傷病手当 で生活している、ま、いわゆる人生の負け組ですが、一応もがくだけもがこうと プログラミングを勉強しだし、前橋さんの著書ポインタ完全制覇を読みました。 そこで、本の内容で、ポインタのポインタについて一切触れられてない点が気になり ました。(そんなに、使う物では無いのかな?と勝手に思ってもいますが) それと、int (*func)();の様な形でプロトタイプ宣言したときに、引数の型を明示してないですが了解している警告として受け入れてはいますが 例えば int (*func)(); int func2(int*); とプロトタイプ宣言し、mainブロック内で func = func2; とした時僕としては、プロトタイプ宣言時に int (*func)(void*); としときたいのですが、別の著書では、void*を引数にすると厳しいコンパイラーでは エラーが出るとの事で(僕はVisual C++6.0で勉強していて、引数にvoid*を指定しても しなくても、警告もエラーも出ず実行できてしまいました) 引数は省略するほうが良いのだろうと思いつつ 警告でるなら、なんかやだな。とも思うんです。 かといって、引数として受け取る時にキャストする方法なんて知りませんし (ただの勉強不足なのでしょうが)そこら辺をもうちょっと本の中で知りたかったです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[765] Re:オブジェクト指向再入門
投稿者:(ぱ)
2007/02/20 02:13:25

>「疑り深いあなたのためのオブジェクト指向再入門」が非常に為になった。 >有り難うございます。 どうもです。あのページはうちのコンテンツの中でも毀誉褒貶が激しいページなので(w ためになったといっていただけるとたいへん励みになりますです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[764] オブジェクト指向再入門
投稿者:penchi
2007/02/20 02:13:25

「疑り深いあなたのためのオブジェクト指向再入門」が非常に為になった。 有り難うございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[762] Re:感謝状
投稿者:(ぱ)
2007/02/20 02:13:25

> そうでもないんですわ。push/popなんて命令も用意してもらえてません(T-T) > だいたい、レジスタに格納した番地のメモリにアクセスすると言う命令すらない(T-T) > 固定番地へのアクセスのみです。 ははあ、なるほど。 そうなると、式評価の途中の値は、レジスタに置くか、それが足りなくなったら どこか決めうちのワークエリアに置くことになるわけですね。その場所は、 コンパイル時に決定できますし。 勉強になりました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[761] Re:感謝状
投稿者:本多
2007/02/20 02:13:25

>>っていうか、対象ハードウエア(自社製ASIC)が構造上どない頑張ってもスタック構造を処理できないので(@_@) >すいません、そういうCPUは触ったことないので質問です。 このハードウエアはCPUとは呼べないでしょうね。 今どきのPCの周辺機器のほうがよほど複雑なプログラム実行が出来そうです(^^;) >eval.cの関数をwrite()に置き換えたとのことなので、そこで吐いているのはpush/popだと >思っていましたが、そうでもないんでしょうか? そうでもないんですわ。push/popなんて命令も用意してもらえてません(T-T) だいたい、レジスタに格納した番地のメモリにアクセスすると言う命令すらない(T-T) 固定番地へのアクセスのみです。 だからメモリの上から順にグローバル変数を割り付けていくと言うことしてます。 (っていうか、メモリも2kだけですし...)。 JMP命令はあるけど、固定JMPのみ、というわけで、関数呼び出しも再起呼び出し禁止、 関数の型はvoid func(void)のみって感じになりました。 コンパイラがwrite()で吐いてるのは 「メモリからレジスタ1へのコピー命令(に対応する数値)」とか 「レジスタ aとレジスタ bの演算命令(に対応する数値)」とか 「特殊機能を実行する機械語(に対応する数値)」とかを データファイルに書き出してます。 実際、(PCではないのですが)本当にあるシステムの周辺機器なので メインのCPU(こっちは汎用CPU!)上で動作するプログラムが 作ったデータファイルからデータを読み込んで対象ハードウエアに書き込み、 対象ハードウエアを起動するという形を取ります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[760] Re:感謝状
投稿者:(ぱ)
2007/02/20 02:13:25

>っていうか、対象ハードウエア(自社製ASIC)が構造上どない頑張ってもスタック構造を処理できないので(@_@) すいません、そういうCPUは触ったことないので質問です。 eval.cの関数をwrite()に置き換えたとのことなので、そこで吐いているのはpush/popだと 思っていましたが、そうでもないんでしょうか? それとも、その程度のスタック操作はできるけど、スタック上のインデクシングができないとか、 そういうことでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[759] Re:感謝状
投稿者:本多
2007/02/20 02:13:25

> 対象とするプログラムが200~300ステップとのことなので、ローカル変数とかは >ばっさり省略されたんでしょうか。crowbar - αだとそんな感じになりそうな気が… はい。ばっさりと。 っていうか、対象ハードウエア(自社製ASIC)が構造上どない頑張ってもスタック構造を処理できないので(@_@) そんなのを作って「C言語のサブセットだ」と言い張るのは少々(だいぶ?)誇張だとは自覚してますが... アセンブラで記述した200~300ステップがC言語で50行以下にできるところが一番の収穫です(^^)
[この投稿を含むスレッドを表示] [この投稿を削除]
[758] Re:感謝状
投稿者:(ぱ)
2007/02/20 02:13:25

> 感謝状なので、わざわざ 丁寧な書き方してみましたが、 > こそばゆかったっすか...(^^;) そりゃもう。 > じゃあ次からは丁寧に書かないようにしますわ(^O^)/ へい。それで結構でございますです。 > crowbar中のeval_...とか、execute_...って関数をwrite()文の羅列に置き換えたので、 > たぶんcrowbarを簡単にしただけです。  対象とするプログラムが200~300ステップとのことなので、ローカル変数とかは ばっさり省略されたんでしょうか。crowbar - αだとそんな感じになりそうな気が…
[この投稿を含むスレッドを表示] [この投稿を削除]
[757] Re:感謝状
投稿者:本多
2007/02/20 02:13:25

>>前略 前橋様 > いつものmanybookの本多さんにこういうことを書かれたとすればさすがにこそばゆいので。 いや、いつもの本多ですが...(^^;) そっか、新しい掲示板はメールアドレスないんですよね。 感謝状なので、わざわざ 丁寧な書き方してみましたが、 こそばゆかったっすか...(^^;) じゃあ次からは丁寧に書かないようにしますわ(^O^)/ >>で一念発起、C言語で書けるようにコンパイラ(もどき)を作ることにしました。 > 正直、機械語を生成するCコンパイラだと、せいぜい構文解析までしか役に立たな >かったのでは、と思いますが、多少なりともお役に立てたのでしたらよかったです。 なにせ、コンパイラを作ろうなどと考えたこともなかったので 構文解析やらなにやらと、全く知らなかったので勉強になりました。 何よりソースコード付で、そのコードを丁寧に説明してあるのが わかりやすくて良かったです。 crowbar中のeval_...とか、execute_...って関数をwrite()文の羅列に置き換えたので、 たぶんcrowbarを簡単にしただけです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[756] Re:感謝状
投稿者:(ぱ)
2007/02/20 02:13:25

>前略 前橋様  はじめまして…でいいですよね?  いつものmanybookの本多さんにこういうことを書かれたとすればさすがにこそばゆいので。 >有益なページの提供に心から感謝します。  や、ありがとうございます。 >で一念発起、C言語で書けるようにコンパイラ(もどき)を作ることにしました。  正直、機械語を生成するCコンパイラだと、せいぜい構文解析までしか役に立たな かったのでは、と思いますが、多少なりともお役に立てたのでしたらよかったです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[755] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

[750] への追補。 > 設計手順としては、まず常識的な is-a を使って継承関係を考えてみた > 上で、それを LSP で検証すればいいんですよ。検証に通らない場合には、 > たとえ常識的なis-a 関係であっても、継承関係にはしません。検証に通 > れば、もちろん継承関係にします。 「常識的な判断」が悪いとは思いません。 ところで、「常識」と「真理」は違います。 日本人の常識とアメリカ人の常識が異なるのと同じように、販売支援ソフトと画像処理ソフトの設計常識が同じはずがありません。要するに、常識ってのはいっぱいあります。 その中から、今回作りたいソフトに適する常識を選ぶ必要があります。 経験に基づいて「常識的な設計手法は、適した設計である可能性が高い」と言うのであれば、俺が言う「いくつもの方法の中から、適したものを選べ」というのと、全く変わりません。 ですから、それを否定する kit さんは、「常識的な設計」すらすることができません。 > これも繰り返しになりますが、「照らすまでもなく」のような暗黙の知識は、 > 法則としては役に立たないんですよ。 では「常識」は暗黙の知識ではなく、明文化されているのですか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[754] 感謝状
投稿者:本多
2007/02/20 02:13:25

前略 前橋様 有益なページの提供に心から感謝します。 最近、自社製の小さなハードウエアに搭載するためのアセンブラプログラムを作る仕事をすることになったんです。 規模がそれほど大きくない(200~300ステップ)のですが、アセンブラはやっぱり大変です。 で一念発起、C言語で書けるようにコンパイラ(もどき)を作ることにしました。 連載「プログラミング言語を作る」の前橋さんの説明とcrowbarソースコードを繰り返し読むことで なんとか2日ででっち上げることに成功しました。 さすがにcrowbarとは欲しい機能とは大分違うのでソースコードをそのまま利用することはしてません(できません)が、このページのおかげで大分楽に作ることが出来ました。 しょせん、ハードウエアの制限でポインタとか文字列とか浮動小数点とか多くの機能が実装しない超簡単コンパイラですし、当面私しか使わないし、出来たコードをデバッグしなくちゃいけないのは変わらないのですが...(^^;) 勉強になりました。どうも ありがとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[753] Re:分析と設計
投稿者:CES
2007/02/20 02:13:25

>>ただ、この手法を更に推し進めるとインターフェイスの多重継承の山になりかねないので要注意でしょう。 >>struct fooable { virtual void do_foo()=0; }; >>struct barable { virtual void do_bar()=0; }; >>struct bazable { virtual void do_baz()=0; }; >>struct hoge : fooable, barable {...}; >>struct piyo : barable, bazable {...}; > >推し進めるというか、どこかで一歩飛んでいる気がします。 >FlyingAnimal は(あるいは、飛行機を統一的に扱おうとしてさらに上位に定義した FlyingObject でさえ)、IFlyable とは一線を画したものであるような気がします。 >なぜそう思うのかは、いまのところ「直感」としか言いようがないのですが。 失礼。 今回は既に bird からしてインターフェイスでしたね。 Java や C# が言うところの「インターフェイス」の意味づけが、自分の中でよくできていない感じです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[752] Re:分析と設計
投稿者:CES
2007/02/20 02:13:25

>ただ、この手法を更に推し進めるとインターフェイスの多重継承の山になりかねないので要注意でしょう。 >struct fooable { virtual void do_foo()=0; }; >struct barable { virtual void do_bar()=0; }; >struct bazable { virtual void do_baz()=0; }; >struct hoge : fooable, barable {...}; >struct piyo : barable, bazable {...}; 推し進めるというか、どこかで一歩飛んでいる気がします。 FlyingAnimal は(あるいは、飛行機を統一的に扱おうとしてさらに上位に定義した FlyingObject でさえ)、IFlyable とは一線を画したものであるような気がします。 なぜそう思うのかは、いまのところ「直感」としか言いようがないのですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[751] Re:分析と設計
投稿者:774RR
2007/02/20 02:13:25

>「こうもり」を派生したくなった時点で、名前をflying_animalとかに変更するのが筋では? 御意。それは大いにありだと思う今日子の頃です。 今回のこの案件A’A”では、それでうまく行きそうです。みな幸せ。 ただ、この手法を更に推し進めるとインターフェイスの多重継承の山になりかねないので要注意でしょう。 struct fooable { virtual void do_foo()=0; }; struct barable { virtual void do_bar()=0; }; struct bazable { virtual void do_baz()=0; }; struct hoge : fooable, barable {...}; struct piyo : barable, bazable {...}; とてもまともに分析したとは思えない醜い設計です。 抽象度は増したのかもしれませんが、実用度が薄すぎます。まともに使いこなせるとはとてもとても。 # 自己反省をかねて age
[この投稿を含むスレッドを表示] [この投稿を削除]
[750] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

kit さんへのまとめ。 俺は当初、kit さんは「オブジェクトの is-a など問題にしなくてよい。LSP のみが確かな判断基準となる」と言っているのだと思っていました。 理由は、 > 設計手順としては、まず常識的な is-a を使って継承関係を考えてみた > 上で、それを LSP で検証すればいいんですよ。検証に通らない場合には、 > たとえ常識的なis-a 関係であっても、継承関係にはしません。検証に通 > れば、もちろん継承関係にします。 これを [715] まで言わなかったことです。 しかし、実態は上記の通り、kit さんも、LSP を適用する前に、オブジェクトの is-a での判断を行っています。 そして、俺が [722] で書いた > 結局、この文献は「どんなものを継承関係にすべきか」という指針には、一言も言及していないのです(「どんなものを継承関係にしてはいけないか」は、LSP を用いて言及しています。<以下略>)。 これは、kit さんにも当てはまります。 上記の [715] の文章は、まさにこれだからです。 LSP で検証したことによって、最初に下した「常識的な判断」が正解だったか間違いだったかは確かに分かりますが、その「常識的な判断」は LSP を用いて下したものではありません。 kit さんも、「どんなものを継承関係にするのが正解か」は、LSP を用いて判断していないのです(判断しているのは「結果的に正解だったか」です)。 > これも繰り返しになりますが、「照らすまでもなく」のような暗黙の知識は、 > 法則としては役に立たないんですよ。 「照らすまでもなく間違いと分かる」のは「まるで神に囁かれたかのごとく、なんとなくわかる」のではありませんよ。「LSP など適用しなくても、分析をしっかりとやることによって、きちんと根拠付けて導かれる」のです。 もっとも、kit さんが求める「分析というステップをすっ飛ばして、『LSP に照らすまでもなく』正解が分かる、設計のお手本」から見れば、これでさえ暗黙的に見えるかもしれませんけれど。 kit さんの求めるものとは、「多くの場合に適用できる(が、たまには失敗することもある)、常識的な設計パターン」さえ超越した、「常に成功を約束された設計パターン」なのでしょう。すなわち、「あるクラスAは、どのような案件であるかによらず、常に、他のクラスの子クラスではないか、あるいは、Bの子クラスであるかのどちらかである」という保証(と、AとBの一対一の対応表)ですね。なぜなら、kit さんは「案件によって、Aの親はBが適切な場合も、Cが適切な場合もある。それは案件を分析してみるまで分からない」というのではダメだとおっしゃるからです。 そのようなパターンが本当に存在するのなら、それは素晴らしいことでしょう。 しかし、もしそれを実践したとすると、失敗するケースの方が多いように思えてなりません。 > むしろこういう説明は、 > この説明に沿って機械的に作業していけば、「オブジェクト指向設計」ができるんだ。 > という印象を与えかねないという点で有害だと思います。 > 確かに、ソフト屋は常に一定以上の品質のプログラムを供給しなければならないものであり、その意味では、「機械的にやっていけば誰でもちゃんとした設計ができる」という手法があるのならば大変結構なことです。しかし、残念ながら、オブジェクト指向設計はそこまでいっていないと私は思っています ※4。 > ていうか正直私は、こういうことは、未来永劫、決して「機械的にできる」ようにはならないと思います。 「疑り深いあなたのためのオブジェクト指向再入門/なぜわからなくなってしまうのか?」より抜粋。 わかってらっしゃるじゃないですか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[749] Re:分析と設計
投稿者:タイガー
2007/02/20 02:13:25

>>もしくは、間違ってfly()させちゃいけないのなら >>例外を投げるのもありかなと思います。 >これは LSP 違反だと思うのです。 >http://www2.ocn.ne.jp/~yamagu/object/LSP-J.pdf >の Rectangle と Square の例[本当の問題]と同等な問題を内在させることになりそうです。 >さて、こういう場合に「そもそも同一視すべきだったか」を私は問いたいのです。 ここで、前提条件として以下のものを考えます。 「struct bird { virtual void fly()=0; }; に対し、birdを継承したbat(こうもり)クラスの実装も クライアント側の処理もうまくいった。 ここで新たにpenguin(ペンギン)クラス(処理)を追加する必要が 生じた。」 この時の設計として、penguinクラスとbatクラスを 同一視(例えば、両方ともbirdから継承)すべきかどうかを考えてみます。 私の前回の発言のように、penguinクラスとbatクラスを 同一視して、penguinのfly()の実装で例外を投げようとすると、 birdを扱うクライアント側の処理でbatとpenguinを 同一扱いできないので、LSPに違反します。 つまり、penguinクラスのfly()の実装でどうしても例外を 投げたいのであれば、明らかに設計ミスで、birdクラスで 例外を投げるように設計しておかなければなりません。 しかし、penguinのfly()を、batクラスのfly()とクライアント側で 同一視できるように実装しておけば問題ありません (例えば、fly() {}のような空実装など)。 すなわち、774RRさんが、[745]の2でおっしゃってるように、 既に実装されているクライアント側の処理にマッチするように penguinのfly()を実装すれば問題ありません。 しかし、現実的には全てのクライアント側の処理を調べるのは 現実的ではないので、LSPを頼りに、 「penguinのfly()の振る舞いがbatのfly()の振る舞いと同等である」 という「常識的な」判断ができれば、クライアント側でbatとpenguinが 同一視できると判断しても妥当と言えるかもしれません。 また逆に、LSPに違反した継承を行った場合でも、 クライアント側で両方に共通した使い方のみで実装してあげれば 問題ありません (もちろん、その後、LSPに違反するような実装をクライアント側の 処理で行う実装を追加すれば問題が起きるので設計としては かなり危険な設計ですが)。 また、774RRさんの[743]での以下の疑問 >さて、こういう場合に「そもそも同一視すべきだったか」を私は問いたいのです。 は、「既に存在するクライアント側の処理がどうなっているか」と 「penguinのfly()の実装をどうしたいか」の両方に依存しているので 常に正解の設計方法論はないと私は思います (クライアント側の処理をあらかじめ規定するには、Design by Contractとかに 類する機能が必要だと思います)。 ここで、私の出た結論としては、私自身かなり混乱しているのですが、 つまり、penguinクラスをbirdから派生させてbatと同一視すべきかどうか という設計を迫られたとき、これがLSPに当てはまるかどうかを 考えようとして、 「penguinのfly()の振る舞いが、batのfly()の振る舞いと同一か」 という疑問を持ったとき、 penguinのfly()を実装しようとした時に、どう転んでも クライアント側の実装がbatのfly()と同一視しかできない実装になっている のであれば、全く問題ない訳で、 クライアント側の実装により、少しでも同一視できない可能性があるなら そういう設計すべきでない訳で、 つまり、それをどう判断できるかと言うと、クライアント側のコードの 予想がつかないため、そんなに単純にLSPで判断できないような気が してきました(クラスが単純ならできる場合もありそうです)。 ここでは、fly()関数1つのみを考えている訳ですが、実際は、クラスは 複数の関数を持つ場合がほとんどなので組み合わせるともっと複雑になるし。 結局、同一視すべきかは、LSPはかなり参考にはなるが、 どんな局面でも通用する設計方法は存在せず、「実装依存」な気がします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[748] Re:分析と設計
投稿者:CES
2007/02/20 02:13:25

>bird 派生クラスは全て「飛べる」必要があり、飛べないものをこいつから派生したらダメ。 >1.だから、この bird からダチョウクラスを派生させるのはダメ。 >2.もしダチョウクラスを bird から派生させたいのであれば bird の実装を再検討。 >ではどのような bird にすればよいか、は要件に応じて再分析が必要。 >その再分析の際に「特定の設計原理(銀の弾丸)」ってものはありえない。 >ただその分析の結果の実装は LSP に則るべし。 鼻血が出るほど同意。
[この投稿を含むスレッドを表示] [この投稿を削除]
[747] Re:分析と設計
投稿者:CES
2007/02/20 02:13:25

概ね、皆さんに同意ですね。 >struct bird { virtual void fly()=0; }; このクラス設計が意味するところは簡単で「鳥は飛べる」ただこれだけです。 論理学風の言い方をすれば「鳥ならば飛べる」。 >Q1.案件B(あるいはA’と言い換えても)では「こうもり」を扱う必要が生じた。 >基底クラスを書き換える/書き換えない?派生クラスの実装をどうする? 「飛べるならば鳥である」ではありませんから、コウモリを鳥のサブクラスにすることはできません。 どうしても統一的に扱いたいのならば、Flying-Animal クラスでも導入すべきです。 >Q2.案件C(あるいはA”)では「ダチョウ」「ペンギン」を扱う必要が生じた。 >基底クラスを書き換える/書き換えない?派生クラスの実装をどうする? これは、前提条件が崩れているわけですから、理想的には一からやり直すべきです。 鳥クラスの下に「飛べる鳥」クラスと「飛べない鳥」クラスを設けて、fly メソッドは飛べる鳥クラスに移動する…と、既存の bird.fly メソッドを使っているコードは動かなくなりますね。 コスト的にやり直しが許されないのならば、飛べない鳥クラスの fly メソッドは、何もしない空実装にするのも手かもしれません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[746] Re:分析と設計
投稿者:のぐー
2007/02/20 02:13:25

>struct bird { virtual void fly()=0; }; オブジェクト指向ぜんぜん分かってない者ですがひとつだけ。 そもそも、birdって言う名前をつかうこと自体、おかしくないですか? 「こうもり」を派生したくなった時点で、名前をflying_animalとかに変更するのが筋では? そしたら「ダチョウ」を派生できないことは明らかなはずで。
[この投稿を含むスレッドを表示] [この投稿を削除]
[745] Re:分析と設計
投稿者:774RR
2007/02/20 02:13:25

んと、他人の意見だけ募集して自分の意見を出さないのはアレげなので私の見解。 LSP=同一基底クラスから派生したオブジェクトは、振る舞いが同一であると契約する 契約=派生クラス実装者と基底クラス利用者の間で取り決め ってことなので、そもそも struct bird { virtual void fly()=0; }; って設計した以上 bird 派生クラスは全て「飛べる」必要があり、飛べないものをこいつから派生したらダメ。 1.だから、この bird からダチョウクラスを派生させるのはダメ。 2.もしダチョウクラスを bird から派生させたいのであれば bird の実装を再検討。 ではどのような bird にすればよいか、は要件に応じて再分析が必要。 その再分析の際に「特定の設計原理(銀の弾丸)」ってものはありえない。 ただその分析の結果の実装は LSP に則るべし。 ってことなんですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[743] Re:分析と設計
投稿者:774RR
2007/02/20 02:13:25

>ダチョウ、ペンギンを例外にするのは良くないので、 >上記の実装なら同一扱いできるので良いと思います。 そこまでは限りなく同意なのですが >もしくは、間違ってfly()させちゃいけないのなら >例外を投げるのもありかなと思います。 これは LSP 違反だと思うのです。 http://www2.ocn.ne.jp/~yamagu/object/LSP-J.pdf の Rectangle と Square の例[本当の問題]と同等な問題を内在させることになりそうです。 さて、こういう場合に「そもそも同一視すべきだったか」を私は問いたいのです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[742] Re:分析と設計
投稿者:タイガー
2007/02/20 02:13:25

面白そうなので勝手に考えてみました。 初期の設計として私なら以下のように考えます。 >Shapeにdraw()を付けたら、その時はうまくいったとして。 > >Q1-1)機能拡張でShapeをグループ化できるようにしたとき、ShapeGroupクラスは > どこに位置づけるべきか? > >Q1-2)機能拡張で「補助線」機能を付けた。補助線は、描画中にだけ使用する機能で、 > 後工程に回らないからデータとしてファイルに保存しない。 > >A1-1(前橋版) >ShapeGroupをShapeのサブクラスにして、draw()をオーバーライドしてその >グループに含まれているShapeのdraw()メソッドを再帰的に呼んでやれば >描画はできますが、それはやっぱりアレなのでShapeのスーパークラスとして >Visibleとかの抽象クラス(またはインタフェース)を作り、ShapeGroupとShapeは >そのサブクラスかなあ。 >たとえば「color」というフィールドは、ShapeGroupには要らないだろうし。 これは、私も(ぱ)さんと同様にします。 つまり、ShapeGroupとShapeを共にVisibleから継承させて、 ShapeGroupにVisibleのリストを持たせます。 そうすればCompositeパターンになり、描画するときは、 トップからつながってるShapeを全て描画できます。 >A1-2(前橋版) >補助線がShapeのコレクションに入らないとすれば、完全に別扱いかなあ。 >もちろんVisibleを導入し、Visibleのコレクションを作って、Shapeは >ShapeコレクションとVisibleコレクションの両方から参照される、という >構造でもいいけど、両方のコレクションをメンテするのも面倒だし。 Visibleのサブクラスとして補助線クラス(AuxLine)を追加します。 AuxLineには、Visibleを集約させて(持たせて)、実際はShapeクラスを 持ちます。必要な機能をShapeから委譲させます。 結局、新たなクラスをShapeのサブクラスにするのは、 結合度が強すぎてガチガチになるので、 ゆるやかな結合で設計しておいた方が良いのかと思います。 これだけの情報だと情報量が少ないですが、 もっとうまい設計があったら教えて欲しいです。 >>Q2.案件C(あるいはA”)では「ダチョウ」「ペンギン」を扱う必要が生じた。 > >具体例が思いつきませんが、「描画されないShape」ですよね。 > >void draw() {} ダチョウ、ペンギンを例外にするのは良くないので、 上記の実装なら同一扱いできるので良いと思います。 もしくは、間違ってfly()させちゃいけないのなら 例外を投げるのもありかなと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[741] Re:分析と設計
投稿者:(ぱ)
2007/02/20 02:13:25

>Q1.案件B(あるいはA’と言い換えても)では「こうもり」を扱う必要が生じた。 >基底クラスを書き換える/書き換えない?派生クラスの実装をどうする? 鳥とかこうもりではあんまり具体的でもないと思うので、私は、例によって ドローツールっぽいものを考えるとします。 Shapeにdraw()を付けたら、その時はうまくいったとして。 Q1-1)機能拡張でShapeをグループ化できるようにしたとき、ShapeGroupクラスは  どこに位置づけるべきか? Q1-2)機能拡張で「補助線」機能を付けた。補助線は、描画中にだけ使用する機能で、  後工程に回らないからデータとしてファイルに保存しない。 A1-1(前橋版) ShapeGroupをShapeのサブクラスにして、draw()をオーバーライドしてその グループに含まれているShapeのdraw()メソッドを再帰的に呼んでやれば 描画はできますが、それはやっぱりアレなのでShapeのスーパークラスとして Visibleとかの抽象クラス(またはインタフェース)を作り、ShapeGroupとShapeは そのサブクラスかなあ。 たとえば「color」というフィールドは、ShapeGroupには要らないだろうし。 Shapeのグループ is a Shape と言って言えないことはないけど、苦しいし。 A1-2(前橋版) 補助線がShapeのコレクションに入らないとすれば、完全に別扱いかなあ。 もちろんVisibleを導入し、Visibleのコレクションを作って、Shapeは ShapeコレクションとVisibleコレクションの両方から参照される、という 構造でもいいけど、両方のコレクションをメンテするのも面倒だし。 >Q2.案件C(あるいはA”)では「ダチョウ」「ペンギン」を扱う必要が生じた。 具体例が思いつきませんが、「描画されないShape」ですよね。 void draw() {} でよさそうな… 以上、べたべたに実装よりの解答でした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[740] 分析と設計
投稿者:774RR
2007/02/20 02:13:25

盛り上がっているのは良いのですが、なんだか飽きて^H^H^Hわからなくなってきたので、 長すぎるスレにつながずに新規発言してみるテスト。 こんな場合、皆様ならどのように対処なさるでしょうか?ご意見拝借。 ある案件Aにおいては、こーいう設計が適切だと分析したので、以下のように書いた。 struct bird { virtual void fly()=0; }; そして現実にうまく行った。 Q1.案件B(あるいはA’と言い換えても)では「こうもり」を扱う必要が生じた。 基底クラスを書き換える/書き換えない?派生クラスの実装をどうする? Q2.案件C(あるいはA”)では「ダチョウ」「ペンギン」を扱う必要が生じた。 基底クラスを書き換える/書き換えない?派生クラスの実装をどうする? 抽象論だけだと理解しきれないのは俺だけ?なんか具体的な例が欲しくなったのです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[739] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>実はオブジェクト指向に限らず、ジェネリックプログラミングとも >通じる真理だと思うんですが… ジェネリックプログラミングに通じるのはわからなくもないですが、だから何です? ジェネリックプログラミングがそうだからといって、オブジェクト指向プログラミングもそうだという理由にはなりません。 >Webで公開されている文書であっても、原文の方で確認をすれば > then S is a subtype of T. >と書かれていますから、後者の意味であることは明らかなんですけどね。 なるほど。 件の本はまだ読んでいませんが、であるにしても、長方形と正方形の例をあのように用いているのであれば、どれほど信用が置けようか、という気はしますね。 >「完全に互換性のある属性と振舞いを示すのであれば、それは一見関係ないよ >うに見えても、実は関係があるのだ」というのが正解でしょう。 >CES さんは、この考え方を、一貫して拒否されているようですが… 属性や振る舞いに互換性があろうがなかろうが、何らかの関係はあります…と言うのも語弊がありますね。 関係は「ある」のではなく「作る」のです。作ろうと思えば、どんな関係だろうと作ることができます。これは、その気になればいくらでも互換性を持たせることができる、とも言えます。互換性は「示す」のではなく「持たせる」のですから。 問題は、その関係をプログラム上に表現することにメリットがあるのかどうかです。 そして、メリットがない関係は「関係ない」としても問題ありません。むしろ、そのような関係を徒に表現することは無駄であり害悪でしょう。 >> 俺は「LSP に照らすまでも無く、継承関係にしてはいけない場合がある」 >> と言う。 > >これも繰り返しになりますが、「照らすまでもなく」のような暗黙の知識は、 >法則としては役に立たないんですよ。だからこそ、明文化された LSP に >意味があるわけです。 俺は法則の話はしていません。 kit さんは「どういう関係を継承関係にすればいいのかという法則」を欲しているようですが、そんなものはありませんから。 LSP は満たすべき継承関係の指針ですが、使うべきところが違うと思うのです。 一応言っておくと、経験を否定しているわけではありません。 特定の案件に直面した時、「過去の経験から、こうすればうまく行くと思う」という提案は(最適ではなかったとしても)有意義です。 そのような場合でも「最適な選択肢は毎回違うのだから、経験などに頼らず、一から分析しなおすべきだ」と発言するのはバカです。 しかし、そのような特定の場面に依存しない、普遍的なガイドラインはない、と言っているのです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[738] Re:オブジェクト指向「初」入門
投稿者:kit
2007/02/20 02:13:25

「オブジェクト指向における is-a の関係は、オブジェクトの振舞い によって定義される」というのが、件の文献が言ってることなわけ ですが、どうも CES さんには受け入れられないみたいですね。 実はオブジェクト指向に限らず、ジェネリックプログラミングとも 通じる真理だと思うんですが… どうも CES さんとの溝は埋められそうにないわけですが、一応、 直接的な疑問には答えておきます。 > 件の文献も言っているではありませんか。 > 「サブタイプならば同じ振る舞いをすべきである」と書かれています。 > 「同じ振る舞いをするならサブタイプである」とは書かれていません。 訳が分かりづらくて、CESさんを誤解させてしまったのかもしれませんね。 Robert C. Martin の「アジャイルソフトウェア開発の奥義」をお持ちだ そうですから、そちらの該当箇所を参照されてみてはどうでしょうか。 144ページから引用します。 ここで望まれるのは、次に述べるような置換可能な性質である。 S型のオブジェクト o1 の各々に、対応するT型のオブジェクト o2が1つ存在し、Tを使って定義されたプログラムPに対して o2の代わりにo1を使ってもPの振る舞いが変わらない場合、 SはTの派生型であると言える。 Webで公開されている和訳では、確かに > 「サブタイプならば同じ振る舞いをすべきである」 と書かれているように読めるかもしれませんが、本当は > 「同じ振る舞いをするならサブタイプである」 と書かれているんです。Web の和訳のこの部分は誤訳に近いですね。 Webで公開されている文書であっても、原文の方で確認をすれば then S is a subtype of T. と書かれていますから、後者の意味であることは明らかなんですけどね。 > あるクラスと互換性のある属性と振る舞いを持つクラスは、そのクラスと何 > らかの関係があるクラスと見るべきです。 ここまでは合意します。 > 逆転させて言えば「関係の無いクラスに、互換性のある属性と振る舞いを持 > たせるべきではありません=継承関係にすべきではありません=LSP が成立 > してはいけません」となるのではないでしょうか。 違いますね。 「完全に互換性のある属性と振舞いを示すのであれば、それは一見関係ないよ うに見えても、実は関係があるのだ」というのが正解でしょう。 CES さんは、この考え方を、一貫して拒否されているようですが… > 小文字の is-a ってどこで使ってますか? ひょっとして原文? > 提示された日本語版には見当たらないのですが… ええと、小文字ではじまるのは「is-a」ではなく、「名詞」です。 また、ここで書いているのは原文の話です。日本語版を読んでいるだけでは、 何のことをさして書いているのか、分からないと思います。 > 俺は「LSP に照らすまでも無く、継承関係にしてはいけない場合がある」 > と言う。 これも繰り返しになりますが、「照らすまでもなく」のような暗黙の知識は、 法則としては役に立たないんですよ。だからこそ、明文化された LSP に 意味があるわけです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[737] Re:プログラミングの入門用言語
投稿者:(ぱ)
2007/02/20 02:13:25

>えーと、以前の言及には気づいていませんでした。 ちょっと検索してみました。 # この掲示板には検索機能はないですが、今のところ # http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&range=800 # とかやると過去の全発言が表示されるのでブラウザ内検索。 # もっと発言が増えてくると破綻しますが… そのうちガードをかけないと… 「一度や二度ではない」は言い過ぎだったようです。2回ですね。 このへんとか。 http://kmaebashi.com/bbs/list.php?boardid=kmaebashibbs&from=372&range=1 >私はゲームプログラミングにはうといのですが、Javaで「継承やオー >バーライドやインタフェースやスレッドを知らなければならない」 >というのは、 > > * やろうとしていることが実は複雑である > * Javaの提供するモデルとやろうとしていることが合ってない いくらなんでもボールがマウスを追いかけるくらいが複雑だとは思えないので、 Javaに関して言えば、「Javaの提供するモデルとやろうとしていることが合ってない」 のだと思います。もちろんこれは用途次第で、ダイアログを使うビジネスアプリケーション ならJavaのモデルでよいわけです。 ただ、Javaの場合、もともとWebページの飾り付け用の言語として世間に投入された はずで、にもかかわらずこのモデルはどうよ? とは思います。これは言語ではなく ライブラリの問題ですけど。 また、Javaの場合、たかがhello, worldでも、classとかpublic static void mainとか System.outとかの謎の言葉が出てきます。これはライブラリでなく言語の問題でしょう。 これを見ておっかなく思う初心者はいるかもしれません。が、実は「決まり文句」と 思っておけば済むことかもしれませんし、クラスがあってもhello, worldを1行で 書ける言語は可能です(Rubyのように)。 たとえばクラスが難しいものだとしても、初心者にクラスが見えないのなら、 初心者向け言語からクラスを外す理由にはなりません。その点で、[731] のyuyaさんの 指摘は的を射ていると思います。 ということで、私もおおむね説得されているわけですが、 a)初心者だからといって入門書を最初から順番にやっていくだけとは限らない。  雑誌に載っていたりネットに転がっているコードを読むこともあるだろう。 b)初心者だってライブラリは使うしマニュアルも読む。 ということは言ってよいと思います。Javaでhello, worldを書くとき、System.outは 決まり文句と思っていればよいかもしれませんが、これを決まり文句と思っている間は APIリファレンスが引けません。 また、C++だと入門書の最初のページでcoutとか使ってるかもしれませんが、 これをちゃんと理解するには演算子のオーバーロードを知らなきゃいけませんし、 ちょっとコレクションを使おうとするとSTLが出てきてtemplateを知らなくては いけなくなったりします。STLでなく(危険を承知で)Cの配列を使おうと決心したと しても、既存の、ゲームを作るのにすごく便利なライブラリが、引数にSTLの vectorを要求してたりして。 そういえば、話としてはずれますが、最初にCを勉強したときには (c = getchar()) != EOF がおっかなく見えたことを思い出しました。 >「削ることによってわかりやすくなる」という意見はよく聞きます >が、実際は「適切なモデル(or 機能)を提供することによってわか >りやすくなる」のであって、削ることだけが能じゃないと思います。 もちろん、なんでもかんでも削ればよいと思っているわけではないです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[736] Re:プログラミングの入門用言語
投稿者:まつもと
2007/02/20 02:13:25

>書き込みありがとうございます。正直、ちょっとびっくりです。 ># ていうかここでMatzにっきにリンクしたのは一度や二度ではないのですが、 ># この話題で書き込みいただけるのはびっくりというか。 えーと、以前の言及には気づいていませんでした。 >> * サンプルで扱おうとしている概念そのものが難しい >> * サンプルの作者が難しく表現してしまった >> >>のいずれかで、それを言語のせいにするのはどうかと思います。 > >たとえば、私が[719]で書いた「マウスを追いかけるボールのプログラム」には、 >初心者がおっかなく思う機能はそんなにないと思います。「サンプルで扱おうと >している概念そのものが難しい」わけではないのではないでしょうか。 >でも、同じことをJavaでやろうと思ったら、継承やオーバーライドやインタフェースや >スレッドを知らなければならないわけです。以下のページは、そういう意図で >書きました。 私はゲームプログラミングにはうといのですが、Javaで「継承やオー バーライドやインタフェースやスレッドを知らなければならない」 というのは、 * やろうとしていることが実は複雑である * Javaの提供するモデルとやろうとしていることが合ってない のいずれかなのではないのですか。だとすると、検討すべきことは 初心者におっかない機能を取り除くことではなく、もう一歩踏み出 して、やろうとしていることを簡潔に記述できる高レベルなものを 提供することではないでしょうか。それが文法なのかライブラリな のかは知りませんが。 >という意見が出ていますが、「とりあえずオブジェクト指向は要らんな。」 >「構造体も要らん。」「変数は全部グローバル。」という意見には賛同しないものの、 >初心者にとっておっかない機能を除きつつ、それなりに実用に使える「落としどころ」 >は、どこかにあるんじゃないかと私は思っているわけです。 「削ることによってわかりやすくなる」という意見はよく聞きます が、実際は「適切なモデル(or 機能)を提供することによってわか りやすくなる」のであって、削ることだけが能じゃないと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[735] Re:「投稿」ボタン
投稿者:(ぱ)
2007/02/20 02:13:25

>プレビュー画面で >「『投稿』ボタンをクリックすると、投稿されます。」 >と言いつつボタンが「送信」になってますね(^^;)  修正しました。ついでに、前から気になっていた、「ちゃんと改行を入れたかどうかチェックしてください」という文言を削除しました。  以前の仕様では、<pre>で囲んでいたので改行を入れないと困ったことになりましたが、今は<tt>で囲んでいるので、改行を入れる必要はなくなったためです。 # 引用しにくい気はしますが、画面幅が不明なとき、改行は入れない方がよいという # 面もあるので、今後はそのへんは投稿者にお任せしますです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[734] Re:プログラミングの入門用言語
投稿者:(ぱ)
2007/02/20 02:13:25

>であって、前橋さんが問題としている >(2)「初心者向きでない機能を使わないと初心者向けのサンプルが書けないこと」 うむむ。確かにそうですね。Javaで、ちょっとしたゲームを作るのが大変なのは 「初心者向きでない機能を使わないと初心者向けのサンプルが書けないこと」の方に 相当します。 私自身、考えがまだまとまっていないのですが、 「初心者向きでない機能があると、それは相当な高確率でプログラムに  顔を出す。たとえその機能を使わずともプログラムが書けたとしても」 というのでなければ、初心者向きでない機能を言語から外す理由にはなりませんね。 問題はこの命題が真かどうかですが。初心者向きでない機能があるが、それを使わずとも 初心者が満足する程度のプログラムが書ける言語を仮定して、 a)初心者向けの本などのサンプルプログラムで、わざわざ初心者向きでない  機能を使っているとしたら、その本の著者がアホ。 b)初心者がベーシックマガジンの投稿プログラムを解読しようとするケースはどうか。  これだと、初心者向きでない機能が使われていることもありそう。 c)ライブラリとかで初心者向きでない機能が使われていて、それを知らないと  重要なライブラリが使えない、とか。 b), c)みたいなケースもあるかなあ、とも思いますが… 現状のJavaScriptプログラマの大半は、たとえばクロージャを知らなくても 幸せにやってるわけで、確かにいらん心配のようにも思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[733] Re:正規表現関連の関数の質問
投稿者:タイガー
2007/02/20 02:13:25

>私のお勧めサイトというと、ここの参考URLですかねえ。 >http://kmaebashi.com/programmer/devlang/array.html ありがとうございます。 1回は既に読んでいたのですが、頭に入っていなかったので 何回も読み直してみます。 >あと、紙ものの資料では、大昔の情報処理学会誌に「ごみ集めの基礎と最近の動向」 >というのがあって、とてもよかったのですが、現在では入手不能だと思います。 >私はというと会社で該当の情報処理学会誌が捨てられる直前に気が付いて、 >コピーしておいたのですが、その後数回の引越しで現在行方不明です…だめだめ。 もったいないですね。でも今回の記事に生かせているのでは ないでしょうか。 >>以下の本を購入しようと思ったのですが、(ぱ)さんは読んだことありますか? >> >>http://www.amazon.co.jp/exec/obidos/ASIN/0471941484/qid=1136566955/sr=1-1/ref=sr_1_10_1/250-0589622-2949018 > >すみません、読んでないです。 有名らしいのですが、読んでなかったのですね。 GCに関してあまり勉強せずにできているなんてすごいですね。 また、投稿します。ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[732] 「投稿」ボタン
投稿者:yuya
2007/02/20 02:13:25

ひさしぶりに投稿してみて初めて気づいたんですが、 プレビュー画面で 「『投稿』ボタンをクリックすると、投稿されます。」 と言いつつボタンが「送信」になってますね(^^;) つまらんこと言ってすみません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[731] Re:プログラミングの入門用言語
投稿者:yuya
2007/02/20 02:13:25

こんにちは。 まつもとさんが「あまり問題にならない」と書いているのは (1)「言語が初心者向きでない機能を持つこと」 であって、前橋さんが問題としている (2)「初心者向きでない機能を使わないと初心者向けのサンプルが書けないこと」 とは別なのではないでしょうか? 私自身は(1)はまつもとさんと同様に「問題にならない」と思いますし、 (2)は前橋さんと同様に「そりゃ問題である」と思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[729] Re:プログラミングの入門用言語
投稿者:(ぱ)
2007/02/20 02:13:25

書き込みありがとうございます。正直、ちょっとびっくりです。 # ていうかここでMatzにっきにリンクしたのは一度や二度ではないのですが、 # この話題で書き込みいただけるのはびっくりというか。 >>これにはいまいち賛同しかねるんですよねえ。サンプルで見かけるプログラムで >>「初心者向きでない機能」が使われていると、おっかなく思う初心者は大勢いそうです。 おっかなく思う初心者がいるから言語からその機能を抜くとすれば、以下の問題が 発生すると思います。 a)おっかなく思うような難しい概念を抜きにして、ゲームとかを作りたいと思う  初心者が達成したい要件を実現できるかどうか。 b)おっかなく思うような難しい概念を抜きにして、上級者の要件を満たせるかどうか。 おっかない機能を抜いても、a), b)の両方を満たしているのであれば、文句なしだと 思います。そりゃ本当の上級者は別の言語を使ったほうが「よりよい」かもしれませんが、 そういう「よりよい」言語との間に十分な「のりしろ」があるなら、初心者も シームレスに移行できるのではないでしょうか。 >>こちらにある、「「初心者(だけ)のための言語」ってのは駄目だと思っている」 >>という意見にも賛成します。 これ↑に矛盾すると思われるかもしれませんけど、要は程度問題で、いずれツールの 移行を余儀なくされるとしても、その時の抵抗が少ないのであれば、許容されるのでは ないでしょうか。HSPやN88BASICはこのへんが… # と言いつつ、HSPやN88BASICで苦労した経験は、その後他の言語のありがたみを # 理解するのに有用かもしれない、とも思ったりもします。この苦労を知らずに # 大人になると、「グローバル変数が便利だったから、あちこちで使った。」に # なりかねないわけで。 > * サンプルで扱おうとしている概念そのものが難しい > * サンプルの作者が難しく表現してしまった > >のいずれかで、それを言語のせいにするのはどうかと思います。 たとえば、私が[719]で書いた「マウスを追いかけるボールのプログラム」には、 初心者がおっかなく思う機能はそんなにないと思います。「サンプルで扱おうと している概念そのものが難しい」わけではないのではないでしょうか。 でも、同じことをJavaでやろうと思ったら、継承やオーバーライドやインタフェースや スレッドを知らなければならないわけです。以下のページは、そういう意図で 書きました。 http://kmaebashi.com/zakki/zakki0027.html#lang イベントリスナを実現するために内部クラスや匿名クラスを使うのは 「サンプルの作者が難しく表現してしまった」のかもしれませんが、それ以外の点に ついては、Javaでは避けようがないでしょう。 >それに初心者がおっかなく思う危険のある機能を取り除いた言語っ >てのは、結局実務に役立たずで学ぶ価値のない言語になりそうです。 まつもとさんも、Cが「実務に役立たずで学ぶ価値のない言語」とは思いませんよね? 現状でCが難しいのは、実行時のチェックがないためとんでもないバグが出ることと、 宣言の構文やポインタと配列の妙な交換性にあると私は思っています。 前者は多少効率を犠牲にすれば回避できる話ですし、後者は単なる言語のバグです。 こういう点を改良したCもどきは作れると私は思っていて、crowbarは、ある意味 その実装のひとつのつもりです(型無しだったり、プロトタイプベースだったり、 クロージャがあったりするのはアレですが)。 こちらにも、 http://www.rubyist.net/~matz/20040925.html#c05 | 文字列型が違和感なく扱えて、便利そうな関数がもっと多くて(?)、引数が常に値渡しであるC言語最強、と思う。 という意見が出ていますが、「とりあえずオブジェクト指向は要らんな。」 「構造体も要らん。」「変数は全部グローバル。」という意見には賛同しないものの、 初心者にとっておっかない機能を除きつつ、それなりに実用に使える「落としどころ」 は、どこかにあるんじゃないかと私は思っているわけです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[728] Re:プログラミングの入門用言語
投稿者:まつもと
2007/02/20 02:13:25

>ただ、 >| 初心者と言えども言語の全ての機能を一度にマスターする必要はない。 >| よって言語が初心者向きでない機能を持つことは、あまり問題にならない。 > >これにはいまいち賛同しかねるんですよねえ。サンプルで見かけるプログラムで >「初心者向きでない機能」が使われていると、おっかなく思う初心者は大勢いそうです。 「おっかなく思う」かもしれませんが、その原因は * サンプルで扱おうとしている概念そのものが難しい * サンプルの作者が難しく表現してしまった のいずれかで、それを言語のせいにするのはどうかと思います。 それに初心者がおっかなく思う危険のある機能を取り除いた言語っ てのは、結局実務に役立たずで学ぶ価値のない言語になりそうです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[727] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

この人たちは、どんなソフトウェアかによらず適用できる、万能の分析手法でも求めているんだろうか… そんなものがありゃ誰も苦労しねぇっつうの。
[この投稿を含むスレッドを表示] [この投稿を削除]
[726] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>CESさんいわく > >>「is-a である関係が、LSP を満たすように作れ」と言っているのです。 > >それじゃあ「CESさん言うところのis-a」がLSPを満たすのは当たり前ですわな。 >そう定義したんだから。 「LSP を満たす関係が is-a である」とは言っていませんよ(そう言っているのは kit さんです)。 結果的にはそうなりますが、それは is-a の定義ではありません。 じゃあ is-a の定義は何なんだって話になりますが、言い換える言葉が見つかりませんね。is-a は is-a です。「A is-a B」は「AはBの一種」です。これがもっともシンプルかつ的確ではないですか。 以前に、ソフトウェアは「分析→設計→実装」の3段階で作られると言う話をしました。 俺の言う「is-a」の関係を決めるのは分析段階、LSP を満たすように作るのは設計段階の話です。 それで設計段階になって、LSP がどうしても満たせなくなったらどうするか? LSP を捻じ曲げて is-a を固持しろなんていってません。分析からやり直すのです。 ちょっと古い投稿を引用すが… [658] > 設計を見直す=分析のしなおし、だよん。って。 その通りではないですか。 あるプロジェクトに直面した時、「AはBの一種である」とも「AはBの一種ではない」とも、どちらの考え方もできます。 どちらが適切なのかを選ぶのが「分析」というプロセスですよ。 >我々は、設計段階で、どういう継承関係にすればうまくいくかを知りたい >ため、設計原則を求めているわけです。 そこで機械的に従えばいいガイドラインを求めるのは、分析プロセスの放棄ですよ。 >>1:オブジェクトが is-a であると仮定した。 >>2:LSP に照らし合わせたらうまく行かなかった。 >>  (照らし合わせるまでも無く判断できる場合もある) >>3:実はオブジェクトは is-a じゃなかったんだ。だから継承関係にはしない。 > >こちらも同様です。is-aの定義が「うまくいくかどうか」で決定されるんなら、 >「うまくいくようにやりなさい」と言ってるだけのことで、結局何も言って >いないのです。 そうですよ。 「どうすればうまく行くのか」は、その場合に応じて変わるのですから、それ以外に言いようが無いではありませんか。 こんな記事見つけました(Wikipedia - 「継承」) http://ja.wikipedia.org/wiki/%E7%B6%99%E6%89%BF > 一般的に、AがBを継承する場合、A is a B. (AはBの一種である)という > 意味的な関係(is-a関係)が成り立つ。従って、同じふるまいを持つから > と言って、意味的に無関係なクラス間に継承関係を持たせるのは適切でない > 場合が多い。 だそうですよ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[725] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

あんまりkitさんに押し付けておくのも申し訳ないのでちょっとだけ書きますが。 >>ところが、CES さんは、「継承してうまく動くような関係が is-a である。 >>したがって、継承してうまく動くような関係に対して、継承を当てはめれ >>ば良い」と言ってるに過ぎないわけです。これは見て分かるようにトート >>ロジーに過ぎず、設計の指針としては、全く役に立たないわけです。 このkitさんの言葉がすべてだと思いますがね。 >違います。 >「どういう関係が is-a であるか」については言及していません。 だから、それが問題なんだってば。既に指摘されているじゃないですか。 [715] >なぜなら、CES さんは、is-a という関係が具体的にどうあるべきかを一切述べ >ていないからです。 CESさんいわく >「is-a である関係が、LSP を満たすように作れ」と言っているのです。 それじゃあ「CESさん言うところのis-a」がLSPを満たすのは当たり前ですわな。 そう定義したんだから。 >1:オブジェクトが is-a であると仮定した。 >2:LSP に照らし合わせたらうまく行かなかった。 >  (照らし合わせるまでも無く判断できる場合もある) >3:実はオブジェクトは is-a じゃなかったんだ。だから継承関係にはしない。 こちらも同様です。is-aの定義が「うまくいくかどうか」で決定されるんなら、 「うまくいくようにやりなさい」と言ってるだけのことで、結局何も言って いないのです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[724] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

あといくつか、最初の方の書き込みに対するレス。 俺が「オブジェクトの is-a は LSP よりも優先されるべきだ」と言ったのは、「まずオブジェクトの is-a で判断し、次に LSP で判断すべきだ」という意味です。 その結果、最初に「is-a」とした判断が誤っていたというケースがあるのは既に言っています。 そのような場合でも、LSP を捻じ曲げて、断固、最初の「is-a」に固執すべきだと言った覚えはありません。 そして、まず「(常識的なオブジェクトの)is-a で判断する」のは、kit さんも同じであると [715] で書かれています。しかし、そう書かれたのはここが初めてです。 俺はてっきり「オブジェクトの is-a は問題にしなくていい。LSP だけで継承関係を判断すればいい」のだと思っていたのですが。 [713] では > なぜ、オブジェクト自身の is-a 関係が継承関係の設計に使えない > 場合があるのか、そのことを説明しているのが LSP です (ただし、 > 正方形や円のケースでは、LSP 以外にも、メモリ効率という別の理 > 由もあります)。継承関係の設計において、オブジェクト自身の > is-a 関係は使えない場合がある弱い判断基準なわけですが、LSP > は常に使える絶対的な判断基準なわけです。実はLSP(オブジェクト > の振舞いに関する is-a) の方が、オブジェクト自身のis-aよりも > むしろ本質的な原則なわけです。 と書かれています。 > オブジェクト自身の is-a 関係が継承関係の設計に使えない場合がある のは事実です。 しかし、そういう「場合がある」のであって、「常に使えない」とは書かれていません。 事実、[715] では > たとえば、「常識的に考えた is-a 関係に対して、継承を当てはめれば良 > い」というのは、正方形と長方形の例のようにうまくいかない例外もあり > ますが、かなり使える原則です。 と書かれています。「is-a の関係は使えないわけではない」のですね。 にも関わらず、[713] では「is-a は役に立たない。LSP こそ基準にすべきだ」と書かれているように見受けられます。 そう読んでしまうのは、俺の読解力不足ですか? [715] を境に、そちらの主張が切り替わっているような気がするのですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[723] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

要点抽出。 >議論が空転している気がするんです。整理しましょう。 >まず(常識的かどうかは置いておくとして)「オブジェクトの is-a」で大まかな関係を作るというのは、どちらも同じことを言ってますね。 >kit さんは、その上で「LSP に照らして破綻したら、継承関係にはしない」と言う。 >俺は「LSP に照らすまでも無く、継承関係にしてはいけない場合がある」と言う。 >結局、どの段階で、最初の「is-a」が間違えていたかを判断するのかが違うだけで、大差ないでしょう。 >問題は「LSP に照らさないと、間違いかどうか判断できないケースはあるのか」だと思うんですよ。 >そのへんどうです? 1:オブジェクトが is-a であると仮定した。 2:LSP に照らし合わせたらうまくいった。 3:継承関係を結んだ。 これに異論を差し挟む余地は無いでしょう。 問題は、そうでないケースですね。 kit さんの場合 1:オブジェクトが is-a であると仮定した。 2:LSP に照らし合わせたらうまく行かなかった。 3:オブジェクトは is-a なんだけど継承関係にはしない。 俺の場合 1:オブジェクトが is-a であると仮定した。 2:LSP に照らし合わせたらうまく行かなかった。   (照らし合わせるまでも無く判断できる場合もある) 3:実はオブジェクトは is-a じゃなかったんだ。だから継承関係にはしない。 結局、違うのは、過程3の前半だけなんですよね。 だから、[712] ではこう書いているんです。 > is-a と LSP をどうしても両立させられない例を一つでも出していただけませんか。 俺の方法ではうまく行かないケース、つまり 「どこからどう見ても疑念を挟む余地無く is-a なんだけど、LSP に照らし合わせたらうまく行かないから、LSP を優先するケース」 があるのか、ということなんです。俺が度々言う「is-a と LSP が矛盾するケース」ってのはこういうことなんです。 「常識的な is-a と LSP が矛盾するケース」ではないですよ。「どこからどう見ても」ってのは、「あらゆる非常識な関係も考慮に入れて」ってことです。 こういう場合があると言えますか? 俺は「あらゆる角度から見る」ことが不可能であるため、そのようなケースは存在しないと思うのですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[722] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>「is-a の意味は常識的なものとは限らない。場合によって、適切なもの >を選べ」というのは、実のところ、まったく意味のない言明です。なぜな >ら、CES さんは、is-a という関係が具体的にどうあるべきかを一切述べ >ていないからです。 どう言えばいいですかねぇ。 「クラスはオブジェクトの集合である」と考えた時、「ある集合Aと、その部分集合Bがあったら、B is-a Aである」でいいですか? もっとも、「どのような基準に従ってオブジェクトを集合に分類するか」には、結局、唯一解がないのは同じことなんですが。 >我々は、設計段階で、どういう継承関係にすればうまくいくかを知りたい >ため、設計原則を求めているわけです。 そんな話は今初めて聞きましたがねぇ… >たとえば、「常識的に考えた is-a 関係に対して、継承を当てはめれば良 >い」というのは、正方形と長方形の例のようにうまくいかない例外もあり >ますが、かなり使える原則です。 それでいいと思いますよ。 我々の社会常識が「大多数にとって都合がいい見方」であるように「多くの場合に都合がいいケース」はあってもおかしくありません。 ただし、それがたまたま成り立たないからといって、それだけを槍玉に挙げないでいただきたい。 ちなみに、件の文献の、長方形と正方形の関係の誤りは、LSP を持ち出すまでも無く「間違いだ」と判断できるものです(まぁ、LSP を考えてみて判断しても構わないのですが。別にそれでも is-a と LSP の矛盾は指摘できませんから)。 オブジェクトの is-a よりも LSP を優先すべきだという根拠にはなりません。 >また、「LSPに従うオブジェクト同士に対して、継承を当てはめれば良い」 >というのは、常に利用可能な原則です。 >ところが、CES さんは、「継承してうまく動くような関係が is-a である。 >したがって、継承してうまく動くような関係に対して、継承を当てはめれ >ば良い」と言ってるに過ぎないわけです。これは見て分かるようにトート >ロジーに過ぎず、設計の指針としては、全く役に立たないわけです。 違います。 「どういう関係が is-a であるか」については言及していません。 「is-a である関係が、LSP を満たすように作れ」と言っているのです。 件の文献も言っているではありませんか。 > あるところで、何か、置き換えが必要なところがあるとする。 > 型Sのオブジェクトo1 と、型Tのオブジェクトo2があって、 > プログラムが既に型Tのオブジェクトを使うように構築されているとする。 > o1がo2で置き換えられても、SがTのサブタイプであるならば、 > Pは同じ振る舞いをするべきである。 「サブタイプならば同じ振る舞いをすべきである」と書かれています。 「同じ振る舞いをするならサブタイプである」とは書かれていません。 結局、この文献は「どんなものを継承関係にすべきか」という指針には、一言も言及していないのです(「どんなものを継承関係にしてはいけないか」は、LSP を用いて言及しています。しかし、それは LSP を用いなくても指摘可能であることは度々述べています)。 >> 全く同じ属性と振る舞いを持つクラスは、同じクラスだと考えるべきです。 >> これは、「LSP が成り立つならば is-a も成り立つ」と言い換えることもできます。 > >一つ目の文章は正しいと思います。 >しかし、一つ目の文章から二つ目の文章を導くことはできません。 突っ込まれるかなーと思っていました。 ちょっと拡大しましょう。 全く同じ属性と振る舞いを持つクラスは、同じクラスだと考えるべきです。 そして、あるクラスと互換性のある属性と振る舞いを持つクラスは、そのクラスと何らかの関係があるクラスと見るべきです。 逆転させて言えば「関係の無いクラスに、互換性のある属性と振る舞いを持たせるべきではありません=継承関係にすべきではありません=LSP が成立してはいけません」となるのではないでしょうか。 >なお、Martin 氏の文章を読み返してみて、私がこれまで説明で使って >用語法が、Martin 氏の用語法と異なっているのに気づきました。 >私がこれまで >1. オブジェクトの振舞いに関する is-a >2. オブジェクト自身に関する is-a >という二つの言葉で区別してきたことを、Martin 氏は >1. 振舞いの is-a == オブジェクト(CamelCase にした名詞)の is-a >2. 物(子文字で始まる名詞)の is-a >と呼んでいますね。 >まあ、独立に読んでいれば意味は通じると思いますが、併せて読むと >混乱するのであまり良くありませんね。どうも申し訳ない。 小文字の is-a ってどこで使ってますか? ひょっとして原文? 提示された日本語版には見当たらないのですが… >設計手順としては、まず常識的な is-a を使って継承関係を考えてみた >上で、それを LSP で検証すればいいんですよ。検証に通らない場合には、 >たとえ常識的なis-a 関係であっても、継承関係にはしません。検証に通 >れば、もちろん継承関係にします。 >簡単でしょう? >本来無関係のオブジェクト同士うんぬんなどと悩む必要はありません。 議論が空転している気がするんです。整理しましょう。 まず(常識的かどうかは置いておくとして)「オブジェクトの is-a」で大まかな関係を作るというのは、どちらも同じことを言ってますね。 kit さんは、その上で「LSP に照らして破綻したら、継承関係にはしない」と言う。 俺は「LSP に照らすまでも無く、継承関係にしてはいけない場合がある」と言う。 結局、どの段階で、最初の「is-a」が間違えていたかを判断するのかが違うだけで、大差ないでしょう。 問題は「LSP に照らさないと、間違いかどうか判断できないケースはあるのか」だと思うんですよ。 そのへんどうです? >なお、もし本来無関係だと思っていたオブジェクト同士にLSPが成り立つ >のであれば、実はそのオブジェクト同士は、たぶん無関係じゃないんですよ。 本当に無関係でないのなら構いませんが、「たぶん」というのはいただけません。 実のところ、「本当に無関係か」を判断することはできません。どうにかして関係を見出すことはできます。 しかし、その関係は、設計者の意図した関係で無い可能性が大きいでしょう。 そのような関係に、LSP を成り立たせることは、メリットがあるとは思えません。 >しかし、通常のソフトウェア開発で、そういう発見を必要とすることは >あまりありませんから、無関係だと思うオブジェクト同士について、 >いちいちLSPを検証してみる必要はありません。 LSP は「たまたま成り立っちゃう」ものではなくて「意図して成り立たせる」ものであると考えます。 であるならば、先のようなデメリットを考えた時に「意図して崩す」ことも、当然ありえる話です。 それをせず、「たまたま成り立っちゃう」のを放置しておくのは、バグの温床になりませんか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[721] Re:プログラミングの入門用言語
投稿者:(ぱ)
2007/02/20 02:13:25

>processingのmouseXの代わりに、get_mouse_x()という関数を用意しました。 get_mouse_x()も、ウインドウ内の座標を返すのですから、ウインドウごとにしないと まずいですね。このへん考えるべきことはいろいろありそうですが、まあ方向性として。 ついでに補足しますけど、私は、HSPに関しては「もう21世紀なのにこの言語はないだろう」 というまつもとゆきひろさんの意見に賛成します。 http://www.rubyist.net/~matz/20040827.html#p01 こちらにある、「「初心者(だけ)のための言語」ってのは駄目だと思っている」 という意見にも賛成します。 http://www.rubyist.net/~matz/20040925.html#p02 ただ、 | 初心者と言えども言語の全ての機能を一度にマスターする必要はない。 | よって言語が初心者向きでない機能を持つことは、あまり問題にならない。 これにはいまいち賛同しかねるんですよねえ。サンプルで見かけるプログラムで 「初心者向きでない機能」が使われていると、おっかなく思う初心者は大勢いそうです。 crowbarはどうでしょうか。クロージャは、[717]を見るとわかるように、言語の作者の 私でさえ使いこなせていない。とほほほほ。 しかし、それはそれとして、オブジェクトの概念自体は必要だと思うし、初心者に わからないものでもないと思います。 w = open_window(800, 500); と書いてウインドウが開くのなら、そしてopen_window()を実行するたびに 何個でもウインドウが開けるのなら、そのウインドウに丸を描くのに w.fill_circle(x, y, 10); と書かなければならないのは、いくら相手が初心者でも、自明じゃないのかなあ。 別にfill_circle(w, x, y, 10); でもいいけど。 んで、シューティングゲームを作るのに敵をたくさん出したければ、自分でクラスっぽい ものを作らざるを得ないし、そのmove()メソッドをオーバーライドすることで、 ポリモルフィズムも自然に利用できるんじゃないかと思うんですけど、どうでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[720] Re:プログラミングの入門用言語
投稿者:(ぱ)
2007/02/20 02:13:25

> if (get_mouse_x() < x) { > x++; あ、条件式逆だった…
[この投稿を含むスレッドを表示] [この投稿を削除]
[719] Re:プログラミングの入門用言語
投稿者:(ぱ)
2007/02/20 02:13:25

>てなことを書かれておられましたが、Processing(http://processing.org/)はどう >でしょうか? 情報ありがとうございます。ちょっと見てみました。 ExamplesのStructureを一通り見ただけですが、 ・やっぱりイベントドリブンなのか。(mouseXという謎の変数が出てきてますが) ・ウインドウをふたつ開くことはできるのか? あたりが感想(と疑問)です。イベントドリブンは、処理が分断されるので、 ゲームとかを作りたい人にはわかりにくいのではないか、と私は思っています。 >これは、言語はJavaそのものですが、IDEによって、クラス定義などの >初心者にとって面倒そうな部分をうまく隠蔽してあって、単なる手続き型言語のように >使えます。これなら初心者にとっても比較的とっつきやすいんじゃないかと思います。 うーん。とっつきやすいかとは思いますが、結構用途が限定された言語にも見えます。 draw()は言語仕様に組み込まれているんでしょうか? たとえば現在私が作っているcrowbarをベースに、ライブラリ関数を追加して、 以下のようなプログラムは作れるようになるのではないでしょうか。 processingのmouseXの代わりに、get_mouse_x()という関数を用意しました。 # マウスを追いかけるボールのプログラム。 w = open_window(800, 500); # 引数はウインドウのサイズ x = 0; y = 0; prev_x = x; prev_y = y; for (;;) { # 直前のボールの消去 w.set_color(BLACK); w.fill_circle(prev_x, prev_y, 10); # 中心のx, y, 半径 if (get_mouse_x() < x) { x++; } elsif (get_mouse_x() > x) { x--; } elsif (get_mouse_y() < y) { y++; } elsif (get_mouse_y() > y) { y--; } w.set_color(WHITE); w.fill_circle(x, y, 10); prev_x = x; prev_y = y; wait(100); # 100msec待ちつつイベントを拾う。最後のイベントで上書き。 } 私が件の雑記で書きたかったのは、「ベーシックマガジン向けプログラミング言語」が あったらいいなあ、ということなんですけど、これぐらい書けたら、汎用性を保ちつつ、 それなりに達成してないでしょうかね? もちろん、fill_circle()だけでなく、 イメージを指定された場所に表示する関数とかも必要ですけれど。 wait()あたりの一等地の名前を使うことについては、名前空間で対処するとして。 でも、processingは、Javaアプレットとして実行できるのはいいと思います。 ゲーム作ったらやっぱり友達に自慢したいと思うので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[718] Re:正規表現関連の関数の質問
投稿者:(ぱ)
2007/02/20 02:13:25

>ご教授ありがとうございます。 >GCに少し興味を持ったのですが、お勧めのサイトなどありますか? 私のお勧めサイトというと、ここの参考URLですかねえ。 http://kmaebashi.com/programmer/devlang/array.html あと、紙ものの資料では、大昔の情報処理学会誌に「ごみ集めの基礎と最近の動向」 というのがあって、とてもよかったのですが、現在では入手不能だと思います。 私はというと会社で該当の情報処理学会誌が捨てられる直前に気が付いて、 コピーしておいたのですが、その後数回の引越しで現在行方不明です…だめだめ。 >以下の本を購入しようと思ったのですが、(ぱ)さんは読んだことありますか? > >http://www.amazon.co.jp/exec/obidos/ASIN/0471941484/qid=1136566955/sr=1-1/ref=sr_1_10_1/250-0589622-2949018 すみません、読んでないです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[717] Re:イテレータ(とCPS)
投稿者:(ぱ)
2007/02/20 02:13:25

土曜はとあるイベントにて大阪で飲んだくれておりまして、ずいぶん返事が遅くなりまして すみません。 それプラス、私自身、クロージャに慣れておらず継続もわかっておらず、今回のNykRさんの サンプルはずいぶん荷が重いものでした。とはいえ放り出していては勉強にならんので、 私なりに解釈してみました。間違い等ありましたらご指摘ください。 さて、単に木をイテレートするだけなら、 tree.each(closure(item) { # このitemについてなんかする }); という形のeachメソッドをツリーに装備するのは簡単で、ツリーの中で再帰して、 要素ごとに、渡されたクロージャを呼び出せばよいのですが、こういう形式(内部イテレータ) だと、あるツリーについて、「ここまで走査した」という状態を保存しておけないのが 問題になるわけですよね。その点、NykRさんの提示されたイテレータでは、こういう 書き方も許される。 # ふたつのイテレータでツリーを並列に走査する。 for (ite1 = iterator_GoF(foreachTree_CPS(tr)), ite2 = iterator_GoF(foreachTree_CPS(tr)); !ite1.isDone() && !ite2.isDone(); ite1.next(), ite2.next()) { print(" " + ite1.currentItem()); print(" " + ite2.currentItem()); } これができるのが外部イテレータの強みです。 Cなどで、再帰を使ってツリーを辿る場合、「ここまで走査した」という情報がスタック上に ありますから、スタックが1本しかない以上、ふたつのイテレータを並行して使うことは できないわけです(片方が片方の繰り返しに完全に含まれるなら可能)。 tr = {13,{5,{3,{},{}},{13,{12,{},{}},{}}},{16,{16,{15,{},{}},{}},{17,{},{}}}}; この例では、nodeの[0]にそのノードの値が、[1]に左の子が、[2]に右の子が 入っていますから、再帰で間順で走査するなら以下のようになります。 function internalIterate(node) { if (node.size() == 0) { } else { internalIterate(node[1]); # ...(a) print(" " + node[0]); # とりあえず表示しておく internalIterate(node[2]); } } (a)の箇所で左の子について再帰呼び出しを行い、それが戻ってきてから続きの処理を やっています。「戻ってきてから続きの処理をやる」ことができるのが再帰の嬉しい ところですが、それを期待していては、外部イテレータは作れない。 そこで、「戻ってきてから続きの処理をする」のではなく、「戻ってきてから やってほしい続きの処理をクロージャとして渡す」とすれば、関数から戻ってこなくても よくなる。その変換をしたのがこれ。 function internalIterate(node, cont) { if (node.size() == 0) { cont(); } else { internalIterate(node[1], closure () { # 続きをクロージャで渡す。 print(" " + node[0]); internalIterate(node[2], cont); }); } } # 第2引数には「処理の続きを渡す」のだから、最後に「おしまい」と表示される。 internalIterate(tr, closure() {print("おしまい");}); さて、この状態では、要素ごとに行う処理がprint()に固定されていますから 汎用性がありません。では引数でなにか関数を渡せば、とこうしても、 internalIterate(node[1], closure () { # 続きをクロージャで渡す。 proc(node[0]); # 処理を引数procで渡す internalIterate(node[2], cont); }); これでは内部イテレータと同じですから意味がありません。 そこで、このproc()にも、続きの処理をクロージャで渡してやることにします。 function foreachTree_CPS(proc) { return closure internalIterate(node, cont) { if (node.size() == 0) { cont(); } else { internalIterate(node[1], closure () { proc(node[0], closure() { internalIterate(node[2], cont); }); }); } }; } 外部イテレータの場合、このprocの第2引数をnext()の際に呼び出せばよいわけですね。 なぜならそれが「処理の続き」だから。 イテレータはこうなります。 function iterator_GoF(foreach_CPS, collection) { this = new_object(); this.first = closure () { this.isDone = closure () { return false; }; foreach_CPS(closure (item, cont) { this.currentItem = closure () { return item; }; this.next = closure () { cont(); }; })(collection, closure(){ # ..(b) this.isDone = closure () { return true; }; }); }; this.first(); return this; } イテレータのfirst()が呼び出されたときに、foreach_CPS()を呼び出して、 internalIetrate()を取得し、それに対しcollectionとクロージャを渡しています(b)。 これがつまり元のソースの internalIterate(tr, closure() {print("おしまい");}); に相当するわけですが、「おしまい」と表示する代わりに、isDoneについて、 trueを返すよう関数を差し替えています。 んで、internalIterate()に渡しているproc()では、 this.currentItem = closure () { return item; }; this.next = closure () { cont(); }; currentItemを設定後、nextに対し、contすなわち「処理の続き」をセットしています。 これで、次に利用者がnext()を呼び出したとき、internalIteratorの続きが実行される、と。 NykRさんのソースとは微妙に変わっていますが、こんな解釈でよいでしょうか? # いやあ、実に勉強になりました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[716] プログラミングの入門用言語
投稿者:みずしま
2007/02/20 02:13:25

こんにちは。 大分前の雑記「プログラミングの入門用言語(2003/5/1)」の最後の方で、 > C, Javaライクな文法で、こういう方向性の言語って、現在あるんでしょうか。 てなことを書かれておられましたが、Processing(http://processing.org/)はどう でしょうか?これは、言語はJavaそのものですが、IDEによって、クラス定義などの 初心者にとって面倒そうな部分をうまく隠蔽してあって、単なる手続き型言語のように 使えます。これなら初心者にとっても比較的とっつきやすいんじゃないかと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[715] Re:オブジェクト指向「初」入門
投稿者:kit1
2007/02/20 02:13:25

> 唯一の正解は無いでしょう。場合によって、適切なものを選べば、それ > が正解です。 これが CES さんのやり方の問題なんです。 「is-a の意味は常識的なものとは限らない。場合によって、適切なもの を選べ」というのは、実のところ、まったく意味のない言明です。なぜな ら、CES さんは、is-a という関係が具体的にどうあるべきかを一切述べ ていないからです。 我々は、設計段階で、どういう継承関係にすればうまくいくかを知りたい ため、設計原則を求めているわけです。 たとえば、「常識的に考えた is-a 関係に対して、継承を当てはめれば良 い」というのは、正方形と長方形の例のようにうまくいかない例外もあり ますが、かなり使える原則です。 また、「LSPに従うオブジェクト同士に対して、継承を当てはめれば良い」 というのは、常に利用可能な原則です。 ところが、CES さんは、「継承してうまく動くような関係が is-a である。 したがって、継承してうまく動くような関係に対して、継承を当てはめれ ば良い」と言ってるに過ぎないわけです。これは見て分かるようにトート ロジーに過ぎず、設計の指針としては、全く役に立たないわけです。 結局、CES さんの主張は、LSP どころか、(常にうまくとは限らない)常識的 な is-a 関係による継承関係の設計よりも、さらに劣るものにしか見えません。 また、CES さんは下記のように書いていますが、これはそもそも意味不明です。 > 全く同じ属性と振る舞いを持つクラスは、同じクラスだと考えるべきです。 > これは、「LSP が成り立つならば is-a も成り立つ」と言い換えることもできます。 この二つの文章のうち、一つ目の文章は、クラスとクラスの等価関係に 関する文章です。 二つ目の文章は、クラスとクラスの包含関係に関する文章です。 等価関係に関する文章と、包含関係に関する文章が、同一の意味である という発想は、まったくもって非論理的だと私は思います。 なぜ、この二つの文章が等価だと発想されたのか、残念ながら、私には 理解できません。 一つ目の文章は正しいと思います。 しかし、一つ目の文章から二つ目の文章を導くことはできません。 なお、Martin 氏の文章を読み返してみて、私がこれまで説明で使って 用語法が、Martin 氏の用語法と異なっているのに気づきました。 私がこれまで 1. オブジェクトの振舞いに関する is-a 2. オブジェクト自身に関する is-a という二つの言葉で区別してきたことを、Martin 氏は 1. 振舞いの is-a == オブジェクト(CamelCase にした名詞)の is-a 2. 物(子文字で始まる名詞)の is-a と呼んでいますね。 まあ、独立に読んでいれば意味は通じると思いますが、併せて読むと 混乱するのであまり良くありませんね。どうも申し訳ない。 > オブジェクト指向の第一目的は「わかりやすくすること」であると(今 > は)思っています > 本来、無関係のオブジェクト同士を継承関係にするのがわかりやすいで > すか? 私が欲しいのは良い設計指針であって、オブジェクト指向の第一目的は 何かという問いの答は実はどうでもいいんですが(なぜなら、人によって 答がそれぞれ違うので、そんなことの統一見解を決めても実益がないから です)、それは置いておいて、かなり誤解されていると思います。 設計手順としては、まず常識的な is-a を使って継承関係を考えてみた 上で、それを LSP で検証すればいいんですよ。検証に通らない場合には、 たとえ常識的なis-a 関係であっても、継承関係にはしません。検証に通 れば、もちろん継承関係にします。 簡単でしょう? 本来無関係のオブジェクト同士うんぬんなどと悩む必要はありません。 なお、もし本来無関係だと思っていたオブジェクト同士にLSPが成り立つ のであれば、実はそのオブジェクト同士は、たぶん無関係じゃないんですよ。 しかし、通常のソフトウェア開発で、そういう発見を必要とすることは あまりありませんから、無関係だと思うオブジェクト同士について、 いちいちLSPを検証してみる必要はありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[714] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>> 正方形は長方形のサブクラスであるとしても成り立つ場合は既に >> 書きました。is-a と LSP をどうしても両立させられない例を一 >> つでも出していただけませんか。 > >CES さんご自身が、正方形を長方形のサブクラスに『しない』方が >いい場合があると、[709]で認めているじゃないですか。常識的に >は、正方形 is-a 長方形ですから、当然、正方形は長方形のサブク >ラスとして継承関係を結ぶべきですし、Robert C. Martin 氏のエッ >セイでも、その方法をまず勧めています。しかし、そうしない方が >いい場合もあるわけですから、オブジェクト自身の is-a は必ずし >も判断基準に使えません。 俺はそういうことを言っているのではありません。 LSP なんか関係なく、「正方形 is a 長方形にならない場合もある」ということです。 その場合は、正方形が長方形でないのは何ら問題ではないのですから、「is a と LSP が矛盾する」とは言えません。 「常識的には」と書かれていますが、それが間違いの元です。 世の中に客観的な視点など存在しないというのは以前に書きました。 正方形 is a 長方形というのは、客観的に見えますが、「数学的に都合がいい見方」に過ぎません。常識と言うのも、大多数に都合がいい見方に過ぎません。真理ではないのです。 件の文献の勘違いは「長方形」の定義が曖昧なことです。 「正方形 is a 長方形」は数学に都合がいい見方、「縦と横の長さが独立していなければならない」は、このプログラムに都合がいい見方であって、数学に都合がいい見方ではない。 どちらの見方が間違いというのではありません。どちらも場合によっては正解なのですが、その「場合」が統一されていないのが間違いなのです。 このプログラムが「長方形」に何を期待しているのかが明確になっていないのがいけないのです。 大本の問題は、何のためのプログラムなのかを明確にしないまま、コードだけ示して煙に巻こうとしたことですね。 仮に、「常識的に考えて、正方形 is a 長方形なのだから、当然サブクラスにすべきだ」というのが正しいとして、では「りんご」は何のサブクラスにすべきですか? 常識的に考えて「果物」のサブクラス? それとも「バラ科の植物」? スーパーマーケットのシステム開発だったら「商品」のサブクラスにすべきではないですか? 唯一の正解は無いでしょう。場合によって、適切なものを選べば、それが正解です。 「正方形 is not a 長方形」にすべき場合は確かにあるでしょう。 それは、LSP に都合が悪いからそうなったのではなく、作りたいソフトの目的に合致しないからそうなったのです。 「is-a は LSP と両立できなかったので泣く泣く諦めた」のではなく「そもそも両立する必要が無かった」のです。 現在は is-a が推奨されています。百歩譲って has-a もまぁ認めるとしましょう。 問題は、「LSP さえ成り立つのなら、まったく無関係のクラス同士を継承関係にしていいのか」ということです。 (どういう設計になるのか知りませんが)LSP が成り立つのなら、車を鳥のサブクラスにするのもアリなのですか? オブジェクト指向の第一目的は「わかりやすくすること」であると(今は)思っています(以前、この掲示板に長期滞在したときは「バグを減らすこと」だと思っていました。考えは変わる可能性があります)。 本来、無関係のオブジェクト同士を継承関係にするのがわかりやすいですか? >> よろしければ、おすすめの本を紹介していただけないでしょうか。 > >今回紹介したエッセイ自身を含んだ、Robert C. Martin 氏の >「アジャイルソフトウェア開発の奥義」はいかがでしょう? >http://hamasyou.com/archives/System/aeeoeeueaconoeoeass.php >http://hamasyou.com/archives/System/aeeoeeueaoeeoeaass.php >に長めの紹介があります。 持ってますけど読んでませんでした。 OCP や LSP の評判を聞いて買ったのですが、買ったきりで。 そのうち読むことにしましょう。 こちらにも一点、考え直したことがあったので、最後にそれについて言及します。 オブジェクト指向において、オブジェクトを特徴付けるものは、属性と振る舞いです(プロパティとメソッドとか、メンバ変数とメンバ関数とか、言語によって呼び方はいろいろあるでしょうが)。 つまり、全く同じ属性と振る舞いを持つクラスは、同じクラスだと考えるべきです。 これは、「LSP が成り立つならば is-a も成り立つ」と言い換えることもできます。 しかし、逆に言えば「違うクラスに、全く同じ属性と振る舞いを持たせるべきではない」「関係の無いクラスに、LSP を成り立たせるべきではない」とも言えます。 そう考えれば、「is-a が成り立つのならば LSP が成り立つのは当然」「is-a が成り立たないのならば、LSP も成り立たせるべきではない」のではないでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[713] Re:オブジェクト指向「初」入門
投稿者:kit
2007/02/20 02:13:25

> 俺がプログラミングを初めてまだ7年、オブジェクト指向が分かっ > てきたのはここ1、2年ほどのことですのでね。 意外と長いんですね。 私はプログラミング歴は24年ぐらい、オブジェクト指向に関しては プログラミング言語C++第1版の和訳や、Smalltalk-80のオレンジブッ クの和訳が出た頃からですから、20年弱くらいですかね。 その前に、先輩から米国byte誌のSmalltalk-80特集号を見せてもらっ たこともありましたが。 > 正方形は長方形のサブクラスであるとしても成り立つ場合は既に > 書きました。is-a と LSP をどうしても両立させられない例を一 > つでも出していただけませんか。 CES さんご自身が、正方形を長方形のサブクラスに『しない』方が いい場合があると、[709]で認めているじゃないですか。常識的に は、正方形 is-a 長方形ですから、当然、正方形は長方形のサブク ラスとして継承関係を結ぶべきですし、Robert C. Martin 氏のエッ セイでも、その方法をまず勧めています。しかし、そうしない方が いい場合もあるわけですから、オブジェクト自身の is-a は必ずし も判断基準に使えません。Robert C. Martin 氏が、エッセイの 「本当の問題」「何が悪いのか?」「Design By Contract」のとこ ろで説明しているのは、そういうことです。オブジェクト自身の is-a で考えるのは誤りであり、オブジェクトの振舞いに関する is-a で考えないといけないのです。前に出た円と楕円の話も同じ です。 このあたりは、和訳を読むよりも、原文 http://www.objectmentor.com/resources/articles/lsp.pdf の "What Went Wrong" のところを読んだ方が、むしろ理解しやす いかもしれません、「a Square object is definitely not a Rectangle object.」と書いてありますから。和訳の「決定的な違 いがあるのです。」という表現では、残念ながら、ここの is-a と is-not-a のニュアンスが消えてしまっています。私は原文の方を 先に読んだので、ここのところが非常に強く印象に残りました。 なぜ、オブジェクト自身の is-a 関係が継承関係の設計に使えない 場合があるのか、そのことを説明しているのが LSP です (ただし、 正方形や円のケースでは、LSP 以外にも、メモリ効率という別の理 由もあります)。継承関係の設計において、オブジェクト自身の is-a 関係は使えない場合がある弱い判断基準なわけですが、LSP は常に使える絶対的な判断基準なわけです。実はLSP(オブジェクト の振舞いに関する is-a) の方が、オブジェクト自身のis-aよりも むしろ本質的な原則なわけです。 現在では、has-a の関係は、継承よりも委譲を使うのが良い解だと されていますが、昔は has-a でも継承を使うことが良くありまし た。今でもたまにそういうプログラムを見ることがあると思います。 これも、アプリケーションを限定すれば、has-a で LSP を満たす 場合があることから来ているわけです。has-a で継承して問題のな いアプリケーションは、オブジェクト自身の is-a 関係で継承して 問題のないアプリケーションよりも、はるかに少ないので廃れてき ているわけですが。 has-a が廃れてきているのに is-a がそうではないのは、オブジェ クト自身についてis-a の関係が成り立つ場合のほとんど(ただし全 てではない)で、同時に、オブジェクトの振舞いに関する is-a 関 係(すなわちLSP)も満たすからです。 > よろしければ、おすすめの本を紹介していただけないでしょうか。 今回紹介したエッセイ自身を含んだ、Robert C. Martin 氏の 「アジャイルソフトウェア開発の奥義」はいかがでしょう? http://hamasyou.com/archives/System/aeeoeeueaconoeoeass.php http://hamasyou.com/archives/System/aeeoeeueaoeeoeaass.php に長めの紹介があります。 ただ、和訳だと上述したように、ニュアンスが失われる部分はある でしょうね。また、data中心でモデリングした結果の扱いについて は、この本の主張に異論がある場合もあるでしょう。この本では常 にOOAを優先すべしという方向ですが、data中心でモデリングした 結果の方を優先した方がいい場合もある筈です。 私は、Robert C. Martin 氏自身の名前は、亡くなられた石井勝さ んのページで知りました。 http://www.objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/oo-principles.html 石井さんがこのページを書かれたのは1999年ですね。 今ではLSPは有名な原則ですが、これが広まったのは Liskov 氏自 身の功績というよりは、Robert C. Martin 氏の功績の方が大きい と思います。私がこの法則を知ったのも今回のエッセイを読んだ からですし、google で The Liskov Substitution Principle を 検索して最初に出てくるのも、このエッセイですし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[712] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>もちろん、「オブジェクトが is-a であるか」と「オブジェクトの『振舞い』 >が is-a であるか」の二つが矛盾しない場合は問題ありません。しかし、矛盾 >した場合に優先すべきなのは、LSP の方です。 >しかしどうやら CES さんは、矛盾した場合、LSP よりも前者を優先すべきだ >とお考えのようですね。 どちらかと言えばそうかもしれません。 LSP を守ることも重要ですが、まずはオブジェクトの is-a を優先し、その上で LSP が守られるように都合をつけるべきだと思います(結果的には、両方守るべきです)。 >Robert C. Martin がこの文書を発表してから、もう10年近く、Liskov から >数えれば、もう15年以上経っており、私は既に常識的な知識だと思っていまし >たが、驚かれたということは、どうやらそうではなかったようですね。 俺がプログラミングを初めてまだ7年、オブジェクト指向が分かってきたのはここ1、2年ほどのことですのでね。 >そもそも LSP や、この文書が有名になったのは、「オブジェクトが is-a である >か」という判定条件が成り立たない場合があるということを、はっきりと示 >しているからだと思うのですが。 >is-a だけで済むのであれば、わざわざ原則として掲げる必要も、文書で解説 >する必要もありません。 >失礼ながら、御自身の考えを他人の掲示版で開陳されるよりも先に、もう少し >オブジェクト指向関係の良書で勉強された方が良いのではないでしょうか。 よろしければ、おすすめの本を紹介していただけないでしょうか。 >少なくともこれまでのところ、私は CES さんの意見に説得される可能性は >ありません。CES さんの考えを証明する具体的な例を一切目にしていません >ので。前の投稿でも書きましたが、私は机上の空論は嫌いですし、具体的な >例のない議論に説得されることは決してありません。 >(ぱ)さんも同様ではないかと思います。 その言葉はそっくりお返しします。 正方形は長方形のサブクラスであるとしても成り立つ場合は既に書きました。 is-a と LSP をどうしても両立させられない例を一つでも出していただけませんか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[711] Re:オブジェクト指向「初」入門
投稿者:kit
2007/02/20 02:13:25

> いや恐れ入った。 > 「オブジェクトが is-a であるか」は守られなくてもいいのか。 その通りです。 もちろん、「オブジェクトが is-a であるか」と「オブジェクトの『振舞い』 が is-a であるか」の二つが矛盾しない場合は問題ありません。しかし、矛盾 した場合に優先すべきなのは、LSP の方です。 しかしどうやら CES さんは、矛盾した場合、LSP よりも前者を優先すべきだ とお考えのようですね。 Robert C. Martin がこの文書を発表してから、もう10年近く、Liskov から 数えれば、もう15年以上経っており、私は既に常識的な知識だと思っていまし たが、驚かれたということは、どうやらそうではなかったようですね。そも そも LSP や、この文書が有名になったのは、「オブジェクトが is-a である か」という判定条件が成り立たない場合があるということを、はっきりと示 しているからだと思うのですが。 is-a だけで済むのであれば、わざわざ原則として掲げる必要も、文書で解説 する必要もありません。 失礼ながら、御自身の考えを他人の掲示版で開陳されるよりも先に、もう少し オブジェクト指向関係の良書で勉強された方が良いのではないでしょうか。 あるいは、もし、「オブジェクトが is-a であるか」は LSP よりも優先する という考えをどうしても主張されたいのであれば、掲示版はそもそも不向きな メディアだと思います。 なぜ LSP よりも優先するのかを、適切な例を含めた上で、ご自分の Web ペー ジで解説された方が良いと思いますよ。 もし、Barbara Liskov や Robert C. Martin も優れた考えであるのなら、 独立した文書として公開する価値が十分あると思います。 少なくともこれまでのところ、私は CES さんの意見に説得される可能性は ありません。CES さんの考えを証明する具体的な例を一切目にしていません ので。前の投稿でも書きましたが、私は机上の空論は嫌いですし、具体的な 例のない議論に説得されることは決してありません。 (ぱ)さんも同様ではないかと思います。 > 「正方形は長方形のサブクラスであるか?」という質問に、唯一の正解はあり > ません。答えは、数学に厳密である必要がある場合には YES 、そうでない場 > 合には NO になります。 あるアプリケーションが、Robert C. Martin が例に示しているような 条件と、数学的に厳密であるという必要があるという条件のどちらも 同時に満たしている必要がある場合はどうすれば良いのでしょうか? もちろん、答えは NO です。 従って、上に書いた CES さんの答え「数学に厳密である必要がある 場合には YES」は、条件に抜けがある誤った答であるということに なります。 私には、CES さんが LSP の本質を理解していないように見えますね。 理解しているなら、上のような文章が出てくる筈はありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[710] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

#ちょっと落ち着いて整理しましょう… >だったら最初からそう書けばいいのに。 >つか、それを読み取れというのは無茶と言うものです。 これは、(お互いに)「自分ではそう言ったつもりだったけど、相手には伝わらなかった」ということで傷み分けにしましょうや。 >私が最初から言っているのは、 > >「クラスを辞書で引いて分類と書いてあるからといって、プログラムの設計の際に、 >クラスを分類として捉えることが正しいことになるわけではない」 > >ということです。 なるほど。 俺は「辞書的用語」と「術語」の問題(あくまで用語の問題で、実際の設計はまた別問題)だと思っていました。 前橋さんは「どう呼ぶか」よりも「実際にどう設計するか」を問題視されていた。そこが齟齬の原因。 ちなみに、それに関する俺の答えは [706] > もちろん、実装の都合上、必ずしもそうとは言えないクラスが出てくることはあり得るでしょう。しかし、それらは例外として考えるべきであり、基礎としては無駄ではありません です。一言で言えば「(例外はあるかもしれないが)原則的に、辞書的意味と同じと考えていい」ということ。 後半は感情的になって煽ってしまったことはお詫びいたします。 #最後の最後で何とかまとまってよかった。
[この投稿を含むスレッドを表示] [この投稿を削除]
[709] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

> リンク先の文章で示されている「正方形を長方形のサブクラスにするのが誤り」という話が的外れであることは、ずいぶん前に書いてますよ。 と言うだけでは何なのでちょっと補足。 「正方形は長方形のサブクラスである」というのは、数学的に見れば、確かにそうです。 しかし、長方形の数学的な性質とは、「4つの角が全て直角である四角形」というだけであって「縦と横の長さが独立していなければならない」という要件はありません。 リンク先の文章では、その数学的には必要とされていない要件を要求しているのですから、もはや「数学的には正方形は長方形のサブクラスだ」という前提は成り立たないのです。 では、正方形クラスを長方形クラスのサブクラスとして設計するのは誤りなのでしょうか? そうとは限りません。 数学的に正しいプログラムを書く必要があって、長方形の縦と横の長さが独立していなければならないという要件が無いのなら、この設計は全く妥当なものです。 「正方形は長方形のサブクラスであるか?」という質問に、唯一の正解はありません。 答えは、数学に厳密である必要がある場合には YES 、そうでない場合には NO になります。 提示された文章では、それがちぐはぐだからおかしなことになっているのです。 [653] あたりで言っているのはそういうことです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[708] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>> 「サブクラスの方が機能が上」という考え方だと、is-a の関係を考えた時 >> に「機能が豊富なものは機能がショボいものの一種」ということになって変 >> だよね。 > >変じゃないですよ? >Robert C. Martin が、Liskovの置換原則に関する有名な文書 >http://www2.ocn.ne.jp/~yamagu/object/LSP-J.pdf >で述べた通り、継承の際に使う is-a の関係は、「オブジェクトが is-a で >あるか」ではなく、「オブジェクトの『振舞い』が is-a であるか」で判断 >すべきです。 >「機能が豊富なものは機能がショボいものの一種」というのは、この原則を >平易な言葉で言い替えたものに過ぎません。 >オブジェクト指向設計の大原則です。 いや恐れ入った。 「オブジェクトが is-a であるか」は守られなくてもいいのか。 LSP を守るべきであるのは当然だけど、リンク先の文章で示されている「正方形を長方形のサブクラスにするのが誤り」という話が的外れであることは、ずいぶん前に書いてますよ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[707] Re:オブジェクト指向「初」入門
投稿者:kit
2007/02/20 02:13:25

抽象論は苦手なので、このスレッドには書かないようにしようと思ってたの ですが、堂々めぐりしているように見えるので。 > 「サブクラスの方が機能が上」という考え方だと、is-a の関係を考えた時 > に「機能が豊富なものは機能がショボいものの一種」ということになって変 > だよね。 変じゃないですよ? Robert C. Martin が、Liskovの置換原則に関する有名な文書 http://www2.ocn.ne.jp/~yamagu/object/LSP-J.pdf で述べた通り、継承の際に使う is-a の関係は、「オブジェクトが is-a で あるか」ではなく、「オブジェクトの『振舞い』が is-a であるか」で判断 すべきです。 「機能が豊富なものは機能がショボいものの一種」というのは、この原則を 平易な言葉で言い替えたものに過ぎません。 オブジェクト指向設計の大原則です。 > 集合論(というか論理学のベン図)で考えれば、スーパークラスはサブクラ > スよりも一段階抽象的なので、直接比較できないことはわかるよね。 これは、「オブジェクトが is-a であるか」を継承関係の設計の判断基準に 使うべきだと述べているように見えます。これは、第一近似として使いやすい 方法ではありますが、Robert C. Martin の文書で示されている通り、厳密に 考えると誤りであり、Liskovの置換原則の方を優先すべきです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[706] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>>「術語としてのクラス」に「辞書的な『分類』という意味」を期待する > >ことについてとやかく言った覚えはありません。 >いや、とやかく言っている、というのならその部分を引用して示してください。 このへん@684 > でも、「クラス」という言葉の辞書的定義が「分類」だったからといって、 > 術語として使われるときそのままの意味とは限らないし、「クラス」という > 言葉を選んだ人が間違えたのかもしれない。だから、その言葉の意味に > 過剰な期待をしてもしょうがないのでは、と言っているのです。 >私が最初から言っているのは、 > >「クラスを辞書で引いて分類と書いてあるからといって、プログラムの設計の際に、 >クラスを分類として捉えることが正しいことになるわけではない」 > >ということです。 だったら最初からそう書けばいいのに。 つか、684 からそれを読み取れというのは無茶と言うものです。 >[684]での引用を再度引用しますが、 > >>この議論の最初のほうで、CESさんは >>>例えば、「クラス」という用語の意味は「分類」であって、「原型」ではありませんから、 > >と書いています。「ありません『から』」なんだというのでしょうか。 >もちろん、術語は用途をちゃんと表しているのにこしたことはないけれど、 >術語の方から、設計や分析についてのあるべき姿を導くことはできない。 「クラス」という用語の意味は「分類」であって、「原型」ではありませんから、「クラスはオブジェクトを作る原型になるもの」ではなく「クラスはオブジェクトを分類したもの」だと捉えるべきだ、ということです。 そして、そう捉えることは、まったく自然なように思われるのです(もちろん、実装の都合上、必ずしもそうとは言えないクラスが出てくることはあり得るでしょう。しかし、それらは例外として考えるべきであり、基礎としては無駄ではありません)。 >だから私は、術語なんかに期待するのではなく、 > >>クラスを分類として考えるのがよいとCESさんがお考えなら、それが具体的に >>有効であるケースを、例示して主張するのがよいのではないでしょうか。 > >と、具体的な例示をするのがよいのでは、と言っているのです。 「クラス」という言葉の「辞書的用法」と「述語的用法」に関しての議論だとばかり思っていたので、「クラスを分類だと考えていない」とはまさか思いませんでした。 こうも書かれているのに。 ># クラスを分類とする考え方を否定しているわけではありません。 > 「そのへんの入門書にある考え方だと、こういう例ではこういうモデリングを > してしまいがちだけど、分類として考えればこんなモデリングになって、 > こういう拡張をするときのことを考えたらこっちのほうが修正箇所が > はるかに少なくてすむよね」とか。 「サブクラスの方が機能が上」という考え方だと、is-a の関係を考えた時に「機能が豊富なものは機能がショボいものの一種」ということになって変だよね。 集合論(というか論理学のベン図)で考えれば、スーパークラスはサブクラスよりも一段階抽象的なので、直接比較できないことはわかるよね。 「サイヤ人とスーパーサイヤ人はどっちがすごいか」は、暗黙のうちに「サイヤ人=スーパーじゃないサイヤ人」という仮定を置かず、「サイヤ人はスーパーサイヤ人のスーパークラス」とする限り、比べられない(作中ではこの仮定が暗黙のうちに成立している)。 「スーパーじゃないサイヤ人とスーパーサイヤ人」ではスーパーサイヤ人の方がすごいけど、スーパーじゃないサイヤ人はスーパーサイヤ人のサブクラスではない。 …でいい? 「こう考えるといいよね」というよりも「こう考えないと明らかに変だよね」という感じなので、修正工数云々で対比することはできない。
[この投稿を含むスレッドを表示] [この投稿を削除]
[705] Re:多態性(ポリモーフィズム)について
投稿者:CES
2007/02/20 02:13:25

ふと思ったのは、「オブジェクト指向データベース」っていう言葉からして破綻している気がするなぁ…というものでした。 「オブジェクト指向データベース」って何なんだ…と思って、易しい入門を読んでみましたが、そこでは結局、「データを隠蔽し、getter と setter を持っているものがオブジェクトである」という程度でした。 結局のところ、「データベース」である以上は「オブジェクト指向言語と相性のいい永続化ストア」を脱し切れなくて、一歩踏み出すならば「オブジェクトベース」にならなければいけないような気がします(その具体的な形がどうなるかまでは分かりませんが)。 #まぁ、汎用機時代からデータスキーマを使いまわすような運用では、そうそうパラダイムシフトも起こせないでしょうけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[704] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>まだ酔っ払ってますか? 何故そんな言葉を持ち出されたのかさっぱり分かりません。 スーパークラスやサブクラスは術語であり、悟空やベジータはスーパーサイヤ人です。 単純に置き換えただけですが何か? >「術語としてのクラス」に「辞書的な『分類』という意味」を期待するのは、 >まったく過剰ではないと思える、ということです。 だったら最初からそう書けばいいのに。 つか、 >>「クラス」も「スーパークラス」も、全く過剰だとは思えないので。 これからそれを読みとれというのは無茶というものです。 で、私は、 >「術語としてのクラス」に「辞書的な『分類』という意味」を期待する ことについてとやかく言った覚えはありません。 いや、とやかく言っている、というのならその部分を引用して示してください。 私が最初から言っているのは、 「クラスを辞書で引いて分類と書いてあるからといって、プログラムの設計の際に、 クラスを分類として捉えることが正しいことになるわけではない」 ということです。 [684]での引用を再度引用しますが、 >この議論の最初のほうで、CESさんは >>例えば、「クラス」という用語の意味は「分類」であって、「原型」ではありませんから、 と書いています。「ありません『から』」なんだというのでしょうか。 もちろん、術語は用途をちゃんと表しているのにこしたことはないけれど、 術語の方から、設計や分析についてのあるべき姿を導くことはできない。 だから私は、術語なんかに期待するのではなく、 >クラスを分類として考えるのがよいとCESさんがお考えなら、それが具体的に >有効であるケースを、例示して主張するのがよいのではないでしょうか。 と、具体的な例示をするのがよいのでは、と言っているのです。 私がどのような例示を求めているのかについて、誤解があるといけないので テンプレまで書いてあげました。 >「そのへんの入門書にある考え方だと、こういう例ではこういうモデリングを >してしまいがちだけど、分類として考えればこんなモデリングになって、 >こういう拡張をするときのことを考えたらこっちのほうが修正箇所が >はるかに少なくてすむよね」とか。 ここまでやっているのにさ。 回答はこれだぜ。 >例示が必要でしょうか? 「is-a」「汎化-特化」の考えは、まさに分類だと >思うのですが(「汎化」「特化」という用語を誰が考えたかは知りませんが、 >いくらこれが術語だからと言って「低機能」「高機能」という意味でないのは >明らかでしょう)。 (特に自分とこの掲示板で)こんな終わり方をするのは私も嫌なんですが、 意思の疎通をする気がないようなので、これまでとしたいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[703] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>>何が過剰なのかわからないのです。 > >[684]に書いたことを繰り返すつもりはありません。 #こういう終わり方は大嫌いなのですが 「意思の疎通ができてないみたいなので、これまでとしましょう」って打ち切っていいですか? >>「クラス」も「スーパークラス」も、全く過剰だとは思えないので。 > >もはや日本語むちゃくちゃになっていませんか? > >「スーパーサイヤ人に過剰な期待をするのはいかがなものか」 >「悟空もベジータも、全く過剰とは思えない」 > >意味不明です。 まだ酔っ払ってますか? 何故そんな言葉を持ち出されたのかさっぱり分かりません。 最初の文の意味が通じなかったのならば補足します。 「術語としてのクラス」に「辞書的な『分類』という意味」を期待するのは、まったく過剰ではないと思える、ということです。 何が「過剰な期待」で、何が「過剰でない期待」なのか。術語には何なら期待していいのか。 [684] を何度読み返しても、それがわからないんですよ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[702] crowbar ver.0.4のバグを修正しました
投稿者:(ぱ)
2007/02/20 02:13:25

># つhttp://www.shiro.dreamhost.com/scheme/docs/cont-j.html 紹介していただいたshiroさんのページは、以前読んだことはあったのですが、 あまり理解できずにそのままになっていました。 そこで今回、以下のページのActionScript版をベースに、crowbar版を書いて 試してみたところ… クラッシュしました。 http://torus.jp/memo/x200403/nandemo_keizoku_as.rd.html 調べてみたら、「配列リテラルの要素にオブジェクトを格納すると、一時的に スタックからの参照が切れることがあり、そのタイミングでGCすると死ぬ」という 潜在バグが(おそらくver.0.2から)あり、かつ、ver.0.4では「毎回GCする」という テスト用の状態でリリースしてしまったために発覚しました。 取り急ぎ修正版をリリースしました。毎度テストが甘くすみません。 力尽きたので今日はここまでです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[701] Re:正規表現関連の関数の質問
投稿者:タイガー
2007/02/20 02:13:25

>crowbarでも、CRB_dev.hにあるオブジェクト確保系の関数群において、自動的に >参照をスタックに積んでしまうことは可能です。ネイティブ関数実行後スタックを >戻す処理も、処理系側で苦もなくできます。 >なぜ今そうなっていないかというと… うーん、何故なんでしょう? (^^; >たとえば、オブジェクトを確保して、すぐに既存の配列の要素にセットする、 >という場合、特にスタックに積む必要はないのでその辺の無駄を嫌ったような >気がしますが、現状の仕様は、「いつGCが起きる可能性があるか」という点について >crowbarの内部実装をネイティブ関数の作者に晒していることになりますから、 >大変よろしくないですね。次バージョンでは修正します。 > >ネイティブ関数側で、大量のオブジェクトの確保/破棄を繰り返すような処理が >あるとすると、スタックが大量に無駄になりますが、そんなことわざわざ >ネイティブ関数で書かないですよねえ… あるいはその場合でも、 >ネイティブ関数用を呼び出したときのCRB_LocalEnvironmentに >local referenceの表を持ち、スタックではなくそちらに参照を入れるようにして >おけば、ネイティブ関数のプログラマに手で解放させることも不可能ではないですし。 ご教授ありがとうございます。 GCに少し興味を持ったのですが、お勧めのサイトなどありますか? 以下の本を購入しようと思ったのですが、(ぱ)さんは読んだことありますか? http://www.amazon.co.jp/exec/obidos/ASIN/0471941484/qid=1136566955/sr=1-1/ref=sr_1_10_1/250-0589622-2949018
[この投稿を含むスレッドを表示] [この投稿を削除]
[700] Re:多態性(ポリモーフィズム)について
投稿者:happie
2007/02/20 02:13:25

>そちらのblogも拝見しました。 ありがとうございます。 >「業務アプリケーションにはオブジェクト指向は >向かない」というのは同意見です。まあ業務アプリでも、フレームワークや、 >アプリケーションの「機能」の側でOOを使うところはたくさんありますが、 >「データ」に処理は結びつかないと思います。 そうなんですね。処理系、GUIアプリだとOOは相性はいいのですが、多くの本で、その辺の区別をせずに何でもOOがいいとして、で業務アプリを例にとって解説しているのですが、構造を見るとあまりOOっぽくない。最近流行のDIも、シングルトンを使ってかつインターフェースに対する実装クラスは一つが基本なので、これってOOなのって思ってしまいます。 >ということで、総論では賛成ですが、「メモリ中心では無理だから」という方の >理由付けはいらないんじゃないでしょうか。メモリに載ろうが載るまいが、 >あるいはオブジェクト指向データベースがディスク上のデータを透過的に見せて >そのへんの問題をすべてクリアしてくれようが、データに処理が結びついていない以上、 >やっぱりオブジェクト指向には合わないのだと思います。 確かにそのとおりですね。データと処理が結びつかないという議論とは別でした。 形上、オブジェクト指向的に作ったところでデータベースとの絡みでいろいろと問題が出てくるし、データベース中心に考えていった方がいいんじゃない、ということで、業務アプリケーションはオブジェクト指向に向いていないということを言おうとしていました。現在のORマッピングツールでは駄目ですね。おっしゃるとおり、たとえオブジェクト指向データベースで完全に透過的になったとしても、やっぱり「オブジェクト指向的」としか言えないでしょうね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[699] Re:多態性(ポリモーフィズム)について
投稿者:(ぱ)
2007/02/20 02:13:25

>はじめまして。happieと申します。 はじめまして。 >また『ポインタの完全制覇』や「疑り深いあなたのためのオブジェクト指向再入門」 >については、本質的なところを突いているため大変興味深く読ませていただきました。 ありがとうございます。 >(ぱ)さんは、ポリモーフィズムに関してあまり記述がなかったように思いますが、 >どのようにお考えですか。 ポリモルフィズムは重要な概念だと思います。 「疑り深い~」でポリモルフィズムについて触れていないのは、今のところまで書いて 力尽きたというか、優先度がそれほど高くないと思ったからです。 マルチプルインスタンスについては、オブジェクト指向を普通に使っている人なら 誰でも普通に使っているにもかかわらず、そして初心者は結構そこでつまずくにも 関わらず、ほとんど誰もそれを重要であると声に出して言わないので、 これはまずいだろ、と思いあれを書いたわけですが、インタフェースと ポリモルフィズムに関しては、私は重要だと思いますし、誰もが重要だと言いますから、 特に声を上げる必要もないかなあ、と。 ただ、ポリモルフィズムが実際にどういう場面でどこまで使えるか、という点に ついては注意を払う必要があるとは思います。 最近、この掲示板の[649]にも書いていますが、「CADを作るとき図形にdraw() メソッドを付けるのは正しいのか」という話を、私はしょっちゅう出しています。 そちらのblogも拝見しました。「業務アプリケーションにはオブジェクト指向は 向かない」というのは同意見です。まあ業務アプリでも、フレームワークや、 アプリケーションの「機能」の側でOOを使うところはたくさんありますが、 「データ」に処理は結びつかないと思います。 業務アプリでは、たくさんのテーブルがあり、また、さらにたくさんの「機能」が あります。そして、しょっちゅう機能追加を行っても、そうそうテーブル定義には 変更を加えません。データが何よりえらいのであって、処理がデータに依存しても、 データが処理に依存してはいけない。これは基本的には「CADで図形にdraw()メソッドを 付けるべきではない」というのと同じことだと思います。 ということで、総論では賛成ですが、「メモリ中心では無理だから」という方の 理由付けはいらないんじゃないでしょうか。メモリに載ろうが載るまいが、 あるいはオブジェクト指向データベースがディスク上のデータを透過的に見せて そのへんの問題をすべてクリアしてくれようが、データに処理が結びついていない以上、 やっぱりオブジェクト指向には合わないのだと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[698] Re:正規表現関連の関数の質問
投稿者:(ぱ)
2007/02/20 02:13:25

>>これは、Cの関数を抜けた後の話ですよね。レジストリに登録するという。 >>crowbarでは、Cの関数の実行中でも、ヒープ関連の関数を呼び出すと >>GCが動く可能性がありますから、ひとまずスタックに積まなければなりません。 > >私はよく分かっていないのですが、このcrowbarのアプローチは >メジャーなのですか? たぶん、メジャーでも、望ましいものでもないと思います。 Rubyだと、GCがCスタックをスキャンするから何もしなくてよく、 Pythonだと、参照カウンタを上げたり下げたりを手でやらなければいけなかったと 思いますが(過去形?)、たとえばJavaのJNIでは、別にCスタックをスキャンする わけでもないのに、確保したオブジェクトについては特に何もする必要はありません。 JavaHouseにある首藤さんの記事によれば、 http://java-house.jp/ml/archive/j-h-b/013314.html | JNI: native method のフレームごとに local references (の表) を用意、 | local references から辿れるオブジェクトは回収しない。 とのことです。 crowbarでも、CRB_dev.hにあるオブジェクト確保系の関数群において、自動的に 参照をスタックに積んでしまうことは可能です。ネイティブ関数実行後スタックを 戻す処理も、処理系側で苦もなくできます。 なぜ今そうなっていないかというと… うーん、何故なんでしょう? (^^; たとえば、オブジェクトを確保して、すぐに既存の配列の要素にセットする、 という場合、特にスタックに積む必要はないのでその辺の無駄を嫌ったような 気がしますが、現状の仕様は、「いつGCが起きる可能性があるか」という点について crowbarの内部実装をネイティブ関数の作者に晒していることになりますから、 大変よろしくないですね。次バージョンでは修正します。 ネイティブ関数側で、大量のオブジェクトの確保/破棄を繰り返すような処理が あるとすると、スタックが大量に無駄になりますが、そんなことわざわざ ネイティブ関数で書かないですよねえ… あるいはその場合でも、 ネイティブ関数用を呼び出したときのCRB_LocalEnvironmentに local referenceの表を持ち、スタックではなくそちらに参照を入れるようにして おけば、ネイティブ関数のプログラマに手で解放させることも不可能ではないですし。 >>ただ、たぶんこの場合、グローバル変数を共有して動かしたいのだと思います。 >>そうだとすれば、外部crowbarスクリプトのトップレベルを動かす方法は >>ありません。ただし、外部crowbarスクリプト中の関数であれば、 >>CRB_compile()とCRB_call_function()を使えば実行可能です。 > >外部crowbarスクリプト中の関数を呼べるということは、 >データを引数でC側からcrowbarの関数側にプッシュしてあげて、 >crowbarスクリプトのglobal変数に保存しておけば、 >データの共有はできると思います。 誤解させる書き方をしてしまったかもしれませんが、CRB_compile()と CRB_call_function()を使う方法なら、インタプリタを共有できますから、 グローバル変数によるデータ共有が可能です(まあ、引数で受け渡しするほうが よいのはよいでしょうけど)。 >私は、(ぱ)さんの本はほとんど持っていますが、もう少し内容を濃くして >「プログラミング言語を作る」もぜひ出版して欲しいです。 >早くていつ頃になりそうですか? いやあ、それはさっぱりわかりません。 まだ企画が動き出したわけですらないですし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[697] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>何が過剰なのかわからないのです。 [684]に書いたことを繰り返すつもりはありません。 >「クラス」も「スーパークラス」も、全く過剰だとは思えないので。 もはや日本語むちゃくちゃになっていませんか? 「スーパーサイヤ人に過剰な期待をするのはいかがなものか」 「悟空もベジータも、全く過剰とは思えない」 意味不明です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[696] 昨晩は酔っ払ってました
投稿者:(ぱ)
2007/02/20 02:13:25

 えー、すみません、興味深い投稿がたくさんされてますが、昨晩は酔っ払って帰って きてそのまま寝てしまいました (^^;  お返事は今晩ということでよろしくお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[695] イテレータ(とCPS)
投稿者:NykR
2007/02/20 02:13:25

http://kmaebashi.com/programmer/devlang/regexp.html > Java流の、要素を取り出すだけで強制的にポインタを進めてしまう仕様は、 > ちょっとどうかと思うんですがねえ。 同感です。マージとかやりにくそう。 というわけでどちらか片方にするなら、GoFの方が良いな、と思ってたりするのですが、以下のような関数を用意すれば、GoF方式とJava方式の両方をあまり手間をかけずに作ることができます。(両方欲しい、という訳ではありませんが) function iterator_GoF(foreach_CPS) { this = new_object(); this.first = closure () { this.isDone = closure () { return false; }; foreach_CPS(closure (item, cont) { this.currentItem = closure () { return item; }; this.next = closure () { cont(null); }; }, closure (ret) { this.isDone = closure () { return true; }; }); }; this.first(); return this; } function iterator_Java(foreach_CPS) { this = new_object(); closure () { this.hasNext = closure () { return true; }; foreach_CPS(closure (item, cont) { this.next = closure () { cont(null); return item; }; }, closure (ret) { this.hasNext = closure () { return false; }; }); }(); return this; } function foreach(foreach_CPS, proc) { # ついでに作った foreach_CPS(closure (item, cont) { cont(proc(item)); }, closure (ret) {}); } # foreach_CPSは CPS(continuation passing style, 継続渡し形式)で書かれたforeachです。 # つhttp://www.shiro.dreamhost.com/scheme/docs/cont-j.html これらの関数に対し、コレクション側でforeach_CPSを用意して渡せば それぞれの関数に対応したイテレータが返されます。 例えば以下のような2分木があったとすれば tr = {13,{5,{3,{},{}},{13,{12,{},{}},{}}},{16,{16,{15,{},{}},{}},{17,{},{}}}}; function foreachTree_CPS(tree) { return closure (proc, fin) { closure internalIterate(node, cont) { if (node.size() == 0) { cont(null); } else { internalIterate(node[1], closure (ret) { proc(node[0], closure (ret) { internalIterate(node[2], cont); }); }); } }(tree, fin); }; } という関数を1つ定義するだけで print("foreach:"); foreach(foreachTree_CPS(tr), closure (item) { print(" " + item); }); print("\n"); print("GoF :"); for (i = iterator_GoF(foreachTree_CPS(tr)); !i.isDone(); i.next()) { print(" " + i.currentItem()); } print("\n"); print("Java :"); for (i = iterator_Java(foreachTree_CPS(tr)); i.hasNext();) { print(" " + i.next()); } print("\n"); のように、3種類のイテレータが使えてまあ便利。 でもシーケンシャルなコレクションだとそれほど嬉しくはありません。 CPSではforやwhileがまともに使えないので、例えば配列用のforeach_CPSは function foreachArray_CPS(array) { return closure (proc, fin) { closure loop(index, cont) { if (index == array.size()) { cont(null); } else { proc(array[index], closure (ret) { loop(index + 1, cont); }); } }(0, fin); }; } なんてことになって、要素数が多いとforeachに渡したときにクラッシュするなあ、とか、初期値と変数が遠いなあ、とか。 今の実装だと末尾再帰の最適化は物凄く大変そうですしね。 # でもこの形式のループは個人的にはむしろ欲しかったりします、crowbar ver.0.3.02にcall/ccを付けたので。ちなみに、この時点で末尾再帰の最適化はやりやすくなったのですが、CRB_Objectが増えたので先にGCを改造しなければならないのでした(どうでもいい報告)。 この手法は、 ・外部イテレータを直接作るのが難しくて ・ループによらないアクセスが簡単な データ構造(木とか) *では* 役に立ちます。 # ライブラリが簡単に書けます。というのはそれほど嬉しいことではない気がする
[この投稿を含むスレッドを表示] [この投稿を削除]
[694] Re:正規表現関連の関数の質問
投稿者:タイガー
2007/02/20 02:13:25

>LuaやJavaScriptの方法だと、名前空間が動的になるんですよね。 >環境作ってないので試してませんけど、Luaで「hoge = string」と書くと、 >hoge.sub()で文字列置換ができるようになるんじゃないでしょうか。 試してみたらできました。 静的、動的な違いというのも理解しました。 ありがとうございます。 >また、単なるテーブル(crowbarならオブジェクト)を名前空間に使うと、 >ライブラリ関数が壊せてしまうというのも、問題だと思います。 >Luaでは、string.subに代入できるんですよね? こちらも試してみたらできました。 確かに問題になりそうですね。 >と言いつつ、実は今crowbarに予約語finalを持ち込んで定数を作れるように >したりしてるので、ライブラリ関数のメンバとか名前空間オブジェクトをfinalに >してしまえば、これでもいい気がしてきました。うーん。 crowbarでfinalで定数作れるようにしてたんですね。 よくimmutableなクラスを作るときにはfinalにしないといけないと 書いてあるので、そういう意味ではfinalは必須な気もします。 Luaには定数にする方法はなかったような…。 >これは、Cの関数を抜けた後の話ですよね。レジストリに登録するという。 >crowbarでは、Cの関数の実行中でも、ヒープ関連の関数を呼び出すと >GCが動く可能性がありますから、ひとまずスタックに積まなければなりません。 私はよく分かっていないのですが、このcrowbarのアプローチは メジャーなのですか? >Luaの仮想スタックって、まさにcrowbarのスタックのような独自スタックでは? >crowbarのような手間がなさそうなところからして、Cの関数の部分だけ、 >Cスタックをスキャンするconservative GCなのかなあ、とも思ったのですが、 >テーブルを確保すると勝手にスタックに積まれること、他の参照型というと >文字列くらいですがCRB_Stringのような型では扱っていないことからして、 >コンサバGCではないようですね。 Luaの仮想スタックは、確かに独自スタックです。 しかし、私の知識不足とLuaのGCのメカニズムは記述がなかったため よく分かりません。 >うーん、CRB_add_native_function()は別にinterface.cの中で呼ぶ必要はないんですが >(実際今はnative.cとかの中で呼んでますし)。実行中でも呼べますから、 >ネイティブ関数内でも登録可能です。 実行中に呼べるのは応用範囲が広がりそうですね。 >これに近いことをするのであれば、(ver.0.4で新設された)CRB_create_closure()で >クロージャ作って、CRB_add_assoc_member()でオブジェクトに登録するなり >CRB_add_global_variable()でグローバル変数に登録するなりもできます。 crowbarのように実際のデータを直接扱えるとコードが分かりやすいと 思います。 Luaみたいに仮想スタック上にデータを作っておいて…みたいのは 分かりにくいです。 >crowbarスクリプトをまったく独立して動かせばよいのなら、インタプリタを >もうひとつ作って実行すればよいです。 >ただ、たぶんこの場合、グローバル変数を共有して動かしたいのだと思います。 >そうだとすれば、外部crowbarスクリプトのトップレベルを動かす方法は >ありません。ただし、外部crowbarスクリプト中の関数であれば、 >CRB_compile()とCRB_call_function()を使えば実行可能です。 外部crowbarスクリプト中の関数を呼べるということは、 データを引数でC側からcrowbarの関数側にプッシュしてあげて、 crowbarスクリプトのglobal変数に保存しておけば、 データの共有はできると思います。 C側に戻したいときもC側から渡す引数につめてあげれば 戻せます。 私は、この(例えば)Cとスクリプトとのデータの共有が一番 重要と思っているのですが、crowbarでも簡単にできそうですね。 だとすれば、既に組み込み言語として十分使えるレベルだと思います。 実は、Luaではこの一番重要な部分が一番面倒くさいです。 >やりたいこと・やるべきことはいろいろあって、その中にはcrowbar以外のことも >含まれます。もう少ししたら、crowbarほっぽりだして別の言語を作り始める >可能性も(かなり高い確率で)あります。企画の趣旨的には、crowbarを実用言語に >するよりも、バイトコードインタプリタのような違う実行形態の言語をもうひとつ >作る、という方が合っている気がしますし。 バイトコードインタプリタはかなり興味深いです。 楽しみにしています。 >ということで、crowbarに期待してくださるのは大変嬉しいことですし、 >私としても励みになるのですが、私の時間が有限である以上お応えできるかどうかは >わからない、ということで、すみませんがご理解ください。 私は、(ぱ)さんの本はほとんど持っていますが、もう少し内容を濃くして 「プログラミング言語を作る」もぜひ出版して欲しいです。 早くていつ頃になりそうですか? >あと、今だと鬼車のライセンス表記をどこかに含めなければいけませんよね。 >次バージョンで検討します。 ソースの理解は、まず動作が分かってからだと思うので、 とりあえず簡単に動かしてみたいという気持ちはあります。 あと、Cとの連携方法など、ユーザの視点でのcrowbarの使い方 みたいな文章も欲しいところです。 時間がないでしょうが、いつも楽しみにしていますので 頑張ってください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[693] 多態性(ポリモーフィズム)について
投稿者:happie
2007/02/20 02:13:25

はじめまして。happieと申します。 以前、拙HPで勝手に(ぱ)さんのページを紹介させていただきました。 また『ポインタの完全制覇』や「疑り深いあなたのためのオブジェクト指向再入門」については、本質的なところを突いているため大変興味深く読ませていただきました。 オブジェクト指向の本質が、マルチプルインスタンスにあるということについても全く同意見です。 ところで、一部のオブジェクト論者の中には、ポリモーフィズムこそがオブジェクト指向の本質で、インターフェースでプログラミングすることが最も重要なことのように謳っています。実際、デザインパターンの解説書ではそのことがたびたび強調されています。 (ぱ)さんは、ポリモーフィズムに関してあまり記述がなかったように思いますが、どのようにお考えですか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[692] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>>もっと言ってしまえば、「クラス」ではなくて「りんご」でも別に良かった…ということ? > >私は「術語に*過剰な*期待をするのはいかがなものか」と言っているのです。 >「術後にまったく期待するな」などと言った覚えはありません。 何が過剰なのかわからないのです。 「クラス」も「スーパークラス」も、全く過剰だとは思えないので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[691] Re:正規表現関連の関数の質問
投稿者:(ぱ)
2007/02/20 02:13:25

>しかし、私はLuaの方法と、モジュールによる名前空間の分割の >本質的な違いを説明することはできません。 LuaやJavaScriptの方法だと、名前空間が動的になるんですよね。 環境作ってないので試してませんけど、Luaで「hoge = string」と書くと、 hoge.sub()で文字列置換ができるようになるんじゃないでしょうか。 Javaなどでもimportでパッケージ指定を省略できたりしますが、その規則は あくまで静的です。これを動的に変えられると、どこで何呼んでるんだか さっぱり、という状態になりそうな気がします。もっとも、 「そんなことしないでしょ」という考え方もありますが。 # でも、s = stringとかしてタイプ量を節約する人はいる気がする。 また、そういう規則では、統合開発環境はお手上げでしょうが、それは 形無し言語全般に言えることかも。 RDEとやらの入力保管機能はどうなってるんだろ、とマニュアルを見てみたら… ううむ。 http://rubyde.sourceforge.net/hiki/ja/Auto%2BComplete.html また、単なるテーブル(crowbarならオブジェクト)を名前空間に使うと、 ライブラリ関数が壊せてしまうというのも、問題だと思います。 Luaでは、string.subに代入できるんですよね? と言いつつ、実は今crowbarに予約語finalを持ち込んで定数を作れるように したりしてるので、ライブラリ関数のメンバとか名前空間オブジェクトをfinalに してしまえば、これでもいい気がしてきました。うーん。 >配列とハッシュが同列なら、配列リテラルがあるので、 >ハッシュリテラルも欲しいところです。 >初期化ができないと不便なので私は必須だと思っています。 ご意見ありがとうございます。 …と言いつつ、やりたいことは他にもあるので、すみませんが優先順位は高くないです。 >(2)に関しては、Luaは、GCされたくなければ、グローバルとして >別に残しておかなければなりません。 これは、Cの関数を抜けた後の話ですよね。レジストリに登録するという。 crowbarでは、Cの関数の実行中でも、ヒープ関連の関数を呼び出すと GCが動く可能性がありますから、ひとまずスタックに積まなければなりません。 >また、LuaがコンサバGCかどうかは不明ですが、 >crowbarのようなcrowbarスタックはLuaには、ないと思います。 Luaの仮想スタックって、まさにcrowbarのスタックのような独自スタックでは? crowbarのような手間がなさそうなところからして、Cの関数の部分だけ、 Cスタックをスキャンするconservative GCなのかなあ、とも思ったのですが、 テーブルを確保すると勝手にスタックに積まれること、他の参照型というと 文字列くらいですがCRB_Stringのような型では扱っていないことからして、 コンサバGCではないようですね。 >現状のCRB_add_native_function()で、ネイティブ関数を登録 >しておかなければならないのは、interface.cのソースを直接 >いじらないといけないので、これはLuaの方が楽だと思います。 うーん、CRB_add_native_function()は別にinterface.cの中で呼ぶ必要はないんですが (実際今はnative.cとかの中で呼んでますし)。実行中でも呼べますから、 ネイティブ関数内でも登録可能です。 >Cで書いた関数(例えば、l_sin()という関数)を、 >lua_pushcfunction(L, l_sin) >lua_setglobal(L, "mysin") >で、登録することによりLuaでmysin()という関数が使えます。 これに近いことをするのであれば、(ver.0.4で新設された)CRB_create_closure()で クロージャ作って、CRB_add_assoc_member()でオブジェクトに登録するなり CRB_add_global_variable()でグローバル変数に登録するなりもできます。 >また、Luaでは、CからLuaのコードを呼ぶ際に、 >Lを、lua_State型の変数とすると、 >lua_dofile(L, "test.lua") >により、test.luaが実行されるのですが、 >crowbarでは、これはどうやればできますか? crowbarスクリプトをまったく独立して動かせばよいのなら、インタプリタを もうひとつ作って実行すればよいです。 ただ、たぶんこの場合、グローバル変数を共有して動かしたいのだと思います。 そうだとすれば、外部crowbarスクリプトのトップレベルを動かす方法は ありません。ただし、外部crowbarスクリプト中の関数であれば、 CRB_compile()とCRB_call_function()を使えば実行可能です。 >ただのプログラミング練習言語で終わらせるのはもったいないと >思います。 >何か特徴を付けて、存在価値のある言語にして欲しいです。 やりたいこと・やるべきことはいろいろあって、その中にはcrowbar以外のことも 含まれます。もう少ししたら、crowbarほっぽりだして別の言語を作り始める 可能性も(かなり高い確率で)あります。企画の趣旨的には、crowbarを実用言語に するよりも、バイトコードインタプリタのような違う実行形態の言語をもうひとつ 作る、という方が合っている気がしますし。 ということで、crowbarに期待してくださるのは大変嬉しいことですし、 私としても励みになるのですが、私の時間が有限である以上お応えできるかどうかは わからない、ということで、すみませんがご理解ください。 >あと、できれば、Windows版のcrowbar.exeもダウンロード >できるようにして欲しいです。 確かに便利だと思いますし、今まで考えなかったわけでもないのですが、 企画の趣旨的にどうかという気もします。 あと、今だと鬼車のライセンス表記をどこかに含めなければいけませんよね。 次バージョンで検討します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[690] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>もっと言ってしまえば、「クラス」ではなくて「りんご」でも別に良かった…ということ? 私は「術語に*過剰な*期待をするのはいかがなものか」と言っているのです。 「術後にまったく期待するな」などと言った覚えはありません。 >例示が必要でしょうか? 「is-a」「汎化-特化」の考えは、まさに分類だと思うのですが(「汎化」「特化」という用語を誰が考えたかは知りませんが、いくらこれが術語だからと言って「低機能」「高機能」という意味でないのは明らかでしょう)。 そんな話をした覚えもありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[689] Re:正規表現関連の関数の質問
投稿者:タイガー
2007/02/20 02:13:25

>ここを見る限り、stringというテーブルに、いろんなメソッドを >クロージャとして埋め込んでいる、という認識でよいでしょうか? その通りです。 私の表現は間違ってました。 stringテーブルにクロージャが入っているですね。 >ここでのstringの使われ方は、純粋に名前空間としてのものですよね。 >現状のcrowbarには、名前空間を分割する機能がないので、今回はreg_で >逃げたわけです。モジュールによる名前空間の分割はいずれそのうちやろうと >思っていますから、現時点で、Lua的な方法(crowbarでやるなら、グローバルな >stringというオブジェクトにクロージャを格納することになるのでしょう)で >解決しようとは思いません。 おっしゃる通り、名前空間と同じ仕組みです。 事実、Luaにはパッケージという概念がなく、テーブルにより パッケージを表現します。 しかし、私はLuaの方法と、モジュールによる名前空間の分割の 本質的な違いを説明することはできません。 しいて言えば、モジュールが一般的な意味のモジュールであれば、 文法を用意してあげることにより、ソースを見たときの 分かりやすさ(明確さ)は増すような気はします。 Javaみたいな感じだとpackageが名前空間を表していることが明確です。 Rubyのモジュールだと結局Luaと同じになるような気がします。 >crowbarの場合、スコープチェーンは「最上位の関数の中」までで止まっていますが、 >これをグローバルな領域まで広げ、グローバルな名前空間もassocで表現するようにして、 >グローバル変数もそのassocに、またグローバルな関数はクロージャとして >格納するようにすれば、名前空間の考え方が統一されるとともに、 >モジュールが欲しければトップレベルのオブジェクトをモジュールとして考えればよい、 >ということになります。実際JavaScriptはそんな感じになっています。 これもおっしゃる通りです。 Luaでは、グローバルなテーブルというものが、あらかじめ存在し、 stringなどは、その中に登録されています。 >ハッシュはですねえ… >もちろん考えていないことはないのですが、問題は、どの階層で実現するかです。 >言語の外で、ライブラリとして提供しても十分だと思うんですが、 >どうでしょうか(基本型のハッシュキーの取得方法は考えるにしても)。 >ハッシュのリテラル(「{"a" => "hoge"}」みたいなの)って要りますかねえ。 >考えるべきところはたぶんふたつあって、 私のイメージでは、配列(リスト)とハッシュは、同じ階層だと 思っています。 私の中で、リスト、ハッシュ、文字列は基本的なデータ構造だと 思います。 また、Luaでは、Table型により、配列とハッシュの両方を表現可能です。 >a)ハッシュのリテラルを言語仕様として用意するかどうか。 >b)ハッシュのオブジェクトを、(JavaScriptやLuaのように)現状のassocの > 別の見え方として考えるかどうか。 > >私としては、a)はまあやるならやってもいいけど(ただし優先順位は低い)、 >b)は嫌、というところです。 a)に関しては、 配列とハッシュが同列なら、配列リテラルがあるので、 ハッシュリテラルも欲しいところです。 初期化ができないと不便なので私は必須だと思っています。 b)に関しては、 assocの別の見え方にするというより、ハッシュを作り、 それでassocを表現するというイメージだと思いますが、 個人的には分けても統一化してもどちらでも良いと思います。 >ええと、私はLuaを使っていないのでご意見をお聞かせ願いたいわけですが、 >現状で、Luaとcrowbarを比べてみてどうでしょうか? >Luaとcrowbarでネイティブ関数を書くときのことを比較すると、 > >(1)引数や戻り値 > Lua…スタックを直接操作 > crowbar…引数や戻り値なので、ちょとはわかりやすいかな。 >(2)GC > Lua…何もしなくていい(?) Ruby的コンサバGC? >  lua_newtable()が「新しい空のテーブルを作り、スタックに積む。」そうだから、 >  スタックにないものは勝手にGCされそうな気もするんですが。 > crowbar…GCされたくなかったらスタックに積んどけ。 >  正直、これは面倒くさいです。せめて、最後のスタックの後始末を処理系側で >  やれば、というか実はそれは造作もないのですが。 >(3)アプリケーション固有データ > Lua…ユーザデータ > crowbar…ネイティブポインタ >  ファイナライザの仕様も含め、そっくりに見えます。また車輪を再設計したか。 (1)に関しては、crowbarの方は、CRB_Valueの構造が一度 分かってしまえば分かりやすいと思います。 Luaでは、常に目に見えない仮想スタックの状態がどうなっているかを 把握しておかないといけないのでかなり分かりづらいです。 (2)に関しては、Luaは、GCされたくなければ、グローバルとして 別に残しておかなければなりません。 また、LuaがコンサバGCかどうかは不明ですが、 crowbarのようなcrowbarスタックはLuaには、ないと思います。 (3)に関しては、Luaの方は、仮想スタック経由で扱うので 関数により抽象化されていて、 crowbarの方は、CRB_Valueで直接アクセスするので、 私個人の考えでは、crowbarの方が、何をやっているのかが 分かりやすいような気もします。 とにかくLuaでは常に仮想スタック経由なので、 そこら辺の仕組みが分かってしまえば良いのですが、 それがメリットなのかはまだ分かっていません。 >いっそ今みたいに特定の引数を持ったネイティブ関数が呼ばれる仕様ではなく、 >また、CRB_add_native_function()で関数を登録する必要もない、というようにして、 >もっと楽にネイティブ関数を書けるようにするというのも考えられますが… >処理系依存のコードはあんまり書きたくないですし。 現状のCRB_add_native_function()で、ネイティブ関数を登録 しておかなければならないのは、interface.cのソースを直接 いじらないといけないので、これはLuaの方が楽だと思います。 Luaでは、ライブラリとして登録するのは同様に面倒ですが、 ただLua側からC側の関数を呼びたいだけなら、 Cで書いた関数(例えば、l_sin()という関数)を、 lua_pushcfunction(L, l_sin) lua_setglobal(L, "mysin") で、登録することによりLuaでmysin()という関数が使えます。 このぐらいの手軽さがないと組み込みとは言えないと思います。 また、Luaでは、CからLuaのコードを呼ぶ際に、 Lを、lua_State型の変数とすると、 lua_dofile(L, "test.lua") により、test.luaが実行されるのですが、 crowbarでは、これはどうやればできますか? >まあ、別にRubyと張り合う気はないんですけど。 >方向性として、組み込み用スクリプトというのは、[685]にも書いたように >そもそも言語処理系に興味を持った時点からありました。 >ただ、今は別の方向も考えています。こんなの↓とか。 > >http://kmaebashi.com/zakki/zakki0027.html#lang ただのプログラミング練習言語で終わらせるのはもったいないと 思います。 何か特徴を付けて、存在価値のある言語にして欲しいです。 あと、できれば、Windows版のcrowbar.exeもダウンロード できるようにして欲しいです。 新しいバージョンをすぐテストしたいので。 よろしくお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[688] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>「術語に対して」過剰な期待をしてもしょうがないのでは、ということです。 >この議論の最初のほうで、CESさんは > >>例えば、「クラス」という用語の意味は「分類」であって、「原型」ではありませんから、 > >ということを書いています。 >でも、「クラス」という言葉の辞書的定義が「分類」だったからといって、 >術語として使われるときそのままの意味とは限らないし、「クラス」という >言葉を選んだ人が間違えたのかもしれない。だから、その言葉の意味に >過剰な期待をしてもしょうがないのでは、と言っているのです。 ># クラスを分類とする考え方を否定しているわけではありません。 では、極論すれば、辞書的な「分類」という意味と、術語としての「クラス」という用語は切り離して考えるべきだ、ということ? もっと言ってしまえば、「クラス」ではなくて「りんご」でも別に良かった…ということ? 「りんご」の辞書的な意味は明らかに違うけれど、術語なんだから、それで通じれば別にいいじゃん…と。 しかし、如何に述語だとは言っても、何の根拠もなく選ばれた言葉であるはずはなし、そして、「クラス」には「分類」という意味があって、オブジェクト指向のクラスを「分類」として捉えると自然なのは事実なんだから、その言葉はそのような意味を持って選ばれたと考えるのは、過剰ではないと思うのですけれど。 本当に「何の根拠もなく選ばれたはずはない」のかどうか、あるいは根拠があったにしても「『分類』という意味を意図して選んだ」のかどうか、その真相はわからないのですが、別に後付けの意味だとしても、それはそれで構わないと思います。意味がないよりはずっといい。 >「それはそうかもしれませんけど」「それほど無理はない」んならいいじゃん、 >術語に過剰な期待をしてもしょうがない、と私は言っているわけです。 「りんご」だったら「それほど無理は無くない」と思うけれど、まぁ極論だからそこに突っ込むのは無し。 >クラスを分類として考えるのがよいとCESさんがお考えなら、それが具体的に >有効であるケースを、例示して主張するのがよいのではないでしょうか。 例示が必要でしょうか? 「is-a」「汎化-特化」の考えは、まさに分類だと思うのですが(「汎化」「特化」という用語を誰が考えたかは知りませんが、いくらこれが術語だからと言って「低機能」「高機能」という意味でないのは明らかでしょう)。
[この投稿を含むスレッドを表示] [この投稿を削除]
[687] Re:正規表現関連の関数の質問
投稿者:(ぱ)
2007/02/20 02:13:25

補遺。 >現状のcrowbarには、名前空間を分割する機能がないので、今回はreg_で >逃げたわけです。モジュールによる名前空間の分割はいずれそのうちやろうと >思っていますから、現時点で、Lua的な方法(crowbarでやるなら、グローバルな >stringというオブジェクトにクロージャを格納することになるのでしょう)で >解決しようとは思いません。 crowbarの場合、スコープチェーンは「最上位の関数の中」までで止まっていますが、 これをグローバルな領域まで広げ、グローバルな名前空間もassocで表現するようにして、 グローバル変数もそのassocに、またグローバルな関数はクロージャとして 格納するようにすれば、名前空間の考え方が統一されるとともに、 モジュールが欲しければトップレベルのオブジェクトをモジュールとして考えればよい、 ということになります。実際JavaScriptはそんな感じになっています。 crowbarがそうなっていないのは、ver.0.1からの流れ、というのも否定できないですが、 printに代入できるのはいかがなものか、とか、名前空間はやっぱり静的なほうが わかりやすいんじゃないか、とか、グローバル変数とローカル変数は分けて考える べきじゃないか、とか、いろいろ考えてこうなっています。この選択が正しかったか どうかはよくわかりませんが。 このへんはいずれ「crowbarプログラマのためのJavaScript入門」(仮題)で 書こうかと思っています。 # タイトルはネタなのであまり怒らないように。
[この投稿を含むスレッドを表示] [この投稿を削除]
[686] Re:正規表現関連の関数の質問
投稿者:(ぱ)
2007/02/20 02:13:25

>最後の方に、正規表現関連の関数がグローバルということが >書かれていましたが、私は、Pythonは、よく知らないのですが、 >何で正規表現の関数をクロージャに押し込んで提供していないのですか? >例えば、Luaであれば、Stringというクロージャに入っています。 Luaは以前リファレンスをちょっと眺めたきりなので、 ここで言う「クロージャ」が何であるのかがよくわからないのですが。 http://lua-users.org/wiki/StringLibraryTutorial ここを見る限り、stringというテーブルに、いろんなメソッドを クロージャとして埋め込んでいる、という認識でよいでしょうか? http://www.uri.sakura.ne.jp/~cosmic/yuno/lab/lua5_manual_ja.html#5.3 ここを見ても、 | 文字列ライブラリはすべて、テーブル string 内の関数として提供される。 と書いてあるし。 ここでのstringの使われ方は、純粋に名前空間としてのものですよね。 現状のcrowbarには、名前空間を分割する機能がないので、今回はreg_で 逃げたわけです。モジュールによる名前空間の分割はいずれそのうちやろうと 思っていますから、現時点で、Lua的な方法(crowbarでやるなら、グローバルな stringというオブジェクトにクロージャを格納することになるのでしょう)で 解決しようとは思いません。 >また、crowbarには、まだハッシュを組み込んでなかったと思うのですが、 >ハッシュは組み込まないのですか? >必須なデータ構造だと思います。 ハッシュはですねえ… もちろん考えていないことはないのですが、問題は、どの階層で実現するかです。 言語の外で、ライブラリとして提供しても十分だと思うんですが、 どうでしょうか(基本型のハッシュキーの取得方法は考えるにしても)。 ハッシュのリテラル(「{"a" => "hoge"}」みたいなの)って要りますかねえ。 考えるべきところはたぶんふたつあって、 a)ハッシュのリテラルを言語仕様として用意するかどうか。 b)ハッシュのオブジェクトを、(JavaScriptやLuaのように)現状のassocの  別の見え方として考えるかどうか。 私としては、a)はまあやるならやってもいいけど(ただし優先順位は低い)、 b)は嫌、というところです。 >あと、最近、Luaを勉強していて、組み込み言語と謳っている割りに >例えば、LuaとCとのインタフェースを書くのがかなり面倒で >少しがっかりしているのですが、crowbarはぜひとも組み込み部分を強化 >して欲しいです ええと、私はLuaを使っていないのでご意見をお聞かせ願いたいわけですが、 現状で、Luaとcrowbarを比べてみてどうでしょうか? Luaとcrowbarでネイティブ関数を書くときのことを比較すると、 (1)引数や戻り値  Lua…スタックを直接操作  crowbar…引数や戻り値なので、ちょとはわかりやすいかな。 (2)GC  Lua…何もしなくていい(?) Ruby的コンサバGC?   lua_newtable()が「新しい空のテーブルを作り、スタックに積む。」そうだから、   スタックにないものは勝手にGCされそうな気もするんですが。  crowbar…GCされたくなかったらスタックに積んどけ。   正直、これは面倒くさいです。せめて、最後のスタックの後始末を処理系側で   やれば、というか実はそれは造作もないのですが。 (3)アプリケーション固有データ  Lua…ユーザデータ  crowbar…ネイティブポインタ   ファイナライザの仕様も含め、そっくりに見えます。また車輪を再設計したか。 いっそ今みたいに特定の引数を持ったネイティブ関数が呼ばれる仕様ではなく、 また、CRB_add_native_function()で関数を登録する必要もない、というようにして、 もっと楽にネイティブ関数を書けるようにするというのも考えられますが… 処理系依存のコードはあんまり書きたくないですし。 >鬼車を搭載しても、まともに張り合ったら、Rubyに対抗するのは >難しいと思いますので、組み込み用スクリプトでメジャーなものは >なさそうなので、そういう方向はどうでしょうか? まあ、別にRubyと張り合う気はないんですけど。 方向性として、組み込み用スクリプトというのは、[685]にも書いたように そもそも言語処理系に興味を持った時点からありました。 ただ、今は別の方向も考えています。こんなの↓とか。 http://kmaebashi.com/zakki/zakki0027.html#lang ていうか、企画本来の主旨であったはずの「プログラミング言語の作り方の紹介」 という観点からすれば、crowbarは、crowbarのような実装方針の言語としては とっくにオーバースペックであり、たぶん私は暴走している状態なわけですが。 ええと誰か止めて。
[この投稿を含むスレッドを表示] [この投稿を削除]
[685] Re:すごいですね。
投稿者:(ぱ)
2007/02/20 02:13:25

>私は、LINUXで動くCADを作りたいと思っています。 リンク欄のsourceforgeのページから、ホームページを辿って見てみました。 http://sagcad.sourceforge.jp/ 浅学にてSagCADは知らなかったのですが、crowbarよりずっとすごいじゃないですか。 BBS(は見えなかったのですがそのGoogleキャッシュ)を見てみると、ドイツの人とか 英語圏の人とかも巻き込んで開発されているようですし。 実は私は10年くらい前、資料などに使う図を描くドローツールについて、 いいのがないので作りたいと思っていました。当時は、ていうか実は今も UNIX上でTgifを使っていますが使い勝手の点で満足していません。 たとえばシステム構成図などでは、データベースとかを円筒形を斜め上から 見た図で表現することがあります。Word付属のドローツールとかでも この円筒形は描けますが、縦に伸ばすと楕円部分の縦横比まで変わってしまう。 これは美しくないわけで、「中に入る文字列に合わせてサイズは自動調整。 でも楕円部分の縦横比は変わらない」という機能が欲しいわけですが、これを ドローツール本体に組み込むのも美しくない。となるとスクリプト言語が必要かなあ… と言語処理系に興味を持ち始めて今に至るわけです。 以後、いくつも言語を作ろうとして作りかけで放棄してきたわけですが (言語処理系を作りかけた人は誰もがこれをやってると思う)、crowbarは仕様で 無理をしなかったことと、何よりも「公開したこと」により、どうにかここまで こぎつけることができました。 というわけで、CADのマクロとして使うというのは、crowbarの実に正当な使い方と いうか、本来あるべき姿のように思います。バグがあったらすみませんですが、 よろしくお願いいたします。 >ホームページ上では、僕が作ったソースに組み込めるようなことが >描いてありました。まだ試していませんが、試せるところまで進んだら >ぜひ、使わせてください。 CADに組み込む際には、スクリプトから図形を作ったり、図形をスクリプトから 操作したりしなければならないでしょうから、「図形」とか「図面」とかを ネイティブポインタ型で表現することになると思います。 その上でネイティブメソッドをいくつか書けば、CADと連携できるのでは、 と思います。 # 「図形」や「図面」にメソッドを付けるには、今の仕様ではcrowbarの # オブジェクトでラップすることになりますが、ネイティブポインタ型に # 「メソッドもどき」を付ける機能があってもいいかな、とも思っています。 それでは、SagCADにcrowbarが組み込まれる日を楽しみにしています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[684] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>よくわかんなくなってきました。「過剰な期待をするな」とはどういうことですか? >「違和感を覚えるな」というのは無理な期待だ、ということでしょうか? 「術語に対して」過剰な期待をしてもしょうがないのでは、ということです。 この議論の最初のほうで、CESさんは >例えば、「クラス」という用語の意味は「分類」であって、「原型」ではありませんから、 ということを書いています。 でも、「クラス」という言葉の辞書的定義が「分類」だったからといって、 術語として使われるときそのままの意味とは限らないし、「クラス」という 言葉を選んだ人が間違えたのかもしれない。だから、その言葉の意味に 過剰な期待をしてもしょうがないのでは、と言っているのです。 # クラスを分類とする考え方を否定しているわけではありません。 CESさんはこうも書いています。 >「クラスとは分類である」という考えをすると、具体的なものはオブジェクトで、 >クラスは全て抽象的なものということになるからです(その点、「抽象クラス」 >ってのは良くないネーミングだと思います)。 私の返答がこう(「スーパークラス」の話は発散するので省略)。 >それはそうかもしれませんけど、具体的なオブジェクトにできないものが >抽象クラスで、具体的なオブジェクトを作れるものがconcrete classってのは、 >それほど無理はないんじゃないでしょうか。 「それはそうかもしれませんけど」「それほど無理はない」んならいいじゃん、 術語に過剰な期待をしてもしょうがない、と私は言っているわけです。 クラスを分類として考えるのがよいとCESさんがお考えなら、それが具体的に 有効であるケースを、例示して主張するのがよいのではないでしょうか。 「そのへんの入門書にある考え方だと、こういう例ではこういうモデリングを してしまいがちだけど、分類として考えればこんなモデリングになって、 こういう拡張をするときのことを考えたらこっちのほうが修正箇所が はるかに少なくてすむよね」とか。 結城浩さんが書いておられるように、「例は嘘をつかない」ですから。 http://www.hyuki.com/dig/eg.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[683] 正規表現関連の関数の質問
投稿者:タイガー
2007/02/20 02:13:25

いつも「プログラミング言語を作る」を楽しく拝見させて頂いています。 早速、「正規表現ライブラリ鬼車の搭載」を拝見させて頂きました。 最後の方に、正規表現関連の関数がグローバルということが 書かれていましたが、私は、Pythonは、よく知らないのですが、 何で正規表現の関数をクロージャに押し込んで提供していないのですか? 例えば、Luaであれば、Stringというクロージャに入っています。 また、crowbarには、まだハッシュを組み込んでなかったと思うのですが、 ハッシュは組み込まないのですか? 必須なデータ構造だと思います。 あと、最近、Luaを勉強していて、組み込み言語と謳っている割りに 例えば、LuaとCとのインタフェースを書くのがかなり面倒で 少しがっかりしているのですが、crowbarはぜひとも組み込み部分を強化 して欲しいです (例えば、C側で、LuaのTableをダイレクトに作れず、Luaのスタックを 経由しないとできないので面倒)。 鬼車を搭載しても、まともに張り合ったら、Rubyに対抗するのは 難しいと思いますので、組み込み用スクリプトでメジャーなものは なさそうなので、そういう方向はどうでしょうか? 私は、D言語やioはあまり知らないですが、組み込み用言語の デファクトスタンダードとか、存在するのでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[682] すごいですね。
投稿者:kappa
2007/02/20 02:13:25

私は、LINUXで動くCADを作りたいと思っています。 その中で、マクロのようなものを組み込みたいと思って、 自分で少し考えていたんですが、これは、これで、また新たな 専門的な知識が必要だと感じましたし、CAD自体まだまだな 自分には、いつになることかとたまに、どこかにないかなと探 し続けていました。 今回ここにたどり着いて、サンプルを動かしてみました。 すごいですね。 ホームページ上では、僕が作ったソースに組み込めるようなことが 描いてありました。まだ試していませんが、試せるところまで進んだら ぜひ、使わせてください。 僕は、プロでもないし、未熟者ですが、そのときは、いろいろ質問 させてください。 最近、あれもやりたい、これもやりたいと悩んで、CAD自体手を付けられない 状態でした。 このサイトに来て、このようなすばらしいものがあるのなら、 今は、マクロについては何も考えず、目標のCADに専念しようと やる気が起きてきました。ありがとうございます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[681] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>何度も繰り返しますが、私が言っているのは、 >「術語に過剰な期待をするのはいかがなものか」 >ということだけです。 >スーパークラスという言葉を否定した覚えも、スーパークラスは集合論で言えば >スーパーセットである、というのを否定した覚えもありません。 よくわかんなくなってきました。「過剰な期待をするな」とはどういうことですか? 「違和感を覚えるな」というのは無理な期待だ、ということでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[680] OTDの掲示板を閉鎖しました
投稿者:(ぱ)
2007/02/20 02:13:25

旧掲示板として存続してきたOTD版の掲示板ですが、最近は広告書き込みばかりで、 その量も尋常ではないので、閉鎖しました。トップページにも案内を出しましたが、 過去ログは以下のURLから参照できます。 http://kmaebashi.com/bbs/otdindex.html どうでもいいことですが、過去ログは、30件ずつブラウザで表示し、 HTML保存(ここは手作業)したものに対し、crowbarで変換をかけることで 生成しました。crowbarで行ったのは、広告やJavaScriptの削除、前後の ページへのリンクの付加です。 バリバリにうちの掲示板のHTMLに依存したスクリプトなので、そのまま 他の人の役に立つ可能性はゼロですが、数少ないcrowbarのサンプルソースとして 以下に公開しておきます。 http://kmaebashi.com/bbs/conv_crb.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[679] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>ただ、違和感を感じるからといって否定するのでは、何かを学習することはできないでしょう。学習は違和感を覚え、それを解消することによって積み重ねていくものです。 だーかーらー。 いつ誰が、スーパークラス、サブクラスという言葉を否定しましたか? 何度も繰り返しますが、私が言っているのは、 「術語に過剰な期待をするのはいかがなものか」 ということだけです。 スーパークラスという言葉を否定した覚えも、スーパークラスは集合論で言えば スーパーセットである、というのを否定した覚えもありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[678] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

> 私が最初から言っているのは、「術語に過剰な期待をするのはいかがなものか」ということです。 > 集合論で見て、サイヤ人はスーパーサイヤ人のスーパーセットですが、やっぱりスーパーサイヤ人の方に「スーパー」が付いている。そういう言葉の使い方が現実にある以上、「スーパークラス」という言葉に違和感を感じる人もそりゃいるだろうねえ、と言っているだけです。 そうかなぁ、とも思ったのですが、一人で3連投するのもどうかと思ったのでやめときました。 「スーパークラス」という用語に違和感を感じるのは構いませんが、しかし「基底クラス」という言い方はもっとまずいと思うのです。前述したように、クラスは上下関係ではなく包含関係にあるからです。 「スーパーサイヤ人の方がスーパーだ」という考えに固執していると、「サブクラス(に属するオブジェクト)は機能が多いものだ」という誤解を招きます。 「スーパークラス」「サブクラス」という用語を使わなくても、自然に集合論的考え方ができるのであれば、それで結構だと思います。 ただ、違和感を感じるからといって否定するのでは、何かを学習することはできないでしょう。学習は違和感を覚え、それを解消することによって積み重ねていくものです。 前にも言いましたが、「スーパークラスはサブクラスよりも『含むものが多い』という点で集合の能力が上、すなわちスーパーだ」という考え方もできます。そして、「スーパーサイヤ人は機能が多い方がスーパーなのに、集合論は機能が少ないほうがスーパーなんだ。そういうものなんだ」と違和感を感じたまま暗記するよりは、是非、違和感を解消していただきたいと思うのです。 というわけで、俺は「スーパークラス」「サブクラス」という呼び方を布教していきたいと思います。 > で、集合論で考えるなら円は楕円のサブセットなのであって、それを「客観的な視点などというものは存在しません」などと言って否定してしまったら、それこそ数学を全部敵に回すと思うんですが、如何? 「円は楕円のサブセットである」というのは、集合論が決めることではありません。数学(幾何学)が決めることです。 (どんな論理に基づくかは知りませんが)「楕円は円のサブセットである」と言っても、それは幾何学的には間違えているかもしれませんが、集合論的には間違えていません。集合論は集合の関係を提供するのみで、その中身の妥当性にまでは関与しないからです。 そして、数学さえ真理ではありません。かつてはユークリッド幾何学が真理とされていた時代もありましたが、今では「ユークリッド幾何学は、いくつかの都合のいい前提の基にのみ成立する、一面の真実でしかない」ということは広く知られています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[676] Re:リンク切れ報告
投稿者:(ぱ)
2007/02/20 02:13:25

>こんばんは。archerと申します。 >「プログラミング言語を作る」のページの下のほうにある、 >「現状の最新版のダウンロードはこちらから。」のリンクが切れている(Not Found)ようです。 ご報告いただきありがとうございます。修正しました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[675] リンク切れ報告
投稿者:archer
2007/02/20 02:13:25

こんばんは。archerと申します。 「プログラミング言語を作る」のページの下のほうにある、 「現状の最新版のダウンロードはこちらから。」のリンクが切れている(Not Found)ようです。 とりあえず、報告まで。
[この投稿を含むスレッドを表示] [この投稿を削除]
[674] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>まさにその程度のプログラムにおいて、そしてそこから大きくしていく過程において、のこと >を自分は想定していました。 >for文やif文の学習という過程から、だんだんと大きなプログラムを組んでいく場合において、 >オブジェクト指向をうまく取り入れられないかな、と考えたわけです。 思うのですが、オブジェクト指向は目的ではなく手段なのだから、 for文やif文の学習という過程から、だんだんと大きなプログラムを組んでいく 場合において、「このままでは破綻する」という状況がオブジェクト指向でうまく 回避できる、というのが想像できればよいのではないでしょうか。 ま、とはいえ世の中には「5000行の関数」を書いてしまうツワモノもいるわけで、 力技でもできる奴(どういう意味で「できる」かはアレですが)はやってしまうという のもあります。実際、5000行はともかく数百行程度なら、どんな書き方をしていても なんとかなってしまう、という面はあります。では一万行に挑んで痛い目に遭ってみれば オブジェクト指向のありがたみがわかるのかというと…そうなのかもしれませんが、 それでは痛い目に遭うためのコストが大きすぎますよね。 そのあたりは、「この方法では、もっと規模が大きくなったときどうなるだろう?」と 想像力で補うのがよいのではないかと思います。 >しかし、これだとサブルーチンという考え方だけで大丈夫だという記述もあり、 サブルーチンで大丈夫な範囲ならサブルーチンで大丈夫。 オブジェクト指向の方がよいのなら、サブルーチンに比べて「どこがどうよいのか」が 説明できなければならない、というのが私の言いたかったところです。 >いろいろなオブジェクト指向入門で見た「コードの再利用」というのも、なんだか疑わしい >と思っています。継承することによって再利用というのがしっくりこなかったです。 これはたぶんRqさんの感覚のほうが正しいのではないかと。
[この投稿を含むスレッドを表示] [この投稿を削除]
[673] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>この違和感が「集合論で考えればわかりやすいね」で解決しなくて「いや、どうしても直感的に受け入れられない」ってことだとすると、オブジェクト指向を集合論で考えちゃいけねぇってことになる。それはいくらなんでも横暴じゃないかなぁ…数学を全部敵に回しそうだ。  私が最初から言っているのは、「術語に過剰な期待をするのはいかがなものか」ということです。  集合論で見て、サイヤ人はスーパーサイヤ人のスーパーセットですが、やっぱりスーパーサイヤ人の方に「スーパー」が付いている。そういう言葉の使い方が現実にある以上、「スーパークラス」という言葉に違和感を感じる人もそりゃいるだろうねえ、と言っているだけです。  いつ私が「オブジェクト指向を集合論で考えちゃいけねぇ」と言いましたか? 言っていると思うのなら、その部分を具体的に引用して示してください。  んで、集合論で考えるなら円は楕円のサブセットなのであって、それを「客観的な視点などというものは存在しません」などと言って否定してしまったら、それこそ数学を全部敵に回すと思うんですが、如何?
[この投稿を含むスレッドを表示] [この投稿を削除]
[672] あけましておめでとうございます
投稿者:(ぱ)
2007/02/20 02:13:25

遅ればせながら、あけましておめでとうございます。 今年もよろしくお願いいたします。 つーわけでもう元日は終わっていますが壁紙変更。 去年もこれやって微塵も反応なかったんですがめげない。
[この投稿を含むスレッドを表示] [この投稿を削除]
[671] Re:オブジェクト指向「初」入門
投稿者:Rq
2007/02/20 02:13:25

こんばんは。前回は、はじめてであるのに名乗らずに失礼しました。 自分が浅学なのを暴露してしまうような気がしますが…こういう理解でいいのかな、と 少し確認の意味で書いてみます。 CES さん: >どの程度のことを「大規模」と言うかわかりませんが、オブジェクト指向が適用できない(適用する必要が無い)ほど小規模なものとなると、せいぜい 50 行…いや、20 ~ 30 行程度のプログラムになってしまうかなー、と。 まさにその程度のプログラムにおいて、そしてそこから大きくしていく過程において、のこと を自分は想定していました。 for文やif文の学習という過程から、だんだんと大きなプログラムを組んでいく場合において、 オブジェクト指向をうまく取り入れられないかな、と考えたわけです。 >> ・プログラムを分割することが大切 > >YES。それすげぇ大切。 この部分で、前にタイガーさんがおっしゃっていた >こうすることで、依存関係を親側に集中化でき、単純化できます。 というようなことを実現するために、分割が必要になってくるのだ、と自分は理解しています。 しかし、これだとサブルーチンという考え方だけで大丈夫だという記述もあり、どのように コードを組めばオブジェクト指向プログラミングとなるのか、というところが未だに自分の 中で曖昧になってしまっています。 いろいろなオブジェクト指向入門で見た「コードの再利用」というのも、なんだか疑わしい と思っています。継承することによって再利用というのがしっくりこなかったです。そこで デザインパターンから継承の利点などを見つけれればと思いましたが、自分にはまだ荷が 重かったようでした。 >目的が良くわかんないです。 >まず、「オブジェクト指向」と「手続き型」は対立しません。 >現在主流のオブジェクト指向言語は、手続き型言語に、オブジェクト指向のサポートを加えたものです。 >ですから、「手続き型の中でオブジェクト指向を実践」するということは、立派にオブジェクト指向です。 > >「手続き型の中でオブジェクト指向を実践」とは、どんなことを意図されて書かれたのでしょう? いろいろな人がオブジェクト指向プログラミングの特徴について書いていますが、 オブジェクト指向プログラミングは、堅牢なコードを書いていく技術であり、そのために データの抽象化や、マルチプルインスタンス(これは堅牢なコードのためじゃないかも しれませんが)があるのかな、と思っています。 そのなかで、技術的なアプローチから入っていこう、とした場合に、まず何を理解して 実践すればいいのかが、現在のオブジェクト指向ではまったくといっていいほど分からない のでは、と思った次第です。 確かに、「再」入門の人々にとっては当たり前なのかもしれませんが、「初」入門の 人にとっては、ということです。(ということで、この質問はかなりこの掲示板の趣旨 からは離れているのかな、と思います。しかし、「初」入門の自分がいろいろな入門を 見てきた中で、一番しっくりきたのがこの「再」入門であったので、何かしらそういう 視点からの助言が得られるのでは…と思い、提示しました(大変参考になりました)。) >まぁ、最初のうちはわからないなりに模索して失敗してみろって事ですね。 >そのうち、だんだんとありがたみがわかってくると思います。 ということなので、今自分が実践できることは、プログラムを分割して、単一の仕事 だけをさせるようにし、責任の所在を分かりやすくしてみることかな、とおもいます。 そして、これから挑戦していくものとして、(ぱ) さんがおっしゃっていた >上に挙げたX-Drawでは、Shape(図形)にdraw()メソッドを付けることで、 >プログラムのあちこちにShapeの種類による分岐(Cならswitch case, Pascalなら >case of文ですか)を書くことを避けることができ、図形の追加が容易にできるので、 >これはまさに上のページやOOSCで挙げている例と合致していると思うのですが… という部分から、if文やcase文を使わないですむコードを書いてみたいと思っています。 具体的すぎる話だけだと、抽象度の高い設計ができないということなので、 データの抽象化というものを具体的にコードにできるようにしたいと思っています。 やってみて考えてみて、経験から分かってくるというのが唯一の正解である、という のは理解できるのですが、具体的にこういう学習をしてみようと思っていると書くこと によって、自分の進んでいるのがオブジェクト指向なのか、それとも間違っているのか について助言が得られたらな、と思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[670] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>>「スーパーサイヤ人」がネタに出ましたね。集合で考えればふつうのサイヤ人が >>スーパーサイヤ人のスーパーセットです(悟飯やトランクスは混血だけど…)。 >>集合で考えれば確かにそうなんだけど、「スーパーサイヤ人」の方がスーパーだ、 >>という言葉の使い方も確実にあるわけで、そこに違和感を覚えてることも >>そりゃあるんじゃないかと。 > >#言うまでもないことだとは思うのですが。 >「スーパーサイヤ人」と、そのスーパーセットである「サイヤ人」では、どっちがすごいか…というのは比べられません。 >「スーパーサイヤ人」と「ノーマルサイヤ人(?)」なら、スーパーサイヤ人の方がすごいですが、これはどちらも「サイヤ人」のサブセットです。 >「サイヤ人=ノーマルサイヤ人」でないところが罠ですね。違和感の元はここかと。 この違和感が「集合論で考えればわかりやすいね」で解決しなくて「いや、どうしても直感的に受け入れられない」ってことだとすると、オブジェクト指向を集合論で考えちゃいけねぇってことになる。それはいくらなんでも横暴じゃないかなぁ…数学を全部敵に回しそうだ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[669] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>「スーパーサイヤ人」がネタに出ましたね。集合で考えればふつうのサイヤ人が >スーパーサイヤ人のスーパーセットです(悟飯やトランクスは混血だけど…)。 >集合で考えれば確かにそうなんだけど、「スーパーサイヤ人」の方がスーパーだ、 >という言葉の使い方も確実にあるわけで、そこに違和感を覚えてることも >そりゃあるんじゃないかと。 #言うまでもないことだとは思うのですが。 「スーパーサイヤ人」と、そのスーパーセットである「サイヤ人」では、どっちがすごいか…というのは比べられません。 「スーパーサイヤ人」と「ノーマルサイヤ人(?)」なら、スーパーサイヤ人の方がすごいですが、これはどちらも「サイヤ人」のサブセットです。 「サイヤ人=ノーマルサイヤ人」でないところが罠ですね。違和感の元はここかと。
[この投稿を含むスレッドを表示] [この投稿を削除]
[668] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>#自分で言語を作ったら別の呼び方にしたいけれど。 では言語を作ることをお勧めしますです。 # と思って「プログラミング言語を作る」を続けてるわけですが。 でも、たとえばcrowbarではオブジェクトの要素を「メンバ」と呼んでいますが、 JavaScriptあがりの人があれをプロパティと呼んだり、Selfとかあがりの人が スロットと呼ぶことを妨げようとは思いません。「crowbarにはプロパティはない」とか 言い始めたら、そりゃトンデモです。 だからもちろんJavaにはポインタが…すみません脱線しすぎました。 >集合の「スーパーセット」と「サブセット」に対応すると考えれば、 >じつにしっくり来るです。 この議論は昔JavaHouseでやったことがあるんですが、その時は 「スーパーサイヤ人」がネタに出ましたね。集合で考えればふつうのサイヤ人が スーパーサイヤ人のスーパーセットです(悟飯やトランクスは混血だけど…)。 集合で考えれば確かにそうなんだけど、「スーパーサイヤ人」の方がスーパーだ、 という言葉の使い方も確実にあるわけで、そこに違和感を覚えてることも そりゃあるんじゃないかと。 >C++ 流儀の「基底クラス」は、スーパーの方が下のように聞こえるので直感的? Straustrupは、そこに違和感を感じたから基底クラス(base class)という言葉にした、 という話を聞いたことがありますが、確か2chで読んだ話だと思うので信憑性は 定かではありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[667] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>>たとえば「スーパー」クラスの方が「サブ」クラスよりへぼいってのも直感には >>反しますよね。術語は所詮術語なので、あんまり厳密性を求めてもしょうがない >>気がします。 > >集合の「スーパーセット」と「サブセット」に対応すると考えれば、じつにしっくり来るです。 >「上位クラス」「下位クラス」というネーミングも、上の方がショボい気がしてよろしくないですね。 >C++ 流儀の「基底クラス」は、スーパーの方が下のように聞こえるので直感的? >ただ、機能に注目するとサブクラスの方が多いんですが、スーパーの方が「範囲が広い」という点は優位ですね。 クラスはオブジェクトの集合なのだから、上下関係ではなくて包含関係で見るべき。 だとすれば、「サブクラスがヘボい」んじゃなくて「スーパークラスもサブクラスも同じ機能を持っているんだけど、スーパークラスではその一部に言及されていないだけ」なのだから、機能の比較はできなくて、広さで優位に立つスーパークラスの方がすごい。 こういうところも、論理面から攻めると違和感を無くすことができました、という例。
[この投稿を含むスレッドを表示] [この投稿を削除]
[666] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>>concrete class って何なのか、参考までにお聞きしてもよろしいでしょうか。 > >通常の定義では、abstractでないクラスがconcrete classでしょう。 >Googleしてもいっぱい出ますし。 やっぱりそれですか。 それでいくと、継承できないと問題が出そうな気もしますけど…まぁそれは置いといて。 >それはそうかもしれませんけど、具体的なオブジェクトにできないものが >抽象クラスで、具体的なオブジェクトを作れるものがconcrete classってのは、 >それほど無理はないんじゃないでしょうか。 現状、そのような用法で広く使われておりますので、あえてそれに反旗を翻すような真似はいたしませんです。 #自分で言語を作ったら別の呼び方にしたいけれど。 >たとえば「スーパー」クラスの方が「サブ」クラスよりへぼいってのも直感には >反しますよね。術語は所詮術語なので、あんまり厳密性を求めてもしょうがない >気がします。 集合の「スーパーセット」と「サブセット」に対応すると考えれば、じつにしっくり来るです。 「上位クラス」「下位クラス」というネーミングも、上の方がショボい気がしてよろしくないですね。 C++ 流儀の「基底クラス」は、スーパーの方が下のように聞こえるので直感的? ただ、機能に注目するとサブクラスの方が多いんですが、スーパーの方が「範囲が広い」という点は優位ですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[665] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>concrete class って何なのか、参考までにお聞きしてもよろしいでしょうか。 通常の定義では、abstractでないクラスがconcrete classでしょう。 Googleしてもいっぱい出ますし。 >「クラスとは分類である」という考えをすると、具体的なものはオブジェクトで、 >クラスは全て抽象的なものということになるからです(その点、「抽象クラス」 >ってのは良くないネーミングだと思います)。 それはそうかもしれませんけど、具体的なオブジェクトにできないものが 抽象クラスで、具体的なオブジェクトを作れるものがconcrete classってのは、 それほど無理はないんじゃないでしょうか。 たとえば「スーパー」クラスの方が「サブ」クラスよりへぼいってのも直感には 反しますよね。術語は所詮術語なので、あんまり厳密性を求めてもしょうがない 気がします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[664] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>class bird { virual void fly()=0; }; >という設計においては「こうもりは鳥」であるし「ダチョウは鳥でない」 これはすごく面白い。深いなぁ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[663] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>以前ここの掲示板でオブジェクト指向のポイントは、以下の >2点であるという結論になっていたと思います。 >1. データの抽象化 >2. マルチプルインスタンス >何ができれば、オブジェクト指向になるのかは難しいと思いますが、 >上記の2点はオブジェクト指向を語る上で重要だと思います。 >あと、データのアクセス制御(制限?)なども重要だと思っています。 アクセス制限は抽象化の範疇だと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[662] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>結局設計に万能の「正解」はなく、たとえば拡張に備えるにしても「どんな拡張が >ありそうか」ということをある程度予測してからでないと設計方針は選べないんじゃ >ないかなあ、と思います。つまらない結論かもしれませんけど。 「分析」→「設計」→「実装」の流れで言うならば、万能の唯一解がないのは「分析」でしょうね。 分析が正しくできていれば、正しい設計はおのずと導かれる気がします。 >そうですよね。実のところ私はconcrete classなんざ継承できなくても >よいのでは、と思っていますが、上で出ている例(Note, PUBLICICATION, Shape)は >どれも抽象クラスですし、使用範囲を間違えなければ、有効に使えると思います。 concrete class って何なのか、参考までにお聞きしてもよろしいでしょうか。 「クラスとは分類である」という考えをすると、具体的なものはオブジェクトで、クラスは全て抽象的なものということになるからです(その点、「抽象クラス」ってのは良くないネーミングだと思います)。 #実装の再利用のためのクラスはクラスである意味が薄いと思いますし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[661] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

#話が脇にそれてたので源流復帰。 > ・大規模なプログラムの開発でないと効果を発揮しない どの程度のことを「大規模」と言うかわかりませんが、オブジェクト指向が適用できない(適用する必要が無い)ほど小規模なものとなると、せいぜい 50 行…いや、20 ~ 30 行程度のプログラムになってしまうかなー、と。 > ・プログラムを分割することが大切 YES。それすげぇ大切。 > ・デザインパターン(設計)を知らないといけない(? 知っていて損はないけれど、必須ではないと思う。俺も知らないし。 >そしてここのオブジェクト指向再入門で言っているマルチプルインスタンスというのは オブジェクト指向の一番の基礎はカプセル化です。 カプセル化ってのは、「データと処理をペアにして、このペアを最小単位として考える」ことです。 マルチプルインスタンスってのは、このペアがいっぱいあることです。 >では、ここからが自分の疑問の核心なのですが、手続き型の学習の中で(あるいは小規模すぎるプログラムの中で)でもオブジェクト指向を実践する方法はないだろうか、ということです。 目的が良くわかんないです。 まず、「オブジェクト指向」と「手続き型」は対立しません。 現在主流のオブジェクト指向言語は、手続き型言語に、オブジェクト指向のサポートを加えたものです。 ですから、「手続き型の中でオブジェクト指向を実践」するということは、立派にオブジェクト指向です。 「手続き型の中でオブジェクト指向を実践」とは、どんなことを意図されて書かれたのでしょう? > ・「開放・閉鎖の原則(OCP:Open-ClosedPrinciple)」 これは「よりよいオブジェクトの設計のための指針」なので、初歩でまず覚えるべきことではないような気がします。 >しかしそのためには手続きを分節化し、プログラムを設計する能力がいるだろう、と思っています。 これはオブジェクト指向でなくとも、多かれ少なかれ必要な能力です。 >このような場合に、デザインパターンが有効なのだと思いますが、具体的にどうプログラムを組むのか、というところで自分は躓いている状況です。 別の掲示板で、素晴らしい言葉を見つけました。この言葉を送ります。 Good judgement comes from experience, and experience comes from bad judgement. (よい判断は経験から来ます。また、経験は悪い判断から来ます。 ) Experience is a wonderful thing. It enables you to recognize a mistake when you make it again. (経験は素晴らしいものです。再びそれを作る場合、それによって誤りを認識することができます。) まぁ、最初のうちはわからないなりに模索して失敗してみろって事ですね。 そのうち、だんだんとありがたみがわかってくると思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[660] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>分析→設計→実装、の段階のどこのレベルで話をするかがきわめて大事。 そう思います。 私は、ビーム砲の弾からインベーダーへの関連を持つというモデルを正解として 紹介していることをもって「憂鬱なプログラマのためのオブジェクト指向開発講座」を 批判していますが、「分析」のレベルなら、ビーム砲の弾からインベーダーへ 線を引っ張るのもよいのかもしれません。実際、そういう文脈で、私も文章を 批判している記事は見たことがあります。 インベーダーゲームにおいて、ビーム砲の弾がインベーダーを破壊するのは 確かですから、ここに線を引っ張るのは、客先の業務でありがちな「暗黙知」を 明確にするという意味では意味があるのかもしれません。 …が、憂鬱本の場合、「クラスのメンバに相手クラスのポインタを持つということで 実際に関連を張るわけです」と明言している点で、これは完璧に実装の本であり、 結局憂鬱本がトンデモ本であるという評価に揺らぐところはないわけですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[659] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>何が言いたいかというと、「円は楕円のサブクラスである」というのは、 >そうであったほうが都合がいい場合にのみ、真実となるわけです。 まったく同意です。私が言いたかったのは、「数学や論理学の世界」を突き詰めると、 円は楕円のサブクラスである、というのを、絶対の真実として突き進んでしまう 危険があるのではないか、ということです。 >「Circle を Ellipse のサブクラスにすることが妥当と思えない」のは >ひとつの真実ですが、絶対の真理ではありません。Circle を Ellipse の >サブクラスにすることが適切な場合もあります。 まあそうかもしれません。(私にはそういう状況が思いつかないというだけで) その意味では、「だからといってCircleをEllipseのサブクラスにすることが 妥当とは思えません」と書いたのは不用意だったかもしれませんね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[658] Re:オブジェクト指向「初」入門
投稿者:774RR
2007/02/20 02:13:25

もう全面的に御意。 分析→設計→実装、の段階のどこのレベルで話をするかがきわめて大事。 >でも、案件Aで今書いたコードが、案件A ver2 でも有効なことはすごく大切。それもひとつの再利用性。 ここんところ、鼻血が出るほど御意。 幸い今までのところ ver2 で設計見直しになった例は(俺の担当範囲では)まだないので 「OOって何」に対する俺の理解はそう外れてはいないのだと思われ。 分析→設計のレベルの話を後輩君にするときにはこういう例を出してる。 class bird { virual void fly()=0; }; という設計においては「こうもりは鳥」であるし「ダチョウは鳥でない」 「こうもりは鳥でない」「ダチョウが鳥である」にしたいのなら、先の設計は変。 設計を見直す=分析のしなおし、だよん。って。
[この投稿を含むスレッドを表示] [この投稿を削除]
[657] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

そして、[651] をちょっと補足。 >>こっちの考え方は、突き詰めると数学や論理学の知識が必要になってしまうので、 >>実装面ほど簡単ではありません(私も勉強したいのですが、それらベースと >>なる知識が足りないため足踏みしています)。 >実装面べたべたで行くと、抽象度の高い設計ができずに後ではまるといった >問題があるのかもしれませんが、実装を離れて理論で突っ走っても、結局変なことに >なってしまうように思います。月並みですがバランスが大事、ということでしょうか。 設計段階においてはその通りです。 ただ、ソフトウェアは「設計」「実装」の2段階ではなく、その前に「分析」を加えた3段階で作られます。そして、(本来は)分析なくして設計はなく、設計なくして実装はありえません。 実装の方が触るのは容易なので、実際には「実装→設計→分析」とスキルアップしていくケースが多いのでしょうか。 たぶん「分析」ができないと、オブジェクト指向の真髄を知ったとは言えないだろうなぁ、と思うわけです(実装だけ知っていれば、「オブジェクト指向プログラミング」は極められるかもしれませんが、「オブジェクト指向」を極めるにはそれだけでは足りません)。 当初のタイトルは『オブジェクト指向「初」入門』ですが、これはつまり『オブジェクト指向プログラミング「初」入門』ということですよね。 分析入門もあればいいのになぁ…と思いつつ、最近こんな本を読んでいたり。 http://www.sra.co.jp/people/aoki/IntroductionToOOAOOD/ ただ、「分析」を行うには、論理学を知っていたほうがいいのはあるかもしれませんが、[651] で意図したのはそういうことではありません。 「オブジェクト指向」そのものの数学的、論理学的意味についてです。 たとえば、クラスは分類だと言いましたが、数学的に言えば、クラスはオブジェクトの集合です。派生クラスは部分集合で、多重継承は積集合で…なんて数学の知識は、実務では分析レベルでもそうそう必要ない気がします。 もっと突っ込むと、群論とか圏論といった、ムズカシイ数学が出てきます(勉強したいのですがさっぱりわかりません)。 ちなみに、圏論には「オブジェクト」「クラス」「モルフィズム」というような用語が登場します。…なんとなくオブジェクト指向チックですよね? こういう方面から攻めるのも併用すると、より理解が深まるんじゃないかな、ってことです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[656] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

> えっと、前橋さんとCESさんと結局同じこといってるようにしか見えないのですが気のせい? > >> 月並みですがバランスが大事 >> 「それをどう見れば都合がいいか」 > 今、やってる案件においてどう設計すれば適切か、バランスとか都合よさとかから決めろ > としか読めん。 たぶん違うこと言ってる。 前橋さんは > 分析レベルでは、確かに「分類」と捉えたほうがよいのかもしれません とも言われているけれど、俺がしている話はどれも分析レベルだったんだ。と、今更気づく。 そこから一段階進んだ「設計」の段階では、確かにバランスが大事。 [653] のレスをつけたのは「円を楕円のサブクラスにすることが間違いとは限らないよ」って言いたかったから。 > 「円と楕円はどっちがスーパークラスか?」という問題で間違った解を選んでしまいそうな気もします。 > 数学や論理学の世界では、円は楕円の特殊形ですが、だからといってCircleをEllipseのサブクラスにすることが妥当とは思えません。 少なくとも、この問題文だけを見て、「円が楕円のサブクラスであるのは間違いだ」とは言えない、ということ。 「常に」という言葉を補って、「Circle を Ellipse のサブクラスにすることが『常に』妥当とは思えません」ということならば、それは正解。 >だから私は「再利用性」って奴にはかなり疑問。 >案件Aにおいては今書いたコードが適切であっても、それは案件Bでは通用しない >ってのはごく普通にありそうですし。 でも、案件Aで今書いたコードが、案件A ver2 でも有効なことはすごく大切。それもひとつの再利用性。 >>「真実はいつもひとつ!」 >いや、真実はいつもひとつです(と、俺は思う)。 >その真実ってのは、人に理解できるような代物ではなかったりすることもある。 >だから、個々人で理解の仕方が違うってのは普通の話。 ひとつしかないのは「事実」だと思う。 それをどう見るかが「真実」。 でも、「真実」という言葉が「人によって違うもの」という意味に合致するかどうかはどうでもいい(というか、自分でもそういう意味なのかは疑問)。 ただ、「真実は人の数だけある」ってよく聞くから、その言葉を使っただけで、「普遍的に正しいものは無いんだよ」ってことが伝わるなら、「真実」って言葉にこだわる必要はない。
[この投稿を含むスレッドを表示] [この投稿を削除]
[654] Re:オブジェクト指向「初」入門
投稿者:774RR
2007/02/20 02:13:25

えっと、前橋さんとCESさんと結局同じこといってるようにしか見えないのですが気のせい? >月並みですがバランスが大事 >「それをどう見れば都合がいいか」 今、やってる案件においてどう設計すれば適切か、バランスとか都合よさとかから決めろ としか読めん。 だから私は「再利用性」って奴にはかなり疑問。 案件Aにおいては今書いたコードが適切であっても、それは案件Bでは通用しない ってのはごく普通にありそうですし。 >「真実はいつもひとつ!」 いや、真実はいつもひとつです(と、俺は思う)。 その真実ってのは、人に理解できるような代物ではなかったりすることもある。 だから、個々人で理解の仕方が違うってのは普通の話。 どの角度から見るかで見え方=コードの実装が異なるだけです。 同じ真実を違う角度で見れば、違うコードになる。ってただそれだけと思う。
[この投稿を含むスレッドを表示] [この投稿を削除]
[653] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

>「円と楕円はどっちがスーパークラスか?」という問題で間違った解を選んで >しまいそうな気もします。 >数学や論理学の世界では、円は楕円の特殊形ですが、だからといってCircleを >Ellipseのサブクラスにすることが妥当とは思えません(ただ、メンバが増えている >からといって、EllipseをCircleのサブクラスにするのが適切とも思えません)。 「真実は人の数だけある」とか、よく言われますよね。 唯一不変の真理なんてものはどこにも無くて、人によって「それをどう見れば都合がいいか」というのが違うわけです(大勢にとって都合がいいことが真理だと勘違いされがちですが…)。 何が言いたいかというと、「円は楕円のサブクラスである」というのは、そうであったほうが都合がいい場合にのみ、真実となるわけです。オブジェクト指向では、よく「正方形は長方形のサブクラスである」という話が問題になりますが、これも同様ですね。 我々の日常でも「リンゴは果物のサブクラスである」というのは一面の真実ですが、唯一の真理ではありません(植物学者には「リンゴはバラ科のサブクラスである」の方が都合がいいでしょうし、スーパーでは「リンゴは商品のサブクラスである」のほうが都合がいいでしょう。これらはどれも真実です)。 客観的な視点などというものは存在しません。 「Circle を Ellipse のサブクラスにすることが妥当と思えない」のはひとつの真実ですが、絶対の真理ではありません。Circle を Ellipse のサブクラスにすることが適切な場合もあります。どちらも正解で、間違いは名探偵のように「真実はいつもひとつ!」だと思うことです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[652] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

>例えば、「クラス」という用語の意味は「分類」であって、「原型」では >ありませんから、「クラスからオブジェクトを作る」という言い方は >おかしいのです(実装面からの理解であれば問題ありません)。 たとえばUMLだと、「継承」という言葉よりも「汎化」という言葉を使いますよね。 クラスという言葉の辞書的な定義はともかく(単に用語が不適切であるという可能性も あるので)、分析レベルでは、確かに「分類」と捉えたほうがよいのかもしれません。 >こっちの考え方は、突き詰めると数学や論理学の知識が必要になってしまうので、 >実装面ほど簡単ではありません(私も勉強したいのですが、それらベースと >なる知識が足りないため足踏みしています)。 ただ、そっち方面を突き詰めると、たとえば(よくある例ですが) 「円と楕円はどっちがスーパークラスか?」という問題で間違った解を選んで しまいそうな気もします。 数学や論理学の世界では、円は楕円の特殊形ですが、だからといってCircleを Ellipseのサブクラスにすることが妥当とは思えません(ただ、メンバが増えている からといって、EllipseをCircleのサブクラスにするのが適切とも思えません)。 実装面べたべたで行くと、抽象度の高い設計ができずに後ではまるといった 問題があるのかもしれませんが、実装を離れて理論で突っ走っても、結局変なことに なってしまうように思います。月並みですがバランスが大事、ということでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[651] Re:オブジェクト指向「初」入門
投稿者:CES
2007/02/20 02:13:25

オブジェクト指向を学ぶには、2つのアプローチがあると思います。 ひとつは技術面から、もうひとつは論理面からです。 技術面からというのは、よく言われている「クラス、継承、カプセル化、多態性、OCP」などのキーワードから理解していく方法です。実装面からのアプローチとも言えます。 プログラムをいかにうまく分割し、個々の保守性を上げるかという点が重要です。 論理面は、思想面とも言えるかもしれません。 例えば、「クラス」という用語の意味は「分類」であって、「原型」ではありませんから、「クラスからオブジェクトを作る」という言い方はおかしいのです(実装面からの理解であれば問題ありません)。 オブジェクトは作るのではなく、既にこの現実世界に存在しているのです。それを抽象化して、分類したものがクラスであるというのが、この考え方の第一歩ではないかと思われます。 こっちの考え方は、突き詰めると数学や論理学の知識が必要になってしまうので、実装面ほど簡単ではありません(私も勉強したいのですが、それらベースとなる知識が足りないため足踏みしています)。 技術面の方がわかりやすいのですが、論理面を知らないと、オブジェクト指向の真髄を知っているとは言えないと思います(技術面だけ理解してオブジェクト指向を知った気になっていると、失敗すると思います)。そして、論理面がわかってくると、技術面が、すとんと胸に落ちるように理解できるようになるのではないでしょうか。 オブジェクト指向がこれだけ流行っているのですから、論理面からの入門ももっとあっていいと思うんですけどね…。
[この投稿を含むスレッドを表示] [この投稿を削除]
[650] Re:オブジェクト指向「初」入門
投稿者:タイガー
2007/02/20 02:13:25

こんにちは。 >いろいろなオブジェクト指向入門を見てきて、オブジェクト指向は > ・大規模なプログラムの開発でないと効果を発揮しない > ・プログラムを分割することが大切 > ・デザインパターン(設計)を知らないといけない(? >という特徴を持っているのではないかと思っています。 私は、上記のどれもオブジェクト指向の特徴を表していないと 思います。 以前ここの掲示板でオブジェクト指向のポイントは、以下の 2点であるという結論になっていたと思います。 1. データの抽象化 2. マルチプルインスタンス 何ができれば、オブジェクト指向になるのかは難しいと思いますが、 上記の2点はオブジェクト指向を語る上で重要だと思います。 あと、データのアクセス制御(制限?)なども重要だと思っています。 >では、ここからが自分の疑問の核心なのですが、手続き型の学習の中で(あるいは小規模すぎるプログラムの中で)でもオブジェクト指向を実践する方法はないだろうか、ということです。 > >今自分が目をつけているのが、 > ・「開放・閉鎖の原則(OCP:Open-ClosedPrinciple)」 >というもので、これにのっとって実践を進めれば今ある機能を追加していくということでオブジェクト指向の利点を理解しやすく、かつ小さなプログラムを大きくしていけるのではないかと考えています。ここでの継承は、コードの再利用ではなく堅実なプログラムを組むため、という理由付けになりオブジェクト指向と呼べるのでは?と思っています。 > >しかしそのためには手続きを分節化し、プログラムを設計する能力がいるだろう、と思っています。 >このような場合に、デザインパターンが有効なのだと思いますが、具体的にどうプログラムを組むのか、というところで自分は躓いている状況です。 私は普段オブジェクト指向言語を使用していないのですが、 オブジェクト指向を意識したプログラミングをしています。 小規模であっても、手続き型言語であってもオブジェクト指向的 発想は可能です。 例えば、GUIのいくつかのパーツがあって、これらが互いに依存しあう 場合、これら同士でお互いを直接呼び出さないようにします。 必ず親(Mediator)を作って、間接的に制御します。 こうすることで、依存関係を親側に集中化でき、単純化できます。 これの本質部分は、全くオブジェクト指向は関係ありません。 GUIパーツ自身は、本来自分がやるべきことのみ やらせるようにします(単一責任の原則)。 あと、OCPにより、小さなプログラムを大きくしていける (コードを再利用する)というのは、私はそんなに単純ではない と思います。 OCPとは、つまり、上側のコードの再利用であり、下側の コード(処理やデータなど)を追加のみするということですが、 それが、そんな単純にうまくいくなら、トップダウンの 開発が重要ということになります。 仕様変更によるプログラムへの影響は多くが、より上側の処理 であり、より下側の処理の方が再利用の確率は高いと 思います。 プログラムを大きくしていく秘訣はいかにプリミティブな 関数など(より下側の処理)を充実していくかとか、 いかにモジュール化により、プログラムを分割していくかに よると思います。 そもそもOCPは、オブジェクト指向言語だけでは不十分で、 例えば、ログの処理やエラー処理が入ると それだけで処理の「汎用性」が失われ、OCPが成立しません (例えば、エラーを出すタイミングを変えるなど)。 アスペクト指向言語があれば十分かは分かりませんが、 あらかじめ仕様変更を予想してOCPが成立するように 再利用可能なコードを組むのは現実的には不可能だと思います。 但し、局所的に(場合によって)は、うまくいく時ももちろんあります。
[この投稿を含むスレッドを表示] [この投稿を削除]
[649] Re:オブジェクト指向「初」入門
投稿者:(ぱ)
2007/02/20 02:13:25

はじめまして。 >いろいろなオブジェクト指向入門を見てきて、オブジェクト指向は > ・大規模なプログラムの開発でないと効果を発揮しない > ・プログラムを分割することが大切 > ・デザインパターン(設計)を知らないといけない(? >という特徴を持っているのではないかと思っています。 デザインパターンはOOPの応用例であって、デザインパターンのためには OOPを知らないといけないけど、逆は真ではないのではないでしょうか。 GoFのパターンにはある意味マニアックなものもありますし。 >では、ここからが自分の疑問の核心なのですが、手続き型の学習の中で >(あるいは小規模すぎるプログラムの中で)でもオブジェクト指向を >実践する方法はないだろうか、ということです。 「小規模すぎる」というのがどの程度かわかりませんが、先に例に出した オセロや、以下のページにおいてあるドローツールなどは、趣味でも 十分作成可能な規模だと思いますがどうでしょうか。 ドローツール「X-Draw」のJavaアプレットによる実行例: http://kmaebashi.com/nazojava/xdraw/index.html サンプルソースはこちら: http://kmaebashi.com/nazojava/index.html >今自分が目をつけているのが、 > ・「開放・閉鎖の原則(OCP:Open-ClosedPrinciple)」 >というもので、これにのっとって実践を進めれば今ある機能を追加していくと >いうことでオブジェクト指向の利点を理解しやすく、かつ小さなプログラムを >大きくしていけるのではないかと考えています。 OCPというと、最近Matzにっき経由でこんなページを見つけましたが http://www.morijp.com/masarl/homepage3.nifty.com/masarl/article/dp-ocp-2.html ここの例だと音符クラスを使っていますね。 元祖MayerさんのOOSC(第1版)だと出版物(PUBLICIATION)クラスです。 上に挙げたX-Drawでは、Shape(図形)にdraw()メソッドを付けることで、 プログラムのあちこちにShapeの種類による分岐(Cならswitch case, Pascalなら case of文ですか)を書くことを避けることができ、図形の追加が容易にできるので、 これはまさに上のページやOOSCで挙げている例と合致していると思うのですが… ただ、ドローツール程度ではこれでよくても、実際大規模なCADなどでこういう 方法が使えるかといえば、 ・draw()といっても、ウインドウシステム等の違いにより描画方法は異なる。  ディスプレイリストを保持するシステムを使うなら、そもそも描画はdraw()じゃないぞ。 ・Shapeだからといってdraw()するとは限らない。データをファイルから  読み込んで解析だけして結果をテキストファイルに吐くようなツールだってあるぞ。 という問題もあるわけでして(あっちこっちに書いてるネタですが)。 結局設計に万能の「正解」はなく、たとえば拡張に備えるにしても「どんな拡張が ありそうか」ということをある程度予測してからでないと設計方針は選べないんじゃ ないかなあ、と思います。つまらない結論かもしれませんけど。 >ここでの継承は、コードの再利用ではなく堅実なプログラムを組むため、 >という理由付けになりオブジェクト指向と呼べるのでは?と思っています。 そうですよね。実のところ私はconcrete classなんざ継承できなくても よいのでは、と思っていますが、上で出ている例(Note, PUBLICICATION, Shape)は どれも抽象クラスですし、使用範囲を間違えなければ、有効に使えると思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[648] オブジェクト指向「初」入門
投稿者:Rq
2007/02/20 02:13:25

オブジェクト指向再入門、とても面白く読ませていただきました。その中で ・手続き型言語を習得している「途中」の自分がどのようにオブジェクト指向を実践していけるのだろうか というところで疑問を抱いたので質問したいと思います。ここでのオブジェクト指向議論とは違う疑問なのかもしれませんが、書きたいと思います。 自分は、対象読者とされている「手続き型言語を習得し」た人ではないです。大学に入ってからプログラミングを習っています。使っている言語はDelphiです。 Delphiはオブジェクト指向言語ということだったのですが、学んでいるのは手続き型の勉強なのではないか、と感じました。そこからオブジェクト指向に興味を持ち、調べたもののこの再入門冒頭に書かれていたとおり、挫折しました。そして、もう一度と思っているところです。 いろいろなオブジェクト指向入門を見てきて、オブジェクト指向は ・大規模なプログラムの開発でないと効果を発揮しない ・プログラムを分割することが大切 ・デザインパターン(設計)を知らないといけない(? という特徴を持っているのではないかと思っています。 そしてここのオブジェクト指向再入門で言っているマルチプルインスタンスというのは、Delphiのコードで言うと Type TStringList = class(TString); でTStringList型が出来て(これが「わけのわからない例え話」だったらすみません…) var Str1,Str2 : TStringList; というPrivate宣言をすることによって Str1 := TStringList.Create; Str2 := TStringList.Create; という具合に、同じ形のものを複数作成できる。そして、 Str1.hogehoge; Str2.hogehoge; というように、命令の主体を明らかにできる、ということが具体的な内容なのかなと考えています。 では、ここからが自分の疑問の核心なのですが、手続き型の学習の中で(あるいは小規模すぎるプログラムの中で)でもオブジェクト指向を実践する方法はないだろうか、ということです。 今自分が目をつけているのが、 ・「開放・閉鎖の原則(OCP:Open-ClosedPrinciple)」 というもので、これにのっとって実践を進めれば今ある機能を追加していくということでオブジェクト指向の利点を理解しやすく、かつ小さなプログラムを大きくしていけるのではないかと考えています。ここでの継承は、コードの再利用ではなく堅実なプログラムを組むため、という理由付けになりオブジェクト指向と呼べるのでは?と思っています。 しかしそのためには手続きを分節化し、プログラムを設計する能力がいるだろう、と思っています。 このような場合に、デザインパターンが有効なのだと思いますが、具体的にどうプログラムを組むのか、というところで自分は躓いている状況です。 しかし、上記のようなオブジェクト指向「初」入門が、オブジェクト指向言語から入った人には必要なのではないか、と思いました。再入門という観点からは不適切かもしれませんが、提起してみました。 乱文失礼いたしました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[647] Re:オブジェクト指向
投稿者:NykR
2007/02/20 02:13:25

>三角格子の各線を(軸でなく)座標値とすれば、隣に行くにはふたつの値を >いじらなければいけませんから、これはNykRさんのものと同じになるのでしょうか。 えーっと、各線に座標値を割り当てて、    |     |    x0     x1    |     |   /\    /\  y0  z0  y1  z1 /    \/    \ 「各マスの中心から、各辺に対して伸ばした線を軸とする」と、 x0=x1, y0≠y1, z0≠z1 だから 隣に行くためにいじる値は2つになりますね。 私のと同じになるみたいです。 んーと、でも三角格子の各線を軸とする方法もあると思いますよ。 私の方法をもう少しまじめに書きます。 んーと、 上から下へのラインを x軸 右上から左下へのラインを y軸 左上から右下へのラインを z軸 とすると、あるマスから例えば左右のマスへ移動するとき、 x軸方向に0、y軸方向に±1、z軸方向に±1 (× 辺の長さ分) 動かさなきゃいけません。 他の2方向についても2つの値をいじらなきゃいけませんよ、と。 で、この場合は、辺と座標軸が1対1に対応しています。 (ぱ)さんの最初の方法は、本来同一平面上にあるマスを別の平面にある要素(配列の)として表そうとしたところに問題があったのではないかと。
[この投稿を含むスレッドを表示] [この投稿を削除]
[646] Re:オブジェクト指向
投稿者:(ぱ)
2007/02/20 02:13:25

>>各マスの中心から、各辺に対して伸ばした線を軸とする、というイメージです。 > >ええと、あるマスが位置(i, j, k)にあったとします。 >このとき周りのマスは ... >右下 と 右隣の左下 のマスは同一のはずなので、別の場所にあるのはまずいのではないかと。 あれっ? 確かにおっしゃる通りです。よく考えずに書いていました。 いやそのマスと座標値が1:1対応しなきゃいかんよね、とは考えていて、 三角格子の交点をつまんでひっぱり挙げるとついて来る線は3本に決まるから、 1:1対応だよな、とか思っていましたが、この時三角格子の各線は座標値を 表しているのであって、軸を表しているわけではないですからね。 とここまでは実は考えていたつもりなんですが、同じだよな、となぜか (2次元の座標系のイメージにひきずられていたのでしょう)考えて 先の投稿のように書いてしまったわけなんですが、 三角格子の各線を(軸でなく)座標値とすれば、隣に行くにはふたつの値を いじらなければいけませんから、これはNykRさんのものと同じになるのでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[645] Re:オブジェクト指向
投稿者:NykR
2007/02/20 02:13:25

横から失礼します。 >>>六角オセロの場合は、3次元の配列にすると、はさむところの判定が >>>楽にできるかもしれませんね。各添え字の上限が一定しないですけど。 >> この場合、最初の2次元は私の書いたx,y座標ですか? >> 3つめの座標はどういう方向になるんですか? > >各マスの中心から、各辺に対して伸ばした線を軸とする、というイメージです。 ええと、あるマスが位置(i, j, k)にあったとします。 このとき周りのマスは 右隣 : (i+1, j, k) 右下 : (i, j+1, k) 左下 : (i, j, k+1) 右隣の左下 : (i+1, j, k+1) にあるはずですよね?(とは限りませんけど、気にしないことにします) 右下 と 右隣の左下 のマスは同一のはずなので、別の場所にあるのはまずいのではないかと。 何か勘違いしてたらすいません。 # こんなの思いつきました。直方体を斜めから見たら6角形になることを利用する訳ですが、 # どっち向きでも添字を2つ動かさなければならない・・・。 / \ / \ / \ |\ /|\ /|\ /| \|/ \|/ \|/ \   |\ /|\ /|\ /| / \|/ \|/ \|/ |\ /|\ /|\ /| \|/ \|/ \|/ \   |\ /|\ /|\ /|   \|/ \|/ \|/
[この投稿を含むスレッドを表示] [この投稿を削除]
[644] Re:オブジェクト指向
投稿者:本多
2007/02/20 02:13:25

>>>六角オセロの場合は、3次元の配列にすると、はさむところの判定が >>>楽にできるかもしれませんね。各添え字の上限が一定しないですけど。 >> 3つめの座標はどういう方向になるんですか? >各マスの中心から、各辺に対して伸ばした線を軸とする、というイメージです。 >4角形だと、辺の数が4だから、軸の数は2, >6角形だと、辺の数が6だから、軸の数は3, >この方法だと、ある軸の数値を変化させることで、次々と隣のマスが現れますから、 >はさむところの判定が楽にできるのではないかと。 なるほどぉ。勉強になります。 ありがとうございます。 ...とは言っても実際にゲームを作ったりはしないのですが 何しろ時間がなくて...能力も?(^^;) >>友人や家族でこのゲームを良くやるのですけど、 >>いつもどうやってプログラムするのかなって考えていたりします<-職業病?(^^;) >>そういう融通が効く人間ってすごいなぁとか思います。 >人間の「知能」って不思議です。 最近、コンピュータなしだとほとんど仕事ができないので 考えるのは全てコンピュータの方で私自身はコンピュータの (特殊な)入力補助装置になりさがっているのではないかなどと 感じ出しているのですが、そう錯覚することが「知能」なのでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[643] Re:オブジェクト指向
投稿者:(ぱ)
2007/02/20 02:13:25

>>六角オセロの場合は、3次元の配列にすると、はさむところの判定が >>楽にできるかもしれませんね。各添え字の上限が一定しないですけど。 > この場合、最初の2次元は私の書いたx,y座標ですか? > 3つめの座標はどういう方向になるんですか? 各マスの中心から、各辺に対して伸ばした線を軸とする、というイメージです。 \ \ \ /\/\/\ ―|00|01|02| \/\/\/\ ― |10|11|12| /\/\/\/ ―|20|21|22| \/\/\/\ ― |30|31|32| \/\/\/ /  /  / 4角形だと、辺の数が4だから、軸の数は2, 6角形だと、辺の数が6だから、軸の数は3, この方法だと、ある軸の数値を変化させることで、次々と隣のマスが現れますから、 はさむところの判定が楽にできるのではないかと。 >友人や家族でこのゲームを良くやるのですけど、 >いつもどうやってプログラムするのかなって考えていたりします<-職業病?(^^;) >そういう融通が効く人間ってすごいなぁとか思います。 昔は「コンピュータがチェスで人間に勝てたら、そのコンピュータには知能が あるとみなしてよいのではないか」という議論があったそうですが、 今じゃ誰もそんなこと言いませんもんねえ。 人間の「知能」って不思議です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[642] Re:オブジェクト指向
投稿者:本多
2007/02/20 02:13:25

>>例えば六角形のマスでも >>普通に二次元で値を保持しておけばいいんですね。 >六角オセロの場合は、3次元の配列にすると、はさむところの判定が >楽にできるかもしれませんね。各添え字の上限が一定しないですけど。 この場合、最初の2次元は私の書いたx,y座標ですか? 3つめの座標はどういう方向になるんですか? >>Catanみたいなボードゲームは、どうやって実装するのか、想像できないですけど。 >ミソは、ゲーム板をばらばらにして組みなおせる、ってところでしょうか。 六角形のマス自身における駒もあり、6個の角における駒もあり、 6個の辺における駒もあって、それぞれどのマスに隣接してるかが 重要になるゲームなので、マスだけに2次元座標を与えちゃダメなんでしょうね。 辺や角に座標を与えたら、それこそワケわからんのですけど(@_@) >その場合は、「隣接するマスを知っている」モデルが使えるかもしれませんね。 おそらくそういうモデルを適用するのでしょうけど、 初期化がすごく大変そうです。 友人や家族でこのゲームを良くやるのですけど、 いつもどうやってプログラムするのかなって考えていたりします<-職業病?(^^;) そういう融通が効く人間ってすごいなぁとか思います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[641] Re:オブジェクト指向
投稿者:(ぱ)
2007/02/20 02:13:25

>例えば六角形のマスでも >普通に二次元で値を保持しておけばいいんですね。 昔ASCIIに載っていた国産初のRPG「アルフガルド」なんかでも、そういう形で 座標を表現していたはずです。ユーザに見せるのがこの形式の座標なので、 内部的にもたぶんそうだったんじゃないかしら。 六角オセロの場合は、3次元の配列にすると、はさむところの判定が 楽にできるかもしれませんね。各添え字の上限が一定しないですけど。 >Catanみたいなボードゲームは、どうやって実装するのか、想像できないですけど。 これですか。 http://www.hanayamatoys.co.jp/catan/index.html ミソは、ゲーム板をばらばらにして組みなおせる、ってところでしょうか。 その場合は、「隣接するマスを知っている」モデルが使えるかもしれませんね。 表示の際の位置決めとか面倒そうですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[640] Re:オブジェクト指向
投稿者:本多
2007/02/20 02:13:25

>六角形や三角形のマスを使うものがあるじゃないですか。 >いったいどう言う形で情報を記憶するんでしょう? >二次元配列じゃ、素直に考えると、うまくない...かな? あ、何か複雑なこと考えすぎていたみたいです。 例えば六角形のマスでも 普通に二次元で値を保持しておけばいいんですね。 /\ |xy|として、下の様に座標を与えておいて \/ 表示するときに工夫すればいい...のかな? /\/\/\ |00|01|02| \/\/\/\ |10|11|12| /\/\/\/ |20|21|22| \/\/\/\ |30|31|32| \/\/\/ 隣り合うモノかどうかの計算もちょっとズレるけど 四角形のマスと大きく変わるわけじゃないんですね。 三角形も同じように出来ますね。 Catanみたいなボードゲームは、どうやって実装するのか、想像できないですけど。
[この投稿を含むスレッドを表示] [この投稿を削除]
[639] Re:オブジェクト指向
投稿者:本多
2007/02/20 02:13:25

全然、話の本筋とは関係ないのですが、オセロみたいなボードゲームに 六角形や三角形のマスを使うものがあるじゃないですか。 あぁいうのをプログラムで実現するとしたら、 いったいどう言う形で情報を記憶するんでしょう? 二次元配列じゃ、素直に考えると、うまくない...かな? 三角形のマスなら二次元目の方向を斜め方向にするのかしら? マス一つ一つがオブジェクトになっていて、 最初に隣り合うマスの情報をマスオブジェクトにあたえるんでしょうか。 初期化や、プレイヤーからの指定が、ちょっとめんどくさそう。
[この投稿を含むスレッドを表示] [この投稿を削除]
[638] Re:オブジェクト指向
投稿者:(ぱ)
2007/02/20 02:13:25

>> これは結構わざとらしい例だと思いますが、 > >全く本筋と関係ない話ですが、4隅の無いオセロは現実に存在します。 > >http://www.google.co.jp/search?hl=ja&c2coff=1&q=%22%EF%BC%98%EF%BC%98%E3%82%AA%E3%82%BB%E3%83%AD%22&btnG=Google+%E6%A4%9C%E7%B4%A2&lr= ややっ。 知りませんでした。情報ありがとうございます。 盤面の絵とかがなかなか見つからなかったのですが、10×10の盤面で、 4隅の3つのマスが存在しないわけですね。 Javaアプレット版88オセロ: http://www.eb.waseda.ac.jp/murata/~kami/othello/othello.html というわけで、 >> これは結構わざとらしい例だと思いますが、 この部分に関しては、撤回いたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[637] Re:オブジェクト指向
投稿者:NykR
2007/02/20 02:13:25

>>「オセロゲームの新しいルールを作ったので、それを反映してください。 >>そのルールとは、4隅が無い物です」 > > これは結構わざとらしい例だと思いますが、 全く本筋と関係ない話ですが、4隅の無いオセロは現実に存在します。 http://www.google.co.jp/search?hl=ja&c2coff=1&q=%22%EF%BC%98%EF%BC%98%E3%82%AA%E3%82%BB%E3%83%AD%22&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=
[この投稿を含むスレッドを表示] [この投稿を削除]
[636] Re:オブジェクト指向
投稿者:(ぱ)
2007/02/20 02:13:25

 はじめまして。ご意見ありがとうございます。 >しかし、オブジェクト指向の世界では「メッセージは非常に重要な要素」ですから、 >この表現では、「オブジェクト指向の世界ではメッセージは重要でない」と >誤解されてしまうおそれがあります。  何があればオブジェクト指向か、という点についてはいろいろ議論があって、 http://www.shiro.dreamhost.com/scheme/trans/reesoo-j.html | オブジェクト指向というものが動く標的であるため、オブジェクト指向の熱心な | 支持者はこのメニューのうちの適当なサブセットを気まぐれに選んで、それを以って | 他の言語はオブジェクト指向ではないと説得しようとする。 という議論もあったりしますね。Ruby作者のまつもとゆきひろさんによれば、 http://www.rubyist.net/~matz/20030807.html  『最低限の条件は「アイデンティティがある」こと』だそうですが、これはだいたい 私と同じことを言っているように感じています(違うかもしれないけど)。もっとも私の 説明だとクラスが前提になっているので、まつもとさんの定義の方が範囲が広いですけど。  オブジェクト指向というものがこのように「動く標的」であるとして、 私が件のページで書いているのは、対象言語をJavaとした範囲のものである、 ということをまずご理解ください。  さて、その上で、実際のモデリングをどのように行うかですが。 >オセロの例がありますが、「石を置く」「置けるかチェックする」「盤面を >初期化する」「マスの状態を返す」の関数をサンプルとしてありますが、 >これでは不十分です。 >何が足りないかというと、「マスそのもののオブジェクト」です。 マスそのもののオブジェクトを作るかどうかの議論は、かつてこのへんで したことがあります(現在過去ログが読めない状態のようなので、 Internet archiveより)。 http://web.archive.org/web/20041114033519/http://www.ogis-ri.co.jp/otc/otc2/oosquare-ml/Archive/200205.month/2713.html 私の結論は、マスなんぞのクラスを持ち込んでもしょうがない、8×8の列挙の 配列にすべきだ、というものです。 >それでは、次のような話を持ちかけられたらどうしますか? >「オセロゲームの新しいルールを作ったので、それを反映してください。 >そのルールとは、4隅が無い物です」  これは結構わざとらしい例だと思いますが、そういう例でも、私が公開している オセロのソースをいじるとして、Board#checkPutPossibility()とBoard#isFull()と reverseDiscs()あたりをちょっと直せば十分なんじゃないかしら…と適当に試したら なんか動いたっぽいです。 なお、(修正前の)ソースはこちらで公開しています http://kmaebashi.com/javaworld/index.html 4隅が(空欄として)存在するのは気に食わないかもしれませんが、そもそものお題が 「4隅が無いオセロ」と定義されているのだからそんなに変とも思えません。 >そう、8x8-4=60のマスすべてにメッセージを送るのです。 ... >60人いる保育所の子供全員に「みんなー!クリアしなさい!」と叫ぶ >先生のようです。 で、結局「先生」は、最低でも「真ん中の4つのマス」を把握していなければ いけません。 石を打つ人は、先生にお願いするのかもしれませんけど、もしそうなら 結局先生はすべての子どもの座標を把握している必要があるでしょう。 そりゃま(x, y)で引けるmapと考えてもいいですが、見るからに格子である あの「盤面」をわざわざそんなふうに捉えることが果たして自然かどうか。 >たとえば、「マスに石が置けるかチェックする」は、自分の8方の隣のマスに >問いかけます。 「8方の隣のマス」という時点で、構造が2次元の格子であることに規定されて いますね。たとえば三角格子や3次元に対応できない点において、sionさんの モデルも二次元配列も似たようなものであるように私には見えます。 ところでもしsionさんのモデルが、各マスが8方の隣のマスへの参照を保持する、 というものであれば、「斜めでは挟めない」という新ルールのオセロにおいて (隅がない、というのよりはありそうなのでは)、無駄になりますよね。 逆もまた真です。 >とても回りくどい、面倒な方法に思われますが、実際のコーディングで表せば、 >一般的なやり方と量はさほど変わりません。 一度ソースを見せていただけないでしょうか。いや、皮肉ではなく。 オセロの盤面は、よっぽど奇妙な拡張を考えない限り、2次元配列で十分だし、 なにしろもとが格子なので2次元配列にするのが自然です。 上で挙げたoosquareの投稿にあるように、以前勉強会でオセロを例にしたときに、 >たとえば、「マスに石が置けるかチェックする」は、自分の8方の隣のマスに >問いかけます。 というモデルで作ってみようとした人はいました。隣のマスを見つける方法が わからなくて挫折してましたけど。 # 彼の名誉のために言っておけば、もちろん全部参照持てばできることは # わかっていたでしょう。「本当にそんなアホなことするの?」と思ったから # やらなかっただけで。 私がああいう文章を書いたのは、オブジェクト指向といえばメッセージだ、 という言葉に惑わされて、そういう変な設計が「オブジェクト指向的」で、 なにやらありがたいものであるかのように思い込まされ、混乱してしまった人が 周囲に結構いたためです。 >たしかにそうです。また、白、黒の他に「赤」という石が追加になったら記述を >追加する必要があります。 >しかし、その追加はオブジェクト(クラス)についてすればよい事になります。 どのクラスについて追加すればよいとお考えでしょうか? >蛇足ですが、20年以上前から有るGPSS等のシミュレーション言語では、 シミュレーションにおいて、actor的なオブジェクト指向がうまくいくケースが あるのは確かでしょう。他にもうまく適用できる分野はあるのかもしれません。 でもたとえば最適値を計算しなければならないようなケースで、こっちのオブジェ クトがちょっと最適じゃないから隣のオブジェクトにメッセージを送って… なんてことやってると、無限ループに陥ることもありますよね。 何事も適材適所。少なくともオセロにおいて、隣のマスにメッセージを送って… などという設計が適切であるとは思えません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[635] オブジェクト指向
投稿者:sion
2007/02/20 02:13:25

大変な長文失礼します 興味深く読ませていただきました。 世の中の多くの解説は 「クラスとインスタンス、そして継承。及びパッケージ化」があればオブジェクト指向である。それがオブジェクト指向の本質である・・・かのような誤った物が多いです。 クラスや継承、ブラックボックス化は、たしかにオブジェクト指向の重要な構成要素になる「事がある」かもしれませんし、便利な物かもしれませんが、それがすべてではありません。 現在存在するオブジェクト指向言語と呼ばれる物もそういった意味では不十分な物ばかりです。 そのような中で、前橋さんのHPの解説はとてもすばらしい物と思いました。 ただ、「なぜわからなくなってしまうか」のページの説明で 「オブジェクト指向をわかりにくいものにしている最大の要因として、「メッセージ」という言葉が挙げられます。」 とあります。 もちろん、これは「現在存在するオブジェクト指向と呼ばれる言語では、実質関数呼び出しなのだからわかりずらい」と言われているのだと思います。 しかし、オブジェクト指向の世界では「メッセージは非常に重要な要素」ですから、この表現では、「オブジェクト指向の世界ではメッセージは重要でない」と誤解されてしまうおそれがあります。 あと、 「カプセル化とは、「実装詳細の隠蔽」のことです。外部に対しては必要最低限のインターフェースのみを公開し、それ以外は隠蔽することで、実装の変更を可能にしたり、そのモジュールを他でも使いまわすことを可能にする、という概念です。」 と有りますが、これは誤りです。 「実装詳細の隠蔽」は、確かに良い事ですし重要ですが、カプセル化の本質は「メッセージのやりとりを行う単位を作成する」ことです。そして、これがオブジェクト指向の根本です。 オセロの例がありますが、「石を置く」「置けるかチェックする」「盤面を初期化する」「マスの状態を返す」の関数をサンプルとしてありますが、これでは不十分です。 何が足りないかというと、「マスそのもののオブジェクト」です。 8x8=64のマスすべてをオブジェクトとする必要があります。 すると、「え?8x8の配列で良いでしょう!?」と思われるかもしれません。 それでは、次のような話を持ちかけられたらどうしますか? 「オセロゲームの新しいルールを作ったので、それを反映してください。そのルールとは、4隅が無い物です」 実際、4隅が無いオセロなんてつまらない物かもしれませんが、まあ、例と言う事で・・。 このような話が持ちかけられたら、残念ながら前橋さんのサンプルでは大きなプログラム修正が必要になってきます。 たとえば、盤の初期化。 真ん中の4石以外はすべてクリアすると思いますが、おそらくC言語的に書くと for (y = 0; y < 8; y++) for (x = 0; x < 8; y++) ban(y,x) = 0 みたいに書くのだと思いますが、これでは、この処理を大きく変更しなければ成りませんね。 何しろ4隅が無いのですから。(まあ、「4隅の分データを無視すれば良いのでは」とか言う話は置いて置いてください。) 石が置けるかチェックする処理なども同じです。 本来のオブジェクト指向の考えでは、たとえば盤のマス一つ一つをオブジェクトにします。 そして、それらのマスに「あなた(たち)の中身をクリア(石がない状態にする)しなさい!」と「メッセージ」を送ればよい事になります。 そう、8x8-4=60のマスすべてにメッセージを送るのです。 「結局60のマスに送るとき、ループ処理するのでは?」と思われるかもしれませんが、それは、現在のオブジェクト指向言語の不備の問題であり、本来のオブジェクト指向の考えでは、60のオブジェクトに大号令すればよい事になります。 たとえば、  masu(all): message (CLR) みたいに。 もちろんこのような例で書ける言語はありません。私の勝手な文法です。 60人いる保育所の子供全員に「みんなー!クリアしなさい!」と叫ぶ先生のようです。 この方法だと、盤が8x8だろうが、4隅が欠けていようとも、6x10のマスであろうが、コーディングを変える必要はなくなります。60人の子供たちは、必死に自分のマスをクリアする事に専念します。 盤の形の変更はマスの初期配置処理(インスタンス生成)さえ変えればよい事になります。 「石を置けるかどうかチェックする」ルーチンも同じです。 60のオブジェクトたちは、互いにメッセージをやりとりしあい、石をひっくり返す事ができるか確かめて答えを返す事になります。 たとえば、「マスに石が置けるかチェックする」は、自分の8方の隣のマスに問いかけます。「今、僕のマスに白を置こうとしているけど、君のところは黒かい?そして、盤が切れるまでの間に、白有るかい?」「僕のところは黒だけど、隣については聞いてみるね」などなど・・・。 この方法だと、たとえ、隣に突然穴があいていたとしても関係有りません。盤の形が変わっても関係有りません。オブジェクト同士がメッセージのやりとりで処理しますから。(もっと根本のルール変更が有ればこのオブジェクトも修正が必要になりますが、修正はこのオブジェクトのみになります。) とても回りくどい、面倒な方法に思われますが、実際のコーディングで表せば、一般的なやり方と量はさほど変わりません。 「’石を置く’、’置けるかチェックする’、’盤面を初期化する’、’マスの状態を返す’の処理を一つにまとめてオブジェクトにしただけで、根本は変わらないのでは?」という声が聞こえてきそうですが、違います。 「マス」というオブジェクト(部品)が作成されています。この部品を利用して、オセロに似た別のゲームができるかもしれません。たとえば、時間とともに盤に穴があくオセロとか・・・。 その例ですと、「時間とともに盤に穴をあける」という処理を追加すればよいだけですが、従来のやり方では、おそらく全面書き直しでしょう。 すると、「結局は穴があくのを前提にマスのオブジェクトを記述しなければならないのでは?」という声が聞こえてきそうです。 たしかにそうです。また、白、黒の他に「赤」という石が追加になったら記述を追加する必要があります。 しかし、その追加はオブジェクト(クラス)についてすればよい事になります。その際は、それこそ「継承」を使って派生クラスを作り、赤石の処理のみを追加すればよいかもしれません。 これで、部品の組み合わせにより「白黒64マスの昔ながらのオセロ」「4隅のないオセロ」「白黒赤石のある64マスのオセロ」「時間とともに穴のあくオセロ」など、様々なバリエーションを作る事ができます。 しかし、従来のコーディング技術では、おそらくバリエーションの数だけプログラムを全面書き直す事になるでしょう。もしくは、if文の嵐になるでしょう。 今度は、「じゃあ、そのマスを関数やサブルーチンにすれば良いのでは?」と疑問があがるかもしれません。 はい、それでかまいません。オブジェクト指向の「本質」は、クラスやインスタンス、継承やブラックボックス化することではなく、「オブジェクト単位で扱うことの考え方」ですので。 場合によっては、昔ながらのBasicでも、その本質は記述する事はできます。(読みづらいでしょうが) オブジェクト指向におけるオブジェクトとメッセージの重要性、わかっていただけたでしょうか? なお、この意見は私の個人的な意見ではありません。20年以上オブジェクト指向に携わってきた経験により他の人からのアドバイス、文献から得た物であります。 ところで、私の文章の中には 「本来のオブジェクト指向の考え」という言葉があります。 「本来の・・・って、誰がいつ考えた物が本来なんだ?」とつっこまれそうですね・・・ただ、現在主流のOOPでは、生産性の向上なんてあり得ない気がするのは確かです。 蛇足ですが、20年以上前から有るGPSS等のシミュレーション言語では、オブジェクトを複数生成してメッセージをやりとりしながら、すべてのオブジェクトが(論理的に)同時進行で処理を行います。 内部的に関数コールでしょ!?って・・・いえ違います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[634] Re2:メモリ管理モジュール(MEM)について
投稿者:エイト
2007/02/20 02:13:25

お返事ありがとうございます。 なるほど、MEM_create_controller で別領域に確保されたMEM_Controllerの初期値を渡してるんですね。 アプリ側では MEM.h をインクルードする前に #define MEM_CONTROLLER apl_ctrlとかで使用する、と言う事ですね。 Alignですが、アライメント用ですか。なるほど気づきませんでした。 K&Rも是非見てみます。 ありがとうございました。 お言葉に甘えて、また質問がありましたら、是非質問させていただきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[633] Re:メモリ管理モジュール(MEM)について
投稿者:(ぱ)
2007/02/20 02:13:25

>エイトと申します。 はじめまして。 >MEM.h の、MEM_Controller は、要は各メモリの根っこやエラー時の動作を握ってる >構造体ですよね。 >実体は memory.c に記載され、アプリ側には不確定形で公開していますよね。 >つまりアプリ側にはどうやったって構造が見えない形になってます。 そうです。 >しかし、MMS_CONTROLLER がdefine されると、defineされた値をMEM_xxx_func で >持ちまわる事が可能になるわけですよね。 >これの利点というか、アプリに選択肢を与えてる理由って、なんでしょうか。 おっしゃる通り、MEM_Controllerは、各メモリの根っこやエラー時の動作を握っています。 で、MEMの上位のプログラムが複数の部分(モジュール)から構成されている場合、 モジュールごとに、メモリの根っこやエラー時の動作を変えたいと思うかもしれません。 たとえば、crowbarを組み込んだアプリケーションを作るとして、そのアプリケーション 側でもMEMを使うとしたら、独立したMEM_Controllerを使いたいのではないでしょうか。 たとえばデバッグのためにMEM_dump_blocks()を呼ぶとして、crowbarで使っている メモリの情報まで吐かれても邪魔です。 MEM_Controllerは不完全型でその内容は隠されていますが、MEM_create_controllerで 独立したMEM_Controllerを取得することが出来ます。 また、独立したControllerを使わせたいなら、MEM_malloc()などで引数として MEM_Controllerを渡すという手もありますが、 引数が増えると面倒ですし、実際にはひとつのMEM_Controllerで済むことが 多いでしょうし、独立したMEM_Storageが使いたいという場合でも、たいていは.c単位で 切り替えられれば充分じゃないかなあ、と考えて、こういう実装になっています。 ただし根っこを静的に押さえているのでマルチスレッドなどを考えると問題になる かもしれません。 # ていうかそれ以前に、複数のMEM_Controllerを使うテストはしてないので、 # ちゃんと動くかどうかは定かではないですが f(^^; >MMS_malloc_func 等を個別で呼べなくなるというデメリットはありますが >MEM_Storage に突っ込んで、アプリに見せなくさせるのも一考かなと思ってますが >いかがでしょうか。 うーん、MEM_Storageは使わない関数もあるので、アプリに見えなくするなら mem_default_controllerにstatic指定を付けてmemory.c以外からは見えなくしてしまう ことになるんでしょうけど。 >2. >memory.c 内に定義されているHeader_tag が、union で定義されているのはなぜでしょうか? >Alignの存在する意味がわからないです。 アライメントを取るためです。 たいていのCPUでは、データ型によって、たとえばdoubleは8バイト刻みの領域にしか 配置できないなどの制限があります。 MEM_malloc()で確保された領域には、何が格納されるかわかりませんから、 MEM_malloc()はもっとも厳しい型で境界調整された領域を返す必要があります。 Alignは、その境界調整を行うための共用体です。 このあたりのことは、「プログラミング言語C」(いわゆるK&R)でサンプル実装している malloc()でも考慮されていますので、K&Rをお持ちであればそちらも参考にしてください。 こんな感じで回答になっていますでしょうか? 追加の疑問点等ありましたらまたお気軽にどうぞ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[632] メモリ管理モジュール(MEM)について
投稿者:エイト
2007/02/20 02:13:25

エイトと申します。 当HPは自分にとって大変勉強になり、無謀ながらcrowbar の解析をしております。 すいませんが、二点程質問が御座います。どうか宜しくお願いします。 1. MEM.h の、MEM_Controller は、要は各メモリの根っこやエラー時の動作を握ってる構造体ですよね。 実体は memory.c に記載され、アプリ側には不確定形で公開していますよね。 つまりアプリ側にはどうやったって構造が見えない形になってます。 しかし、MMS_CONTROLLER がdefine されると、defineされた値をMEM_xxx_func で持ちまわる事が可能になるわけですよね。 これの利点というか、アプリに選択肢を与えてる理由って、なんでしょうか。 MMS_malloc_func 等を個別で呼べなくなるというデメリットはありますが MEM_Storage に突っ込んで、アプリに見せなくさせるのも一考かなと思ってますがいかがでしょうか。 2. memory.c 内に定義されているHeader_tag が、union で定義されているのはなぜでしょうか? Alignの存在する意味がわからないです。 お時間ある時で構いませんので、返答の程、どうかよろしくお願いいたします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[631] Re:「体当たり学習」誤植
投稿者:a
2007/02/20 02:13:25

>ご指摘ありがとうございます。 > >正誤表に追加しました。チェック漏れが多く申し訳ありません。 > kkkkk
[この投稿を含むスレッドを表示] [この投稿を削除]
[630] Re:「体当たり学習」誤植
投稿者:(ぱ)
2007/02/20 02:13:25

ご指摘ありがとうございます。 正誤表に追加しました。チェック漏れが多く申し訳ありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[629] 「体当たり学習」誤植
投稿者:yuya
2007/02/20 02:13:25

こんにちは。「体当たり学習」の初版第1刷が手元にあるのですが、 まだ正誤表にない誤植がありましたのでお知らせします。 p.125 Fig 3-3 ASCIIコード表 (1) 表中の最右列2段目、正しくは「i 105(69)」と、小文字の「i」であるべきところが 大文字の「I」になってしまっています。 (2) 同列の最下段、チルダの十進表記は「126」なのに「127」になっています。 下の註●も同様です。十六進表記(7E)のほうは合ってますね。 (3) 2つ目の註●で「日本では¥が割り当てられていることが多い」となっていますが、 それならば表中の該当部分は「¥ 92(5C)」ではなく「\ 92(5C)」と すべきではないでしょうか? お忙しいとは思いますが、どうぞご確認ください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[628] [業務連絡]サーバが止まるそうです
投稿者:(ぱ)
2007/02/20 02:13:25

レンタルサーバ屋さんより、メンテナンスのため下記期間サーバが止まるという 連絡がありました。 10月31日(月) 午前2時-午前5時 この期間は、kmaebashi.comを閲覧できません。また、この掲示板も使用できません。 ただし、私宛のメール(PXU00211@nifty.ne.jp) および(なぜかケロロ軍曹に乗っ取られた)裏掲示板 http://otd9.jbbs.livedoor.jp/maebashi/bbs_plain は動作します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[627] Re:PHPでのLocation
投稿者:太郎
2007/02/20 02:13:25

説明不足で申し訳ございませんでした。 また、ご指摘いただきましてありがとうございました。 状況はご指摘いただいたとおりでした。  教えていただいたページで解決できました。 貴重なお時間をいただき本当にありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]