の背後にある Nim のポリシーについて決心しようとしていexpression has no address
ます。特に、データ バッファーのポインター (+ 長さなど) を受け取る C 関数があります。この関数がデータを変更しないことはわかっています。簡略化:
type
Buffer = object
data: seq[float]
proc wrapperForCCall(buf: Buffer) =
# accessing either buf.addr nor buf.data.addr produces
# Error: expression has no address
# workaround:
var tmp = buf.data # costly copy
callToC(tmp.len, tmp.addr) # now it works
一方では、これは理にかなっています。パラメーターは、let
「アドレスを持たない」バインドとまったく同じように動作するように見えるからです。一方、私はマニュアルの次の記述に困惑しています。
var パラメーターは、効率的なパラメーターの受け渡しには必要ありません。
私の知る限り、データのコピーを回避する唯一の方法は次のいずれかです。
- パラメータを次のように渡す
buf: var Buffer
- 参照を渡す、つまり
ref object
.
どちらの場合も、これは私の関数がデータを変更することを示唆しています。さらに、呼び出し元サイトに可変性が導入されます (つまり、ユーザーはバッファーに let バインディングを使用できなくなります)。私にとっての重要な質問は次のとおりです。「私は知っている」callToC
が読み取り専用であるため、コピーなしで両方の不変性を許可するように Nim を説得できますか? 呼び出しが不変であることを確実に知る必要があるため、これは危険です。したがって、これにはある種の「安全でないアドレス」メカニズムが必要になり、不変データへのポインタを強制できますか?
そして、パラメーター アドレスの最後の謎: タイプを に変更して、コピーの必要性を明示しようとしましたBuffer {.bycopy.} = object
。この場合、コピーは呼び出し時に既に行われており、今すぐアドレスにアクセスできると予想されます。この場合もアクセスが拒否されるのはなぜですか?