HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0302
Noapプリプロセッサの配列の添え字における定数展開の不具合9解決


Noap

リンク

2016/3/2(Wed) 19:49:09|NO.74742

定数を配列の添え字に使用した際、プリプロセッサがときどき妙な展開をします。
#constを使っていますが#defineも同じ挙動でした。
定数に小文字を使うことは少ない気と思います。
3.4、3.5 beta 2、3.5 beta 3でみました。
定数名が大文字ではじめる場合おこりません

変な動作


//1次元と3次元の添え字なら展開される //2次元と4次元の添え字のdは展開されない #const d 10 a.d=100 //a.0.d=200 a.0.0.d=100 //a.0.0.0.d=200 mes a.10 mes a.0.0.0 mes a.0.0.10 mes d


モジュール中での動作


//dは展開されない //グローバル領域にdという変数がある (d) #module #const d 10 #deffunc test a.0.d=100 mes a.0.0 mes d return #global //d=5 test

モジュール中での動作2


//deは展開されない //モジュール領域にdeという変数がある (de@m0) #cmpopt ppout 1 #module #const de 10 #deffunc test a.0.de=100 mes a.0.0 mes de return #global test

でも定数名が大文字から始まる場合は展開してくれます


#const D 10 a.0.D=100 mes a.0.0 mes a.0.10 mes d

モジュールの場合


#module #const De 10 #deffunc test a.0.De=100 mes a.0.0 mes a.0.10 mes De return #global test



この記事に返信する


KA

リンク

2016/3/3(Thu) 06:23:56|NO.74744

正式な推奨される使い方をすれば問題有りません。


#const d 10 dim a,11,11,11,11 a(d,0,0,0)=1 a(0,d,0,0)=2 a(0,0,d,0)=3 a(0,0,0,d)=4 mes a( 0, 0, 0, 0) mes a(10, 0, 0, 0) mes a( 0,10, 0, 0) mes a( 0, 0,10, 0) mes a( 0, 0, 0,10) mes d



Noap

リンク

2016/3/3(Thu) 19:59:26|NO.74749

(説明もれ等を訂正しました)

同じような投稿を連続でしてすみません
下の説明があっているかはわかりません
間違っている気がします

この説明はOpenHSPのhspcmp/token.cppのことについてです

プリプロセスで最初に

1行ごとにExpandTokensからExpandTokenを繰り返し呼んでExpandTokenからReplaceLineBufを呼んでマクロ評価をしていくので
順番に左からExpandTokenで評価していきます


#define d 10 buf.d.d = 10




buf.10.d.d.d = 10

になって0.dで先頭が数字なのでdは読み飛ばされるので二つ目のdはdという変数として解釈されます
ここで読み飛ばされるのは指数表記などで使うk、f、d、eです (1190行から1203行の箇所で読み飛ばしています)

このことは


#define aa 10 #define d 1 a.d.daa=100




a. 1.d 10=100

と展開されることで確認できました

その後も同じようにして


buf.10.d.10.d = 10

になります

でも定数の名前の頭がk、f、d、eでなかったり


#define d 1 a.d. d=100

のように空白でくぎれば1147行でExpandTokensに戻るので別べつに処理されることになりdは両方ともマクロとして評価してくれます

また


#define d 1 a.d.(d)=100

のようにすれば数字の後に「d」ではなく「(」が続くので読み飛ばされません

なので

かっこを使う
空白をいれる
定数の頭文字を小文字のk、f、d、eにしない
HSP3式の書き方をする

こうすると問題はおきませんでした

間違っているかもしれません
間違っていたらごめんなさい



KA

リンク

2016/3/3(Thu) 20:03:48|NO.74750

>>#define d 10
>>buf.d.d = 10
>>は
>>buf.10.d.d.d = 10
>>になって
dim buf,d+1,d+1
の様に配列を定義するのが普通です。

定義しなくても使える前提の話がおかしいような。
いや、使えるような言語仕様の甘さが悪いのか。



Noap

リンク

2016/3/3(Thu) 20:42:35|NO.74751

説明を簡略にするために省きました。省かないほうが分かりやすかったのであればごめんなさい。
代入時に配列は自動確保されるとマニュアルに書いてありました。
またHSP2の配列書式もマニュアルに書いてありました。

HSP3 プログラミング・マニュアル
スクリプト記述の基本
配列変数
http://www.onionsoft.net/hsp/v35/doclib/hspprog.htm#ARRAY



KA

リンク

2016/3/3(Thu) 22:11:17|NO.74756

>>代入時に配列は自動確保されるとマニュアルに書いてありました。
同様に
>>配列要素の自動確保で次元を拡張することはできません。
と書いていますよ?

と、これは最初の例の問題で、その後の例とは別問題です。
>>いや、使えるような言語仕様の甘さが悪いのか。
甘くすればするほど変な不具合がふえますからね。

自動拡張なんか当てにせず、自分で管理するのが一番です。



Noap

リンク

2016/3/4(Fri) 20:54:32|NO.74770

完全にその文は見落としていました。指摘していただき感謝します。
言語仕様についてはスレッドの内容とは関係ないのとわたしにはどうしようもできないので、このスレッド以外でお願いします。



おにたま(管理人)

リンク

2016/3/4(Fri) 22:48:03|NO.74777

ご指摘ありがとうございます。
#constや#defineは、あくまでもプリプロセッサ命令でソースコードの文字列を置き換える処理であることを留意してください。
「.」や「d」といった短い記号や文字列は、置き換えを行なった際に別な解釈の文字列となってしまう可能性があります。
なので、展開の不具合というよりはマクロの展開で起こる想定外の動作と考えた方が良いかと思います。
#constで定義するラベルは変数とは異なる扱いになるため、短い文字数の定義は避けた方が良いでしょう。



科学太郎

リンク

2016/3/12(Sat) 17:56:28|NO.74886

おにたま(管理人)さん
質問者のNoapさん

・列挙定数の不具合?発見!
http://hsp.tv/play/pforum.php?mode=pastwch&num=58681

この現象と関係すると思います。

> なので、展開の不具合というよりはマクロの展開で起こる想定外の動作と考えた方が良いかと思います。
> #constで定義するラベルは変数とは異なる扱いになるため、短い文字数の定義は避けた方が良いでしょう。
凄く単純なソースでも不具合があるのでマクロ展開のアルゴリズムが原因だと思います。



科学太郎

リンク

2016/3/12(Sat) 17:59:01|NO.74887

追記。

記号定数の先頭文字が「d」「e」「f」の3文字が可笑しくなるらしい。
つまり、浮動小数点で使うプリフィックスが原因だろうな。



ONION software Copyright 1997-2023(c) All rights reserved.