On Tuesday, 14 March 2023 at 05:47:35 UTC, Jeremy wrote:
Hi, in C and C++ you can use #define to substitute a value in place of an identifier while preprocessing. If you initialize a new string and don't change its value after that, will the compiler substitute the string identifier with its value, like #define in C, or will it make a string in memory and refer to that?

Manifest constants in D have a similar effect as #defined values, e.g.:

```d
enum someVal = 10;

writeln(someVal);
```

Here, the effect is the same as if you'd written `writeln(10)`. The difference is that with the preprocessor, it's a text replacement on the source before the compiler gets ahold of it, but in D the compiler handles the substitution internally.

The same is true for string literals:

```d
enum str = "Hello";
writeln(str);
```

String literals get special treatment from the compiler in that they are "interned".

```d
auto s1 = "What's up?";
auto s2 = "What's up?";
```

The literal "What's up?" *should* be stored in the binary only once, so both s1 and s2 will point to the same location. Substitute a manifest constant and the effect should be the same:

```d
enum greeting = "What's up?";
auto s1 = greeting;
auto s2 = greeting;
```

Just be aware that there's a consequence for array literals:

```d
enum vals = [1, 2, 3];

auto a1 = vals;
auto a2 = vals;
```

This allocates two dynamic arrays, not one. Everywhere you use `vals` it's just like using the literal directly, which usually means an allocation.


Reply via email to