Thread overview
Question for compiler gurus about compile-time strings
Dec 09, 2017
Stefan Koch
Dec 10, 2017
Jonathan M Davis
December 09, 2017
I was thinking that all strings generated at compile-time have a null-terminator added. But then I thought, wait, maybe that's only specifically for string literals.

What is the true answer? If you generate a string, let's say via a CTFE call, does it have a null terminator?

-Steve
December 09, 2017
On Saturday, 9 December 2017 at 18:45:18 UTC, Steven Schveighoffer wrote:
> I was thinking that all strings generated at compile-time have a null-terminator added. But then I thought, wait, maybe that's only specifically for string literals.
>
> What is the true answer? If you generate a string, let's say via a CTFE call, does it have a null terminator?
>
> -Steve

The results of CTFE calls are literals. Therefore they are treated the same.
Thus the answer to your question is yes.

However there might be rare corner-cases in which the null termiantor is not there.
Should this happen please file a bug and sent me a mail specifically.
December 09, 2017
On Saturday, December 09, 2017 23:38:46 Stefan Koch via Digitalmars-d-learn wrote:
> On Saturday, 9 December 2017 at 18:45:18 UTC, Steven
>
> Schveighoffer wrote:
> > I was thinking that all strings generated at compile-time have a null-terminator added. But then I thought, wait, maybe that's only specifically for string literals.
> >
> > What is the true answer? If you generate a string, let's say via a CTFE call, does it have a null terminator?
> >
> > -Steve
>
> The results of CTFE calls are literals. Therefore they are
> treated the same.
> Thus the answer to your question is yes.
>
> However there might be rare corner-cases in which the null
> termiantor is not there.
> Should this happen please file a bug and sent me a mail
> specifically.

My initial reaction was that of course the null terminator wouldn't be there if it wasn't an actual string literal, but I tested it, and it was, but then when I thought it through some more, there really isn't any difference in the generated string between these options:

enum str = "hello world";

enum str = "hello" ~ " world";

string foo()
{
    string retval = "hello wor";
    retval ~= 'l';
    retval ~= 'd';
    return retval;
}

enum str = foo();

In all cases, the compiler has to execute what's on the right-hand side to generate the value, and in all cases, it would go where string literals go in the binary, because there really isn't any difference from the compiler's perspective at that point (at least not from what I understand). Aside from the function call case, it probably even generates pretty much the same binary (whether the function call case would depend on whether the linker removed the function from the binary).

I tried to think of a case where the result wouldn't be equivalent to a string literal, and I couldn't think of any. I didn't really want to make any statements about what was guaranteed though, since I'm not a compiler dev and not very familiar with the compiler internals.

- Jonathan M Davis