0
votes

In some code that I inherited, I get the compile error "Unsigned" not declared in "System".

I'm trying to compile this using GNAT, but ultimately the code must compile with the original tools, which I don't have ready access to. So I'd like to understand how to resolve this from within the development environment (including the project file), and not modify the existing code.

I checked the file system.ads, and Unsigned is not defined there. Am I referring to the wrong libraries? How would I resolve this with the self imposed constraint mentioned above (to compile in the original environment)?

2
Can you get hold of System.ads from the original tools and post the relevant declaration here? Or any documentation as to the range of Unsigned values? - user_1818839
@BrianDrummond That may take some time, but I'll see what I can do. - Jim
It will probably confirm that something very like Keith's answer is correct. - user_1818839

2 Answers

4
votes

unsigned is the name of a predefined type in C. If what you need it an Ada type that matches the C type, what you need is Interfaces.C.unsigned. An older Ada implementation (before Interfaces.C was introduced by the 1995 standard) might have defined System.Unsigned for this purpose.

It would help to know what Ada implementation the code was originally written for.

You should examine the code to see whether it uses that type to interface to C code. If not (i.e., if it's just being used as a general unsigned integer type), you might instead consider defining your own modular type.

If I understand correctly, you need the code to compile both in the original environment and with GNAT. That might be difficult. One approach would be to define a new package with two different versions, one for the original environment and one for GNAT (or, ideally, for any modern Ada implementation). For example:

-- version for original environment
with System;
package Foo is
    subtype Unsigned is System.Unsigned;
end foo;

and:

-- version for GNAT
with Interfaces.C;
package Foo is
    subtype Unsigned is Interfaces.C.Unsigned;
end Foo;

Picking a better name than Foo is left as an exercise, as is determining automatically which version to use.

1
votes

You could rebuild the GNAT runtime system (RTS) with a slightly modified system.ads.

There’s a Makefile.adalib in the system RTS (well, there is in GNAT GPL 2014) which lets you do this. It’s at the last directory indicated in the “Object Search Path” section of the output of gnatls -v.

The RTS source is similarly indicated in the “Source Search Path” section.

Create a directory say unsigned with subdirectories adainclude, adalib.

Copy the RTS source into unsigned/adainclude, and edit system.ads to include

type Unsigned is mod 2 ** 32;

(I’m guessing a bit, but this is probably what you want!)

Then, in unsigned/adalib,

make -f Makefile.adalib ADA_INCLUDE_PATH=../adainclude ROOT=/opt/gnat-gpl-2014

(ROOT is where you have the compiler installed; it will be different on your system, it’s one above the bin directory in which gnatls and friends are installed).

There will be several errors during this, all caused (when I tried it) by units that use System.Unsigned_Types;. Work round this by inserting this immediately after the package body in the .adb:

subtype Unsigned is System.Unsigned_Types.Unsigned;

The files I had to change were

s-expmod.adb
s-expuns.adb
s-imgbiu.adb
s-imgrea.adb
s-imguns.adb
s-imgwiu.adb
s-valint.adb
s-valuns.adb
s-vercon.adb

It may be best at this stage to remove all the .ali and .a files from unsigned/adalib and repeat, to get a clean build.

Now, you should be able to use System.Unsigned by

gnatmake --RTS=/location/of/unsigned t.adb

In my case, t.adb contained

with System;
with Ada.Text_IO; use Ada.Text_IO;
procedure T is
begin
   Put_Line ("first: " & System.Unsigned'First'Img);
   Put_Line ("last:  " & System.Unsigned'Last'Img);
   Put_Line ("42:    " & System.Unsigned'Value ("42")'Img);
   Put_Line ("16#42#:" & System.Unsigned'Value ("16#42#")'Img);
end T;

and the output was

$ ./t
first:  0
last:   4294967295
42:     42
16#42#: 66