问题描述
发帖的原因有两个:(1)对于这样一个简单的问题,我在无助的编译器错误上停留了太长时间,并且我希望下一个人在我的(或其他)答案中搜索这些消息,以及(2 )我仍然不明白禁止使用子句,因此我自己的回答确实不完整。
为了在两个地方使用几乎相同的参数调用程序,我想使用'&'附加到默认内联列表中:
declare
Exit_Code : constant Integer := GNAT.OS_Lib.Spawn (Program_Name => "gprbuild",Args => (Default_GPR_Arguments & new String'(File_Name_Parameter)));
begin
if Exit_Code /= 0 then
raise Program_Error with "Exit code:" & Exit_Code'Image;
end if;
end;
但是,编译器抱怨System.Strings.String_List
需要use子句:
operator for type "System.Strings.String_List" is not directly visible
use clause would make operation legal
但是插入use System.Strings.String_List
会产生:
"System.Strings.String_List" is not allowed in a use clause
我也收到了这个警告:
warning: "System.Strings" is an internal GNAT unit
warning: use "GNAT.Strings" instead
因此,我在with和use子句中将GNAT替换为System,除了原始的“您需要System.Strings.String_List的use子句”之外还得到了一个额外的错误:
"GNAT.Strings.String_List" is not allowed in a use clause
为什么use子句中不允许使用GNAT.Strings.String_List?关于use子句的8.5节似乎并未在不允许的软件包中声明任何内容,因此这是编译器错误吗?是否可以定义一个没有use子句的新程序包?
解决方法
在形式的use子句中
recipeA
do_bar
必须是程序包名称。 recipeB
是子类型名称,而不是程序包名称。
有多种方法可以为PACKAGE_EXCLUDE
调用use Name;
。最简单的是使用全名:
Name
,但是大概您希望能够将其用作前缀表示法GNAT.Strings.String_List
中的运算符。降低特异性的方法:
-
"&"
这样可以直接看到此特定功能。 -
String_List
使所有类型的基本操作符直接可见。 -
GNAT.Strings."&" (Left,Right)
使所有类型的原始操作(包括非操作符操作)直接可见。 -
Left & Right
这样可以直接查看包中的所有内容。
看起来这是设计决定。 System
中的许多其他软件包都遵循此规则。从s-string.ads(System.String的软件包规范)中:
-- Note: this package is in the System hierarchy so that it can be directly
-- be used by other predefined packages. User access to this package is via
-- a renaming of this package in GNAT.String (file g-string.ads).
我猜为什么要这样做:因为它不在Ada规范中,而是从GNAT扩展而来。