Using an Ada 2022 spec from an Ada 2012 client

(TL;DR: I came at this with the impression that aspects, just like pragmas, could be ignored when unknown. This seems not to be mandated, but only allowed, by the ARM 2022.)

The idea I was attempting is that a library can use Ada 2022 features but an Ada 2012 client can still “with” it, without maintaining two sets of sources, by ignoring unknown pragmas.

However, “future” aspects are reported as an error (using GNAT 14.1):

pragma Ada_2012;

package Multiver is  
   
   type Modern is null record   
     with Aggregate => (Empty       => Empty,
                        Add_Unnamed => Drop),
          Integer_Literal => From_Int,
          Unknown_Aspect;
   
   function Empty return Modern is (null record);
   procedure Drop (X : in out Modern; I : Integer) is null;
   
   function From_Int (X : String) return Modern is (Empty);

end Multiver;

Output:

multiver.ads:6:24: error: incompatible with Ada version set at line 1
multiver.ads:9:11: warning: "Unknown_Aspect" is not a valid aspect identifier [enabled by default]

That’s a self-contained example, but the same happens in the intended usage with two separate projects, library using -gnat2022 and client withing Multiver using -gnat12 and no Pragma Ada_2012 in the source.

Note:

  • Expected warning on line 9
  • Error instead of warning on line 6
  • Unexpected silence about line 8, which is maybe a bug.

So the thing is: if that error could be downgraded to a warning, I could have my cake and eat it.

(Just tested that the same happens with all GNATs in Alire, from 11 upwards. GNAT 10 rejects all unknown aspects).

After some digging, I find that the ARM 2012 says nothing about unknown aspects. The ARM 2022 gives permission to ignore unknown aspects: 13.1 Operational and Representation Aspects | Ada Programming Language, but does not mandate it so…

This seems to come from Version 1.4 of ai12s/ai12-0389-1.txt

So, after all that, I think it boils down to: is there some GNAT switch to enable ignoring all unknown aspects? Not practical for me anymore, since older GNATs would likely not have it, but at this point I’m just curious. And the lesson learned is that aspects are not just syntactic sugar on top of pragmas.

1 Like

I was sure that there was permission to ignore unknown aspects in Ada2012.
Maybe I’m misremembering. (I know there’s permission for ignoring unknown pragmas.)

There are some which are, though. (By definition.)
And that’s where the confusion can come from.

Then, adding any of the SPARK implementation-defined aspects to an Ada program could render it unportable to other compilers, if they choose to reject unknown aspects? I didn’t expect that, I thought aspects were like pragmas in that regard.

ObjectAda used to treat SPARK aspects as errors. When I pointed out that it is not impossible that someone might want to use OA to compile code proven with SPARK, they changed it to ignore SPARK aspects, so I presume that means it’s OK for an Ada-12 compiler to ignore aspects it doesn’t implement. I think it still treats non-SPARK unknown aspects as errors.

In my opinion, all Ada compilers should implement a switch to ignore all the unknown aspects (and maybe only raise a warning). Otherwise, the permission to add implementation-defined aspects breaks the portability of the standard language. That didn’t happen with pragmas.

For GNAT, I’ve found this:

NF-T622-002 Unknown aspects ignored (2020-06-22)

  By default, GNAT will now ignore unknown aspects and generate a
  warning instead of rejecting them with an error, to provide a
  handling similar to unknown pragmas and better compatibility
  across different Ada and GNAT compiler versions.

From https://docs.adacore.com/R/relnotes/features-21

So no switch, in principle, is necessary, but it seems that known aspects belonging to a future Ada version have a different logic, and they aren’t considered “unknown”.

IMO, Ada should apply strict rules regarding implementation of the standard. Long ago you could not call a compiler Ada compiler if you did not implement all Ada standard.

As for pragmas, that is no so simple. Some pragmas are more pragmas than others, e.g. pragma Atomic, pragma Import, representation pragmas etc.

The problem is that both pragmas and aspects (the difference is in the syntax only) can influence the semantics or be just a compiler hint/correctness annotation. You cannot ignore them in the former case. If only the language clearly separated the cases…

1 Like