[OSASK 6488] sprintf(Re: 要望になってしまいますが).

  こんばんは、川合です。

  昨日[OSASK 6485]を書いているときに[OSASK 6484]が届いてちょっと
入れ違いになってしまいました。


KOYANAGI, Masaaki さんは 2003/09/24 23:57:49 の「[OSASK 6484] Re
: FORM:  要望になってしまいますが.」で書きました:

>アプリが大きくなってしまうのは、今のところ OSASK において、Cで書かれた
>プログラムが DLL を使用することができず、printf* 系の関数もスタティック
>リンクするしかないからというのも理由の一部かと思います。
>Linux では、*printf系は、libc.so にあって、ダイナミックリンクして
>使われるのが普通ですし。

  C言語で書かれたプログラムはDLLを利用できないとか、(これはこの
メールには書いてありませんが)DLLはC言語では書けない、というのは
正しくない認識です。まあ、C言語だけでは書けない、というのなら確
かにそうですが。

  ほんのちょっとだけASKAの助けを借りれば、DLLをC言語で書いたり、
呼び出したりできます。そもそも、今のAPIはDLLなわけで、みなさんC
言語で普通にAPIを利用しているのですから、DLLがC言語から利用でき
ないということは、断じてありません。lib_execcmd()的な関数を、ASK
Aでちょこっと作って橋渡しにさせればOKなのです。

  ということでサンプルを作りました。test049です。ベータリリース
してあります。sprintf()をDLLに追い出して、countdownをやって遊ん
でいます。

>>   初心者は、printf()があるとどうしてもこれを使いたくなってしまい
>> 、これに頼る傾向が出てくるでしょう。そうすると、setdec()のような
>> ことをやる人が少なくなって、setdec()はなんだか知らないが高度なこ
>> とだという誤った印象が広がって、結局みんなでかいアプリばかり作る
>> というOSASKらしくない結論にいたる可能性があります。それだけが心
>> 配です。
>
>これは上のスタティックリンクの件も含めてはっきりと説明して、その上で
>アプリ製作者に判断を任せるというので問題ないでしょう。

  それはよくないと思います。初心者はprintf()を最初に使えば、最後
までprintf()を使います。setdec()をつくろうなんて思いもよりません
し、そもそも文字列というのは、charの配列であるという基本的なこと
すら理解しないことがあります。文字列の長さはstrlen()じゃないと数
えられないとか、strcat()なしには連結できない、なんてプログラマが
知り合いにいました(それでもC言語のプログラミング歴1年以上なんで
すが)。

  まあよく言えば、彼は「文字列」というものを抽象化して理解してい
たために、内部構造なんて気にもかけなかったのでしょう。だからでき
なかったんだと思います。標準ライブラリばかり使うプログラミングに
最初に慣れてしまうと、こういうプログラムしか書けなくなるから、僕
は嫌なんです。

  どんなに説明しても、printf()とsetdec()をいっしょに説明するなら
初心者は簡単なprintf()のほうだけを理解して、setdec()のほうを流し
読みします。そして理解してないsetdec()を使いませんし、あとで勉強
してみようという気にもなりません。そしてその人はいつまで経っても
駄目なプログラムを作り続けます。僕はそんなプログラムは「エミュレ
ータを使わないで走るアプリケーション」くらいにしか思っていません
。ちっともOSASKらしくありません。OSASKアプリといったら、やっぱり
小さくて速いものであってほしいです。

  今のOSASKが小さくて速いアプリにあふれているのは、まさにこの僕
の作戦が功を奏しているのです(もちろんOSASKのAPIの優位性も効いて
いますが)。

  しかし、何もかもちゃんとわかった上級者にprintf系の関数を提供す
るというのには反対しません。だからベイサイドさんに使ってもらおう
と思って、test047を作りました。この点においては、「説明して、そ
の上でアプリ製作者に判断を任せる」というのに賛成です。

>説明の例
>(1)OSASK アプリケーションのエディタ teditc は 10kB 程度だが、それに比べて
>*printf系の関数は??kBと大きい。
>(2)sprintf(buf, "%d %c %s", i, j, buf); を setdec() 他を用いて書き直すと
>??kB の節約となる
>(3)だからアプリケーションを書く場合は、*printf() は必要最小限にして欲しい
>
>実際のところ、問題としている sprintf() 関数はどれくらい大きいのですか?

  面白いテーマだと思ったので、ちょっとやってみました。この手の考
察にはなると思います。

  test048もベータリリースしてあるのですが、これには、GOでコンパ
イルしたcntdwncとtest048が入っています。これにtest049を加えて、
こんな考察ができます。

  まずこの3つのプログラムについてまとめます。

  ・動作はみんな同じ
  ・cntdwnc :  414バイト  setdec仕様
  ・test048 : 1293バイト  sprintf仕様(スタティックリンク)
  ・test049 :  629バイト  sprintf仕様(ダイナミックリンク)
        (DLLは1034バイト)

  この場合%3dしか使っていません。ちょっとsprintf()には酷かもしれ
ません。しかし例えばnaskもsprintfを使っていますが、%sも%cも使っ
ていません(%dと%Xを多用している)。実用プログラムでsprintfがあ
りがたいのは、%sや%c以外の変換でしょう。

  とりあえずcntdwncとtest048の差を取ると、879バイトになります。
これが現状でのsprintfのコストだといえるでしょう。test049は414バ
イトよりも215バイトも多いですが、これは今のOSASKのAPIのDLLサポー
トが弱いせいです。予定しているDLLサポート用のAPIが追加されれば、
オーバヘッドは小さくなって、差は50バイトくらいで済むと思います。
DLL側の1034バイトというのは、多分変わりません。差の155バイトは、
DLLをまたぐオーバヘッドみたいなものです(その代わり、今のAPIと同
じくファンクションをキューで渡せますので、うまく使えば速度的なオ
ーバーヘッドは最小になります)。

  なお、この879バイトという差をどう思うかですが、僕はこれはまあ
我慢できないことはないと思います。しかし今のsprintf()はサブセッ
トです。%fや%eをサポートする必要あります。これをサポートしたら、
2KB以上になるのは多分避けられないと思います。そしてそういうsprin
tf()ができたら、きっとそちらを使うことになると思います。だから%d
程度のためにスタティックリンクでsprintf()を使うのは、OSASKアプリ
としてはかなりよろしくない、ということになるでしょう。DLLならサ
イズの問題はありません。sprintf()は処理が多くて重たい関数なので、
処理頻度の高いところに使うのはお勧めしませんが、そうじゃなければ
積極的に使っていいと僕は思います。

  初心者は頻度の高いところにもsprintf()を使うので、というか、spr
intf()しか理解しようとしないので、たとえDLLであってもsprintf()を
与えたくはありません。

>どうも [OSASK 6482] は、
>
>「*printf() をスタティックリンクされるとアプリケーションのサイズが
>大きくなるから、(川合さんは) *printf() という選択支を提供するのに気が
>進まない」
>
>と私には聞こえて納得できません。もう少し詳しい説明をお願いします。

  ということで、僕がprintf族をことさらに嫌がっているのは、初心者
向けの教育上好ましくない、という点だけであります。ベイサイドさん
や小柳さんやI.Tak.さんのような、その辺のことが何もかも分かってい
る人は、小柳さんのいうとおり自分で正しい判断ができますので、提供
しない理由にはなりません。

  僕は今までprintf()のサポートをするべきじゃないかという提案に対
して反対し続けてきたのは、その動機が「初心者がhello, worldするた
め」だったからです。しかしベイサイドさんみたいな用途でということ
なら(その苦労はよくわかりました)、僕は賛成しますし、手も貸すわ
けです。

  ということで、あとは初心者が初心者を脱するまで、sprintf()の存
在を知らないでいてくれることを強く願うばかりです。みなさんもアド
バイスの際には極力言及しないようにしてほしいです。introaにstdio.
hを入れないで、introeあたりにstdio.hだけ入れようかなと思っていま
す。


  それでは。

--
    川合 秀実(KAWAI Hidemi)
OSASK計画代表 / システム設計開発担当
E-mail:kawai !Atmark! imasy.org
Homepage http://www.imasy.org/~kawai/

ML番号でジャンプ
ML単語検索