3 ms·
From the documentation you linked, it seems slicing creates a brand new String, which is more like std::string than std::string_view. In other words, it allocat
by whytevuhuni 1y ago
From the documentation you linked, it seems slicing creates a brand new String, which is more like std::string than std::string_view. In other words, it allocates and copies all of the string's characters (although it might allocate on and copy those bytes to the stack).
Also, the Unbounded_String owns its copy of the data, as opposed to referencing other data. The difference with String seems to be just that it can grow. It's still more like std::string than std::string_view.
Note that both std::string and std::string_view are essentially just a pointer and a length (std::string also has a capacity but let's ignore that). The difference is that trying to duplicate a std::string will end up duplicating (deep-copying) the data behind the pointer as well, where as duplicating a std::string_view will not.
Could you help me understand/interpret that link the same way you do, in case I'm missing something?
- shakna 1y agoAllocating a new String, requires... "new String". You issue the "new" command, or the source does. But what Unbounded does is... "U.Reference (U.First .. U.Last)". It returns a reference. It's not duplicating, because that would defeat the point of its entire existence. Its the buffer, containing one or more string objects, and you're just slicing a reference out of it - because that's the point. If you want a String, you need to allocate one. function Slice (Source : in Unbounded_String; Low : in Positive; High : in Natural) return String; For this - there is no `out` marked. What you're grabbing is part of Unbounded, and the compiler won't let you deallocate it. Because it's owned, as a reference, to the Unbounded String. For example, here's the actual GNAT source of the function [1]: function Slice (Source : Unbounded_String; Low : Positive; High : Natural) return String is begin -- Note: test of High > Length is in accordance with AI95-00128 if Low - 1 > Source.Last or else High > Source.Last then raise Index_Error; else return Source.Reference (Low .. High); end if; end Slice; A pre-existing reference is returned. There is no allocation that happens whatsoever. [1] https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgnat/a-strunb.adb#L968C1-L981C14 https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgna...
- whytevuhuni 1y agoI tried to get some sort of proof based on Godbolt, to see if it generates any memcpy's, but I couldn't manage to do that after quite a few tries. :( It's really difficult to understand this given how much I know about Ada, so the best I can do is to keep throwing questions at ChatGPT. And I keep getting results that go against what you said. I've also tried a couple direct review examples from o4-mini-high, one without the documentation link [1] and one with it [2]. It matches what I've managed to learn as well. I know how LLMs work and that they hallucinate a lot, so I can't tell who here is wrong, since you seem to be really experienced, and I barely know anything... what are your thoughts? Oh, and I really appreciate you walking me though this! Like, a lot a lot! Thank you very much! [1] https://chatgpt.com/share/684341e3-8e20-8012-b8d0-9847742af907 https://chatgpt.com/share/684341e3-8e20-8012-b8d0-9847742af9... [2] https://chatgpt.com/share/68434538-fe24-8012-bdb7-b07db343718e https://chatgpt.com/share/68434538-fe24-8012-bdb7-b07db34371...
- shakna 1y agoNever, ever, throw any non mainstream language at an LLM. You will get absolutely nothing but bullshit back. They do not comprehend, and so they cannot move away from generalisation to actually speak about the language. There is not a large enough public source to train the model. If you're throwing something to a con-artist, don't be surprised if everything you get back does not line up with reality. EDIT: Here's a simple example on godbolt: https://godbolt.org/z/hcxhvGnTc https://godbolt.org/z/hcxhvGnTc As you can see, it just returns a pointer. No copying happens. There's a different length marked along with the pointer, but that's it.
- whytevuhuni 1y agoI see it does what you're saying on the "else" branch, but that just returns the previous string unmodified, which makes sense. The more important one is the "if" branch though. Looking at your Godbolt example's assembly, even if I add -O3, I see it does a call to "ada__strings__unbounded__unbounded_slice", but until I know the contents of that I can't say whether the pointer it returns is derived from the same allocation as the original one, or from a new allocation that the string was copied to. You're using the Unbounded_Slice function [1], which calls To_Unbounded_String [2], which calls `new String` [3], which you mentioned in a previous comment that it will allocate, right? The kind of operation I'm looking for is something like a "Trim_Whitespace" function that re-uses the old allocation without copying all the data, even when there is whitespace to trim. [1] https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgnat/a-strunb.adb#L1150 https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgna... [2] https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgnat/a-strunb.adb#L1030 https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgna... [3] https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgnat/a-strunb.adb#L1037 https://github.com/gcc-mirror/gcc/blob/master/gcc/ada/libgna...