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


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0608
木村引数を定義する#deffunc命令を#define中に入れる際の条件が分かりにく過ぎます5解決


木村

リンク

2010/6/8(Tue) 16:36:37|NO.33137


#define llog(%1,%2) #deffunc %1 str s1 %c if %2 : logmes s1 %c return goto *a #define T 9901 llog log_init,T *a log_init "ひゃっはー"
 上記のllogマクロは実際に使おうとするとコンパイル時点でエラーとなります。strの部分が
パラメータタイプの『str』ではなく標準マクロの『str@hsp』と読み込まれてしまい、異常と
判断されてしまうのです。


#undef str #define llog(%1,%2) %c #deffunc %1 str s1 %c if %2 : logmes s1 %c return goto *a #define T 72 llog log_init,T #define str str@hsp *a log_init "ひゃっはー"
 一応、llogマクロ使用時の間だけstr標準マクロを黙殺する事で運用する事はできました。
しかし、普通に書いた状態ならば成立するプリプロセッサ命令が、#defineマクロに入った
瞬間に成立しなくなるというのは、非常に厄介です。
(更に厄介な事に

#define def(%1,%2) #deffunc %1@ %c mes@hsp %2@ def test,a return def test2,a return
というサンプルスクリプトがあるせいで『改行コードを%cに変換すれば#defineマクロ中にも
#deffunc命令を定義できそうだ』というミスリードがなされています)

 #define〜#deffunc構文、乃至#define〜#defcfunc構文は大量のダミー関数の生成を楽に
してくれる構文です。その構文が、このように非常に分かりづらい所に罠を張っているのは
問題だと思います。ですので、


1,#define⇒#deffunc中のstrを標準マクロに誤読されないようにする
2,それが無理なら、strと重複しないパラメータタイプのみを定義する新マクロの実装(label,var,array,localの類)
 等はできないのでしょうか?



この記事に返信する


KA

リンク

2010/6/8(Tue) 22:14:10|NO.33140

意味が分からない・・・・。
何か間違っている様な気がします。



test

リンク

2010/6/8(Tue) 22:37:47|NO.33142

そのサンプルは、#deffuncのヘルプに載っていたものですね。そのサンプルの直前に、
> ただし、現状ですべてのプリプロセッサがマクロ展開に対応しているわけではありません。多用しすぎると、かえって見難くなることもありますので、よくご理解の上お使いください。
とあります。
もともと、strやintは普段は関数であるのに、#deffuncで引数を設定するときのみ特別な意味を持つということになっています。
対して、#define内で#deffuncを使う場合、あくまで#define内でstrが使われていると見なされ、エラーが起きます。
そこで、これは"罠"などではなく仕様だと見るべきだと思います。

木村さんの提示した解決策は、1の案は労力的に大変かもしれず非実現的だと思いますが、2の案は簡単(マクロではないですが)なのでいいかもしれませんね。



木村

リンク

2010/6/9(Wed) 07:28:09|NO.33152

>>KAさんへ
 初めに訳の分からない文章を読ませてしまった事をお詫びします。申し訳ありません。
 あの理解不能な説明で言いたかった事とは、#define命令のヘルプ説明の中に、
>>『複数のプリプロセス文に展開されるようなマクロを
>>定義する用途などに使用することができます』
と書いてあるのに、実際には様々な条件を満たした極一部のプリプロセス分しか定義できない
というのは問題だろうという主張です。

 まず#ifdef,#endif系統のコンパイル制御命令、#module,#global系統のモジュール命令、
#define,#undef系統のマクロ関連命令、#include,#addition系統のスクリプト接続命令、
#cmpopt,#packopt系統の実行時オプション指定命令、軽く調べただけでも標準プリプロセッサ
命令33種の内、実に19種のプリプロセッサ命令が#defineマクロの中に含める事のできないものと
なっています。(残り14種についても動作確認をしていないだけで、有用に動くのは#deffunc命令と
#defcfunc命令のみでしょう)

 そして、その#deffunc命令にしてもヘルプに書かれていない様々な制約条件が与えられており
#defineマクロの中に組み込むには非常に面倒で技巧的な手法に頼らざるを得ないのです。
 こう書かれるだけでは多分理解し辛いと思うので以下に実例を挙げます。


//1,引数を取る場合、マクロ展開時にstr,double,intを無効化しないといけない
 私が一番最初にこのスレットに書いたソースを参考にしてください。『#undef str』を消すと
コンパイルの段階で弾かれます。最初のコメントでも言いました通り、#define内では自動的に
str等が標準マクロとして読み込まれるようなのです。
 それでも、問題点がこれだけであれば一応サンプルもあるので何とか利用する事はできます。
しかし以下に示す第2の問題点により、そのサンプル自体が使えなくなってしまうのです。



//2,モジュール中では#define⇒#deffunc構文(=サンプル)すら使えなくなる(以下は具体例) //モジュール内でmesset(#define〜#deffunc構文)を定義した場合 #module XXX #define messet(%1,%2) %c #deffunc %1 %c mes %2 : return messet mes_module,"[モジュール内]" #global //グローバル空間でmessetを定義した場合 #define messet(%1,%2) %c #deffunc %1 %c mes %2 : return goto *@f messet mes_global,"[グローバル空間]" messet mes_global2,"[ぐろおばるくうかん]" *@ //グローバル空間のmessetで定義した命令は普通に働くものの、 //モジュール内のmessetで定義した命令はプリプロセッサ段階で弾かれる //(そもそも#deffunc命令なのにグローバル空間との命令重複が無視されている) mes_global : mes_global2 ;mes_module
 『;mes_module』をコメント状態から解除してやると、即座にコンパイル段階で弾かれます。
コンパイル後のソースを見れば少しだけですが原因が分かってきます。

#module xxx goto@hsp *_xxx_exit ##22 #deffunc@xxx mes_module@xxx mes@hsp "[モジュール内]" : return@hsp ##25 #global *_xxx_exit ##25 goto@hsp *@f #deffunc mes_global mes@hsp "[グローバル空間]" : return@hsp ##31 #deffunc mes_global2 mes@hsp "[ぐろおばるくうかん]" : return@hsp ##32 *@ mes_global : mes_global2
 このソースを見て分かる通り、モジュール中の#defineはマクロを置き換える際に、丁重な
事にモジュール名を添え字として付けるようなのです。そして、添え字をされた#deffunc命令は
真っ当なプリプロセッサ命令として認識されず、結果モジュール中では#define⇒#deffunc構文が
使用不能になるのです。


 最後に結論を言えば、この現状が仕様でも何でも良いので、まるで#defineならプリプロセッサ
命令の置き換えもできると読めるようなヘルプの内容を次回辺りのマイナーチェンジで修正して
ほしいのです。
 特にあのサンプルはモジュールに放り込んだ瞬間に無力化する代物なので、最低限の注意書きは
書い添えておいてほしいと思うのです。

 本題は以上ですが、この件を調べている内に仕様なのかバグなのか分からない不思議な現象に
ついて書いておきます。

#module //このコメント部分を開放するとpythagorasが使えなくなる ; #undef int ; #define int int@hsp #deffunc pythagoras int a,int b mes a*a+b*b return #global pythagoras 3,4


>>testさんへ
 確かに『全ての命令が対応していない』とは書かれていましたが、実際は33種中2種+αしか
利用できないというのは問題だと思います。
 モジュール中の挙動やパラメータタイプの異常もありますし、ある程度の自由度があるかの
ように読み取れるヘルプの書き方は使い手を惑わせるだけだと思います。



佐伯

リンク

2010/6/30(Wed) 07:07:30|NO.33505

int というキーワードは#deffunc 等のための特殊なもので
元々int@hspという命令形で定義されていないものと思われます

(以下のスクリプトは動作しない)

#module
#deffunc mes2 int@hsp a
mes a
return
#global

mes2 6



木村

リンク

2010/7/1(Thu) 22:50:54|NO.33517

>>佐伯様
 確かに、int@hspとすると完全に関数と認識されてしまいますね。やはり、test様の
仰られた通り、#deffuncプリプロセッサ命令中の無属性intのみが特別な意味を持って解釈
されると言う仕組みらしいです。
 問題は#define中にどうやって無属性のintを作るか……ですが、どうしたものでしょうか……



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