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.