K.Maebashi's BBS

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

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


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


[2128] いろいろ愚痴りたい((プログラミング言語を作る3章〜5章 )
返信


投稿者:mano
2018/04/30 19:02:25

Link:
ゴールデンウィークで読み終えられるかなと思っていたけど全然そうじゃなかった。
やっと、5章まで読み終わった。で、いろいろ愚痴りたい。(今回は投稿にパスワードをつけたので消す準備はバッチリです。)

まずは、環境依存の問題
今週末は一人で0x0d問題にぶち当たり全然読み進められなかった。
test.crbを食わせても以下のメッセージしか出ない。
5:(0x0d)@ 
win_sjisのtest.crbだと、改行にCR(0x0d),LF(0x0a)が入れられていて、
今使っている処理系(Microsoft Windows Subsystem for Linux上のubuntu)
では、0x0dを無視してくれず、改行コード\n(=0x0a)に到達する前に不正な文字で引っかかっている、がubuntuのターミナルは、SJISを解釈してくれず文字化けを起こす。結局が悪いのかがわからない。
今の時代趣味でやる分にはsjisもeucも地雷じゃないかなあ?

で、読む気力がそがれたので、重箱の隅を突っ込みながら(またしても)表面をなぞる程度の読み込みになっちゃった。ちゃんと読めるのはいつのことになるんだか。。。

で、突っ込みはこんな感じ。
電卓の場合yyparse()で無限ループしているのに、crowbarではyyparse()以降の処理に進んでいることは誰も疑問に思わないのかな、
とか

p.121 2個目のelse if文の中の処理、
 left_val.u.double_value=left_val.u.int_value;
  eval_binary_double(...)
の部分で、left_val.typeは変えずに(INTのまま)格納する共用体にはdouble値を入れている。
その後left_valはそのまま使わず、left_val.u.double_valueのみ使っているので問題にはならいけど、読んでて不安になる。なぜdouble(専用のというか普通)の型のローカル変数を使わないのかな?
とか、

p.141の網掛けの以下の記述
 a={1,2,3};
  a={2,3,4};
のあとの図で、aから出ている矢印が{4,5,6}を指している。
{4,5,6}というのはどこから出てて来た?というか{2,3,4}はどこいった?
とか、

p.145のビットフィールド。別にCのプロフェッショナルを目指す本ではないので、ビットフィールドなんて説明が必要な機能なんて使わずにしれっとCRB_Boolean使ったり、そのままズバリintを使えばいいじゃない。
とか、

p.153のダイナミックスコープの説明でnextから辿る場合、
仮に自身と呼び出し元に同じ変数名を定義し、自身内で変数を参照する場合、先に呼び出し元の変数が検知されてしまうので、ダイナミックスコープの動きと違うのでは?
とか、

p.178
mbstate_をmemset()等でゼロクリアというmbstate_ってどこから出てきた?

って感じです。あと、5章UNICODEについては、組み文字以外にデータ内に入っている(文字送り方向や字形の変更など)
制御コードをどう扱っているのかも書いてあればななあとも思いました。この辺って、例えば1文字のはずなのにデータは100byteとか作れそうで、セキュリティホールになりやすい感じがするので、なぜ問題にならないかを聞きたかったかも。

[ この投稿を含むスレッドを表示] [ この投稿を削除]



[2129] Re:いろいろ愚痴りたい((プログラミング言語を作る3章〜5章 )
返信


投稿者:(ぱ)こと管理人
2018/05/02 16:46:30

Link:
>win_sjisのtest.crbだと、改行にCR(0x0d),LF(0x0a)が入れられていて、
>今使っている処理系(Microsoft Windows Subsystem for Linux上のubuntu)
>では、0x0dを無視してくれず、改行コード\n(=0x0a)に到達する前に不正な文字で
>引っかかっている、

なるほど、crowbar.lでは「\n」だけを改行扱いにしていますから、
UNIX環境下では0x0dは不正な文字として扱われますね。
もともと、Windows(かつてはDOS)にてCでテキストファイルを扱う際、
改行を\r\nとして扱わなければならないのでは既存のUNIXベースの
ソースが軒並み壊滅するので、Windows/DOS環境下では、fopen()とか
fgetc()とかの標準入出力ライブラリのレベルで、\r\nを\nに変換するという
対策を取っています(バイナリファイルを扱いたいときにはfopen()に
"r"の代わりに"rb"を渡す)。「Microsoft Windows Subsystem for Linux上のubuntu」
ではこの動きにならないのは、WindowsではなくLinuxであるためでしょう。

>今の時代趣味でやる分にはsjisもeucも地雷じゃないかなあ?

まあそのあたりは、2009年の本ですので(その当時でもちと古かったのかも
しれませんが)。

>電卓の場合yyparse()で無限ループしているのに、crowbarではyyparse()以降の
>処理に進んでいることは誰も疑問に思わないのかな、

電卓では入力が終わりませんからね。

>p.121 2個目のelse if文の中の処理、
> left_val.u.double_value=left_val.u.int_value;
>  eval_binary_double(...)


>の部分で、left_val.typeは変えずに(INTのまま)格納する共用体にはdouble値を入れている。
>その後left_valはそのまま使わず、left_val.u.double_valueのみ使っているので
>問題にはならいけど、読んでて不安になる。なぜdouble(専用のというか普通)の
>型のローカル変数を使わないのかな?

ちょっと当時の意図は思い出せませんが、左辺をdoubleに型変換した
感じを出したかったのかもしれません。確かに今見ると、ちょっと意図の
よくわからないコードになっているとは思います。

>p.141の網掛けの以下の記述
> a={1,2,3};
>  a={2,3,4};
>のあとの図で、aから出ている矢印が{4,5,6}を指している。
>{4,5,6}というのはどこから出てて来た?というか{2,3,4}はどこいった?
>とか、

p.146ですね。誤植のようです。正誤表に載せておきます。
ご指摘ありがとうございました。

>p.145のビットフィールド。別にCのプロフェッショナルを目指す本ではないので、
>ビットフィールドなんて説明が必要な機能なんて使わずにしれっとCRB_Boolean
>使ったり、そのままズバリintを使えばいいじゃない。

これにはたぶん段階のようなものがあって、
(1)unsigned long flagsみたいは変数にフラグを押し込んで、
 自力でビット演算
(2)ビットフィールド
(3)しれっとなんでもCRB_Boolean
当時、実用に供されているCのコードだと、(1)が多かったと思います(ひょっとすると
今でも)。それに比べれば進歩(?)だと思っておいてください。
(本にも「まあ、富豪的プログラミングの感覚からすれば、1ビットのフラグでも、
CRB_Boolean型ひとつ割り当てるべきなのかもしれませんけど。」と書いていますが)

>p.153のダイナミックスコープの説明でnextから辿る場合、
>仮に自身と呼び出し元に同じ変数名を定義し、自身内で変数を参照する場合、
>先に呼び出し元の変数が検知されてしまうので、ダイナミックスコープの動きと
>違うのでは?

最新のLocalEnvironmentを起点にnextをたどって変数を検索すると、
先に検知されるのは呼び出し元ではなく自身の方なのでは……?
一応ver.0.2のeval.cのalloc_local_environmentを確認しましたが、
新LocalEnvironmentのnextに、その時点でのトップのLocalEnvironmentを
連結していますし。

635: ret->next = inter->top_environment;
636: inter->top_environment = ret;


>p.178
>mbstate_をmemset()等でゼロクリアというmbstate_ってどこから出てきた?

文脈からすると「mbstate_t」の誤りのようです。正誤表に載せておきます。


>って感じです。あと、5章UNICODEについては、組み文字以外にデータ内に入っている
>(文字送り方向や字形の変更など)制御コードをどう扱っているのかも書いてあれば
>ななあとも思いました。この辺って、例えば1文字のはずなのにデータは
>100byteとか作れそうで、セキュリティホールになりやすい感じがするので、
>なぜ問題にならないかを聞きたかったかも。

この本のプログラムでは、「mbrtowc()を信頼する」というスタンスですかね……
[ この投稿を含むスレッドを表示] [ この投稿を削除]



[2130] Re:いろいろ愚痴りたい((プログラミング言語を作る3章〜5章 )
返信


投稿者:mano
2018/05/03 16:13:46

Link:
回答ありがとうございます。(1か月ぐらいした後に消そうと思っていて、正直回答を期待していなかったので少し驚きました。)

>>p.153のダイナミックスコープの説明でnextから辿る場合、
>>仮に自身と呼び出し元に同じ変数名を定義し、自身内で変数を参照する場合、
>>先に呼び出し元の変数が検知されてしまうので、ダイナミックスコープの動きと
>>違うのでは?
>
>最新のLocalEnvironmentを起点にnextをたどって変数を検索すると、
>先に検知されるのは呼び出し元ではなく自身の方なのでは……?
>一応ver.0.2のeval.cのalloc_local_environmentを確認しましたが、
>新LocalEnvironmentのnextに、その時点でのトップのLocalEnvironmentを
>連結していますし。
>
>635: ret->next = inter->top_environment;
>636: inter->top_environment = ret;
>
>

うーん、コード読んでないのがバレました。(だって人が書いた長いコードをインタビューなしで読むのはしんどいもの。。。)で、nextの音の響きから、左から右、上から下、低層から高層(深層)の方向と想定してました。
だから、「最新のLocalEnvironmentのみから検索しますが、nextをたどって、呼び出し経路すべてのLocalEnvironmentから検索するようにすると、」の記述を、
「「最新のLocalEnvironmentのみから検索しますが、【トップレベルでの(グローバル変数に格納された)LocalEnviromnent型の変数を参照の後】nextをたどって、呼び出し経路すべてのLocalEnvironmentから検索するようにすると、」
と補って読んでいました。
なので、nextの本来の使い道はガベージ判定で、ダイナミックスコープ判定の用途でも使えることを言っているのかな?と類推していました。

ま、この部分の私の理解は大体間違っていましたね。

とりあえず、私の理解不足を棚上げしておいて、別の意味に捉えかねないnextの名前が悪い、っと愚痴っときます。(えぇ暴論ですとも。)
[ この投稿を含むスレッドを表示] [ この投稿を削除]