# Non-visible declaration / bounded\_strings and package

**URL:** https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809
**Category:** General
**Created:** [October 7, 2026, 6:42pm UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809 "2026-10-07T18:42:09Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![BlueAlmost](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/bluealmost/32/953_2.png) [@BlueAlmost](https://forum.ada-lang.io/u/BlueAlmost)
#### Post date: [October 7, 2026, 6:42pm UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/1 "2026-10-07T18:42:10Z")

</div>

_ **I am stumped.** _ The stripped-down example contains a package with a function “get\_strings” that reads the lines of “readme.txt” into an array of bounded strings. The “run\_test” will compile and run without “_**Put\_Line(To\_String…)**_”. But with that line we get compile error shown in comments in _ **run\_test.adb** _ below.

**q\_pkg.ads contents:**

```ada
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Bounded;

package Q_pkg is

  package B_str is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => 100); use B_Str;
  type B_array is array (Natural range <>) of B_str.Bounded_String;
  function get_strings return B_array;

end Q_pkg;

```

**q\_pkg.adb contents:**

```ada
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Bounded;

package body Q_pkg is

  function get_strings return B_Array is

  Dummy : B_str.Bounded_String;

  N_lines : Integer := 0;
  F_In : File_Type;
  Input_File_Name : constant String := "readme.txt";

  begin

    Open (F_In, In_File, "readme.txt");
    while not End_Of_File (F_In) loop
      Dummy := To_Bounded_String(Get_Line(F_In));
      N_Lines := N_Lines+1;
    end loop;
    Reset (F_In);

    declare
      A1 : B_array (1 .. N_Lines);
    begin
      for I in A1'Range loop
        A1(I) := To_Bounded_String(Get_Line(F_In));
      end loop;
      return A1;
    end;
  end get_strings;
end Q_pkg;

```

**and run\_test.adb:**

```ada
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Strings.Bounded;

with Q_pkg; use Q_pkg;

procedure run_test is

begin
  declare
    A : B_Array := get_strings;
  begin
    for I in A'Range loop
      Put_Line(Integer'Image(I));
     
      -- Put_Line(To_String(A(I)));
      -- uncommenting line above gives:
      -- run_test.adb:16:16: error: "To_String" is not visible
      -- run_test.adb:16:16: error: non-visible declaration from "b_str" at a-strbou.ads:130, instance at q_pkg.ads:7

    end loop;
  end;
end run_test;

```

**readme.txt:**

```ada
1
2
3

```

I must be missing something about bounded strings, etc. Can anybody see the issue?

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [October 7, 2026, 7:51pm UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/2 "2026-10-07T19:51:25Z")

</div>

To\_String is declared in an instance of Ada.Strings.Bounded, which is Q\_Pkg.B\_Str. Thus its fully qualified name is `Q_Pkg.B_Str.To_String`. Add `use B_St`r to make it visible.

**P**. **S**. You can also rename it inside Q\_Pkg.

**P**. **P**. **S**. Ada is not C. Never use End\_Of\_File.

---

<div class="post-metadata">

### Author: ![BlueAlmost](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/bluealmost/32/953_2.png) [@BlueAlmost](https://forum.ada-lang.io/u/BlueAlmost)
#### Post date: [October 7, 2026, 8:08pm UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/3 "2026-10-07T20:08:17Z")

</div>

Dmitry, Thank you! This makes perfect sense now that I see it.

Two follow-ups, if I may:

1. How would I “rename it inside Q\_Pkg”? I do not understand this.

2. The “End\_of\_File” used above comes from:

> **[Standard library: Files and streams - learn.adacore.com](https://learn.adacore.com/courses/intro-to-ada/chapters/standard_library_files_streams.html)**

What might be used instead of “End\_of\_File”.

Thanks in advance,  
/James

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [October 7, 2026, 8:36pm UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/4 "2026-10-07T20:36:09Z")

</div>

> [@BlueAlmost](#):
>
> 1. How would I “rename it inside Q\_Pkg”? I do not understand this.

```ada
function To_String (Source : B_Str.Bounded_String) return String
   renames B_Str.To_String;

```

> [@BlueAlmost](#):
>
> 1. The “End\_of\_File” used above comes from:

You should read files once because there exist files that do not allow repositioning.

Instead of testing for file end simply read it in an infinite loop and catch Use End\_Error exception. The patter is:

```ada
begin
   loop
      ... -- read file
   end loop;
exception
  when End_Error =>
      null;
end;

```

Note that you selected bounded string which means that it is likely be allocated out of the pool. Therefore you will get all on the stack and therefore you should expect stack overflow coming quite quickly. If not, you can write a function that utilize stack making recursive calls to get array in chunks. No extra pass of lines counting is needed.

The general rule is that bounded strings are basically useless. You either go full pool e.g. doing Unbounded\_String + Vector. Or else you use an arena to allocate strings there if you want stay with stack keeping it as tight as possible. Arena can sit in a pool too, but allocated just once.

There is also middle way like having an array of access to string automatically freeing strings. It has the advantage that strings will be accessible directly like in case of arena. Unbounded\_String is quite clumsy and inefficient to access.

---

<div class="post-metadata">

### Author: ![BlueAlmost](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/bluealmost/32/953_2.png) [@BlueAlmost](https://forum.ada-lang.io/u/BlueAlmost)
#### Post date: [October 8, 2026, 4:12am UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/5 "2026-10-08T04:12:21Z")

</div>

Very helpful and description information here. Your efforts to provide great detail are appreciated!

---

<div class="post-metadata">

### Author: ![JC001](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/j/e56c9b/32.png) [@JC001](https://forum.ada-lang.io/u/JC001)
#### Post date: [October 8, 2026, 9:05am UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/6 "2026-10-08T09:05:02Z")

</div>

> [@dmitry-kazakov](#):
>
> **P**. **P**. **S**. Ada is not C. Never use End\_Of\_File.

This is true for Ada.Text\_IO (and similar), where End\_Of\_File is broken. End\_Of\_File works fine for Direct\_IO and Sequential\_IO.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [October 8, 2026, 10:03am UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/7 "2026-10-08T10:03:26Z")

</div>

Direct\_IO has the function Size for the purpose. Sequential\_IO faces same problem as Text\_IO. An implementation of End\_Of\_File requires read-ahead and buffering. Which precludes in-place I/O semantics (OK, UNIX never cared of) and causes unnecessary blocking when working with pipes, terminals, network.

**P**. **S**. Thanks to AI (sorry, SI 😄) hype memory becomes an issue again. Good chance for Ada and solid engineering.

---

<div class="post-metadata">

### Author: ![Nordic\_Dogsledding](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/nordic_dogsledding/32/547_2.png) [@Nordic\_Dogsledding](https://forum.ada-lang.io/u/Nordic_Dogsledding)
#### Post date: [October 8, 2026, 1:28pm UTC](https://forum.ada-lang.io/t/non-visible-declaration-bounded-strings-and-package/4809/8 "2026-10-08T13:28:51Z")

</div>

> [@JC001](#):
>
> > [@dmitry-kazakov](#):
> >
> > **S**. Ada is not C. Never use End\_Of\_File.
> 
> This is true for Ada.Text\_IO (and similar), where End\_Of\_File is broken. End\_Of\_File works fine for Direct\_IO and Sequential\_IO.

End\_of\_File works fine for files written with Ada.Text\_IO because closing a file (also implicitly) adds an end marker (RM A.10.2(3)) which then is read by look-ahead (note: Ada is well defined). Files written by other means might not do this, so End\_of\_File is doomed to fail. End\_Error always works.
