String copying fails when output from assert

Jonathan M Davis newsgroup.d at jmdavisprog.com
Tue Nov 21 19:05:21 UTC 2017


On Tuesday, November 21, 2017 18:49:40 David Zhang via Digitalmars-d-learn 
wrote:
> Hi,
>
> I've been trying to copy a string, then output it from an
> `assert(false)` statement, but the copy seems to be corrupted
> somehow.
>
> void main()
> {
>   string str = "some string";
>
>          //initializing `chars` with any value doesn't do anything
>   char[64] chars;
>   //char[64] chars = '!';
>
>   //memcpy doesn't work either, though the output's different
>   //import core.stdc.string;
>   //memcpy(&chars[0], &str[0], str.length);
>
>   chars[0..str.length] = str;
>   assert(false, chars[0..str.length]);
> }
>
> What am I missing here?

Well, the assertion is going to throw an AssertError, which takes a string
for its message. It doesn't copy the contents of the string. It's just
taking a slice just like whenever you pass a string to any other function.
So, it refers to the same memory as what's passed in. So, if what it's
passed is a string that refers to memory on the stack, then when it goes to
print the message, it's going to be garbage, because the stack was unwound,
and the static array is gone.

Honestly, I'd argue that it's a bug that it allows you provide a message as
a char[] instead of immutable(char)[]. It seems that the compiler is
implicitly converting char[] to immutable(char)[] in this case, which is
very bad. It would matter less if you were giving the assertion a char[]
that referred to memory on the heap, but it still shouldn't be allowed.

You really should be giving assertions a value that is an actual string that
lives on the heap when providing a message, not a char[], and definitely not
a char[] that's a slice of a static array.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list