Joh*_*ica 4 delphi compiler-errors delphi-xe2
我为什么要来
[DCC错误] ProjectCOWArray.dpr(23):E2426内联函数不能包含asm块
program ProjectCOWArray;
{$APPTYPE CONSOLE}
{$R *.res}
type
PRefCount = ^TRefCount;
TRefCount = array[0..1] of integer;
TCOWArray<T> = record
private
fData: TArray<T>;
private
procedure IncRefCount; <<-- not inline
end;
{ TCOWArray<T> }
procedure TCOWArray<T>.IncRefCount;
asm
{$if defined(win32)}
mov eax,fData;
lock inc dword ptr [eax - 8];
{$ifend}
{$if defined(win64)}
mov rax,fData;
lock inc dword ptr[rax -12];
{$ifend}
end;
begin
end.
Run Code Online (Sandbox Code Playgroud)
Delphi XE2没有AtomicIncrement,所以如何解决这个问题呢?
它想保留汇编程序,因为否则我不能使用lock前缀,我不想使用,InterlockedIncrement因为这是一个WinAPI函数,我不希望这种开销.
这是因为泛型功能是在内联引擎之上实现的.适用于内联函数的相同限制适用于泛型函数.编译器编写者只是没有采取额外的步骤来使特定于泛型而不是内联函数的错误消息.
我认为InterlockedIncrement对于没有AtomicIncrement内在函数的Delphi版本,调用可能是你最好的选择.或者,或者,创建自己的版本 AtomicIncrement,仅在Delphi版本中定义,不包含它.并且该函数可以用asm编写.嗯,显然必须写在asm当然.
{$IFNDEF AtomicFunctionsAvailable}
function AtomicIncrement(var Target: Integer): Integer;
asm
....
end;
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
或者正如@TLama建议,您可以使用TInterlocked从System.SyncObjs单位提供的原子操作.
尽管如此,我认为没有必要以这种方式干涉内部.SetLength(...)无论何时写入数组,都要通过调用来实现写数组的副本.例如,这是一个关于写数组实现的非常简单的副本:
unit COWArray;
interface
type
TCOWArray<T> = record
private
FItems: TArray<T>;
function GetLength: Integer;
procedure SetLength(Value: Integer);
function GetItem(Index: Integer): T;
procedure SetItem(Index: Integer; const Value: T);
public
class function New(const Values: array of T): TCOWArray<T>; static;
property Length: Integer read GetLength write SetLength;
property Items[Index: Integer]: T read GetItem write SetItem; default;
end;
implementation
function TCOWArray<T>.GetLength: Integer;
begin
Result := System.Length(FItems);
end;
procedure TCOWArray<T>.SetLength(Value: Integer);
begin
System.SetLength(FItems, Value); // SetLength enforces uniqueness
end;
function TCOWArray<T>.GetItem(Index: Integer): T;
begin
Result := FItems[Index];
end;
procedure TCOWArray<T>.SetItem(Index: Integer; const Value: T);
begin
System.SetLength(FItems, System.Length(FItems)); // SetLength enforces uniqueness
FItems[Index] := Value;
end;
class function TCOWArray<T>.New(const Values: array of T): TCOWArray<T>;
var
i: Integer;
begin
System.SetLength(Result.FItems, System.Length(Values));
for i := 0 to high(Values) do
Result.FItems[i] := Values[i];
end;
end.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
439 次 |
| 最近记录: |