comp.lang.ada
 help / color / mirror / Atom feed
* storage error: stack overflow
@ 2015-08-11 21:53 hreba
  2015-08-11 22:19 ` Jeffrey R. Carter
                   ` (4 more replies)
  0 siblings, 5 replies; 42+ messages in thread
From: hreba @ 2015-08-11 21:53 UTC (permalink / raw)


I am developing a program on 3 computers in parallel (depending on where 
I am). On 2 of them the executable works as expected, on one I get:

raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack 
overflow (or erroneous memory access)

The computers are:

a) a 32 bit desktop PC running Windows 7
b) a 32 bit desktop PC running LinuxMint release 13
c) a 64 bit Notebook running LinuxMint release 17.1

It is machine c) which makes the trouble.
On each machine I compile the program (no warnings) with gnat/GPS.

How can I find out what is wrong?
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-11 21:53 storage error: stack overflow hreba
@ 2015-08-11 22:19 ` Jeffrey R. Carter
  2015-08-12 15:01   ` hreba
  2015-08-12  8:27 ` briot.emmanuel
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-11 22:19 UTC (permalink / raw)


On 08/11/2015 02:53 PM, hreba wrote:
> I am developing a program on 3 computers in parallel (depending on where I am).
> On 2 of them the executable works as expected, on one I get:
> 
> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or
> erroneous memory access)
> 
> The computers are:
> 
> a) a 32 bit desktop PC running Windows 7
> b) a 32 bit desktop PC running LinuxMint release 13
> c) a 64 bit Notebook running LinuxMint release 17.1
> 
> It is machine c) which makes the trouble.
> On each machine I compile the program (no warnings) with gnat/GPS.
> 
> How can I find out what is wrong?

Are you running 32- or 64-bit Linux Mint on machine C?

Have you examined all your overridings of Adjust and Finalize for controlled
types for something that might use a lot of stack memory or do an erroneous
memory access?

-- 
Jeff Carter
"I'm a vicious jungle beast!"
Play It Again, Sam
131


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-11 21:53 storage error: stack overflow hreba
  2015-08-11 22:19 ` Jeffrey R. Carter
@ 2015-08-12  8:27 ` briot.emmanuel
  2015-08-13  1:34   ` hreba
  2015-08-12 10:31 ` Markus Schöpflin
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 42+ messages in thread
From: briot.emmanuel @ 2015-08-12  8:27 UTC (permalink / raw)


Since the problem occurs on linux, run your executable with valgrind. It will help a lot identifying the issue.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-11 21:53 storage error: stack overflow hreba
  2015-08-11 22:19 ` Jeffrey R. Carter
  2015-08-12  8:27 ` briot.emmanuel
@ 2015-08-12 10:31 ` Markus Schöpflin
  2015-08-13  1:36   ` hreba
  2015-08-12 10:57 ` Simon Wright
  2015-08-18  2:16 ` hreba
  4 siblings, 1 reply; 42+ messages in thread
From: Markus Schöpflin @ 2015-08-12 10:31 UTC (permalink / raw)


Additionally to the other suggestions you should check with 'ulimit -s' if 
your stack size is limited on the machine where your Ada program acts up.

I think that Linux Mint by default has a stack size limit of 8MB.

HTH,
Markus

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-11 21:53 storage error: stack overflow hreba
                   ` (2 preceding siblings ...)
  2015-08-12 10:31 ` Markus Schöpflin
@ 2015-08-12 10:57 ` Simon Wright
  2015-08-13  0:55   ` hreba
  2015-08-18  2:16 ` hreba
  4 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2015-08-12 10:57 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> I am developing a program on 3 computers in parallel (depending on
> where I am). On 2 of them the executable works as expected, on one I
> get:
>
> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack
> overflow (or erroneous memory access)

> How can I find out what is wrong?

Use the debugger and 'catch exception storage_error'?

I'd think it's more likely an erroneous memory access than a stack
overflow. As I remember, GNAT catches a SIGSEGV and does its best to
work out what the problem was, but at that level it can be hard to tell.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-11 22:19 ` Jeffrey R. Carter
@ 2015-08-12 15:01   ` hreba
  2015-08-12 16:00     ` AdaMagica
  2015-08-12 17:51     ` Jeffrey R. Carter
  0 siblings, 2 replies; 42+ messages in thread
From: hreba @ 2015-08-12 15:01 UTC (permalink / raw)


On 08/11/2015 07:19 PM, Jeffrey R. Carter wrote:
> On 08/11/2015 02:53 PM, hreba wrote:
>> I am developing a program on 3 computers in parallel (depending on where I am).
>> On 2 of them the executable works as expected, on one I get:
>>
>> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or
>> erroneous memory access)
>>
>> The computers are:
>>
>> a) a 32 bit desktop PC running Windows 7
>> b) a 32 bit desktop PC running LinuxMint release 13
>> c) a 64 bit Notebook running LinuxMint release 17.1
>>
>> It is machine c) which makes the trouble.
>> On each machine I compile the program (no warnings) with gnat/GPS.
>>
>> How can I find out what is wrong?
>
> Are you running 32- or 64-bit Linux Mint on machine C?
>
> Have you examined all your overridings of Adjust and Finalize for controlled
> types for something that might use a lot of stack memory or do an erroneous
> memory access?
>

I am running 64-bit LinuxMint.
I don't override Adjust and Finalize.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-12 15:01   ` hreba
@ 2015-08-12 16:00     ` AdaMagica
  2015-08-12 17:51     ` Jeffrey R. Carter
  1 sibling, 0 replies; 42+ messages in thread
From: AdaMagica @ 2015-08-12 16:00 UTC (permalink / raw)


Am Mittwoch, 12. August 2015 17:02:01 UTC+2 schrieb hreba:
> I am running 64-bit LinuxMint.
> I don't override Adjust and Finalize.

Then they do nothing. If you have to deallocate storage, you must override Finalize.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-12 15:01   ` hreba
  2015-08-12 16:00     ` AdaMagica
@ 2015-08-12 17:51     ` Jeffrey R. Carter
  2015-08-13  2:17       ` hreba
  1 sibling, 1 reply; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-12 17:51 UTC (permalink / raw)


On 08/12/2015 08:01 AM, hreba wrote:
>>>
>>> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or
>>> erroneous memory access)
> 
> I am running 64-bit LinuxMint.
> I don't override Adjust and Finalize.

That makes life interesting. Are you using the same version of GNAT on all the
machines? Are you compiling with -fstack-check?

-- 
Jeff Carter
"Oh Lord, bless this thy hand grenade, that with it thou
mayst blow thine enemies to tiny bits, in thy mercy."
Monty Python and the Holy Grail
24


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-12 10:57 ` Simon Wright
@ 2015-08-13  0:55   ` hreba
  2015-08-13  6:58     ` Simon Wright
  0 siblings, 1 reply; 42+ messages in thread
From: hreba @ 2015-08-13  0:55 UTC (permalink / raw)


On 08/12/2015 07:57 AM, Simon Wright wrote:
> hreba <f_hreba@yahoo.com.br> writes:
>
>> I am developing a program on 3 computers in parallel (depending on
>> where I am). On 2 of them the executable works as expected, on one I
>> get:
>>
>> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack
>> overflow (or erroneous memory access)
>
>> How can I find out what is wrong?
>
> Use the debugger and 'catch exception storage_error'?
>
> I'd think it's more likely an erroneous memory access than a stack
> overflow. As I remember, GNAT catches a SIGSEGV and does its best to
> work out what the problem was, but at that level it can be hard to tell.
>

The name of my program is "sos". Calling it with gdb:

-----------------------------------------------------
~/Projects/SOS/Exec $ gdb sos
<some infos about gdb>
Reading symbols from sos...done
(gdb) catch exception storage_error
Unable to insert catchpoint. Try to start the program first.
(gdb) run
Starting program: /home/frank/Projects/SOS/Exec/sos
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1"

(process:2365): Gtk-WARNING **: Locale not supported by C library.
         Using the fallback 'C' locale

Program received signal SIGSEGV, segmentation fault.
0x00007ffff627a1a0 in ada.strings.unbounded.reference () from 
/usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1
(gdb) catch exception storage_error
Your Ada runtime appears to be missing some debug information.
Cannot insert Ada exception catchpoint in this configuration.
---------------------------------------------------------

I compiled my program for debugging, but the debug information perhaps 
is missing in libgnat. Anyway, the problem has to do with 
Ada.Strings.Unbounded. For more, see my answer to Emmanuel Briot.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-12  8:27 ` briot.emmanuel
@ 2015-08-13  1:34   ` hreba
  2015-08-13  2:53     ` Jeffrey R. Carter
                       ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: hreba @ 2015-08-13  1:34 UTC (permalink / raw)


On 08/12/2015 05:27 AM, briot.emmanuel@gmail.com wrote:
> Since the problem occurs on linux, run your executable with valgrind. It will help a lot identifying the issue.
>

My first contact with valgrind. Executed it as described in the Quick 
Start Guide with

valgrind --leak-check=yes ./sos

The valgrind's response starts as follows:

-----------------------------------------------------------------
==4823== Memcheck, a memory error detector
==4823== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4823== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for 
copyright info
==4823== Command: ./sos
==4823==

(process:4823): Gtk-WARNING **: Locale not supported by C library.
	Using the fallback 'C' locale.
==4823== Invalid read of size 4
==4823==    at 0x66FF1A0: ada__strings__unbounded__reference (in 
/usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
==4823==    by 0x6703851: ada__strings__unbounded___assign__2 (in 
/usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
==4823==    by 0x425FE5: surfaces__deep_copy_base (surfaces.adb:12)
==4823==    by 0x426076: surfaces__deep_copy__2 (surfaces.adb:28)
==4823==    by 0x428081: detectors__deep_copy__2 (detectors.adb:40)
==4823==    by 0x42D936: setups__define_setup (setups.adb:43)
==4823==    by 0x43E5F3: main_gui__initialize (main_gui.adb:73)
==4823==    by 0x43FEBC: 
main_proc__data_handlers__marshallers__void_marshaller__call.4284 
(gtk-marshallers.adb:1111)
==4823==    by 0x441482: main_proc__data_handlers__first_marshaller.4777 
(gtk-handlers.adb:1280)
==4823==    by 0x5E3E3B7: g_closure_invoke (in 
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==4823==    by 0x5E4FD3C: ??? (in 
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==4823==    by 0x5E57A28: g_signal_emit_valist (in 
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4002.0)
==4823==  Address 0x4 is not stack'd, malloc'd or (recently) free'd
==4823==
==4823== Warning: client switching stacks?  SP change: 0x6ad0d40 --> 
0xffeffed18
==4823==          to suppress, use: --max-stackframe=68590690264 or greater

raised PROGRAM_ERROR : adjust/finalize raised STORAGE_ERROR: stack 
overflow (or erroneous memory access)
----------------------------------------------------------------

I didn't read the following 330kB of output about memory losses line by 
line, but most of them are related to libgobject and libgtk.

The referenced line of my program surfaces.adb:12 is
	dest.name := source.name;
These record fields are declared as UBString which is defined as
	subtype UBString is Ada.Strings.Unbounded.Unbounded_String;
So it seems that assigning unbounded strings can be a problem.

By the way, I use the gnat version from the regular repository of my 
LinuxMint distribution, which is 4.6.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-12 10:31 ` Markus Schöpflin
@ 2015-08-13  1:36   ` hreba
  0 siblings, 0 replies; 42+ messages in thread
From: hreba @ 2015-08-13  1:36 UTC (permalink / raw)


On 08/12/2015 07:31 AM, Markus Schöpflin wrote:
> Additionally to the other suggestions you should check with 'ulimit -s'
> if your stack size is limited on the machine where your Ada program acts
> up.
>
> I think that Linux Mint by default has a stack size limit of 8MB.
>
> HTH,
> Markus

Correct. On both Linux machines the response is 8192.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-12 17:51     ` Jeffrey R. Carter
@ 2015-08-13  2:17       ` hreba
  0 siblings, 0 replies; 42+ messages in thread
From: hreba @ 2015-08-13  2:17 UTC (permalink / raw)


On 08/12/2015 02:51 PM, Jeffrey R. Carter wrote:
> On 08/12/2015 08:01 AM, hreba wrote:
>>>>
>>>> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack overflow (or
>>>> erroneous memory access)
>>
>> I am running 64-bit LinuxMint.
>> I don't override Adjust and Finalize.
>
> That makes life interesting. Are you using the same version of GNAT on all the
> machines? Are you compiling with -fstack-check?
>

GNAT version 4.6 on both Linux machines.

I hadn't compiled with -fstack-check. Now I did. Nothing changed.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-13  1:34   ` hreba
@ 2015-08-13  2:53     ` Jeffrey R. Carter
  2015-08-13  7:05     ` Simon Wright
  2015-08-13  7:19     ` Simon Wright
  2 siblings, 0 replies; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-13  2:53 UTC (permalink / raw)


On 08/12/2015 06:34 PM, hreba wrote:
> 
> The referenced line of my program surfaces.adb:12 is
>     dest.name := source.name;
> These record fields are declared as UBString which is defined as
>     subtype UBString is Ada.Strings.Unbounded.Unbounded_String;
> So it seems that assigning unbounded strings can be a problem.

Interesting. I've done plenty of assigning of unbounded strings without
encountering this.

-- 
Jeff Carter
"Oh Lord, bless this thy hand grenade, that with it thou
mayst blow thine enemies to tiny bits, in thy mercy."
Monty Python and the Holy Grail
24


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-13  0:55   ` hreba
@ 2015-08-13  6:58     ` Simon Wright
  0 siblings, 0 replies; 42+ messages in thread
From: Simon Wright @ 2015-08-13  6:58 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> (gdb) catch exception storage_error
> Your Ada runtime appears to be missing some debug information.
> Cannot insert Ada exception catchpoint in this configuration.

I wrote about something similar at [1]. The workround there was to say,
in gdb,

   (gdb) print __gnat_debug_raise_exception

which managed to find and cache the symbol that 'catch exception' was
looking for, after which 'catch exception' worked.

[1] http://forward-in-code.blogspot.co.uk/2012/01/catching-exceptions-in-gdb.html

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-13  1:34   ` hreba
  2015-08-13  2:53     ` Jeffrey R. Carter
@ 2015-08-13  7:05     ` Simon Wright
  2015-08-14 13:53       ` hreba
  2015-08-13  7:19     ` Simon Wright
  2 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2015-08-13  7:05 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> ==4823==    at 0x66FF1A0: ada__strings__unbounded__reference (in
> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
> ==4823==    by 0x6703851: ada__strings__unbounded___assign__2 (in
> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
> ==4823==    by 0x425FE5: surfaces__deep_copy_base (surfaces.adb:12)

If you built your program with -g it should have linked with the static
version of the libraries rather than the dynamic one, which would
probably have been able to provide line number information within
libgnat. Is it possible you don't have libgnat.a installed? Is there
some -dev version of the libraries that you don't have? (I don't know
Debian-based systems well).


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-13  1:34   ` hreba
  2015-08-13  2:53     ` Jeffrey R. Carter
  2015-08-13  7:05     ` Simon Wright
@ 2015-08-13  7:19     ` Simon Wright
  2015-08-14 13:20       ` hreba
  2 siblings, 1 reply; 42+ messages in thread
From: Simon Wright @ 2015-08-13  7:19 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> ==4823== Invalid read of size 4
> ==4823==    at 0x66FF1A0: ada__strings__unbounded__reference (in
> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
> ==4823==    by 0x6703851: ada__strings__unbounded___assign__2 (in
> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)

There's no Assign in the code of Ada.Strings.Unbounded, so I expect it's
a subprogram generated by the compiler to manage assignment.

It could be from the finalize of the 'dest' object prior to assignment,
but I think it's from the adjust after the bitwise copy of the 'source'
object; Adjust does contain a call to Reference.

Given that, is it possible that something has corrupted the 'source'
object? (at least 'source.name')


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-13  7:19     ` Simon Wright
@ 2015-08-14 13:20       ` hreba
  0 siblings, 0 replies; 42+ messages in thread
From: hreba @ 2015-08-14 13:20 UTC (permalink / raw)


On 08/13/2015 04:19 AM, Simon Wright wrote:
> hreba <f_hreba@yahoo.com.br> writes:
>
>> ==4823== Invalid read of size 4
>> ==4823==    at 0x66FF1A0: ada__strings__unbounded__reference (in
>> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
>> ==4823==    by 0x6703851: ada__strings__unbounded___assign__2 (in
>> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
>
> There's no Assign in the code of Ada.Strings.Unbounded, so I expect it's
> a subprogram generated by the compiler to manage assignment.
>
> It could be from the finalize of the 'dest' object prior to assignment,
> but I think it's from the adjust after the bitwise copy of the 'source'
> object; Adjust does contain a call to Reference.
>
> Given that, is it possible that something has corrupted the 'source'
> object? (at least 'source.name')
>

The statement
	
     dest.name := source.name;

is the first line in the body of the subprogram

    procedure Deep_Copy_Base
       (source: Surface; dest: in out Surface'Class);

Setting a breakpoint at this subprogram, "p source" gets me

$1 = (name => (prev => 0x0, next => 0x0, reference => 0x0), dist => 0.0, 
zabs => 1500.0, zmin => 0.0, zmax => 0.0, ap => 0x722a90)

and on the other Linux machine, without the error, I get

$1 = (name => (prev => 0x0, next => 0x0, reference => 0xf22b98, last => 
0), dist => 0.0, zabs => 1500.0, zmin => 0.0, zmax => 0.0,
     ap => 0x8126b80)

The value of source.name comes from a call of 'To_Unbounded_String("")'.
The null reference is strange.

I made a simple test program with 2 variables a, b of type 
'Unbounded_String' and an assignment and it worked. After assigning the 
empty string to a its value is

$1 = (prev => 0x0, next => 0x0, reference => 
0x7ffff7dca6a0)<ada.strings.unbounded.empty_shared_string>)

I reinstalled GNAT, GPS and GtkAda from the Ubuntu repository and 
nothing changed. I'll continue my investigation when I have more time.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-13  7:05     ` Simon Wright
@ 2015-08-14 13:53       ` hreba
  2015-08-14 16:01         ` Simon Wright
  2015-08-14 17:00         ` Simon Wright
  0 siblings, 2 replies; 42+ messages in thread
From: hreba @ 2015-08-14 13:53 UTC (permalink / raw)


On 08/13/2015 04:05 AM, Simon Wright wrote:
> hreba <f_hreba@yahoo.com.br> writes:
>
>> ==4823==    at 0x66FF1A0: ada__strings__unbounded__reference (in
>> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
>> ==4823==    by 0x6703851: ada__strings__unbounded___assign__2 (in
>> /usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1)
>> ==4823==    by 0x425FE5: surfaces__deep_copy_base (surfaces.adb:12)
>
> If you built your program with -g it should have linked with the static
> version of the libraries rather than the dynamic one, which would
> probably have been able to provide line number information within
> libgnat. Is it possible you don't have libgnat.a installed? Is there
> some -dev version of the libraries that you don't have? (I don't know
> Debian-based systems well).
>

All project files have "-g" as Compiler switch. One imported project 
file has it additionally as builder and linker switch. Makes it a 
difference?

The installed files from libgnat are
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libgnarl-4.6.so.1
/usr/lib/x86_64-linux-gnu/libgnat-4.6.so.1
/usr/share
/usr/share/doc
/usr/share/doc/libgnat-4.6
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/libgnat-4.6

So there are only dynamic libraries. 'find /usr -name libgnat.a' found
/usr/lib/gcc/x86_64-linux-gnu/4.6/rts-native/adalib/libgnat.a
but I don't know where this comes from (perhaps I tried AdaCore earlier, 
I don't remember) and if this directory is being searched.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-14 13:53       ` hreba
@ 2015-08-14 16:01         ` Simon Wright
  2015-08-14 17:00         ` Simon Wright
  1 sibling, 0 replies; 42+ messages in thread
From: Simon Wright @ 2015-08-14 16:01 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> All project files have "-g" as Compiler switch. One imported project
> file has it additionally as builder and linker switch. Makes it a
> difference?

Should be a Builder switch, so it gets applied in all the packages that
need it; I'm pretty sure the Binder needs to see it as well as the
Linker (and, for your code of course) the Compiler.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-14 13:53       ` hreba
  2015-08-14 16:01         ` Simon Wright
@ 2015-08-14 17:00         ` Simon Wright
  1 sibling, 0 replies; 42+ messages in thread
From: Simon Wright @ 2015-08-14 17:00 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> So there are only dynamic libraries. 'find /usr -name libgnat.a' found
> /usr/lib/gcc/x86_64-linux-gnu/4.6/rts-native/adalib/libgnat.a
> but I don't know where this comes from (perhaps I tried AdaCore
> earlier, I don't remember) and if this directory is being searched.

I have wheezy (Debian 7) installed, and find

   $ dpkg -S libgnat.a
   gnat-4.6: /usr/lib/gcc/x86_64-linux-gnu/4.6/rts-native/adalib/libgnat.a

i.e. what you have is part of the standard 4.6 package, and linking with
-g should pick it up.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-11 21:53 storage error: stack overflow hreba
                   ` (3 preceding siblings ...)
  2015-08-12 10:57 ` Simon Wright
@ 2015-08-18  2:16 ` hreba
  2015-08-18  5:49   ` Jeffrey R. Carter
  2015-08-18  7:24   ` Egil H H
  4 siblings, 2 replies; 42+ messages in thread
From: hreba @ 2015-08-18  2:16 UTC (permalink / raw)


On 08/11/2015 06:53 PM, hreba wrote:
> I am developing a program on 3 computers in parallel (depending on where
> I am). On 2 of them the executable works as expected, on one I get:
>
> raised PROGRAM_ERROR ; adjust/finalize raised STORAGE_ERROR: stack
> overflow (or erroneous memory access)
>
> The computers are:
>
> a) a 32 bit desktop PC running Windows 7
> b) a 32 bit desktop PC running LinuxMint release 13
> c) a 64 bit Notebook running LinuxMint release 17.1
>
> It is machine c) which makes the trouble.
> On each machine I compile the program (no warnings) with gnat/GPS.
>
> How can I find out what is wrong?

Replying to my own post: With your help I was able to localize the 
error. Now I wrote a simple test program which behaves as the original 
one: runs on the machines a) and b) and provokes the error on c). Here 
it is:

with Ada.Strings.Unbounded;

procedure testUBS is

    type TA is record
          name:		Ada.Strings.Unbounded.Unbounded_String;
    end record;

    type TB is record
       a:	TA;
    end record;

    function New_TB  (name: String:="")  return access TB is
    begin
       return new TB'
         (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name)));
    end New_TB;

    b:	 access TB:= New_TB (name=>"Det");
    name: Ada.Strings.Unbounded.Unbounded_String;

begin
    name:= b.a.name;
end testUBS;

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18  2:16 ` hreba
@ 2015-08-18  5:49   ` Jeffrey R. Carter
  2015-08-18  7:24   ` Egil H H
  1 sibling, 0 replies; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-18  5:49 UTC (permalink / raw)


On 08/17/2015 07:16 PM, hreba wrote:
> 
> with Ada.Strings.Unbounded;
> 
> procedure testUBS is
> 
>    type TA is record
>          name:        Ada.Strings.Unbounded.Unbounded_String;
>    end record;
> 
>    type TB is record
>       a:    TA;
>    end record;
> 
>    function New_TB  (name: String:="")  return access TB is
>    begin
>       return new TB'
>         (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name)));
>    end New_TB;
> 
>    b:     access TB:= New_TB (name=>"Det");
>    name: Ada.Strings.Unbounded.Unbounded_String;
> 
> begin
>    name:= b.a.name;
> end testUBS;

This works fine on my 64-bit Linux (LMDE2) with the default compiler (GNAT 4.9.2).

-- 
Jeff Carter
"I wave my private parts at your aunties."
Monty Python & the Holy Grail
13

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18  2:16 ` hreba
  2015-08-18  5:49   ` Jeffrey R. Carter
@ 2015-08-18  7:24   ` Egil H H
  2015-08-18 12:23     ` hreba
  1 sibling, 1 reply; 42+ messages in thread
From: Egil H H @ 2015-08-18  7:24 UTC (permalink / raw)


On Tuesday, August 18, 2015 at 4:16:38 AM UTC+2, hreba wrote:
> 
> with Ada.Strings.Unbounded;
> 
> procedure testUBS is
> 
>     type TA is record
>           name:		Ada.Strings.Unbounded.Unbounded_String;
>     end record;
> 
>     type TB is record
>        a:	TA;
>     end record;
> 
>     function New_TB  (name: String:="")  return access TB is
>     begin
>        return new TB'
>          (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name)));
>     end New_TB;
> 
>     b:	 access TB:= New_TB (name=>"Det");
>     name: Ada.Strings.Unbounded.Unbounded_String;
> 
> begin
>     name:= b.a.name;
> end testUBS;
> 

This fails as described with Gnat Pro 6.4.1 (GCC 4.5.2), 
but seems to be fixed in later versions, at least Gnat Pro 7.1.1 (GCC 4.7.3).

You should try to avoid anonymous access types if at all possible.
However, you could try to work around the problem using an extended return, 
like this:

function New_TB
   (Name : String := "")
    return access TB
is
begin
   return Foo : access TB := new TB do
      foo.all := TB'
         (A => TA'
            (Name => Ada.Strings.Unbounded.To_Unbounded_String(Name)));
   end return;
end New_TB;

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18  7:24   ` Egil H H
@ 2015-08-18 12:23     ` hreba
  2015-08-18 12:37       ` Jacob Sparre Andersen
                         ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: hreba @ 2015-08-18 12:23 UTC (permalink / raw)


On 08/18/2015 04:24 AM, Egil H H wrote:
> On Tuesday, August 18, 2015 at 4:16:38 AM UTC+2, hreba wrote:
>>
>> with Ada.Strings.Unbounded;
>>
>> procedure testUBS is
>>
>>      type TA is record
>>            name:		Ada.Strings.Unbounded.Unbounded_String;
>>      end record;
>>
>>      type TB is record
>>         a:	TA;
>>      end record;
>>
>>      function New_TB  (name: String:="")  return access TB is
>>      begin
>>         return new TB'
>>           (a=>TA'(name=>Ada.Strings.Unbounded.To_Unbounded_String(name)));
>>      end New_TB;
>>
>>      b:	 access TB:= New_TB (name=>"Det");
>>      name: Ada.Strings.Unbounded.Unbounded_String;
>>
>> begin
>>      name:= b.a.name;
>> end testUBS;
>>
>
> This fails as described with Gnat Pro 6.4.1 (GCC 4.5.2),
> but seems to be fixed in later versions, at least Gnat Pro 7.1.1 (GCC 4.7.3).
>
> You should try to avoid anonymous access types if at all possible.

I need an access type because in my real program TB is a tagged type and 
I need class-wide variables. As long as everything works I prefer the 
anonymous type because it saves me a type conversion. But I am still in 
doubt about the best practice, there is some discrepancy between the 
examples in my Ada book (Barnes) and the posts in this group.

> However, you could try to work around the problem using an extended return,
> like this:
>
> function New_TB
>     (Name : String := "")
>      return access TB
> is
> begin
>     return Foo : access TB := new TB do
>        foo.all := TB'
>           (A => TA'
>              (Name => Ada.Strings.Unbounded.To_Unbounded_String(Name)));
>     end return;
> end New_TB;
>

Didn't know about extended return (the Ada 95 book was cheaper -:). But 
there is a problem: the TB in my original program is not only tagged, it 
is limited too (and New_TB is for initialization). So "foo.all:=..." is 
forbidden.

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 12:23     ` hreba
@ 2015-08-18 12:37       ` Jacob Sparre Andersen
  2015-08-18 14:02         ` hreba
  2015-08-18 14:15       ` Egil H H
  2015-08-18 14:16       ` Jeffrey R. Carter
  2 siblings, 1 reply; 42+ messages in thread
From: Jacob Sparre Andersen @ 2015-08-18 12:37 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> I need an access type because in my real program TB is a tagged type
> and I need class-wide variables.

This is generally not a reason to use access types in Ada.

Greetings,

Jacob
-- 
"Don't get me wrong, perl is an OK operating system, but it
 lacks a lightweight scripting language."

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 12:37       ` Jacob Sparre Andersen
@ 2015-08-18 14:02         ` hreba
  2015-08-18 14:11           ` Dmitry A. Kazakov
  2015-08-18 14:16           ` Jeffrey R. Carter
  0 siblings, 2 replies; 42+ messages in thread
From: hreba @ 2015-08-18 14:02 UTC (permalink / raw)


On 08/18/2015 09:37 AM, Jacob Sparre Andersen wrote:
> hreba <f_hreba@yahoo.com.br> writes:
>
>> I need an access type because in my real program TB is a tagged type
>> and I need class-wide variables.
>
> This is generally not a reason to use access types in Ada.
>
> Greetings,
>
> Jacob
>

Huh? As much as I know you cannot declare variables of a type with 
unknown storage requirements at compile time, such as class-wide types 
and arrays with unknown range.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:02         ` hreba
@ 2015-08-18 14:11           ` Dmitry A. Kazakov
  2015-08-18 14:16           ` Jeffrey R. Carter
  1 sibling, 0 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2015-08-18 14:11 UTC (permalink / raw)


On Tue, 18 Aug 2015 11:02:40 -0300, hreba wrote:

> On 08/18/2015 09:37 AM, Jacob Sparre Andersen wrote:
>> hreba <f_hreba@yahoo.com.br> writes:
>>
>>> I need an access type because in my real program TB is a tagged type
>>> and I need class-wide variables.
>>
>> This is generally not a reason to use access types in Ada.

> Huh? As much as I know you cannot declare variables of a type with 
> unknown storage requirements at compile time, such as class-wide types 
> and arrays with unknown range.

Of course you can, e.g.

declare
   Line : String := Get_Line;
begin
   ...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 12:23     ` hreba
  2015-08-18 12:37       ` Jacob Sparre Andersen
@ 2015-08-18 14:15       ` Egil H H
  2015-08-19 13:07         ` hreba
  2015-08-18 14:16       ` Jeffrey R. Carter
  2 siblings, 1 reply; 42+ messages in thread
From: Egil H H @ 2015-08-18 14:15 UTC (permalink / raw)


 
> Didn't know about extended return (the Ada 95 book was cheaper -:). But 
> there is a problem: the TB in my original program is not only tagged, it 
> is limited too (and New_TB is for initialization). So "foo.all:=..." is 
> forbidden.
> 

Then "foo.A :=..."
...

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:02         ` hreba
  2015-08-18 14:11           ` Dmitry A. Kazakov
@ 2015-08-18 14:16           ` Jeffrey R. Carter
  2015-08-18 20:56             ` Randy Brukardt
  2015-08-19  1:48             ` hreba
  1 sibling, 2 replies; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-18 14:16 UTC (permalink / raw)


On 08/18/2015 07:02 AM, hreba wrote:
> 
> Huh? As much as I know you cannot declare variables of a type with unknown
> storage requirements at compile time, such as class-wide types and arrays with
> unknown range.

These are "indefinite types". You can declare an object of an indefinite type as
long as you supply an initialization expression:

S : String := "Hello";

V : T'Class := Some_Function;

-- 
Jeff Carter
"Blessed are they who convert their neighbors'
oxen, for they shall inhibit their girth."
Monty Python's Life of Brian
83


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 12:23     ` hreba
  2015-08-18 12:37       ` Jacob Sparre Andersen
  2015-08-18 14:15       ` Egil H H
@ 2015-08-18 14:16       ` Jeffrey R. Carter
  2015-08-19 13:12         ` hreba
  2015-08-19 20:47         ` Bob Duff
  2 siblings, 2 replies; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-18 14:16 UTC (permalink / raw)


On 08/18/2015 05:23 AM, hreba wrote:
> 
> I need an access type because in my real program TB is a tagged type and I need
> class-wide variables.

You do not /need/ access types for this. Avoiding them requires some thought,
but that's what S/W engineers do.

> Didn't know about extended return (the Ada 95 book was cheaper -:). But there is
> a problem: the TB in my original program is not only tagged, it is limited too
> (and New_TB is for initialization). So "foo.all:=..." is forbidden.

If your type is limited then you will have to use an extended return for Ada >
95. Does

return Foo : access TB :=
   new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) );

work?

-- 
Jeff Carter
"Blessed are they who convert their neighbors'
oxen, for they shall inhibit their girth."
Monty Python's Life of Brian
83

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:16           ` Jeffrey R. Carter
@ 2015-08-18 20:56             ` Randy Brukardt
  2015-08-19  1:48             ` hreba
  1 sibling, 0 replies; 42+ messages in thread
From: Randy Brukardt @ 2015-08-18 20:56 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> wrote in message 
news:mqvejr$hai$2@dont-email.me...
> On 08/18/2015 07:02 AM, hreba wrote:
>>
>> Huh? As much as I know you cannot declare variables of a type with 
>> unknown
>> storage requirements at compile time, such as class-wide types and arrays 
>> with
>> unknown range.
>
> These are "indefinite types". You can declare an object of an indefinite 
> type as
> long as you supply an initialization expression:
>
> S : String := "Hello";
>
> V : T'Class := Some_Function;

And if you need to change the type of the object after initialization, you 
can use the "Holder" container, which exists for this very purpose:

      package T_Class_Holder is new Ada.Containers.Indefinite_Holders 
(T'Class);

      V : T_Class_Holder.Holder;
  begin
      V.Replace_Element (Some_Function);
      ...
      V.Replace_Element (Some_Other_Function);
      ...
   end;

In Ada 2012, you can also use the reference function to modify the object, 
but you can't change the tag that way. That is:

    V.Reference := Some_Function;

As noted, this will raise Constraint_Error if the tag of V.Reference is 
changed.

I may sound like a broken record (scratched CD?? ;-), but using a Holder 
rather than explicit access types lets the library do the storage management 
rather than the programmer. There are much less likely to be bugs that way.

And of course, you can do this with all of the containers; if you need a Map 
or Tree or Vector [including an array] of T'Class, just instantiate the 
appropriate container and again let someone at your compiler vendor get the 
storage management right, rather than doing it yourself.

                                              Randy.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:16           ` Jeffrey R. Carter
  2015-08-18 20:56             ` Randy Brukardt
@ 2015-08-19  1:48             ` hreba
  2015-08-19  5:10               ` Jeffrey R. Carter
                                 ` (2 more replies)
  1 sibling, 3 replies; 42+ messages in thread
From: hreba @ 2015-08-19  1:48 UTC (permalink / raw)


On 08/18/2015 11:16 AM, Jeffrey R. Carter wrote:
> On 08/18/2015 07:02 AM, hreba wrote:
>>
>> Huh? As much as I know you cannot declare variables of a type with unknown
>> storage requirements at compile time, such as class-wide types and arrays with
>> unknown range.
>
> These are "indefinite types". You can declare an object of an indefinite type as
> long as you supply an initialization expression:
>
> S : String := "Hello";
>
> V : T'Class := Some_Function;
>

If the object is initialized, the storage requirement is known at 
compile type. My situation is a typical object orientation case as shown 
in a lot of examples where you have a (possibly abstract) base type and 
several extensions and where the dynamic type of a variable is not known 
at compile time. Classic example would be an inhomogeneous list (I know 
in practice you use a container for that, it is just an example).
My knowledge of Ada exceeds Ada 95 only by very little but I am pretty 
sure that in such a case one uses variables of a class-wide type, and as 
one cannot initialize them one has to declare them as access types.

Or, if I am wrong, what would be the best practice for that?
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19  1:48             ` hreba
@ 2015-08-19  5:10               ` Jeffrey R. Carter
  2015-08-19  8:44               ` Georg Bauhaus
  2015-08-19 20:53               ` Bob Duff
  2 siblings, 0 replies; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-19  5:10 UTC (permalink / raw)


On 08/18/2015 06:48 PM, hreba wrote:
> 
>> V : T'Class := Some_Function;
>
> If the object is initialized, the storage requirement is known at compile type.
> My situation is a typical object orientation case as shown in a lot of examples
> where you have a (possibly abstract) base type and several extensions and where
> the dynamic type of a variable is not known at compile time. Classic example
> would be an inhomogeneous list (I know in practice you use a container for that,
> it is just an example).
> My knowledge of Ada exceeds Ada 95 only by very little but I am pretty sure that
> in such a case one uses variables of a class-wide type, and as one cannot
> initialize them one has to declare them as access types.
> 
> Or, if I am wrong, what would be the best practice for that?

If an object is initialized by a function call, as above, the size is not known
at compile time. Consider

S : String := Ada.Text_IO.Get_Line;

The size of S is not known until run time. Thus it is often possible to use a
normal object declaration for a value of an indefinite type not known until run
time. Block statements are useful for delaying a declaration until then.

As Randy pointed out, an indefinite holder can be used as a variable of a
class-wide type. Holders were introduced in Ada 12, but it's easy enough to
write one if you're using an earlier compiler.

Your application code does not use access types in either case.

You'll need to use an access type to implement an indefinite holder, but such
use will be in a single place and so easier to get correct than with access
values scattered throughout your application

-- 
Jeff Carter
"Blessed are they who convert their neighbors'
oxen, for they shall inhibit their girth."
Monty Python's Life of Brian
83


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19  1:48             ` hreba
  2015-08-19  5:10               ` Jeffrey R. Carter
@ 2015-08-19  8:44               ` Georg Bauhaus
  2015-08-19 11:56                 ` hreba
  2015-08-19 20:53               ` Bob Duff
  2 siblings, 1 reply; 42+ messages in thread
From: Georg Bauhaus @ 2015-08-19  8:44 UTC (permalink / raw)


On 19.08.15 03:48, hreba wrote:
> My knowledge of Ada exceeds Ada 95 only by very little but I am pretty sure that in such a case one uses variables of a class-wide type, and as one cannot initialize them one has to declare them as access types.

The assumption that limited objects cannot be initialized like non-limited
(by sort of copying a value) is no longer true, and it wasn't the whole truth
in Ada 95.
There are cases when nothing but an access type will do. But due
to build-in-place, limited tagged objects can be declared and initialized,
by aggregate or by function call, using just traditional syntax as
Jeffrey Carter explains. This includes objects of a class-wide type,

Built-in-place (in situ), perhaps simplifying,  means that the limited
object is declared and passed/used behind the scenes, for initialization.
For example, the object that is declared becomes the to-be-returned
object if there is a function call after “:=” in the declaration.
(See "extended return" of Ada 2005.)

Given

package Classwide is

    type T0 is abstract tagged limited null record;

    type T1 is new T0 with private;
    function Make return T1;

    function Produce (Variant : Boolean) return T1'Class;

private
    type T1 is new T0 with
       record  -- note default values for "default construction"
          Name : Character := '?';
       end record;
end Classwide;

package body Classwide is
    type T2 is new T1 with
       record
          Count : Natural;
       end record;
    function Make return T2;

    function Make return T1 is
    begin
       return T1'(T0 with Name => '*');
    end Make;

    function Make return T2 is
    begin
       return T2'(T1'(Make) with Count => 0);
    end Make;

    function Produce (Variant : Boolean) return T1'Class is
    begin
       case Variant is
       when False =>
          return T1'(T0 with Name => 'T');
       when True =>
          return T2'(T0 with Name => 'F', Count => 0);
       end case;
    end Produce;
end Classwide;


Then, the type hierarchy above includes limited T0, T1, and invisible T2.
All of these types can be used to declare or create objects of specific
types and of class-wide types.

with Classwide;
procedure Main is
    use Classwide;
    X  : T1;
    C  : T1'Class := Make;
    CC : T1'Class := Produce (Variant => False);
    procedure Takes_T1C (Object : in T1'Class) is separate;
    procedure Mods_T1C (Object : in out T1'Class) is separate;
begin
    Takes_T1C (X);
    Takes_T1C (C);
    Takes_T1C (CC);
    Takes_T1C (Make);
    Takes_T1C (Produce (Variant => True));
    Mods_T1C (X);
    Mods_T1C (C);
    Mods_T1C (CC);
end Main;

The Ada Rationale will illustrate and explain.


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19  8:44               ` Georg Bauhaus
@ 2015-08-19 11:56                 ` hreba
  0 siblings, 0 replies; 42+ messages in thread
From: hreba @ 2015-08-19 11:56 UTC (permalink / raw)


On 08/19/2015 05:44 AM, Georg Bauhaus wrote:
> On 19.08.15 03:48, hreba wrote:
>> My knowledge of Ada exceeds Ada 95 only by very little but I am pretty
>> sure that in such a case one uses variables of a class-wide type, and
>> as one cannot initialize them one has to declare them as access types.
>
> The assumption that limited objects cannot be initialized like non-limited
> (by sort of copying a value) is no longer true, and it wasn't the whole
> truth
> in Ada 95.
> There are cases when nothing but an access type will do. But due
> to build-in-place, limited tagged objects can be declared and initialized,
> by aggregate or by function call, using just traditional syntax as
> Jeffrey Carter explains. This includes objects of a class-wide type,
>
> Built-in-place (in situ), perhaps simplifying,  means that the limited
> object is declared and passed/used behind the scenes, for initialization.
> For example, the object that is declared becomes the to-be-returned
> object if there is a function call after “:=” in the declaration.
> (See "extended return" of Ada 2005.)
>
> Given
>
> package Classwide is
>
>     type T0 is abstract tagged limited null record;
>
>     type T1 is new T0 with private;
>     function Make return T1;
>
>     function Produce (Variant : Boolean) return T1'Class;
>
> private
>     type T1 is new T0 with
>        record  -- note default values for "default construction"
>           Name : Character := '?';
>        end record;
> end Classwide;
>
> package body Classwide is
>     type T2 is new T1 with
>        record
>           Count : Natural;
>        end record;
>     function Make return T2;
>
>     function Make return T1 is
>     begin
>        return T1'(T0 with Name => '*');
>     end Make;
>
>     function Make return T2 is
>     begin
>        return T2'(T1'(Make) with Count => 0);
>     end Make;
>
>     function Produce (Variant : Boolean) return T1'Class is
>     begin
>        case Variant is
>        when False =>
>           return T1'(T0 with Name => 'T');
>        when True =>
>           return T2'(T0 with Name => 'F', Count => 0);
>        end case;
>     end Produce;
> end Classwide;
>
>
> Then, the type hierarchy above includes limited T0, T1, and invisible T2.
> All of these types can be used to declare or create objects of specific
> types and of class-wide types.
>
> with Classwide;
> procedure Main is
>     use Classwide;
>     X  : T1;
>     C  : T1'Class := Make;
>     CC : T1'Class := Produce (Variant => False);
>     procedure Takes_T1C (Object : in T1'Class) is separate;
>     procedure Mods_T1C (Object : in out T1'Class) is separate;
> begin
>     Takes_T1C (X);
>     Takes_T1C (C);
>     Takes_T1C (CC);
>     Takes_T1C (Make);
>     Takes_T1C (Produce (Variant => True));
>     Mods_T1C (X);
>     Mods_T1C (C);
>     Mods_T1C (CC);
> end Main;
>
> The Ada Rationale will illustrate and explain.
>

Thanks for your explications Jeffrey an Georg. Apparently Barnes: 
"Programming in Ada 95" is obsolete with respect to this topic (not 
regarding correctness, just best practices). What didactic text about 
object oriented programming in Ada would you recommend?

-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:15       ` Egil H H
@ 2015-08-19 13:07         ` hreba
  0 siblings, 0 replies; 42+ messages in thread
From: hreba @ 2015-08-19 13:07 UTC (permalink / raw)


On 08/18/2015 11:15 AM, Egil H H wrote:
>
>> Didn't know about extended return (the Ada 95 book was cheaper -:). But
>> there is a problem: the TB in my original program is not only tagged, it
>> is limited too (and New_TB is for initialization). So "foo.all:=..." is
>> forbidden.
>>
>
> Then "foo.A :=..."
> ...
>

Works now. Thanks for your help!
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:16       ` Jeffrey R. Carter
@ 2015-08-19 13:12         ` hreba
  2015-08-19 20:47         ` Bob Duff
  1 sibling, 0 replies; 42+ messages in thread
From: hreba @ 2015-08-19 13:12 UTC (permalink / raw)


On 08/18/2015 11:16 AM, Jeffrey R. Carter wrote:
> On 08/18/2015 05:23 AM, hreba wrote:
>>
>> I need an access type because in my real program TB is a tagged type and I need
>> class-wide variables.
>
> You do not /need/ access types for this. Avoiding them requires some thought,
> but that's what S/W engineers do.
>
>> Didn't know about extended return (the Ada 95 book was cheaper -:). But there is
>> a problem: the TB in my original program is not only tagged, it is limited too
>> (and New_TB is for initialization). So "foo.all:=..." is forbidden.
>
> If your type is limited then you will have to use an extended return for Ada >
> 95. Does
>
> return Foo : access TB :=
>     new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) );
>
> work?
>

This got me a GNAT BUG DETECTED message upon compilation.
Will follow the request to send a bug report.
I am happy with Egil's workaround.

Thanks for your hints and help.
-- 
Frank Hrebabetzky		+55 / 48 / 3235 1106
Florianopolis, Brazil

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-18 14:16       ` Jeffrey R. Carter
  2015-08-19 13:12         ` hreba
@ 2015-08-19 20:47         ` Bob Duff
  2015-08-19 21:47           ` Jeffrey R. Carter
  2015-08-20 20:48           ` Randy Brukardt
  1 sibling, 2 replies; 42+ messages in thread
From: Bob Duff @ 2015-08-19 20:47 UTC (permalink / raw)


"Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:

> On 08/18/2015 05:23 AM, hreba wrote:
>> 
>> I need an access type because in my real program TB is a tagged type and I need
>> class-wide variables.
>
> You do not /need/ access types for this. Avoiding them requires some thought,
> but that's what S/W engineers do.

I don't think it's fair to say that people who use access types
(i.e. pointers) aren't proper "S/W engineers".  It's true that Ada
doesn't require pointers in many cases where other languages do.
But Ada still requires pointers if the class-wide variable
needs to change its tag.  And pointers are required for recursive
data structures.  Etc.

I think what you and Randy have been saying (or should have been?)
is more like:

    1. Try to avoid using pointers.

    2. When you have to use them, try to encapsulate.

    3. When possible, use the encapsulations already provided by the
       language (i.e. the Ada.Containers).

But there are all sorts of reasons why Ada.Containers might not be
suitable, so in those cases, you WILL use pointers, preferably
encapsulated.  But that's different from saying "never use pointers"
(or "never use access types").

>> Didn't know about extended return (the Ada 95 book was cheaper -:). But there is
>> a problem: the TB in my original program is not only tagged, it is limited too
>> (and New_TB is for initialization). So "foo.all:=..." is forbidden.
>
> If your type is limited then you will have to use an extended return for Ada >
> 95. ...

I'm not sure what you mean by that.  There is no rule that return of a
limited type requires extended return.  This:

    return expression;

means exactly the same thing as:

    return Result : T := expression do
        null;
    end return;

whether T is limited or not.

You only need extended return when you want to have a name for the
function result (so you can assign into parts of it, for example).

And anyway, the example is returning an access value, which is not
limited.

> ...Does
>
> return Foo : access TB :=
>    new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) );
>
> work?

Maybe you were just hoping that the extended return version wouldn't
tickle the same compiler bug?  That's possible, but unlikely;
I didn't try it.

Anyway, that could be written:

    return new TB'( (A => TA'(Name => To_Unbounded_String (Name) ) );

and mean the same thing.

- Bob

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19  1:48             ` hreba
  2015-08-19  5:10               ` Jeffrey R. Carter
  2015-08-19  8:44               ` Georg Bauhaus
@ 2015-08-19 20:53               ` Bob Duff
  2 siblings, 0 replies; 42+ messages in thread
From: Bob Duff @ 2015-08-19 20:53 UTC (permalink / raw)


hreba <f_hreba@yahoo.com.br> writes:

> On 08/18/2015 11:16 AM, Jeffrey R. Carter wrote:
>> On 08/18/2015 07:02 AM, hreba wrote:
>>>
>>> Huh? As much as I know you cannot declare variables of a type with unknown
>>> storage requirements at compile time, such as class-wide types and arrays with
>>> unknown range.
>>
>> These are "indefinite types". You can declare an object of an indefinite type as
>> long as you supply an initialization expression:
>>
>> S : String := "Hello";
>>
>> V : T'Class := Some_Function;
>>
>
> If the object is initialized, the storage requirement is known at compile
> type.

No, as Jeff and Randy have pointed out, when you initialize an object
with a call to a function that returns an indefinite subtype (such as
String, or T'Class), the size of the object is determined at run time.
What's more, it's determined by the function body -- it is not known
in the callee until the function has returned.

But that only works if you can initialize the object on its
declaration.  Sometimes, the declaration needs to occur at
a certain place for visibility reasons, and only later is
initialized.  You need access types for that (possibly
encapsulated in Holders, or whatever).

It also doesn't work if the Tag needs to change.  In the above,
V'Tag is set to whatever Some_Function returns, and can never
be changed.

- Bob


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19 20:47         ` Bob Duff
@ 2015-08-19 21:47           ` Jeffrey R. Carter
  2015-08-20  7:18             ` Dmitry A. Kazakov
  2015-08-20 20:48           ` Randy Brukardt
  1 sibling, 1 reply; 42+ messages in thread
From: Jeffrey R. Carter @ 2015-08-19 21:47 UTC (permalink / raw)


On 08/19/2015 01:47 PM, Bob Duff wrote:
> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
>>
>> You do not /need/ access types for this. Avoiding them requires some thought,
>> but that's what S/W engineers do.
> 
> I don't think it's fair to say that people who use access types
> (i.e. pointers) aren't proper "S/W engineers".  It's true that Ada
> doesn't require pointers in many cases where other languages do.
> But Ada still requires pointers if the class-wide variable
> needs to change its tag.  And pointers are required for recursive
> data structures.  Etc.

I didn't say that people who use access types aren't proper S/W engineers. I
implied that people who use access types unnecessarily because they're unwilling
or unable to do the extra thinking needed to avoid aren't S/W engineers.

> I think what you and Randy have been saying (or should have been?)
> is more like:
> 
>     1. Try to avoid using pointers.
> 
>     2. When you have to use them, try to encapsulate.
> 
>     3. When possible, use the encapsulations already provided by the
>        language (i.e. the Ada.Containers).
> 
> But there are all sorts of reasons why Ada.Containers might not be
> suitable, so in those cases, you WILL use pointers, preferably
> encapsulated.  But that's different from saying "never use pointers"
> (or "never use access types").


Almost. Using an abstraction that happens to be implemented using pointers is
not the same as using pointers. The whole point of the abstraction is so the
user doesn't have to think in the terms of its implementation.

For example, when I write Ada, the compiler implements it in machine code. Ada
is an abstraction that allows me to not have to think in terms of machine code.
I consider it incorrect to refer to using Ada as using machine code. I also
think it's incorrect to refer to using an abstraction implemented with pointers
as using pointers.

So I'd probably say:

Before using pointers,

1. Try to use an existing abstraction that doesn't require using pointers, such
as Ada.Containers.

2. If that's not possible, try to create an abstraction that encapsulates the
use of pointers and doesn't require its user to use pointers.

3. If that's not possible, then see if there's anything else that will allow you
to avoid using pointers.

4. If that's not possible, then use pointers.

-- 
Jeff Carter
"Alms for an ex-leper!"
Monty Python's Life of Brian
75

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19 21:47           ` Jeffrey R. Carter
@ 2015-08-20  7:18             ` Dmitry A. Kazakov
  0 siblings, 0 replies; 42+ messages in thread
From: Dmitry A. Kazakov @ 2015-08-20  7:18 UTC (permalink / raw)


On Wed, 19 Aug 2015 14:47:41 -0700, Jeffrey R. Carter wrote:

> On 08/19/2015 01:47 PM, Bob Duff wrote:
>> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
>>>
>>> You do not /need/ access types for this. Avoiding them requires some thought,
>>> but that's what S/W engineers do.
>> 
>> I don't think it's fair to say that people who use access types
>> (i.e. pointers) aren't proper "S/W engineers".  It's true that Ada
>> doesn't require pointers in many cases where other languages do.
>> But Ada still requires pointers if the class-wide variable
>> needs to change its tag.  And pointers are required for recursive
>> data structures.  Etc.
> 
> I didn't say that people who use access types aren't proper S/W engineers. I
> implied that people who use access types unnecessarily because they're unwilling
> or unable to do the extra thinking needed to avoid aren't S/W engineers.

Actually it is the access type which require extra thinking. I remember how
hard it was to understand the meaning of C's declarations like char *argv[]

I think it is rather the first language which forms the ways of thinking of
future SW engineers. People coming from GC languages have no less strange
ideas than ones with a C background. (Good that functional languages are
not taught as massively as C and C# are (:-))

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: storage error: stack overflow
  2015-08-19 20:47         ` Bob Duff
  2015-08-19 21:47           ` Jeffrey R. Carter
@ 2015-08-20 20:48           ` Randy Brukardt
  1 sibling, 0 replies; 42+ messages in thread
From: Randy Brukardt @ 2015-08-20 20:48 UTC (permalink / raw)


"Bob Duff" <bobduff@theworld.com> wrote in message 
news:87k2srf1j8.fsf@theworld.com...
> "Jeffrey R. Carter" <spam.jrcarter.not@spam.not.acm.org> writes:
>
>> On 08/18/2015 05:23 AM, hreba wrote:
>>>
>>> I need an access type because in my real program TB is a tagged type and 
>>> I need
>>> class-wide variables.
>>
>> You do not /need/ access types for this. Avoiding them requires some 
>> thought,
>> but that's what S/W engineers do.
>
> I don't think it's fair to say that people who use access types
> (i.e. pointers) aren't proper "S/W engineers".  It's true that Ada
> doesn't require pointers in many cases where other languages do.
> But Ada still requires pointers if the class-wide variable
> needs to change its tag.  And pointers are required for recursive
> data structures.  Etc.
>
> I think what you and Randy have been saying (or should have been?)
> is more like:
>
>    1. Try to avoid using pointers.
>
>    2. When you have to use them, try to encapsulate.
>
>    3. When possible, use the encapsulations already provided by the
>       language (i.e. the Ada.Containers).
>
> But there are all sorts of reasons why Ada.Containers might not be
> suitable, so in those cases, you WILL use pointers, preferably
> encapsulated.  But that's different from saying "never use pointers"
> (or "never use access types").

I say "never* use access types in the visible part of a package 
specification". And do what you have to implement that specification. Bodies 
of any good abstraction tend to turn into a groddy mess (especially once 
performance considerations get into the mix). That doesn't mean that the 
specification (the interface) of the abstract has to also be a groddy mess!

The problem with putting access types in a specification is that you are 
then dictating how the client does storage management (they can no longer 
let a container or other abstraction do the management for them). That's the 
worst possible situation, letting the client decide on the optimal storage 
management for their uses is preferable, and the alternative of managing the 
storage within the abstraction is likely better as well.

* As with all programming rules, there never is an absolute rule. There 
probably is some case where putting an access type into a specification 
would be better than trying to work around it. If you have a strong 
justification for doing so (one that does not appeal to knowledge of some 
other programming language!!), then go ahead (and document the reasoning). 
We had to use one in Claw because we needed a version of the Parent function 
that had reference semantics for its return. (I recall that without that, 
some operation became an infinite regress of copying.) I agonized about that 
for weeks, but couldn't find a better solution. (The solution ended up being 
an encapsulated access value that was part of inspiration for generalized 
references and how they're used in the containers. We could have done that a 
lot better in Ada 2012, but there still would be an access type.)

                                                          Randy.



^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2015-08-20 20:48 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-11 21:53 storage error: stack overflow hreba
2015-08-11 22:19 ` Jeffrey R. Carter
2015-08-12 15:01   ` hreba
2015-08-12 16:00     ` AdaMagica
2015-08-12 17:51     ` Jeffrey R. Carter
2015-08-13  2:17       ` hreba
2015-08-12  8:27 ` briot.emmanuel
2015-08-13  1:34   ` hreba
2015-08-13  2:53     ` Jeffrey R. Carter
2015-08-13  7:05     ` Simon Wright
2015-08-14 13:53       ` hreba
2015-08-14 16:01         ` Simon Wright
2015-08-14 17:00         ` Simon Wright
2015-08-13  7:19     ` Simon Wright
2015-08-14 13:20       ` hreba
2015-08-12 10:31 ` Markus Schöpflin
2015-08-13  1:36   ` hreba
2015-08-12 10:57 ` Simon Wright
2015-08-13  0:55   ` hreba
2015-08-13  6:58     ` Simon Wright
2015-08-18  2:16 ` hreba
2015-08-18  5:49   ` Jeffrey R. Carter
2015-08-18  7:24   ` Egil H H
2015-08-18 12:23     ` hreba
2015-08-18 12:37       ` Jacob Sparre Andersen
2015-08-18 14:02         ` hreba
2015-08-18 14:11           ` Dmitry A. Kazakov
2015-08-18 14:16           ` Jeffrey R. Carter
2015-08-18 20:56             ` Randy Brukardt
2015-08-19  1:48             ` hreba
2015-08-19  5:10               ` Jeffrey R. Carter
2015-08-19  8:44               ` Georg Bauhaus
2015-08-19 11:56                 ` hreba
2015-08-19 20:53               ` Bob Duff
2015-08-18 14:15       ` Egil H H
2015-08-19 13:07         ` hreba
2015-08-18 14:16       ` Jeffrey R. Carter
2015-08-19 13:12         ` hreba
2015-08-19 20:47         ` Bob Duff
2015-08-19 21:47           ` Jeffrey R. Carter
2015-08-20  7:18             ` Dmitry A. Kazakov
2015-08-20 20:48           ` Randy Brukardt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox