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


HSPTV!掲示板


未解決 解決 停止 削除要請

2019
1111
とあるプログラマ#include のスクリプト途中利用8解決


とあるプログラマ

リンク

2019/11/11(Mon) 13:51:43|NO.88834

#includeは普通、スクリプトの先頭に書いてヘッダファイルなどを結合すると思いますが、
メインのスクリプトが長くなる場合に分割し別ファイルに保存、段階ごとに#includeするのはプログラミング書法としてどうなんでしょうか。


例えば、スクリプトで A、B、C という段階があった場合、

#include "〜" //user32.asやa2d.hspなど … /* 先の処理 */ #include "a.hsp" //段階Aの処理を実行 #include "b.hsp" //段階Bの処理を実行 #include "c.hsp" //段階Cの処理を実行 /* 後の処理 */ stop
のように別ファイルに分けて結合とする感じです。
(#module〜#globalではなく、そのまま繋がるように記述)

ジャンプ(別ファイルへの移動)の多用によるスパゲティプログラム化の懸念がありますが、
#include元のスクリプトを本流とし、原則として#include先のファイルで更なる#includeを禁止し最大1層のネストを維持すれば回避は可能なのではと思っています。


プログラミング・マニュアルにも

#include "filename" [別ファイルを結合] "filename"で指定されたファイルも同時にコンパイルされます。 スクリプトエディタで入りきらないスクリプトも、includeで別ファイルに 分割すればコンパイルすることができるようになります。
とあるのでスクリプトの分割は有用だと思うのですが、HSPではこの手法はご法度になるのでしょうか。



この記事に返信する


ソラ

リンク

2019/11/11(Mon) 14:38:11|NO.88836

特に問題ないかと。
自分もたまにやってますが、一人で作る分には特に不都合は感じていませんね。
まぁバグが出た時に処理を追うのは多少面倒ですが。



とあるプログラマ

リンク

2019/11/12(Tue) 18:39:08|NO.88845

特に問題は無い感じですかね。

ただこの方法だとラベルを設置してのジャンプが同じファイルに記述できない… どうしたものか…



MillkeyStars

リンク

2019/11/13(Wed) 07:42:35|NO.88849

前の質問の時の #ifndef が役に立つんじゃないかなー。

#ifndef ???
#define ???
#endif

名前空間と思えばいいだけだと思うよ。
#ifndef ??? は、そこまでに定義されていない場合、実行しなさいという命令なのでこれを応用すればいいと思うよ。

[A.HSP]
#ifndef __A_HSP__
#define __A_HSP__
... __A_HSP__ が定義されていない場合、コンパイラ出力指示と __A_HSP__ の定義
#endif

[B.HSP]
#ifndef __B_HSP__
#define __B_HSP__
#ifndef __A_HSP__
... B.HSP は、A.HSP に依存するので__A_HSP__ が定義されていない場合、この時点で __A_HSP__ を #include
#include "A.HSP"
#endif
#endif

[C.HSP]
#ifndef __C_HSP__
#define __C_HSP__
#ifndef __A_HSP__
... C.HSP は、A.HSP に依存するので__A_HSP__ が定義されていない場合、この時点で A.HSP を #include
#include "A.HSP"
#endif

#ifndef __B_HSP__
... C.HSP は、B.HSP に依存するので__B_HSP__ が定義されていない場合、この時点で B.HSP を #include
#include "B.HSP"
#endif
#endif

うん、スパゲッティになりました。
#ifdef・#ifndef は、前方に定義されている場合しか見てませんので、こんな時にしか使い道がない。
これを A.HSP および B.HSP での同じ命令を定義している空間の定義されているかされていないかの空間判断に使えるってだけだけどね。

#ifndef __LABEL_A__
#define __LABEL_A__
*label_a
return
#endif

こんな感じで、A.HSP / B.HSP 両方に書いちゃえば、先に #include した方しか出力されないから、多重にならない。



とあるプログラマ

リンク

2019/11/13(Wed) 11:57:44|NO.88850

#ifdef・#ifndefはコンパイル時のスイッチなんで処理ごとの振り分けの設定ができないんですよね (上手く説明できない)


例えば、

"test1.hsp"の内容

#include "test2.hsp" #define __STOP__ onexit goto *exit //ラベル無しエラーになる stop
"test2.hsp"の内容

#ifndef __STOP__ mes "処理" #else *exit end #endif
こういうのは無理なんですよね…


うーん、素直にモジュール化して#deffunc hoge onexitとかモジュール内に*hogeを設置する方法のほうが利口に思えてきた…
しかしそうするとモジュールの命名と変数の扱いが… (ブツブツ)



MillkeyStars

リンク

2019/11/13(Wed) 19:21:18|NO.88855

#ifndef は、定義されていない場合にスクリプトを出力させる命令。
#ifdef は、定義されている場合にスクリプトを出力させる命令。

test1.hsp で、#define __STOP__ を定義しちゃだめだよ。

なにも include してない状態で説明すると

#ifndef __STOP__ //← ifn = __STOP__ が定義されていないか? YES
#define __STOP__ //上記 ifn で出力が実行されているのでこの行を出力 (__STOP__ を初めて定義)
...
...
...
#endif //ここまで、__STOP__ が定義されていない場合の処理。



とあるプログラマ

リンク

2019/11/13(Wed) 20:47:07|NO.88856

自分の書いた物が通常と違う方法での#ifndef・#defineの使用ということは把握しています。

しかし結局、#module〜#globalを使わないで1つのファイルに 複数の別の機会で呼び出す内容は記述できませんよね?(起動時・終了時に別の部分を呼び出すなど)
MillkeyStarsさんの書いたコードは恐らく、「AやBの自身以前のコードが定義(既に実行)されているときに、1度だけ実行する」という書き方だと思うのですが (間違っていたら申し訳ないです)

となるとやっぱり、#module〜#global空間で#deffuncやラベルを使うしか方法はないんじゃないかと…



MillkeyStars

リンク

2019/11/13(Wed) 23:40:25|NO.88860

ん・・・?
#ifndef は、定義を一つだけにする場合にしか使わないよ。

>>#include元のスクリプトを本流とし、原則として#include先のファイルで更なる#includeを禁止し最大1層のネストを維持すれば回避は可能なのではと思っています。
これが書き込みの理由。

#include でスクリプトを結合させる際に、絶対に多重ロード(ネスト)させないようにするには。という理由だけの #ifndef と #define です。


[A.HSP] #ifndef __A_HSP__ #define __A_HSP__ スクリプトの内容... #endif
上記を単純に二回 #include しても、プリプロセッサ判定でスクリプト... が出力されないから、多重ネストされない。
上記 A.HSP を B.HSP から#include しても、多重ネストされない。

#include するファイルの先頭と終端に上記の判定処理を入れるだけで、多重ネストを防止させることができるってだけね。
"user32.as" とかのコモンファイル系は、ほぼこの方式。



とあるプログラマ

リンク

2019/11/14(Thu) 22:02:40|NO.88865

あーえっと、言葉選びが悪かったですね…

>>#include元のスクリプトを本流とし、原則として#include先のファイルで更なる#includeを禁止し最大1層のネストを維持すれば回避は可能なのではと思っています。
これは「被#includeファイルで更に別ファイルを#includeしない」ということです。

つまり、コンパイル&実行される大元のファイルから別のファイルを#includeする際に 更に別のファイルを#includeして、#includeによるどんどんファイルの枝分かれをさせない ということです。
要はスパゲティプログラムの防止が目的で、多重#includeを防止する目的ではないんです。

語弊を生んでしまい申し訳ないです…



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