在 Delphi XE2 中使用泛型和前向声明时的编译器错误

Posted

技术标签:

【中文标题】在 Delphi XE2 中使用泛型和前向声明时的编译器错误【英文标题】:Compiler bug when using generics and forward declaration in Delphi XE2 【发布时间】:2012-07-12 21:57:17 【问题描述】:

我在 Delphi 2010 上开始项目,然后迁移到 XE,现在我尝试迁移到 XE2。 在 XE2(更新 4 修补程序 1)中编译后,单元测试开始以 AV 失败。 经过一番调试,很明显以下代码没有正确编译:

program ForwardDeclaration;

$APPTYPE CONSOLE

uses
    System.SysUtils;

type
    TEntityBase = class(TObject)
    protected
        FModel: Integer;
    public
        constructor Create(const AModel: Integer);
    end;

    TEntity<TKey> = class(TEntityBase)
    end;

    TMyEntity2 = class;

    TMyEntity1 = class(TEntity<Integer>)
        FData: Integer;
    end;

    TMyEntity2 = class(TMyEntity1)
    end;

constructor TEntityBase.Create(const AModel: Integer);
begin
    inherited Create;
    FModel := AModel;
end;

var
    MyEntity: TMyEntity1;
begin
    try
        Writeln(TEntityBase.ClassName, ': ', TEntityBase.InstanceSize, ' bytes');
        Writeln(TMyEntity1.ClassName, ': ', TMyEntity1.InstanceSize, ' bytes');
        MyEntity := TMyEntity1.Create(100);
        Assert(MyEntity.FData = 0);
    except
        on E: Exception do Writeln(E.ClassName, ': ', E.Message);
    end;
end.

程序输出:

TEntityBase: 12 bytes
TMyEntity1: 12 bytes <-- Must be 16 bytes!
EAssertionFailed: Assertion failure (ForwardDeclaration.dpr, line 41)

是否可以通过调整编译器选项来解决问题?

这个问题是否会在其他人身上重复出现?

附: QC107110

【问题讨论】:

将此提交给 QualityCentral。此外,前向声明在哪里进入。唯一没有使用这样的声明。 代码是最简化的,所以编译器错误被重现了。在实际项目中使用前向声明。如果这个问题不仅在我身上,那么我会写信给 QC。 好的。当您提交错误时,您应该进一步删除它。看起来前向声明不相关。只是 InstanceSize 的代码生成问题。如果您有支持合同,您可以提出支持问题,尽管这样做并不一定意味着您会得到回应。 没有前向声明代码效果很好,并且 TMyEntity1.InstanceSize 是 16 字节。没有泛型代码运行良好。问题在于前向声明和泛型。 这很有趣。未使用的前向声明的存在会改变行为。诡异的! FWIW,您的代码按预期运行,TMyEntity1.InstanceSize=16 在 XE2 更新 3 上。 【参考方案1】:

是否可以通过调整编译器选项来解决问题?

,您无法通过调整来修复错误,这是编译器中的一个(非常具体的)错误。

[Can有人告诉我]这个问题是否会在其他人身上重复出现?

我可以重现代码,但仅限于 XE2 更新 4。

我无法在 XE3 中检查它(没有那个版本)。 它在 XE4 中是固定的(根据 cmets)。

所以让代码工作的唯一方法是:

一个。删除不需要的前向声明。 湾。使用不同版本的 Delphi。

【讨论】:

以上是关于在 Delphi XE2 中使用泛型和前向声明时的编译器错误的主要内容,如果未能解决你的问题,请参考以下文章

C++ 简单循环引用和前向声明问题

XSD 包含导入的 xsd 时的 Delphi XE2 XML 数据绑定向导错误

使用 Delphi XE2 在 MacOS 中不显示 Webview

使用泛型和合并对象的 Typescript 声明文件

使用泛型和简单地将字符串值转换为枚举时将字符串值转换为枚举时的混淆

泛型和Object的区别?