6 ms·
But doesn't this copy the entirety of that slice? That's not what I meant, I was referring to a shared reference, akin to &str in Rust or std::string_view in C+
by whytevuhuni 1y ago
But doesn't this copy the entirety of that slice? That's not what I meant, I was referring to a shared reference, akin to &str in Rust or std::string_view in C++.
- LegionMammal978 1y agoDoing it normally should create a copy of the value, as far as I can tell. Unless you use it to create a renamed variable or by-reference parameter, the same way you can create references in C++. I think the closest thing to a &str in Ada would be an "access String" or "access constant String", which you would get either from an allocated "String" or from a declared "aliased String". You'd create a subslice with "string(x..y)'Access". Though I'm not sure whether that actually works without explicitly declaring an array of "aliased Character", the Manual is dense (as with C++, it's nearly meaningless unless you already know what it's supposed to mean) and the tutorials generally avoid talking about access objects.
- whytevuhuni 1y agoThank you! I assume 'Access types are not memory-safe, right? Is there a SPARK equivalent which still does not copy (i.e. it only references) that is memory safe? To be more specific, how would one implement something like a "Get_First_Word" or "Trim_Whitespace" without copying?
- LegionMammal978 1y agoI think it's supposed to be safe in Ada by default? As far as I can tell, basic allocated objects cannot be deallocated without an "unchecked" operation, and access objects created from "aliased" declarations are subject to scoping rules [0]. (If you want to know the full details, go figure out however "accessibility levels" are supposed to work [1].) It should preclude functions from returning access objects without a "prefix'Unchecked_Access" operation. I'm not sure how SPARK's borrowing system is tied into all of this. [0] https://www.adaic.org/resources/add_content/docs/craft/html/ch11.htm https://www.adaic.org/resources/add_content/docs/craft/html/... [1] http://www.ada-auth.org/standards/22rm/html/RM-3-10-2.html http://www.ada-auth.org/standards/22rm/html/RM-3-10-2.html
- shakna 1y agoThat's for String, not the referenced Unbounded String.
- shakna 1y agoIt's a slice, with basically the same implementation as std::string_view. [0] If you want a copy, with Unbounded String, you'll need to call To_String on the slice. [0] https://sites.radford.edu/~nokie/classes/320/std_lib_html/ada-strings-unbounded.html#46 https://sites.radford.edu/~nokie/classes/320/std_lib_html/ad...
- whytevuhuni 1y agoFrom 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...