Maple(バージョン14、重要な場合)では、mapleでグローバルに定義された式を使用するプロシージャを定義しますが、コード生成に進むと、変数が期待したものではないと想定します。
a:=x+y*x
p := proc (x::float, y::float); return a; end proc;
C(p)
私が期待しているのは、式がコードに挿入されたC関数ですが、代わりに...
double p (double x, double y)
{
return(a);
}
Maple(バージョン14、重要な場合)では、mapleでグローバルに定義された式を使用するプロシージャを定義しますが、コード生成に進むと、変数が期待したものではないと想定します。
a:=x+y*x
p := proc (x::float, y::float); return a; end proc;
C(p)
私が期待しているのは、式がコードに挿入されたC関数ですが、代わりに...
double p (double x, double y)
{
return(a);
}
これは、「設計による」ものの1つです。この特定の状況では厄介に思えるかもしれませんが、(現代の)Mapleの部分でのこの字句スコープの動作は、多くの場合、利点であり、非常に慎重です。そして、あなたの期待を得るために、それを回避するいくつかの方法があります。
この場合の最も簡単な回避策は、次のとおりです。
restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;
p := proc(x::float, y::float) return a end proc;
CodeGeneration:-C( subs('a'=a,eval(p)) );
double cg (double x, double y)
{
return(x + y * x);
}
上で達成されたことは、procの新しいインスタンスを形成subs('a'=a,eval(p))
し、proc本体での明示的な値(つまり、何に評価されるか)に置き換えられることです。次の出力に注意し、最初に作成されたときの上記の出力と比較してください。p
a
a
a
p
subs('a'=a,eval(p));
proc(x::float, y::float) return x + y*x end proc;
この非常に単純な回避策の例では明らかではありませんが、グローバル名x
とy
そのコピーへの指定された置換は、p
実際にはMapleのスコープルールを使用してトリッキーなゲームをプレイしていることに注意してください。より複雑なスコーピング状況では、これはうまくいかない可能性があります。しかし、本当に必要なのがインライン化である場合は、より明示的で制御された方法でそれを取得できます。p
この次の例で最初に作成されたときのエコー出力を見てください。
restart:
a := proc(A,B) option inline; A+B*A: end proc;
a := proc(A, B) option inline; A + B*A end proc;
p := proc(x::float, y::float) return a(x,y); end proc;
p := proc(x::float, y::float) return x + y*x end proc;
CodeGeneration:-C( p );
double p (double x, double y)
{
return(x + y * x);
}
うまくいけば、これらの2つのアプローチで十分に理解できます。
何かに気付くために、簡単に元の例に戻りましょう。グローバル名x
とy
の値に表示されるa
名前は、最初に作成されたプロシージャの2つの正式なパラメータの名前とほとんど同じではありませんp
。それらは、単に同じ名前のように見えるもののまったく異なるインスタンスです。検討、
restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;
p := proc(x::float, y::float) return a end proc;
p(4.0, 5.0);
x + y x