Joh*_*ica 10 delphi pass-by-reference
德尔福有:
var:通过引用传递; 参数是输入和输出.
out:通过引用传递; 参数仅输出.
const:通过......好吧,这取决于; 参数仅为输入.
in :通过引用传递; 参数仅为输入,不会更改 没有"在".
我不介意没有勺子,但我想念in; 考虑到以下代码,是否有更简洁的方法来做到这一点?
type TFastDiv = record
strict private
FBuffer: Int64;
other fields
....
//Must be `var` because `const` would pass a Int64 by value
// |||
// VVV
function DivideFixedI32(var Buffer: Int64; x: integer): integer;
asm
mov r9,rcx
imul dword ptr[rcx] // do stuff with the buffer
..
mov ecx, [r9+4] // do other stuff with the rest of the buffer
Run Code Online (Sandbox Code Playgroud)
{将代码更改为imul ecx;...;shr r9,32;mov ecx,r9d允许按值传递,但我们假设代码不得更改.}
class operator TFastDiv.IntDivide(x:integer; const buffer:TFastDiv):integer;
begin
Result:= DivideFixedI32(Int64((@buffer.FBuffer)^), abs(x)); <<-- Ugly
if (x < 0) then Result:= - Result;
end;
Run Code Online (Sandbox Code Playgroud)
DivideFixed永远不会改变缓冲区.例程的重点是buffer预先计算的值不会改变.
在类运算符中,我将缓冲区声明为const,因为记录不能更改.
现在的问题是:
如果我坚持声明buffer参数IntDivide作为const有编码的更清洁的方式还是我停留在pointer_to/points_to破解?
Chr*_*ton 13
较新的编译器版本(从XE3开始)支持[Ref]装饰器:
procedure Foo(const [Ref] Arg1: Integer; [Ref] const Arg2: Byte);
Run Code Online (Sandbox Code Playgroud)
从文档中改编的示例,强调[Ref]可以在const关键字之前或之后进行.
如果你想确保传递引用,唯一的选择(pre Delphi XE3)就是传递一些东西.
即大于sizeof(指针)
type TFastDiv = record
strict private
FBuffer: Int64; <<-- make sure this is the first member
other fields
....
function DivideFixedI32(const Buffer: TFastDiv; x: integer): integer;
...
class operator TFastDiv.IntDivide(x:integer; const buffer:TFastDiv):integer;
begin
Result:= DivideFixedI32(buffer, abs(x));
Run Code Online (Sandbox Code Playgroud)
这行在Delphi帮助文件中:
设置,记录和1,2或4个字节的静态数组作为8位,16位和32位值传递.较大的集合,记录和静态数组作为32位指针传递给该值.此规则的一个例外是记录总是直接在cdecl,stdcall和safecall约定下的堆栈上传递; 以这种方式传递的记录的大小向上舍入到最近的双字边界.
是误导性的,应改为/读作:
直到SizeOf(指针)的集合,记录和静态数组作为8位,16位和32位值(x64上的64位值)传递.大于SizeOf(指针)的集合,记录和静态数组作为指针传递给值.此规则的一个例外是记录总是直接在cdecl,stdcall和safecall约定下的堆栈上传递; 以这种方式传递的记录的大小向上舍入到最近的SizeOf(指针)边界.
| 归档时间: |
|
| 查看次数: |
1234 次 |
| 最近记录: |