I am just a beginner in Ada,
my code looks like this,
with Ada.Strings.Unbounded;
use Ada.Strings.Unbounded;
procedure final is
Input : Unbounded.String;
begin
null;
end final;
When i compile this code with gnatmake,
compiler gives error "Unbounded" is not visible", what does this mean?
The use clause for Ada.Strings.Unbounded makes declarations inside that package directly visible. It does not make the package name itself (Unbounded) directly visible, so any reference to the name Unbounded that's not preceded by a . is going to be incorrect.
Furthermore, the type is called Unbounded_String, not String.
Change this:
Input : Unbounded.String;
to this:
Input : Unbounded_String;
(And please indent your code.)
Related
Posting for two reasons: (1) I was stuck on unhelpful compiler errors for far too long for such a simple issue and I want the next person to google those messages to come upon my (or other) answers, and (2) I still don't understand disallowing a use clause, so my own answer is really incomplete.
In order to call a program in two places with mostly the same arguments, I want to use the '&' to append to a default list inline:
declare
Exit_Code : constant Integer := GNAT.OS_Lib.Spawn (Program_Name => "gprbuild", Args => (Default_GPR_Arguments & new String'(File_Name_Parameter)));
begin
if Exit_Code /= 0 then
raise Program_Error with "Exit code:" & Exit_Code'Image;
end if;
end;
However, the compiler complains that System.Strings.String_List needs a use clause:
operator for type "System.Strings.String_List" is not directly visible
use clause would make operation legal
But inserting use System.Strings.String_List yields:
"System.Strings.String_List" is not allowed in a use clause
I also got this warning:
warning: "System.Strings" is an internal GNAT unit
warning: use "GNAT.Strings" instead
So I substituted GNAT for System in the with and the use clause and got an extra error in addition to the original 'you need a use clause for System.Strings.String_List' one:
"GNAT.Strings.String_List" is not allowed in a use clause
Why is GNAT.Strings.String_List not allowed in a use clause? Section 8.5 on use clauses doesn't seem to state anything on disallowed packages, so is this a compiler bug? Is it possible to define a new package that cannot have a use clause?
In a use clause of the form
use Name;
Name must be a package name. GNAT.Strings.String_List is a subtype name, not a package name.
There are a number of ways to invoke "&" for String_List. The simplest is to use the full name:
GNAT.Strings."&" (Left, Right)
but presumably you want to be able to use it as an operator in infix notation, Left & Right. Ways to achieve this, in decreasing specificity:
function "&" (Left : GNAT.Strings.String_List; Right : GNAT.Strings.String_List) return GNAT.Strings.String_List renames GNAT.Strings."&"; This makes this specific function directly visible.
use type GNAT.Strings.String_List; This makes all primitive operators of the type directly visible.
use all type GNAT.Strings.String_List; This makes all primitive operations of the type (including non-operator operations) directly visible.
use GNAT.Strings; This makes everything in the package directly visible.
Looks like it is a design decision. And many other packages in System follows this rule. From the s-string.ads (package specification for System.String):
-- Note: this package is in the System hierarchy so that it can be directly
-- be used by other predefined packages. User access to this package is via
-- a renaming of this package in GNAT.String (file g-string.ads).
My guess why this is done in that way: because it isn't in the Ada specification, but extension from GNAT.
I have a package called Linked_List(.ads) Here is the code in it:
Generic
type T is private;
package Linked_List is
type List is tagged record
Data : T;
end record;
end Linked_List;
and here is the code in the package which contains the main function (main.adb)
with Ada.Text_IO; use Ada.Text_IO;
with Linked_List;
procedure Main is
type ListOfIntegers is new Linked_List(T => Integer);
begin
null;
end Main;
I'm getting this error:
4:30 subtype mark required in this context
found "Linked_List" declared at linked_list.ads:3
found "Linked_List" declared at linked_list.ads:3
4:41 incorrect constrain for this kind of type
Any help is appreciated.
new Linked_List(T => Integer) defines a new package, not a new type. The error messages you’re getting are because the compiler thinks you’re declaring a type, so seeing the name of a package at column 30 confused it; it wanted to see the name of a (sub)type.
Line 4 should read
package ListOfIntegers is new Linked_List(T => Integer);
after which there is a type ListOfIntegers.List, so you can write
My_List : ListOfIntegers.List;
You may find having to say ListOfIntegers. all the time annoying; you can say
use ListOfIntegers;
after which you can just write
My_List : List;
but it’s usually thought best not to overdo this (if you have dozens of “withed” packages, “using” them all makes it difficult to know which one you’re referring to).
By the way, normal Ada usage is to use underscores to separate words in identifiers: List_Of_Names.
I want to use a package spec inside a procedure.
Something is missing for that, but i don't know what.
using_ads_package.adb:14:11: "var" is not visible
using_ads_package.adb:14:11: non-visible declaration at line 8
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
Procedure using_ads_package is
Package variable is
var : Unbounded_String ;
end variable ;
Begin
get_line(var);
End using_ads_package ;
In
procedure Using_Ads_Package is
package Variable is
Var : Unbounded_String;
end Variable;
begin
you’ve created a new scope in package Variable. Outside Variable, Var isn’t directly visible.
Outside Variable, you have two ways of referring to Var.
First, you can name the package in which it’s declared explicitly:
Get_Line (Variable.Var);
Alternatively, you can use Variable:
package Variable is
Var : Unbounded_String;
end Variable;
use Variable;
begin
Get_Line (Var);
Without compiling I’d suggest that the line:
get_line(var);
should be:
get_line(variable.var);
I created an array like this one:
type coef_list is array(Integer range 0..50) of Integer;
But the message appears when I call this function:
t:= times(r,q); --that multiply two polynoms.
Why? I need a dynamic array? with Ada.Vectors but how to used it? if there is any simple example to guide me, please share? Thx
Ada procedures (and similar for functions) require this structure:
procedure Foo is
-- declarations goes here
begin
-- code goes here
end Foo;
In your code, both polynomials and Main is missing the begin.
You have also put declarations (value1 : integer := 1; etc) after begin in print_polynoms, which is illegal.
Other problems with your code:
You redefine the built-in type String.
The type zero is not defined anywhere.
The type String_Pointer is not defined anywhere.
This syntax makes no sense: type Polynom is new Integer(p,p1,p2,p3,p4,q,q1,q2); And the type Polynom is never used. Why declare it?
The variable zero is not defined anywhere.
Why have an inner procedure Main here? It does nothing anyway. And is never called. Probably better to move print_polynoms out of Main, as an inner function of polynomials directly.
The polynomials procedure does nothing, print_polynoms will never be called.
Also, the code you pasted seems to not be the same as the code you tried to compile. (main is not declared at line 9)
I have a little problem in using get_line to be more concret I must take a line from a file and use it. I don't know how especially if the lines aren't constitute just from characters there's also float can I use get_line in this case?
Thank you. Let's start with this little example:
with Ada.Text_Io;
use Ada.Text_Io;
procedure Getline is
A:String;
T:string;
begin
Open(File => F, Mode => In_File, Name => Nom_Fichier);
A:=Get_Line(F,In_File, T);
Put(A);
end Getline;`
It looks like you're just guessing the parameters you should pass to Get_Line. I suggest you have a look at the relevant part in the ARM: The function Get_Line only takes a File_Type and returns a String; the procedure Get_Line takes a File_Type and, as output parameters, a String and a Natural.
Then, String is an indefinite subtype, meaning that you have to assign something to A at declaration, or provide boundaries for it. Here's a working version of your example code:
with Ada.Text_IO; use Ada.Text_IO;
procedure Getline is
F : File_Type;
File_Path : constant String := "testfile.stl";
begin
Open (File => F, Mode => In_File, Name => File_Path);
declare
A : String := Get_Line (F);
begin
Put (A);
end;
Close (File => F);
end Getline;
Before you try something more complex, you should get familiar with the basics of the language. The wikibook is a good place to start. If you want to get your actual question about reading floats from the line answered, you need to provide more details about how a potential line looks like.
Get_Line simply interprets the "line" (set of characters up to the next line terminator or end of file) as text, and gives it to the caller that way. Thus if the file contains:
10.52
Then your call to Get_Line will return the string "10.52".
It may be true that if you tried to read that using Float_Text_IO you would get the float value 10.52 back. However, there's no metadata associated with text in text files, so the computer has no way of knowing that text happens to be a representable float without parsing it and seeing if it can make a float out of it. It of course isn't going to bother to do that unless you ask it to via something like a call into Float_Text_IO