1

I want to rename a constant in the public part of a package (the original name is deprecated) that is defined in the private part. I tried this but GNAT says:

full constant declaration appears too late

package Sample is

  type The_Type is private;
  My_Constant : constant The_Type;

  My_Renamed_Constant : The_Type;

private

  type The_Type is ...;
  My_Constant : constant The_Type := ...;

  My_Renamed_Constant : The_Type renames My_Constant;

end Sample;
Gneuromante
  • 560
  • 3
  • 12

2 Answers2

5

Is there a reason you want a rename instead of (say)
function My_Renamed_Constant return The_Type;
which simply returns My_Constant in the package body?

Functionally identical... and should inline if you're worried about speed.

Later in the deprecation process, make My_Renamed_Constant the constant and My_Constant the function instead. Then, when you think you're ready to retire it, have function My_Constant raise Program_Error or a custom exception indicating "using deprecated constant" to catch any usage you missed.

  • That might be a good solution if a renaming is impossible. I tried renaming the constant with the function, just like enumeration values can be renamed as function, but it didn't work. What I don't see clearly is the actual inlining. I think GNAT requires so much conditions, that it would probably not be applied. – Gneuromante Jan 08 '18 at 22:53
  • I don't understand what "renaming the constant with the function" is, or what didn't work. As far as inlining/optimisation is concerned, Gnat is pretty smart and has the full range of gcc optimisations, plus Ada's clean semantics (unlike C "const") allow proper constant folding. So I would expect Gnat to streamline either of these answers nicely. –  Jan 08 '18 at 23:01
  • I mean: function My_Renamed_Constant return The_Type renames My_Constant; This was also rejected by the compiler, but for enumeration values it does work. – Gneuromante Jan 08 '18 at 23:08
  • 1
    Oh no, I wouldn,t expect that to behave differently to a rename. I was suggesting a function body which returns the value. –  Jan 08 '18 at 23:16
  • 1
    And (Ada2012) the function body could be in the spec: `function My_Renamed_Constant return The_Type is (My_Constant);`. – Simon Wright Jan 09 '18 at 08:12
  • I like the Ada-2012 version. Would you have to move it to the package body when you wanted it to `raise Program_Error;`? –  Jan 09 '18 at 10:46
  • 1
    No: `function My_Renamed_Constant return The_Type is (raise Program_Error);` compiles OK. – Simon Wright Jan 09 '18 at 11:15
3

You probably don’t need to use a renaming; would this do? (this may depend on exactly what the full declaration of The_Type is in your case)

package Sample is

  type The_Type is private;
  My_Constant : constant The_Type;

  My_Renamed_Constant : constant The_Type;

private

  type The_Type is new Integer;
  My_Constant : constant The_Type := 42;

  My_Renamed_Constant : constant The_Type := My_Constant;

end Sample;
Simon Wright
  • 25,108
  • 2
  • 35
  • 62
  • I wanted to avoid that, since the private type is a record with one field depending on a size parameter (the package is actually generic). I wanted to avoid wasting memory and I suppose that this solutions uses different memory for each object. Or is the compiler so smart to share the memory? I don't think so. – Gneuromante Jan 08 '18 at 22:50