Interestingly enough I asked now having a reasonable idea of the answer if ‘Image uses the secondary stack.
_______________________________________
Notebooklm grounded in the ARM stated that
_______________________________________
“Based on the sources, the term “secondary stack” is not explicitly used in relation to the Image attribute. However, the mechanism by which Image functions operate, and certain implementation requirements, provide insight into their memory usage.
Specifically:
• The S'Image attribute, along with S'Wide_Image and S'Wide_Wide_Image, functions by calling S'Put_Image.
• The S'Put_Image procedure typically stores a sequence of character values in a text buffer.
• After S'Put_Image populates this buffer, the S'Image function then retrieves the contents from that buffer using a Get function (e.g., Get for S'Image, Wide_Get for S'Wide_Image, Wide_Wide_Get for S'Wide_Wide_Image).
Regarding memory allocation for this text buffer, the sources state:
• If a Max_Image_Length restriction applies to any compilation unit in a partition, then S'Image, S'Wide_Image, and S'Wide_Wide_Image shall be implemented without any dynamic allocation within that partition.
While the sources do not use the specific term “secondary stack,” the requirement to implement image attributes without dynamic allocation when the Max_Image_Length restriction is in effect implies that the buffer used by S'Put_Image would need to be allocated on the primary call stack of the executing task or in a statically allocated region of memory, rather than on the heap (which is typically what “dynamic allocation” refers to in this context).
General mentions of stack usage in the sources relate to:
• The Storage_Size attribute for a task object, which denotes the number of storage elements reserved for the task, including the size of its stack.
• The possibility that objects created by allocators, when passed as actual parameters to an access parameter, may be allocated on the stack and automatically reclaimed.
• Requirements for implementations to document the minimum stack space necessary for interrupt handlers.
• Documentation requirements for reviewable programs to identify the length of fixed-size and non-fixed-size portions of memory reserved on a run-time stack for constructs like subprograms and tasks.
In summary, the sources indicate that S'Image uses an internal text buffer, and under the Max_Image_Length restriction, this buffer must avoid dynamic allocation. While the specific term “secondary stack” is not used, this restriction suggests that the buffer would reside on a stack or in static memory if dynamic allocation is disallowed.“
____________________________________________
CoPilot/ChatGPT came up with this including the incorrect statements like the light runtime does not have secondary stack support. Unbounded strings aren’t available for the user to use in the light runtime.
____________________________________________
In Ada, 'Image is an attribute that produces a string representation of a value — for example, Integer'Image(42) yields " 42" (note the leading space for positive numbers).
Whether 'Image uses a secondary stack depends on your Ada implementation and run‑time model, but in most modern GNAT‑based compilers:
-
'Image is implemented as a function that returns a String.
-
The compiler typically allocates that string in the secondary stack (also called the secondary storage pool) rather than the main call stack.
-
This is because the size of the string is determined at run time, and the secondary stack lets Ada handle variable‑length temporaries without fixed frame allocations.
-
The exact mechanism can vary — with optimizations, some small 'Image results might be placed in registers or on the primary stack.
Why it matters:
If you’re working in an environment where the secondary stack is small or fragmented, heavy use of 'Image (especially in loops or on large arrays) can cause stack‑space pressure. In those cases, you might want to:
-
Reuse a preallocated buffer and use 'Wide_Wide_Image-like logic manually.
-
Convert values to strings via Ada.Text_IO into an existing string or buffer.
-
Control secondary stack use with compiler switches (-gnatS, -gnatD, etc. in GNAT to inspect allocations).
If you let me know which Ada compiler or environment you’re using, I can give you more specific behaviour details for 'Image in that context.
“Ah, that changes things quite a bit. In the light runtime profile, Ada’s run‑time library is slimmed down — which affects how 'Image and other string‑producing attributes are handled.
Here’s the key difference:
-
No secondary stack support:
The light runtime omits the usual secondary stack mechanism that the full GNAT run‑time uses for unconstrained temporaries. That means 'Image can’t quietly allocate a variable‑length string there.
-
Static or heap allocation instead:
In this profile, 'Image typically allocates the return string on the heap via Ada.Strings.Unbounded‑style routines, or uses static buffers inside generated code if the maximum size is known at compile‑time (e.g., for fixed‑range discrete types).
-
Implication for your code:
-
You won’t hit secondary stack exhaustion, but you can incur dynamic heap allocations every time you call 'Image.
-
On small or embedded targets, that can create heap‑fragmentation risks or latency spikes.
-
If deterministic memory usage is important, you’ll want to avoid repeated 'Image calls in tight loops, and instead reuse preallocated buffers.
Possible workarounds in light runtime:
-
Use Ada.Text_IO into a pre‑allocated buffer.
-
Implement a custom integer‑to‑string or enumeration‑to‑string conversion that writes directly into an existing array.
-
Profile memory usage — heap use is your main pressure point here.
If you tell me which target/board you’re compiling for, I can suggest patterns that completely avoid heap allocation in the light profile.“