Here are a couple of things that recent versions of GNAT reject, and I suspect that these are GNAT errors, but would appreciate input from
language lawyers to be sure. If they're not GNAT errors, then they seem
like things that make Ada less easy to use than I'd like.
The first is gcc bug 108157 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108157). GNAT.Sockets has
package GNAT.Sockets is
...
type Selector_Type is limited private;
...
procedure Connect_Socket
(Socket : Socket_Type;
Server : Sock_Addr_Type;
Timeout : Selector_Duration;
Selector : access Selector_Type := null;
Status : out Selector_Status);
-- Connect Socket to the given Server address using Connect_Socket, waiting
-- no longer than the given timeout duration. Status is set to
indicate
-- whether the operation completed successfully, timed out, or was aborted.
-- If Selector is not null, the designated selector is used to wait
for the
-- socket to become available, else a private selector object is
created
-- by this procedure and destroyed before it returns. If Timeout is
0.0,
-- no attempt is made to detect whether the connection has succeeded;
it
-- is up to the user to determine this using Check_Selector later on.
...
private
...
type Selector_Type (Is_Null : Boolean := False) is limited record
case Is_Null is
when True =>
null;
when False =>
R_Sig_Socket : Socket_Type := No_Socket;
W_Sig_Socket : Socket_Type := No_Socket;
-- Signalling sockets used to abort a select operation
end case;
end record;
...
end GNAT.Sockets;
Kazakov's GNAT.Sockets.Server had (since modified to work with recent versions of GNAT)
package GNAT.Sockets.Server is
...
type Connections_Server is tagged limited private;
...
private
...
procedure Do_Connect
(Listener : in out Connections_Server'Class;
Client : in out Connection_Ptr);
...
type Connections_Server is tagged limited record
-- limited because Selector_Type is limited
Selector : aliased Selector_Type;
end record;
...
end GNAT.Sockets.Server;
and
package body GNAT.Sockets.Server is
...
procedure Do_Connect
(Listener : in out Connections_Server'Class;
Client : in out Connection_Ptr)
is
Status : Selector_Status;
begin
Connect_Socket
(Socket => Client.Socket,
Server => Client.Client_Address,
Timeout => 0.0,
Selector => Listener.Selector'Unchecked_Access,
Status => Status);
end Do_Connect;
...
end GNAT.Sockets.Server;
Beginning with GNAT 12, the parameter association
Selector => Listener.Selector'Unchecked_Access,
gives the error
object subtype must statically match designated subtype
The FSF GNAT maintainers have decided not to change this, citing
-- Ada 2005 (AI-363): Require static matching when designated
-- type has discriminants and a constrained partial view, since
-- in general objects of such types are mutable, so we can't
-- allow the access value to designate a constrained object
-- (because access values must be assumed to designate mutable
-- objects when designated type does not impose a constraint).
I think that those who use anonymous access types get what they deserve,
but had the parameter been mode "in out", there would be no problem. I
think that access parameters should work the same as "in out" parameters
as much as possible.
So, GNAT or Ada problem, or is this a reasonable restriction?
The other instance is in PragmARC.B_Strings (https://github.com/jrcarter/PragmARC):
package PragmARC.B_Strings is
type B_String (Max_Length : Positive := 1024) is tagged limited
private;
-- Default initial value is Null_B_String
Null_B_String : constant B_String; -- A string of zero characters
...
private -- PragmARC.B_Strings
type B_String (Max_Length : Positive := 1024) is tagged limited record
Len : Natural := 0;
Value : String (1 .. Max_Length) := (1 .. Max_Length => ' ');
end record;
Null_B_String : constant B_String := (Max_Length => 1, others => <>);
end PragmARC.B_Strings;
Beginning with GNAT 13, an error on the full declaration of the constant
says that its subtype does not statically match that of the deferred declaration.
A workaround is to explicitly declare the discriminant value on both declarations. Probably making the full declaration be (others => <>) would also work.
I don't see this in ARM 7.4; only constants of an anonymous access type
have to statically match. So this is probably a compiler error, but I
thought I would see what the experts think.
--
Jeff Carter
"Ada is a management tool. It selects for software
engineers and encourages the hackers to quit."
Robert C. Leif
204
Regarding your second problem, refer to AI22-0041-1.
Essentially, there are problems if predicates are involved. We changed the rule to require static compatibility (as a Binding Interpretation). I don't have the energy to look up what "static compatibility" requires in this case (enjoy figuring out 4.9.1). In some cases, it requires static matching, in others, it has weaker requirements.
I don't have the time or energy tonight to look into your other problem.
(I'm waiting for a backup to finish, or I would have already gone home -- since I only got back from Lisbon last night, I'm not equipped for my usual late night work...)
On 2023-06-17 09:28, Randy Brukardt wrote:
Regarding your second problem, refer to AI22-0041-1.
Essentially, there are problems if predicates are involved. We changed the rule to require static compatibility (as a Binding Interpretation). I don't have the energy to look up what "static compatibility" requires in this case
(enjoy figuring out 4.9.1). In some cases, it requires static matching, in others, it has weaker requirements.
There are no predicates involved. One can cut it down to just the type and constant:
gcc -c -gnatl12 b_strings_prob.ads
gnatmake -gnatl2022 b_strings_prob.ads
GNAT 12.2.0
Copyright 1992-2022, Free Software Foundation, Inc.
Compiling: b_strings_prob.ads
Source file time stamp: 2023-06-17 17:38:32
Compiled at: 2023-06-17 18:38:38
1. package B_Strings_Prob is
2. type B_String (Max_Length : Positive := 1_000) is taggedlimited private; 3.
4. Null_B_String : constant B_String; -- A string of zero characters
5. private -- B_Strings_Prob
6. type B_String (Max_Length : Positive := 1_000) is tagged limited record
7. Len : Natural := 0;
8. Value : String (1 .. Max_Length) := (1 .. Max_Length => ' ');
9. end record;
10.
11. Null_B_String : constant B_String := (Max_Length => 1, others => <>); 12. end B_Strings_Prob;
13.
13 lines: No errors
I get, in macOS, with:
gcc -c -gnatl12 b_strings_prob.ads
and the same with with:
gnatmake -gnatl2022 b_strings_prob.ads
13 lines: No errors
Bug in GNAT 13??
On 2023-06-17 09:28, Randy Brukardt wrote:
Regarding your second problem, refer to AI22-0041-1.
Essentially, there are problems if predicates are involved. We changed
the
rule to require static compatibility (as a Binding Interpretation). I
don't
have the energy to look up what "static compatibility" requires in this
case
(enjoy figuring out 4.9.1). In some cases, it requires static matching,
in
others, it has weaker requirements.
There are no predicates involved. One can cut it down to just the type and constant:
package B_Strings_Prob is
type B_String (Max_Length : Positive := 1_000) is tagged limited
private;
Null_B_String : constant B_String; -- A string of zero characters
private -- B_Strings_Prob
type B_String (Max_Length : Positive := 1_000) is tagged limited record
Len : Natural := 0;
Value : String (1 .. Max_Length) := (1 .. Max_Length => ' ');
end record;
Null_B_String : constant B_String := (Max_Length => 1, others => <>);
end B_Strings_Prob;
and still get the error:
$ gnatmake -gnatc b_strings_prob.ads
x86_64-linux-gnu-gcc-13 -c -gnatc b_strings_prob.ads b_strings_prob.ads:12:04: error: subtype does not statically match
deferred declaration at line 5
gnatmake: "b_strings_prob.ads" compilation error
I don't see any mention of AI22-0041-1 in ARM 7.4.
I don't have the time or energy tonight to look into your other problem.
(I'm waiting for a backup to finish, or I would have already gone home --
since I only got back from Lisbon last night, I'm not equipped for my
usual
late night work...)
I'm surprised you're this functional already.
--
Jeff Carter
"I was in love with a beautiful blonde once, dear.
She drove me to drink. That's the one thing I'm
indebted to her for."
Never Give a Sucker an Even Break
109
You missed my point: The requirement that the subtypes are statically compatible was newly added. That applies to *all* subtypes, not just those with predicates. The reason the requirement was added had to do with predicates, but it might affect some marginal cases beyond that. It's a weaker requirement than static matching, but stronger than no requirement at all.
As I said the other day, you need to check if 4.9.1 allows or disallows your example (that's where the definition of static compatibility is found). If
it allows it, then it's a compiler bug, if it doesn't allow it, it's an incompatibility with a language fix and you need to find a different way to do whatever it is you are doing.
I don't have the energy tonight to go
through that exercise myself (I apparently brought back a bug from Lisbon, and have spent much of the last several days in bed - but for some reason I seem to only be able to sleep during the day. Really louses up life...).
"Jeffrey R.Carter" <spam.jrcarter.not@spam.acm.org.not> wrote in message news:u6jtue$16d9e$1@dont-email.me...
On 2023-06-17 09:28, Randy Brukardt wrote:
Regarding your second problem, refer to AI22-0041-1.
Essentially, there are problems if predicates are involved. We changed
the
rule to require static compatibility (as a Binding Interpretation). I
don't
have the energy to look up what "static compatibility" requires in this
case
(enjoy figuring out 4.9.1). In some cases, it requires static matching,
in
others, it has weaker requirements.
There are no predicates involved. One can cut it down to just the type and >> constant:
package B_Strings_Prob is
type B_String (Max_Length : Positive := 1_000) is tagged limited
private;
Null_B_String : constant B_String; -- A string of zero characters
private -- B_Strings_Prob
type B_String (Max_Length : Positive := 1_000) is tagged limited record >> Len : Natural := 0;
Value : String (1 .. Max_Length) := (1 .. Max_Length => ' ');
end record;
Null_B_String : constant B_String := (Max_Length => 1, others => <>);
end B_Strings_Prob;
and still get the error:
$ gnatmake -gnatc b_strings_prob.ads
x86_64-linux-gnu-gcc-13 -c -gnatc b_strings_prob.ads
b_strings_prob.ads:12:04: error: subtype does not statically match
deferred declaration at line 5
gnatmake: "b_strings_prob.ads" compilation error
I don't see any mention of AI22-0041-1 in ARM 7.4.
I don't have the time or energy tonight to look into your other problem. >>> (I'm waiting for a backup to finish, or I would have already gone home -- >>> since I only got back from Lisbon last night, I'm not equipped for my
usual
late night work...)
I'm surprised you're this functional already.
--
Jeff Carter
"I was in love with a beautiful blonde once, dear.
She drove me to drink. That's the one thing I'm
indebted to her for."
Never Give a Sucker an Even Break
109
On 2023-06-22 11:51, Randy Brukardt wrote:
You missed my point: The requirement that the subtypes are statically
compatible was newly added. That applies to *all* subtypes, not just
those
with predicates. The reason the requirement was added had to do with
predicates, but it might affect some marginal cases beyond that. It's a
weaker requirement than static matching, but stronger than no requirement
at
all.
As I said the other day, you need to check if 4.9.1 allows or disallows
your
example (that's where the definition of static compatibility is found).
If
it allows it, then it's a compiler bug, if it doesn't allow it, it's an
incompatibility with a language fix and you need to find a different way
to
do whatever it is you are doing.
Sorry, but I think you're wrong. The problem isn't static compatibility;
it's static matching. The error msg says the subtypes must statically
match, and the wording in 7.4(6/3) for deferred constants (which this is) refers to statically matching constraints. So static compatibility doesn't seem to be the issue.
Sigh. :Let's start over. My theory was that the problem came from an attempt by AdaCore to implement AI22-0041-1, a post Ada-2022 binding interpretation. That AI adds a static compatibility requirement to 7.4(6/3) (making it 7.4(6/6)). (It of course could just be a bug, too, but AI22-0041-1 seems
like the only sane reason to be changing the matching code in a working compiler that passes the ACATS.)
There is *no* version of the RM currently that includes the wording from post-Ada 2022 AIs (because of we had to wait for ISO to publish the thing first). You can only find that in the >50 approved AIs.
a.. If the deferred constant declaration includes a subtype_indication that defines a subtype S1, then the subtype_indication in the full declaration shall define a subtype S2 that is statically compatible with S1 (see 4.9.1). If S1 is a constrained subtype, the constraint defined by S2 shall statically match the constraint defined by S1. [Redundant: If the subtype S1 of the deferred constant is unconstrained, then the full declaration is still allowed to impose a constraint.]
On 2023-06-23 11:55, Randy Brukardt wrote:
Sigh. :Let's start over. My theory was that the problem came from an
attempt
by AdaCore to implement AI22-0041-1, a post Ada-2022 binding
interpretation.
That AI adds a static compatibility requirement to 7.4(6/3) (making it
7.4(6/6)). (It of course could just be a bug, too, but AI22-0041-1 seems
like the only sane reason to be changing the matching code in a working
compiler that passes the ACATS.)
There is *no* version of the RM currently that includes the wording from
post-Ada 2022 AIs (because of we had to wait for ISO to publish the thing
first). You can only find that in the >50 approved AIs.
Thanks for this clarification. I didn't realize I would have to look at
the AI itself. I'm using -gnat12, in hopes that the Ada-12 rules would be applied, but that doesn't seem to work.
[New version of 7.4(6):]
a.. If the deferred constant declaration includes a subtype_indication
that defines a subtype S1, then the subtype_indication in the full
declaration shall define a subtype S2 that is statically compatible with
S1
(see 4.9.1). If S1 is a constrained subtype, the constraint defined by S2
shall statically match the constraint defined by S1. [Redundant: If the
subtype S1 of the deferred constant is unconstrained, then the full
declaration is still allowed to impose a constraint.]
As my case doesn't involve the concepts involved in the other PPs, aliased and null exclusion, I presume that this PP applies. The essential parts of the code are
type B_String (Max_Length : Positive := 1_000) is tagged limited
private;
Null_B_String : constant B_String;
...
Null_B_String : constant B_String := (Max_Length => 1, others => <>);
I would think that the subtype indications in the two, being identical,
would be statically compatible. But my understanding of this may be wrong.
I'm not sure whether the deferred declaration has a constrained subtype, which would result in the constraint from the initialization expression of the full declaration not matching. But that rule has existed since Ada 95.
I think it would be a mistake for the language to require explicit discriminant associations for this case.
So I'm still not able to tell if this is a compiler error or intended by
the language.
B_String is an unconstrained type, which technically has a "null constraint" (see 3.2(7/2), rather unfortuate terminology, IMHO(. These always statically match, so they're always statically compatible as well.
So this appears to be a compiler bug. It might be related to the relatively new rule that Object_Size must match for static matching to work -- but that only applies to non-default Object_Size values (and there are none of those given here).
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 399 |
Nodes: | 16 (2 / 14) |
Uptime: | 111:43:07 |
Calls: | 8,369 |
Calls today: | 8 |
Files: | 13,165 |
Messages: | 5,899,168 |