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


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0717
ななしDLL デフォルト引数4未解決


ななし

リンク

2017/7/17(Mon) 12:37:44|NO.80636

C++でDLLを作ったとします

extern "C" __declspec(dllexport) int add(int a, int b = 5) { return a + b }
このとき、HSP側で
#cfunc add "add" int, int
#cfunc add_default "add" int
add_default(3)
としたとき、結果が8となることは、アセンブリレベルで保証されているのでしょうか。
よろしくお願いします。



この記事に返信する


掘木

リンク

2017/7/17(Mon) 18:52:38|NO.80644

個人的に思うのはそれコンパイル可能なのかまず疑問だったので調べてみた。
VSCommunity2017さんはコンパイルを許してくれました。意外すぎてびっくりした…。

>結果が8となることは、アセンブリレベルで保証されているのでしょうか。
結果は8になる保証はない。少なくともこっちの環境では8を出さなかった。

こちらあたりを参考にしました。
http://d.hatena.ne.jp/kabakiyo/20120323/1332508180



ななし

リンク

2017/7/17(Mon) 19:52:49|NO.80645

こちらでやってみても8にはなりませんでした。
いけたと思ったのになぁ…
出力されたアセンブリもデフォルト引数あり/なしで同じでした。
やはり、示していただいたページの通り、コンパイル段階で処理されているようです。



3k

リンク

2017/7/17(Mon) 23:39:25|NO.80649

既に表題の件のみについて言及するなら片がついた話だとは思いますが、蛇足ながらちょっと書き込ませて頂きます。

・デフォルト引数
C++からDLLにするときに機械語にコンパイルされますが、そもそも機械語のレベルで引数の数は取得する手段がないため、既に結論でてますが不可能です。
どうしても引数の数が欲しい場合、”引数の数”(もしくはそれに準ずるもの)を引数として渡すのが通例です。
(可変長引数の代表格であるprintfも、最初の文字列型引数中に存在する”%付き文字”から引数の数が分かる構造になっています)

機械語レベルでは処理する関数側は”引数は既に決まった数が積まれているもの”として処理するからで、C++側の機能はご推察の通り、”この関数で引数が足りなかった場合、デフォルト引数があったら自動でそれを付け足して呼び出したことにする”だけだったりします。
つまりはコンパイラが自動でしてくれるただの置き換え操作なので、完全に蛇足ですが突き詰めるとこういう関数も作れます。


#include <cstdlib> // 引数なしで呼ぶと乱数を返し、引数ありで呼ぶと引数を返す int a( int f = rand() ) { return f; }

こういうグローバルに副作用を伴う関数がデフォルト引数に刺さっていることはまず有り得ないですが、原理的にこういうことも出来るんですよ、程度の小咄に。

・置き換え
さて、HSPには関数のデフォルト引数はないのでガッカリしつつ、単なる置き換えという言葉から何か出来ないかと探すと、HSPではちょうど#defineというのが存在します。
で、なんとHSPの#defineにはデフォルト引数というのが存在します、関数にはないのに。
そして今回のやりとりを見る限り、あくまでC++の関数をHSPから使いたいという要望であればこの機能が必要十分に機能するように思います、サンプルスクリプトで示すと…


#cfunc add "add" int, int #define ctype add_default(%1, %2 =5) add((%1), (%2)) add_default(3)

としてみるとうまくいくんじゃないでしょうか。
デフォルト引数の定義箇所がC++ではなくHSPに移ってきてしまいましたが、処理する次元から考えればこっちの方が私には自然に思えます。



ななし

リンク

2017/7/18(Tue) 10:32:10|NO.80652

確かに、アセンブリでは関数側で引数の数だけスタックからPOPしてるだけですからね。

しかしなるほど、HSPではC++でコンパイル段階で処理されているデフォルト引数の処理を
プリプロセッサ段階に移したことで仕様を単純化しているとも…(何言ってんだろ)
でもHSPでの#deffuncって、プリプロセッサみたいなのに実行時に処理してるみたいで意味が分からん
コールバックに標準対応したら、ラベルでなく命令を指定できるようになるんだろうか…(どんどん脱線していく)

いやー書きたいこと書いてちょっとすっきりしました。

何はともあれ、#defineのデフォルト引数で行こうと思います。ありがとうございました。



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