www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - cast(string) for mutable array

reply Vindex9 <tech.vindex gmail.com> writes:
Is this code normal? Why can't it be marked with ` safe`? Can 
only `idup` be used for ` safe` in such cases?

```d
string fn()  trusted pure {
     char[] arr;
     // some manipulations...
     return cast(string) arr;
}
```

Where is the line between cases where the ` trusted` tag can be 
used and cases where the ` system` tag can be used?
Jul 31
next sibling parent reply user1234 <user1234 12.de> writes:
On Friday, 31 July 2026 at 13:52:12 UTC, Vindex9 wrote:
 Is this code normal? Why can't it be marked with ` safe`? Can 
 only `idup` be used for ` safe` in such cases?

 ```d
 string fn()  trusted pure {
     char[] arr;
     // some manipulations...
     return cast(string) arr;
 }
 ```

 Where is the line between cases where the ` trusted` tag can be 
 used and cases where the ` system` tag can be used?
The cast is not memory safe because it breaks the type system (`string` element-type is `immutable(char)` and `immutable` is part of the type). So callers may think that the elements are indeed immutable while they are actually allowed to change. But for a simple example like this it's obvious that the problem wont happen (i.e mutation of the elements), hence you can mark the function ` trusted`. spec: https://dlang.org/spec/memory-safe-d.html
Jul 31
next sibling parent reply "H. S. Teoh" <hsteoh qfbox.info> writes:
On Fri, Jul 31, 2026 at 02:53:23PM +0000, user1234 via Digitalmars-d-learn
wrote:
 On Friday, 31 July 2026 at 13:52:12 UTC, Vindex9 wrote:
 Is this code normal? Why can't it be marked with ` safe`? Can only
 `idup` be used for ` safe` in such cases?
 
 ```d
 string fn()  trusted pure {
     char[] arr;
     // some manipulations...
     return cast(string) arr;
 }
 ```
 
 Where is the line between cases where the ` trusted` tag can be used and
 cases where the ` system` tag can be used?
[...] If the function is pure, you should be able to just return char[] and the caller will be able to assign it to string. No need for a cast. Just specify the return type as `char[]`. T -- It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe?
Jul 31
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 01/08/2026 3:10 AM, H. S. Teoh wrote:
 On Fri, Jul 31, 2026 at 02:53:23PM +0000, user1234 via Digitalmars-d-learn
wrote:
 On Friday, 31 July 2026 at 13:52:12 UTC, Vindex9 wrote:
 Is this code normal? Why can't it be marked with ` safe`? Can only
 `idup` be used for ` safe` in such cases?

 ```d
 string fn()  trusted pure {
      char[] arr;
      // some manipulations...
      return cast(string) arr;
 }
 ```

 Where is the line between cases where the ` trusted` tag can be used and
 cases where the ` system` tag can be used?
[...] If the function is pure, you should be able to just return char[] and the caller will be able to assign it to string. No need for a cast. Just specify the return type as `char[]`. T
```d string foo(ref char[] val) pure { char[] temp; temp ~= '2'; val = temp; return cast(string)temp; } ``` And this is why it isn't special cased and allowed to happen. Pure in D isn't very strong.
Jul 31
prev sibling parent "H. S. Teoh" <hsteoh qfbox.info> writes:
On Fri, Jul 31, 2026 at 08:10:39AM -0700, H. S. Teoh via Digitalmars-d-learn
wrote:
 On Friday, 31 July 2026 at 13:52:12 UTC, Vindex9 wrote:
 Is this code normal? Why can't it be marked with ` safe`? Can only
 `idup` be used for ` safe` in such cases?
 
 ```d
 string fn()  trusted pure {
     char[] arr;
     // some manipulations...
     return cast(string) arr;
 }
 ```
 
 Where is the line between cases where the ` trusted` tag can be
 used and cases where the ` system` tag can be used?
[...] If the function is pure, you should be able to just return char[] and the caller will be able to assign it to string. No need for a cast. Just specify the return type as `char[]`.
[...] Proof of concept: ``` import std; char[] pureStringFunc() pure safe { // N.B. returns mutable char[] char[] arr; arr ~= "abc"; foreach (i; 0 .. 5) { arr ~= i.to!(char[]); } return arr; } void main() safe { string s = pureStringFunc(); // N.B. assigns to (immutable) string writeln(s); } ``` Output: ``` abc01234 ``` T -- How many guacas are in 1 guacamole? 6.022*10^23, also known as Avocado's Number.
Jul 31
prev sibling next sibling parent Nick Treleaven <nick geany.org> writes:
On Friday, 31 July 2026 at 13:52:12 UTC, Vindex9 wrote:
 ```d
 string fn()  trusted pure {
     char[] arr;
     // some manipulations...
     return cast(string) arr;
 }
 ```

 Where is the line between cases where the ` trusted` tag can be 
 used and cases where the ` system` tag can be used?
` trusted` must have a memory-safe interface. So if the elements of `arr` cannot be accessed as mutable after the cast, it is OK to use ` trusted` to cast them to immutable. ` system` is used for a function which does not have a safe interface (e.g. one that accepts a `char*` parameter pointing to a C zero-terminated string).
Jul 31
prev sibling parent reply Kagamin <spam here.lot> writes:
Works on my machine:
```
string test()  safe pure
{
	char[] a=[1];
	a[0]=2;
	return a;
}
```
Aug 01
parent reply Kagamin <spam here.lot> writes:
Such functions are known as strongly pure, and the return value 
of a strongly pure function is implicitly castable to immutable.
Aug 01
parent reply Vindex9 <tech.vindex gmail.com> writes:
OK, thank you all.
It's actually not very convenient to think about these things all 
the time. Over the years, I've gotten used to using ` system` by 
default. But now it turns out that you can almost always use 
` trusted`.
Aug 03
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, August 3, 2026 1:54:48 AM Mountain Daylight Time Vindex9 via
Digitalmars-d-learn wrote:
 OK, thank you all.
 It's actually not very convenient to think about these things all
 the time. Over the years, I've gotten used to using ` system` by
 default. But now it turns out that you can almost always use
 ` trusted`.
You frequently can, but remember that when you mark something as trusted, you're telling the compiler that you've verified that the code is memory-safe (whereas with safe, the compiler has verified that). So, if you mark code with trusted when it's not actually memory-safe, you make it so that safe code can call code which isn't memory-safe, and the safe code then isn't actually memory-safe. So, ideally, you'd do whatever system stuff you need to do within a function and encapsulate the system stuff in a way that you can mark the function as trusted and have an API which is memory-safe, but whether you can do that or not depends on what your code is doing. - Jonathan M Davis
Aug 03
parent Vindex9 <tech.vindex gmail.com> writes:
 You frequently can, but remember that when you mark something 
 as  trusted, you're telling the compiler that you've verified 
 that the code is memory-safe (whereas with  safe, the compiler 
 has verified that). So, if you mark code with  trusted when 
 it's not actually memory-safe, you make it so that  safe code 
 can call code which isn't memory-safe, and the  safe code then 
 isn't actually memory-safe.

 So, ideally, you'd do whatever  system stuff you need to do 
 within a function and encapsulate the  system stuff in a way 
 that you can mark the function as  trusted and have an API 
 which is memory-safe, but whether you can do that or not 
 depends on what your code is doing.

 - Jonathan M Davis
This is a really good explanation, thank you.
Aug 04