1

I'm trying to insert new elements in a record. I have default values set in the record and looked up how to initialize a record, but the compiler keeps saying, "warning: null value not allowed here," "warning: 'Constraint_Error' will be raised at run time." The following is the block I am working on.

type employee;
type employeePtr is access employee;
type employee is
record
  id : Integer := 0;
  name : Unbounded_String := To_Unbounded_String("");
  departmentname : Unbounded_String := To_Unbounded_String("");
  jobtitle : Unbounded_String := To_Unbounded_String("");
  payrate : Unbounded_String := To_Unbounded_String("");
  next : employeePtr := null;
end record;

employeeList : employeePtr;

procedure insertNew(employeeid : Unbounded_String; employeename : Unbounded_String; department : Unbounded_String; title : Unbounded_String; rate : Unbounded_String) is
  currentEmployee : employeePtr;
  --tmp : employeePtr := employeePtr'(id => 0, name => "", departmentname => "", jobtitle => "", payrate => "");
  tmp : employeePtr;
  tmpSkp : employeePtr;
  eid : Integer;
  placeAtEnd : Integer;
begin
  eid := Integer'Value(To_String(employeeid));
  tmp.id := eid;
  tmp.name := employeename;
  tmp.departmentname := department;
  tmp.jobtitle := title;
  tmp.payrate := rate;

  if employeeList.id = 0 then
     employeeList := tmp;
  else
     placeAtEnd := 1;
     while currentEmployee.next /= null loop
        if currentEmployee.next.id > eid then
           tmpSkp := currentEmployee.next;
           tmp.next := tmpSkp;
           currentEmployee.next := tmp;
           placeAtEnd := 0;
           exit;
        else
           currentEmployee := currentEmployee.next;
        end if;
     end loop;
     if placeAtEnd = 1 then
        currentEmployee.next := tmp;
     end if;
  end if;
end insertNew;

Right after begin, where I am trying to set the values of members of tmp, is where I am getting these errors. Am I initializing the record incorrectly? Is there something similar to try/catch from Java that could fix this?

Jacob Sparre Andersen
  • 6,733
  • 17
  • 22
NikonJR
  • 59
  • 7
  • 1
    (Apparently not applicable in your case, but I'll leave this comment here for others that get the same error message) That error message usually comes from explicitly (or detectable at compile time) assigning `null`to a value of a `not null` access type – egilhh Apr 18 '18 at 04:44
  • 1
    Is this a homework assignment/learning exercise? Because otherwise the correct way to do this is with an instantiation of Ada.Containers.Doubly_Linked_Lists. – Jeffrey R. Carter Apr 18 '18 at 08:17

2 Answers2

3

Compiling with -gnatl (inside a wrapper, so the line numbers are off by 3) gives

21.       tmp : employeePtr;

All access variables are default-initialized to null. I’d have written

          tmp : constant employeePtr := new employee;

(constant because you’re not going to change the pointer, just what it points to).

Returning to the code,

27.       tmp.id := eid;
          |
    >>> warning: null value not allowed here
    >>> warning: "Constraint_Error" will be raised at run time

because Constraint_Error is the required run time error for accessing via a null pointer.

28.       tmp.name := employeename;
          |
    >>> warning: null value not allowed here
    >>> warning: "Constraint_Error" will be raised at run time

29.       tmp.departmentname := department;
          |
    >>> warning: "tmp" may be null

I think the compiler has stopped adding detail to the repeated warning.

30.       tmp.jobtitle := title;
31.       tmp.payrate := rate;

and now it’s stopped warning at all.

Simon Wright
  • 25,108
  • 2
  • 35
  • 62
0

I didn't know that new is something in Ada, but that was the problem. Similar to malloc, in order to initialize an instance of a record, you use the keyword new, just like in Java.

NikonJR
  • 59
  • 7
  • 1
    You use `new` only when dealing with access types (similar to pointers in C, but not quite), like your `employeePtr` – egilhh Apr 18 '18 at 04:38