我像这样声明一个联合类型:
type Access_Kind is (Named, Indexed);
type Array_Type is array (0 .. 1) of Integer;
type Record_Type (Kind : Access_Kind := Access_Kind'First) is record
case Kind is
when Named =>
X, Y : Integer;
when Indexed =>
S : Array_Type;
end case;
end record;
pragma Unchecked_Union (Record_Type);
pragma Convention (C_Pass_By_Copy, Record_Type);
function Create (X, Y : Integer) return Record_Type;现在,当我尝试创建派生类型时:
type Integer2 is new Record_Type;GNAT给了我以下警告:
warning: in instantiation at line [pragma Convention...]
warning: variant record has no direct equivalent in C
warning: use of convention for type "Integer2" is dubious所以看起来杂注约定适用于派生类型,但Unchecked_Union不适用。我不能再次将它应用于派生类型,因为Record_Type已经定义了基元操作(Integer2是在另一个包中定义的)。
这是正确的行为还是GNAT错误?如何正确地从Unchecked_Union类型派生,以便新类型继承Unchecked_Union杂注?
GNAT版本: GNAT GPL 2012 (20120509)。
发布于 2013-02-03 18:34:25
一种可能是在一个嵌套的包中声明Record_Type的操作,比如Ops,这样它们就不是原始的:
package Union is
type Access_Kind is (Named, Indexed);
type Array_Type is array (0 .. 1) of Integer;
type Record_Type (Kind : Access_Kind := Access_Kind'First) is record
case Kind is
when Named =>
X, Y : Integer;
when Indexed =>
S : Array_Type;
end case;
end record;
pragma Unchecked_Union (Record_Type);
pragma Convention (C_Pass_By_Copy, Record_Type);
-- If P was declared immediately within Union, it would be
-- primitive, and it wouldn't be possible to declare
-- representation aspects for Integer2.
package Ops is
procedure P (R : Record_Type) is null;
-- "is null" only so that I can use -gnatR without needing a
-- body.
end Ops;
type Integer2 is new Record_Type;
pragma Unchecked_Union (Integer2);
pragma Convention (C_Pass_By_Copy, Integer2);
end Union;使用-gnatR显示所选的表示形式,我得到
$ gnatmake -c -u -f -gnatwa union.ads -gnatR
gcc -c -gnatwa -gnatR -gnat05 union.ads
Representation information for unit Union (spec)
------------------------------------------------
for Array_Type'Size use 64;
for Array_Type'Alignment use 4;
for Array_Type'Component_Size use 32;
for Record_Type'Size use 64;
for Record_Type'Alignment use 4;
for Record_Type use record
Kind at ?? range 0 .. -1;
X at 0 range 0 .. 31;
Y at 4 range 0 .. 31;
S at 0 range 0 .. 63;
end record;
for Integer2'Size use 64;
for Integer2'Alignment use 4;
for Integer2 use record
Kind at ?? range 0 .. -1;
X at 0 range 0 .. 31;
Y at 4 range 0 .. 31;
S at 0 range 0 .. 63;
end record;也就是说,我认为GNAT的行为是错误的。
ARM 13.1(0.1)说有代表性和操作性两个方面,而(1)定义了代表性方面。(10)就是我们需要避免原语操作的原因。(15)说表示方面是由派生类型继承的;但是(15.1)说操作方面是而不是,“除非为特定方面指定”。我猜“指定的”意味着“在ARM中用于语言定义的方面,或者由供应商用于供应商定义的方面”。
B3.3(3.1)指出,Unchecked_Union是一个表示方面。因此,它应该被继承。
B3.1(0.1)指出,接口方面,包括Convention,是表示方面。因此,应该继承C_Pass_By_Copy。
我会写一份错误报告。
https://stackoverflow.com/questions/14663316
复制相似问题