忘れないうちにメモをしろ 2004-01〜


 プログラミングにまつわることで、思い出したこと、考えたこと、気になること など、ともかく低レベルでもみっともなくても中途半端でいいからメモを取ろう、 と思うページ(忘れてしまって困るのは己なのだ)...

※ 勢いでろくにチェックせずにアップしとりますんで、 鵜呑みにせず、ソースはバグってるかもで、気いつけたってください。





 2004-01-11 indent 2.2.9 のコンパイルやら


 HDDの整理をせねばー、で、中身確認してて、作りかけやら移植しかけやら 書きかけのページやらをみてると、ついまた弄っちゃう、ということがあり―― とそんな現実逃避的に今更だけど GNU indent 2.2.9 を win 用にコンパイル。 (ものはこちら)

 実のところNLS/国際化(gettext)関係を無視すれば、簡単にコンパイルできる代物だけれど、 折角メッセージの邦訳があるのに使われないのは悔しく...でいろいろ思うもgettext/libintl の事情は面倒くさそで結局日本語専用にgettext()モドキを用意してお茶を濁す。 (cygwin環境ならgettext使えるようだけど...MSysはどうなんか... 普通のDOS窓だとさてどうしたものか、と)

 indent のチェックのため( regression/TEST を実行するため)に、MSys 環境をインストール。 (こちらの説明をみながら)。
 インストールして出来るMSYSアイコンから起動する環境(rxvt)は日本語(フォント)が表示できないようで ちょっと悲しい...だったが、なんのことはなく sh.exe を使えばとりあえず大丈夫そう。 (msys.batの代わりに cd bin; sh --login -in; をするバッチを用意、と)
 cygwinにしろmsysにしろあえて避けてたけれど、cygwinよりかは単純そうで、ま、ええか。 dos/unixの習慣の違いやシェル命令の違い, 環境の辻褄合わせ?の影響等、慣れないうちははまりそうだけど。

 indent のコンパイルは vc でやったのだが mingw でもコンパイルできるはずなんで 確認のため試すと全角2バイト目\関係でおこられる。 cpp_sj 入れてなかったっけ、と、入れてみる駄目... どうやら gcc v3 からは外部 cpp を使わなくなっいた模様(今頃きずくなよ、だ)。

 でも、すでにgccの日本語対応化とか もあるようなんで、それを使えば、ええのよね。実行パッケージはこちら。 微妙に環境依存があるのか、デフォルトのincludeパスとか見に行ってくれない... -I でパス指定すればいいのだけど(makefile書けば、と)。 で、set CLANG=C-SJIS して改造indentをコンパイルするとコンパイラが落ちたのだった(stack overflow)。 環境設定失敗したか...includeして6Kバイト弱の"文字列"を使ってるソースが無作法なのは棚にあげて、と^^;


gettextは、winでは、どうするもんなんでしょ。 cygwin や MinGW/MSys 環境前提が無難なんかなあ... libintlとかの dll や *.gmo(*.po) を置くフォルダ(share/locale/)をどこにするのか... win の場合、 *.po を自前で変換して各国語対応で .res 化しちゃって exe に組み込んじゃうってのも よさげに思えてくるのだけど(なんかすでにありそうな気もする)... 、で、どっかそのようなツールないかなあ。

NLS/gettext関係の検索メモ。




 2004-01-17 indent やら astyle やら。


 前回書いてから cpp_sj に関してはcc1をラップして gcc v3 に対応させてみた。 ラッパーゆえの問題はあるけれど、ちょっとしのぐには、で。

# 行番号 "ファイル名"

を使えば簡単にすむ問題だったのですね。 変換ソースの頭に # 1 "srcname.c" があれば、で。

 あと、indent が c++ に対応していないということで、 他のツールを探して 
Artistic Style  とか  bcpp 
て、いうのを知る。bcppのほうは、ちょっと簡単には全角対応できなさそう だったけれど、astyle に関しては簡単だったのでやってしまったり。

※その他の検索メモ: indent++まだまだのよう

2004-02-04 書きかけで放置してたのをとりあえずアップロード



 2004-02-04 D言語を触ってみた


 嫌いなわけじゃないんだが C++ の本末転倒なカオスっぷりに くたびれてるためか、アンチテーゼ的な D言語につい、心惹かれてしまうのでした。

 仕事で使うことはないだろーけどね、で、現実逃避的に^^; (少なくともターゲット環境向けのDコンパイラができたとしてもその頃には コンシューマ機は次世代になってるだろうし、第一己自体が現役プログラマ でなくなってる可能性も大いにあるわけだし)。

とりあえず、どういった言語かについては
DIGITAL MARS(言語作者のサイト 仕様や実物やら).  マニュアルの日本語訳  D言語研究(Wiki)  D言語研究室  D言語ML  D言語の四方山話  D memo  (2ch)D言語スレ  D言語関係のアンテナ 
あたりを見て、と(定番リンク)。

 で、まずはこちらを 参考に秀丸用のhilightファイルを用意して、と。

 ちょっと使って、ひっかかるのは、  英語圏なコンパイラなんで、例の'\'問題がやはり、ある... で、早速 cc1_sj を元に dmd向けラッパーを作... てたら、D言語はデフォルトで Unicode な世界ということに気づく。 .d のソースはUTF-8(UTF16でもokかも)固定が基本の模様。 しかし、過度期なためか、ライブラリの表示関数等は os のAPIに生で文字列わたすので、UTF8 な文字列を画面ではシフトJISで 表示しようとして、文字化けだらけなのでした。とほほ... (ああr"や`で囲めば\問題回避できるんやしで)

 で、作りかけた勢いで&Dの練習がてらに、 unicodeなソース中の "文字列" '文字' `文字`だけ シフトJIS(マルチバイト)文字に変換してコンパイラに渡す ラッパーを作ってみたのでした。ものは

これ(dmd_usj)

単純置換につき文字列定数がchar[]かwchar[]かってのは判別つかないので wchar[],dchar[]に文字列定数渡さないソース前提だけど。

...作ったあとで、 「文字コードにまつわるエトセトラ」 で、素直な正攻法での対応が載ってて脱力 (正攻法することが頭になかった自分が情けない)。

ま、こんなもんでも、触ってみるといろいろ判って楽しかったり。 出会いたくもないバグにであったりもするが... それは日本語のMLに投げてたのでそれ以外の思ったことちょっとメモ。

・関数内で、関数が定義できるのは、 しかも、Pascal 的に外側の関数のローカル変数にもアクセスできるってのは、 ちょっとしたルーチンの場合、下手にクラス化せずに 下位ルーチンのスコープを限定できるので、 結構お手軽でうれしいカモ (もちろん、でかくなるならクラスにすべしだけれど)。 Cだと関数内#defineで擬似的にやらざるえなかったことが、 Dだとちゃんと文法でサポート、と。 (逆に思えば、C の#define の置き換え処置、て面もあるのかな)。

・ライブラリ、エラーは例外を投げるが基本、ってので面倒臭(低レベル)とか思うも、 エラー処理を用意しなかったら(catchしなかったら)、 標準ライブラリ側でエラーメッセージを表示してくれるので、かなりオキラクにすみそ (少なくとも簡易なコマンドライン・ツール作りでは)。 もっともエラーメッセージを日本語にしたいと思うと、(gettext的な?)某かのメッセージ 差し替え方法がほしくなるけれど。

・std.stream と std.c.stdio の両方をimportすると stdin, stdout, stderr の名前が衝突しちゃうのが ちょっと残念(衝突しにくいようにstdIn,stdOut,stdErrと...思うも、過度期ゆえ、なんで、 std.c.*を使わずにすむようになるまでの話か)。 エラー出力に stream の stderr を使おうと思っただけだが... std.stream.stderrと直接書くかそれをaliasしちゃえばいいのだけれど、デバッグ出力はなるべく お手軽に書きたいねえ、で。...お手軽にしたければタダの printf 使え、なんだろうけど、 char[]文字列は終端\0を持たない問題を避けようと思うとstreamの writeLine()のほうが 楽に思えることもあるわけで。(追記:単に %.*s ですむ問題だった)
ああ std.c.stdioをimportしなけりゃいいのだけどね。sprintfを使ってしまった、と。 streamにprintfあるんだから string.printfなんかもあるとうれしいんだが。 (追記:std.outbufferが実はそれに近いものなのかも^^;) できればchar[]向けのフォーマット指定があれば... 暫定のprintfでなく D言語標準のフォーマット付出力が決まってくれるのでも。




 2004-02-04 D言語というよりUTF8の問題だけれど..


 Dのプログラムじゃないけれど、D言語さわりはじめたのにあわせて、 自作の小物をちょっと修正。 ( c2htmのD対応と タブ変換ツールを utf8に対応... phobosのソースで 8タブのものがあったりなんで)

で、やってて、思うのは、UTF8 ってまだまだ色々不便だよなあ、で(己の環境では^^;)。
デバッガが対応してないと、変数内容の文字列はさっぱり、だし、 *.txtで吐き出したら、シフトJIS優先なツールを使ってると、よく化けてしまうし。 つーかUTF8未対応のツールをまだまだ使ってるわけで (WinFDのテキスト表示がUTF8未対応ぽい...移行時期か...)

 MSなマルチバイト文字だと、1バイトか2バイトで、基本的に2バイト文字は1バイト文字の 2文字分として扱かえるので(すくなくともdos/winな日本語では)バイト数と桁数の関係が 単純にすむけれど、UTF8だと1〜6バイトになりえ、見た目をどうするかもフォント/OS環境 で条件かわってくる...(シフトJIS同様と割り切ってしまえば同様にはなるけれど)。

 いや、ま、タブの処理を修正してて、さてどうしたものか、とちょっと迷ったのね。 0x80〜0x7fffの2バイトコード(元1バイト文字)系をどうしたものか、と、 JIS範囲にないものなら半角扱いでいいんだろうけど、JISにある ギリシア文字やロシア文字は、さて...ローマ字は倍幅文字があるが... 余計なこと考えて泥沼。 結局は、当面の己の環境(常用のフォントでどう表示されるか)を思えば、 いままでの延長(JIS漢字)が基本で、 とりあえず 0x80 以上は全角扱い(半角2文字分)にして 半角カナ(UFF61〜UFF9F)だけ 半角1文字扱いにして対処する、 で逃げてしまったのだけれど (1文字は1文字で幅無しで扱う、って処理もできたほうがよさげだが...そのうち)。

 ネット検索してると、やっぱり Unicodeって気にしだすといろいろやっかいなこと多そうですね。 同一コードでの字体の違いの問題や、習慣上の字幅の問題等、 国別に個々に対応せにゃならん問題は残ってくるわけで、 知らない国の事情をどこまで考慮できるものやら。 (Unicodeと他のコード系との変換にからむ問題もあるし)




 2004-02-27 Digのインストール

DでのGUIライブラリの dig v0.0.14はどんなものかな、と、 インストールしようとしてシクハク。 標準ライブラリ(phobos)の構成が変わってから更新されていないらしく、 いろいろコンパイラに怒られる。

多少なら、と書き換えてみるも...きりがないので検索しなおしたら、 こちらこちらの頁に 他の人が修正したものが(元作者の人は結局停止しちゃったのか?)。とりあえず、 日付の新しかったこちらのをお試し。

比較的すんなり、とはいっても己のdmd環境は \dmd でなく \Tool\dmd なんて場所にしているため、 多少手直しの必要あり。 makefile 先頭の BASEDIR = C:\ を BASEDIR = C:\TOOL にすればok、と いけばよかったのだけど...
まずmakefileの41行目の色を変えた場所に r を追加して

@echo module net.BurtonRadons.dig.common.baseDirectory; char [] digPlatformBaseDirectory = r"$(BASEDIR)"; <net/BurtonRadons/dig/common/baseDirectory.d

また、net/BurtonRadons/digc/program.d の 200行目付近の

        command ~= r" -I\dmd\src";
        command ~= r" -I" ~ dmd_src;
に。一応、go.batでコンパイルは通るようになる。 (なんかmakefile中のcopyが実行できないと怒られるのだが、その辺は適当にやっちゃって、と)
(※追記: 単に パス区切りに \ だけでなく / を受け付けるシェル/cmd.com を 使われてただけのようですね。/を使ってりゃ r つける必要もないし...)

あ、インストール途中 dmd/src/dig/下を丸ごと消すように makefile がなってるいるので、 インストール元フォルダは dmd/src/dig以外にしとかないとちょっと不幸(T T)なんで 96行目のrmdirをコメントアウトするほうがよいかも。

 ...dmd/binのパス位置を埋め込むために再コンパイルってのはいまいち情けない不便なんで、 どうせ digc.exe を dmd/bin に置くの前提なんだから、とすれば、 net/BurtonRadons/digc/digc.d の13行目

 13://import net.BurtonRadons.dig.common.baseDirectory;
 13:char[] digPlatformBaseDirectory;
に置き換えて、さらに 506,7行あたりに、
507:    digPlatformBaseDirectory = replace(argv[0], r"\dmd\bin\digc.exe", "");
を挿入すれば、すむ模様。

 あ、と、digc は dmd の代わりに使う単なるコンパイラドライバのよう。 当然digcを使わなくてもdigは使えるけど、 digで使うwinライブラリの.libを補完してくれたりソースファイルにワイルドカード使えたり .defや.resを補完してくれたり時間比較してたり、とちょっとだけ助けてくれる。 まあ、規模が膨らむなら自分でmakefile書いたほうがよさそだけど。

と、インストールしたはいいが、ちょこっとサンプルコンパイルしただけで、気力は尽きてしまったのだった。
インストールすると、.exe や .dll をかってに別のフォルダにほりこむので、結構うっとうしいし。 案の定、A系のwin-api使ってるからUTF8で書くと日本語とか化けるし、一部 W系になってるから9x系は駄目?ぽいし。

あと、別のGUIライブラリWindyも気になるが...

※digのライセンスは基本的にPDSだけど一部windows.hがLGPLてのは、参照元のwindows.hがLGPLだった、てことなのかな?


追記:いじくった dig や digc は こちらにさらしてます...


 2004-02-27 Dメモ


うだうだとdmd(0.79)をさわったりDがらみの検索してた時の覚書。

■Foo foo; 
と書いたつもりで、
 foo foo;
と、未定義の名前を型名と変数名にしてしまったらクラッシュ(T T)。

あと、挫折したけどdigを自前で辻褄あわせしようとした折、import絡みが不安定ぽく、 privateにしてて起きる筈のないstd名のコンフリクトで怒られたり (どうも互いにimportしあうモジュール2つを別のモジュールからimportすると ぽい...のだが、ミニマムな例/状態を作ってみると起きない... alias もからんでる? その他の要因もまだありそ...)。 ちょっと、徒労感。


■ D対応になってうれしい doxygen だけど dfilter は必要なのね?で... やっぱり Unicode に未対応なのは不便、なので、 ちょっと対応してみた。

これ。

ものは こちらの「D言語のソースにdoxygenを使う」にある ddoc.zip に同根の dfilter.d を改造したもの。
(dfilter 自体は dig にも同じソースの古い版と思われるものが入っていたりするけれど)。

 下手にUTF/SJIS自動判定なので(dmd_usjの使いまわし) 判定ミスはするだろうから、UTFは極力BOM付でないと不幸せかも、と。 (SJISオンリーなら、使わないほうが無難やろー)。

dfilter.exe は doxygen のフォルダか dmd/bin のフォルダに置くことになるかな (各自のpath次第...)。
ああと、dig を構築すると勝手に dig の dfilter が dmd/bin にほりこまれて path 設定によっては 悲しい目にあったり。


DIDE(0.993)は、 フォントを日本語設定にすれば、SJISテキストを 不完全ながらも日本語表示できるんですね。 編集は2バイト文字考慮してくれなくて、 表示が一部化けてるけど... で、化けてる文字ってのは、 /*コメント*/中の全角下位バイトが0x20のもの... //コメントは化けないので、/**/用に何か特別に解析とかやってるんかな。

 D言語モードを持つエディタ(IDE) zeus は、 フォントを設定すれば日本語表示されるけど、編集は未対応。 結構よさげな環境の雰囲気で心引かれるものがあるが... 海外製のエディタってtab文字の視覚化って無いものなのね... 当然全角空白とかもなく^^; (なんてつまらんことが気になったり)


open-watcom の デバッガ(wdw)に dmd -g でコンパイルした.exeを与えたらデバッガがクラッシュしてしまった。 (-g無しなら大丈夫だけれどデバッグ情報無しは意味ないし)。

lcc-win32 td32(5.5) は、クラッシュはしないけど、 -g付でもデバッグ情報が無いとのたまわれる。 c++builderX も同様ぽいか(できそなのかもだがソースでBP等効かず...Cでもデバッグ設定ちゃんとせんと同様な 罠に落ちたような気がするが、dmd用のデバッグ設定はさて、と)。

DM-C CD版のIDEは一応ソースでBPはったりステップ実行できるがSJIS/MBCに(当然UTFも)未対応。

結局フリーの範囲ならwindbg、 製品であればVSでやるのがベター、 というありきたりの結論にしかならなかったのだった。
(ソースをUTFで書いててokなのはVS.netだけやし... ああCodeWarriorとかはどうなんだろ)

あ、と、VSでも、変数名等に日本語を用いた場合は、ソース以外のローカル変数表示等ではさすがに化けてしまうのだった。 (ちょっと野望?が遠のく)


■ 人のソースを見てると、やっぱり、d用にもインデンタがほしいなあ、とか、思ってしまう。
で、物は試しに astyle に食わせてみると、 何も改造せずとも、結構まともに整形されたのだった。

c/c++/c#/java 対応の代物のおかげでよくも悪くもぬるい?判定が功をなしてるのかなあ、と。 当然、思いもかけないもの(他言語向けの予約語)がへんに処理されちゃう場合もあるけれど。

己としては、 KRスタイルぽくできればいいや、なんで、とりあえずはやりすごせそう。
(ただastyle の KRモードは cの教科書(KR)のじゃなく、 c++の教科書(Stroustrup)のだったり... linuxスタイルのほうが希望のKRに近いか...)。


追記:in(,out),body,unittestブロックがあると、それらは関数とみなされないため、 その中のインデントはおかしくなりやすいのだった...やっぱり、D対応のindentがほしい....


 2004-03-04 Dメモ: std.string.toStringz

std.string の toStringz(char[]) はちょっとリスク、というか、バグがあるような... どうも、いまいちよくない実装のよう。

ちと意図(仕様)外の使い方かもだけど...

    1 : import std.string;
    2 : void main() {
    3 :     char[4][2] s;
    4 :     s[0][0 .. 4] = "abcd";
    5 :     char* t = toStringz(s[0]);
    6 :     printf("s[0]=%#x:%-4.*s s[1]=%#x:%-4.*s t=%#x:%s\n", &s[0][0], s[0], &s[1][0], s[1], t, t);
    7 :     s[1][0 .. 4] = "efg\0";
    8 :     printf("s[0]=%#x:%-4.*s s[1]=%#x:%-4.*s t=%#x:%s\n", &s[0][0], s[0], &s[1][0], s[1], t, t);
    9 : }
なんてやると、
s[0]=0x12ff34:abcd s[1]=0x12ff38:     t=0x12ff34:abcd
s[0]=0x12ff34:abcd s[1]=0x12ff38:efg  t=0x12ff34:abcdefg
のように、後続と連結しちゃう...

toStringzは引数文字列の最後の文字のに '\0' があるなら、そのまま文字列 の先頭アドレスを返し、無ければ'\0'を足したc文字列を新規に作ってアドレスを返すモノだけど、 その'\0'の存在チェックが単純にポインタで超えた部分をアクセスしてるだけなんですね。 (文字列の(長さでなく)メモリの領域サイズは別段、参照してなかったのね、と)

最も toStringz のソースに注意書きで static な"文字列"の最後やchar[]でアロケートしたときは 余分に'\0'つくよ、とあるので...
逆に言えばそうでないメモリはこの関数に渡しちゃ駄目って仕様なのかも。 (固定配列やらmallocしたメモリは渡すな、と)

けどアロケート後の文字列の拡張で、領域目いっぱいなったときとかは、やっぱり アロケートしたメモリの範囲外をアクセスしちゃうようにも思え...

phobos/internal/gc/*.d からメモリの確保されかたを確認して、意図的に

    1 : import std.string;
    2 : void main() {
    3 :     uint[] a;
    4 :     char[] b;
    5 :     a.length = 4;   /* 16/uint.size */
    6 :     b = "0123456789ABCDE";
    7 :     b ~= 'F';
    8 :     char*  bz = toStringz(b);
    9 :     printf("a=%#x:%-4.*s b=%#x:%-4.*s bz=%#x:%s\n", &a[0], a, &b[0], b, bz, bz);
   10 :     a[0] = 0x6867;
   11 :     printf("a=%#x:%-4.*s b=%#x:%-4.*s bz=%#x:%s\n", &a[0], a, &b[0], b, bz, bz);
   12 : }
上記を-releaseでコンパイルすると 動的に取られる 16バイトのメモリ2つ(b,a)が 連続に配置されるので、後半のメモリの先頭に最初 0を置いておいてtoStringz後 0以外に すれうと、どうなるか、で、結果は
a=0x900fd0:     b=0x900fc0:0123456789ABCDEF bz=0x900fc0:0123456789ABCDEF
a=0x900fd0:gh   b=0x900fc0:0123456789ABCDEF bz=0x900fc0:0123456789ABCDEFgh
のように やっぱり bz にゴミが付いちゃうのだった.
実際のプログラムでは、11行目に相当するものがもっと後に行われたり、 変数aに関する処理が他のルーチン/スレッドで行われたりするわけで... ちょっとイヤな状況になる可能性がありえる.... (って、 スレッドのこと思うとやっぱりバグだよなあ)。

てことで、効率が悪くても cast(char*)(str ~ "\0") をしたほうがよさそうに思えてくるのだった。

(ひょっとして、b ~= "F"; のような場合でも メモリをちゃんと確保して必ず最後に"\0"が付くのが仕様で、たんに今はバグってるだけ、って可能性は あるのかな...)


 2004-03-07 Dメモ:雑多

■ dmd v0.80 が公開されてたので、早速入れてみたのだけど、toUTF32()のハングは未修正の模様(utf.dがv0.79と同じだった)。 自前ルーチンで1クッションかますの、とっととやめたいのだけど...

synchronized()は、まだ、駄目かも(使うと Access Violation)。

win98 で gc.fullCollect(); で落ちる、というのは直った模様(digのサンプルが動いた)。

未定義のmodule名(enum,class名)を使ったとき、コンパイルクラッシュになりやすくなったかも...?

追記:phobos のソースを v0.79 と比較してみたら、修正があったのは

std/date.d   floor()追加
std/string.d  基本型用のtoString()で足りていなかったものを追加
std/thread.d  getCurrentThreadHandle(); 修正
std/c/windows/windows.d GetCurrentProcess();宣言追加
std/typeinfo/{
ti_double.d ti_float.d
ti_idouble.d ti_ifloat.d
ti_ireal.d ti_real.d }  (float->int)キャスト修正

てことで、その他のファイルに、違いはなし...(T T)
(std.c.time.d の size_tも残ってた)

追記:未定義ラベルの件、v0.79 であった foo foo; で foo が未定義だと 落ちる件は直ったようですが、 v0.80では、逆に Foo foo のような普通の宣言で Foo が 未定義だと落ちるようになった模様... import し忘れてると落ちてくれるわけで、かなり不便かも。 しかたないので、0.79を文法チェッカ代わりに使うことに。 protectedバグの件もあってコンパイラだけ 0.79 に戻すことに。

追記:3/8 速攻出たv0.81でprotectedと未定義ラベルの件は直った模様。

■ DIGにつづいてwindy試しに UTF16/MBC対応してみた。 結構すんなり。
 windows.h for D が使われていることもあって TCHAR を用いて win-api は A/Wをつけない記述に変更し、 toString,toStringzの代わりにTCHAR用の toTCS,toTCSz を用意して置換、 "string" はT("string")に書き換えておいて、 日本語モードならT()内で辞書に登録した"日本語文字列"に置換、というやり方。

digでの反省で、他国(日本)語にするなら基本的に TCHAR=wchar でUTF16にするのがいいかなあ、で。 一応 TCHAR=char (win32.ansi時) でUTF8-> MBC(SJIS) 化も行えるようにしたけれど、 MBC/UTF8の区別を気つけないと破綻しやすいような...

■ digのほうはいじらないつもりだったけど、dmd v0.80の仕様変更でコンパイルが通らなくなったので とりあえず、通る状態には修正

けっこう、げっそり気力体力消耗。なんとかしのいだけど、(ファイル名)行番号無しで エラーを出されるファイルに限ってでっかいファイルだったりで。

windy での対応方法と同じやり方に書き換えたい気持ちも起きるけど、 windows.d を自前で用意してたり A系W系apiをチャンポンで使ってたりなんで、 やりだすとちょっと手間そう...

■ dmd_usj で __FL__ 等を使ってデバッグしてると、たまにエラー表示がテンポラリ名のままだったり ... #line がきちんと(コンパイラ側で)機能していないってことか。

■dm 付属の make、 けっこう pure な make なようで泣けでくる。 if条件分岐 や 部分文字列置換の類が無い(勘違い。ちゃんとあった)... 場合分けについては makeの引数で変更内容を渡すことで対処できたけど、 .d を .obj に置換して、ってのは 結局コピペして
※嘘ツキでした。duiのmakefile見てたら使ってたので試したら使えた(前は何かへまっただけか)。

標準(付属品)にこだわらずに gnu make 当たりを使えばええという話ではあるけれど。

■ dig や windyをいじってて思うのは、 import foo; で fooモジュールの全てのpublic名が読み込み側に展開されてしまうのは、 名前の衝突が起き易くて面倒が多いなあ、と。

衝突するとモジュール名つきで記述するか、 予め alias で定義することになるので、数が増えてくると... (モジュール名付きで書く場合ディレクトリ構成の依存度が増して、それはそれで 硬直した状態になっていくわけで)

展開せずに モジュール名. 経由でないとアクセスできないようにする指定とかが、ほしいところ。 例えば foo モジュールに abc();という関数があるなら abc()だけでは駄目で必ず foo.abc(); にという風に。

で、名前の衝突が起きた場合に、モジュール名必須のほうとなしで済ませられるモノを 制御できたら、もちっと作業が楽になるなあ、で。

現状では

[file foo_base.d]
    module foo_base;
    void abc() {....}

[file foo.d]
    module foo;
    private import foo_base;
    alias foo_base FOO;

[file bar.d]
    import foo;
    void main() {
        FOO.abc();
        //abc();       // これはエラー
    }
のように実体を一旦privateでimportして、外に対してはそのモジュール名をaliasで公開することで、 とりあえず名前を閉じ込めることは可能だけど。 あるいは template を用いても可能 (って、templateで十分か?) できれば aliasで違う名前にせず module名 のままアクセスしたい、てことで。
追記:これって、やね氏のとこで書かれてる namespace の問題のことだわな。

■ alias名同士の名前の衝突の場合、せめて定義の中身が全く同じなら、 (基本型名のみとかmodule名込みのフルネームが一緒なら)、 衝突を見逃してほしいなあ、と思ったり。(cの#define と同様に...)

TCHAR を win32.windows.d か win32.ansi.windows.d かそれらを importしないプログラムの場合、なんて場合わけをやろうとして シクハク... 結局 versionラベルを増やして、対処。




 2004-03-14 Dメモ
本業が忙しくなってきてる... 病気で休んだからといって納期が延びるわけでないので仕方なし。 今後のために作り直す予定だった部分も可能な限り旧作から流用... なんだが見返してるとやっぱりウゲゲと目を背けたくなる(悪循環)。

てことで忙しくなりすぎる前に Dメモ。

■ 現状では贅沢な要望なんだろうけど、 デバッガ向けにもちっと型情報を吐き出してほしいなあ、と思う。 ほとんどのポインタが void* で、クラスメンバとか見れないのは辛い (他の人達よくやってるなあ)... せめて基本型のポインタや64bit整数になっちゃう動的配列くらいは 対応するcの型名になってほしい...。
(いちいちキャスト指定してウォッチするのは面倒くさい)

■ int side; となっているのに

    xx = x * (side ^ 1) + y * (side) - count;
なんて感じに書いたら、"side is used as a type" と怒られてしまった。
どうやら後ろの (side)-count をキャストと解釈してるらしい。 () を外したら通った。

ささやかなコンパイラバグ(?仕様?)だけど... すっぱり (型) スタイルのキャストを仕様から 捨てて cast(型) スタイルのみにしてたら、これはなかったろうなあ。 いや、個人的には cスタイルの指定のほうが楽でつい使っちゃうしで、 cast()の立場が中途半端だなあ、で。

■ phobos/D での基本の文字列は UTF8 なわけで ... 少なくともファイル名の指定などは(まだ未対応が多いとしても)。

UTF8文字列を直接扱うのは面倒が多いけれど、 UTF16 は UTF8/UTF32の全てを表現することはできない... 普通の用途なら UCS2 の範囲でことたりるだろうで 今は表現できなくても問題は(少)ないとしても、 気になりだすと気になる。 やっぱり内部表現としては dchar のほうが 楽な場合もままありそうで...

てことで、ちょっとプログラム内の文字列をTCHARベース(char/wchar)でと考えるも、 TCHAR=dcharは WIN-API で破綻するので挫折。 TCHARは WIN-API とのやり取り専用の型と考えるが無難なんだろうな。

■前回の名前を閉じ込める件、structやclass にして static で構成でも可能だけど static書くのが嫌で眼外にしてたのだが、

class Foo {
    import std.stream;
    static int foo(int a) {return a*a;}
    static void bar() {printf("%d\n", foo(num_));}
private:
    this();  //{assert(0);}
    static int num_ = 5;
}

void main() {
    Foo.stdout.printf("Foo.size = %d\n", Foo.size);
    Foo.bar();
    Foo a;
    a.bar();
}
aliasする必要がないし、C++のような :: と . -> との表現の違いもないから それほど悪くはないのかもって気がしてきた。(変数定義できちゃうのは我慢で)

■と、上記例を class を struct に書き換えて(this()をコメントアウトして) 試すと、"no property 'stdout' for tye 'Foo'" と怒られるのだった。 これはバグなのか仕様なのか... 用途的に struct 内で import 出来ること自体が 禁止でも理屈にはなると思うけど。

ちなみにv0.79にあった class内での private import が private にならない バグは直っている模様。

が、Foo.stdout.printf でなく Foo.printf だと使えてしまうのだった。
std.stream でなく 中身からっぽの module を class内で import しても同じ。 (class内でimportしない限りは使えない)
phobos/object.d に定義されたものが現れちゃうんだろうなあ。

■ 上記の例(struct変更前のclassの状態)で、 main()中 Foo a = new Foo; としたとき this()がprivateでも怒られない模様。 バグなのかc++とはルールが違うのか (同一ファイル内だと friend扱いになる件かと思い、 class Foo を別ファイルに切り分け import しても同じ) ... リンク時にはエラーになるのだが、生成されているシンボルからは、 Fooのthisの実体がないってことには気づきにくい。
現状では、this() {assert(0);} として実行時にファイル行/番号が出力させる ほうがまだデバッグしやすいそ。




 2004-03-14 Dメモ: もっと in,out,inout

 極力ポインタ(宣言)を使わずにプログラムするのが D の作法なんだろうけど、 C のライブラリを使わざるえない局面等を思うと、 const ポインタを言語でサポートしてほしいなあ、と思う。

できれば、"const"を指定したいんじゃなくて、デフォルトでは 指してる先は読込のみで、必要に応じて書換許可を与えるってのが... ポインタ先用のin/out/input属性がほしい、と。


同様に、class/module のメンバー変数も、in,out,inout 属性が 付けれるとありがたいと思う。 class/module 内部は読書自由で、お外に対して制限かけたい。 デフォルトは out (お外からは読めるだけ)で。

class Foo {
  int       x, y;  // 外から読める. out 省略.
  out int   c;     // 外から読める.
  in  int   rq;    // 外から読めないが、書き込める。
  inout int val;   // 外から読み書きされる
}
当然意味があるのは public/protected の時のみだけど。

D の場合 module も class もデフォルト pablic なので、 せめてリードオンリーなら関数と同程度の危険度ですむので ぜひ、と思ってしまう。
(ある程度以上の規模のソフト開発向けとしては、 デフォルト public って大概のアセンブラにも劣る C言語のレガシー要素の筆頭に思うんだけど)

プロパティを使えば外部に対し同じ状態を 作れるけど、class 内部を作る手間がふえるのもなあ、で。
(外部に書き換えられないのを保証するために関数経由にするってのは c++なら必要悪みたいなもんだと思うんだが、プロパティで、変数と 同じ表現にできちゃうと益々本末転倒な気がしてくる...)

struct の場合は 用途的 にデフォルト inout でいいように 思うけれど。効率を気にして class の代用として使われる structではマズイかもだけど、それは別問題として (代用せざるえない状況向けに struct でなく class として template等や効率化のためにstructのようなメモリ配置の (結局はc++と同様の) class 定義が別途できてほしいなあ、と)。



 Dを知った当初、関数の引数に in,out,inout があるのをみたときは てっきりメンバー変数にも付けれるだろう、とぬか喜びしたのだけど ... ちらちらと過去仕事のソースを再利用目的で見返してたら、 こういうしょうもないレベルの管理負担はやっぱり 減ってほしいと思う気分が沸いてくるのだった。

作法的には、変数は private で書き換えは関数/プロパティ経由で、 が徹底できればいいんだろうけど、 一定レベル以上のスキルの人間だけでチームを組める、 なんて恵まれた環境でもないので。

(もちろん、壊滅的な人はわざわざ全部 public にしたり inputにしてくれるだろうけど。 switch の default なんかもね... 実際、仕事向けのスクリプトで default 無かったときの範囲チェックを 組み込んでたら、全部にdefaultを差し込んでくれるスクリプタさんいたし... C言語経験者と油断したら... て Cしか知らないせいだろうけど)。

はたして現場で D を使う未来があるかは別として、 新規言語なんだから、もちょっと夢に近づいてほしいなあ、と。


 2004-03-25 dmd/dmc で unicows.lib

■ とりあえず Digital Mars C/C++/D 向けに libunicows0.6.4 をコンパイルできた模様。

わかってしまえば基本的にたった1行の追加。
BORLAND 版に対し、

    group FLAT _TEXT _DATA
だけ。

わかるまでは、ひどく遠回りして時間を食ったのだけど... 86系の セグメントのある世界なんてすっかり忘れてたし、 nasm と Digital Mars C の双方とも事情がよくわかってないし 英文マニュアルも苦手だし。 結局、逆汗結果からの類推で適当にいろいろやっててやっとこさ。

...例?によって DM の obj2asm は微妙にバグってたようで(T T)、 FLAT GROUP の行をちゃんと生成してくれてたら....(と、これは逆恨み)。

ま、サンプルは動いて、Dでもごく簡単なテストだけど動作。 (逆にいえば、これ以上のことは何もしてない、と^^;) とりあえず変更ソースとlibはこちら

■ MS が配布している MSLU というW付(Unicode)API で作成したWindowsプログラムを Win98系でも実行できるように補助する dll があり、 libunicows は、 それを他のコンパイラ(mingw,bcc,watcom)でも使うためのインポートライブラリ。 で、DM用がまだのようだったので、試した、と。

基本的にこのlibを一緒にリンクするだけ...
が、実際には、いろいろ手間もあるらしい。

MSLU関係の検索メモ:  UNICODEプログラムの作り方(内部) (入力&表示) (補足)  wxWindowsと日本語  サクラの小枝研  たっけの日記 unicows.dll  Note/AnsiUnicode

■で、上記のlibは DMD だけでなく DM-C/C++ でも使えるのだけど、 肝心のコンパイラの日本語文字列モードがバグっているために v8.40では-j0を指定すると必ずエラーになってしまう... v8.38だとSJISはいいけどwchar_t/Unicodeは機能していないような 感じに文字化け... 結局 DM-D でしか今のところ役立たずなのだった。

■ 上記のmakefile は、できれば DM 製の make 用で、と、思いはしたけれど
{gen_asm}.asm{build\dmc}.obj:
のようなディレクトリ付きの指定の代わりがあるかどうかわからず 結局 MS nmake と GNU make で書いてしのいだ。

マニュアルを見る限りでは、 DM のフリー版の make は、結構 pure なんですね。
実際には、前にも書いたとおり、
OBJS=$(SRCS:.c=.obj)
ができたり、今回試してたら include も機能したので、そこそこの感じは あるのだけど、他の一応フリーで入手できる、 GNU, MS, Borland, OpenWatcom の make と比べると(条件文もないし)、 やっぱり不便になってしまう。

DM のシュア版ツールにある smake のほうだと条件文はあるようだけれど、 ディレクトリ付きのは... { } を用いた複数ディレクトリ 指定があるようなので、何かできそうな気はするけれど、さて、と。

DM有料化したツールって微妙に恨めしい状態かな。 cでアセンブラ出力しようとしたら obj2asm が必要だし。 必須というほどではないけれど、あって当たり前みたいなものが入ってたりするわけで。

値段や需要を想像するとなんでシュアにしたんだろて気もしてくる (以外と購入されるものなのか?). dmd 普及させるんなら make くらいケチらないでよ、って気もして^^; (あるいはいっそmake.exeを外しておいてくれれば..)

CD版 DM-C との差額を思うと、どうしても割高に感じるような (どうせなら CD版 DM-Cを、と仕向けるためとか:-)

けど、結局こちらのように、 OpenWatcomの同様ツール で代用って状態も発生してしまい... 標準状態の消失は、あまり幸せではないよなあ。


DM-C検索メモ: 2chスレ 16ビット版: [WonderWitch/Digital Mars C++]  DMCでlogger..  WonderWitchメモ


 2004-04-06 ゴミ

ネタはないが、とりあえず嬉しがりの痕跡。
libunicows DM版は、とりあえず本家に反映してもらえた模様。 ただでさえ文章書くの遅いのに英文メールだと短くてもやたら時間かかる... で何度も読み返してたはずだが、自分の名前のiがぬけてたのだった(T T) 折角名前書いてもらえたのに。(己のマヌーであって作者さんのミスじゃないのだ)

D も要望だしたいなあ、とか思うもやっぱり書けないので沈没. 以前のclassメンバのin/outのこととか、エンディアン指定な変数/メモリとか(structにだけでも)... 低レベルな欲求なんで、例え言葉が通じてもあまり意味ないだろうけど。

(目先の仕事に集中?するため Dは触れてないし... dmd 0.82 は解凍して phobos のファイル比較しただけ... windows.d, linux.d, syserror.d, date.d, recls_fileinfo_unix.cpp,と makefileの類 ...gdc絡みが主なのか... gdc誰かwinで動かしてくれないかしらん...)




 2004-09-20 久しぶりのメモ

 あまりに放置しすぎて、どうするつもりだったかスッカリいろいろ忘却だが、 些細なメモ書きだけでも。

追記) 今日は2005/02/14ですが、 上記日付のころに書いたはいいけど、も少し書き足すつもりでアップせずに 放置状態だったもので(その後のソフトのバージョンアップ等を ちゃんと調べたり確認したりは)いろいろ面倒なんで そのままアップ。

■ dm-c v8.41、まだ -j0(SJISソース対応) にバグありのようで、

#define FOO(a)    (a)
#define BAR(b)    FOO(b)
int main() {
    printf("%d\n", BAR(1));
    return 0;
}
のように、マクロ中で別のマクロを使用していて、 かつ、外からの引数を中のマクロに渡しているようなマクロを使うと、 “プリプロセッサエラー: マクロ引数が終了していない” と怒られてしまうのだった。
 最初単純なソースで試したらうまく通ったので喜んだのだけど、 現状、4.38 あたりが安定版ってことになるのかな。
 ちなみに -j0での L"文字列" は UTF16 にならずに SJIS のままのよう... 今となってはWin用として不便な仕様。 asiaな文字対応は、本人がメンテ面倒な他人なソース部分なんでせうか、ね。 DM-C 使いたい理由が dmd と一緒に使いたい、って所にあるので、 もー SJIS(-j)はほっちゃって、まずは Unicode 対応して、って気も。

■ 雑誌付録から Visual Studio 2005(beta) 入れてみました。 パネルの配置が逆になっててちょっと脱力(VS6に同じに戻ったとも... 最初から変えずにすませてくれれば... どうでもいい話だけど)。
 で、dmd で-debugコンパイルしたものをソリューションで開けてソース ほりこんで、ブレークポイントを張って実行... BP で止まりません(T T) てか、BP張れてません_no
 やっぱり、Microsoft は意地悪のようです。

■ gdc が入ってるってことで、cygwin 入れてみました。 昔に比べて随分と楽チンインストールになってて、結構魅力に思えてきたり。

が mbc<->unicode 変換がうまく機能していない。 ググったところ、cygwinでは は不具合ありってのを見かけるも 日付からするともう直ってるようだし、、、で、結局、自分の cygwin環境の日本語設定がマズいだろう、ってのが一番ありそう、です。 (で、結局つかわない...)

■ open watcom-c もやっとこさ、1.2/1.3 を入れてみました。
1.3 からは c99対応のやら最近風の c++ ヘッダが入っているのですが stl 関係は入っていない... stlport からってことなんでしょうが、 最新の安定版(4.6.2)とβ版(5.0-0125) を入れてみるも全然うまくいかず。 stlport/config/config_watcom.h をいろいろ弄ってみたり、 検索したら見つかった 4.5.3 の修正方法を元に 4.5.3 を入れてみるも、 やっぱり駄目。 stl4.5.3とコンパイラv1.2 の環境(てかヘッダ)との組み合わせが一番 エラーが少なくはなるけれど... map使ってたら class template requires more parameters for instantiation なんて怒られて。  stlport って Open Watcom (ver12) になってからのには、だれも 対応してなさそうなんですかね。なんとなく watcom v11.0c 当たりで 止まってそうな気もしてくる... もっとも watcom 側でそのうち対応しそうな気配だけれど。 (watcom-c の news で1.4で某と何か書いてたような)



[前] [戻る]