www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Newbie style question about string constants

reply Ian <ian iangarcia.net> writes:
Hello,

What's the recommended D way to declare a string constant? Say, 
for example, for a path used inside a class constructor? I've 
seen const string, immutable, enum etc...

Is this the place for these kinds of questions? Is there a D 
stack overflow?

Cheers,
  Ian
Feb 24
next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Monday, 24 February 2025 at 16:07:07 UTC, Ian wrote:
 Hello,

 What's the recommended D way to declare a string constant? Say, 
 for example, for a path used inside a class constructor? I've 
 seen const string, immutable, enum etc...
enum vs value is a tradeoff of when a decision is made; not some oo thoery If something is known compile time and you cant even consider how it would change, make it an enum and your have less runtime errors, dodge some conversions, allow more free optimization ~~const and immutable can be deleted from the language~~
Feb 24
prev sibling next sibling parent reply Elias Batek (0xEAB) <desisma heidel.beer> writes:
On Monday, 24 February 2025 at 16:07:07 UTC, Ian wrote:
 Hello,

 What's the recommended D way to declare a string constant? Say, 
 for example, for a path used inside a class constructor? I've 
 seen const string, immutable, enum etc...

 Is this the place for these kinds of questions? Is there a D 
 stack overflow?

 Cheers,
  Ian
For string constants you’ll usually want to mark them as `static immutable`. Strings with this combination will usually be put into read-only sections (ROM) of the resulting binaries. Unlike `static immutable` which specifies that data exists once in a specific location, `enum` (“compile-time constant”) is more similar to copy & paste where the compiler inserts the value into each location where it is referred to.
Feb 24
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, February 24, 2025 11:19:48 AM MST Elias Batek (0xEAB) via
Digitalmars-d-learn wrote:
 For string constants you’ll usually want to mark them as `static
 immutable`. Strings with this combination will usually be put
 into read-only sections (ROM) of the resulting binaries.

 Unlike `static immutable` which specifies that data exists once
 in a specific location, `enum` (“compile-time constant”) is more
 similar to copy & paste where the compiler inserts the value into
 each location where it is referred to.
When an enum is used, it's replaced with the value of the enum, so it's not strictly copy-paste. Any functions that were called to produce that value are called at compile time. The issue that you run into with most arrays is that you then get a different copy of that array (so a new allocation) every time that you use the enum (so it is copy-paste in that sense). However, with strings, that doesn't happen. You only end up with one allocation, and everywhere that you use the enum, it uses the same string. It's just that unlike an actual variable, it's an rvalue, so you can't take its address. I'm not aware of any reason to prefer a static immutable string over an enum unless you actually need to take its address for some reason. - Jonathan M Davis
Feb 24
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, February 24, 2025 9:07:07 AM MST Ian via Digitalmars-d-learn wrote:
 Hello,

 What's the recommended D way to declare a string constant? Say,
 for example, for a path used inside a class constructor? I've
 seen const string, immutable, enum etc...

 Is this the place for these kinds of questions? Is there a D
 stack overflow?
For strings, the way that you normally do constants is with enum, e.g enum foo = "dlang"; An enum like this is called a manifest constant. And you use manifest constants for most constants in D, with the caveat that for anything other than a string which involves an allocation, you probably don't want to use an enum. That's because enums are not variables, and their values are essentially copy-pasted wherever they're used. So, if you do something like enum foo = [1, 2, 3]; everywhere that you use foo, it'll be the same as if you used [1, 2, 3] directly. And because [1, 2, 3] allocates a new array, that means that each use of the enum allocates a new array. In such a situation, using a static variable would be better, e.g. static immutable foo = [1, 2, 3]; That does create a variable, so wherever you use foo, the array is sliced (so you get two arrays referring to the same piece of memory) rather than resulting in a new allocation. However, for strings, this is not an issue. This is because the compiler stores string literals directly in the program (in the ROM section of the binary on some OSes) and then slices that memory rather than allocating a new string every time you use the string literal. So, if you used "dlang" all over your program, you wouldn't get any allocations (unlike with [1, 2, 3]). And using an enum that's a string has the same result. So, typically, enums are used for constants which are strings - the same with int and other types which involve no allocations - whereas for other types of arrays, an immutable static variable is generally better. - Jonathan M Davis
Feb 24
parent reply Ian <ian iangarcia.net> writes:
On Tuesday, 25 February 2025 at 00:34:45 UTC, Jonathan M Davis 
wrote:
 For strings, the way that you normally do constants is with 
 enum, e.g

     enum foo = "dlang";

 An enum like this is called a manifest constant. And you use 
 manifest constants for most constants in D, with the caveat 
 that for anything other than a string which involves an 
 allocation, you probably don't want to use an enum. That's 
 because enums are not variables, and their values are 
 essentially copy-pasted wherever they're used. So, if you do 
 something like

      enum foo = [1, 2, 3];

 everywhere that you use foo, it'll be the same as if you used 
 [1, 2, 3] directly. And because [1, 2, 3] allocates a new 
 array, that means that each use of the enum allocates a new 
 array. In such a situation, using a static variable would be 
 better, e.g.

     static immutable foo = [1, 2, 3];

 That does create a variable, so wherever you use foo, the array 
 is sliced (so you get two arrays referring to the same piece of 
 memory) rather than resulting in a new allocation.

 [. . .]
Somehow I missed all of these responses. Thank you. It seems that in some cases static immutable is preferred, so why not use that always then, rather than having to keep two cases in my head? Ian
Mar 16
next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 16, 2025 9:22:04 AM MDT Ian via Digitalmars-d-learn wrote:
 On Tuesday, 25 February 2025 at 00:34:45 UTC, Jonathan M Davis
 wrote:
 For strings, the way that you normally do constants is with
 enum, e.g

     enum foo = "dlang";

 An enum like this is called a manifest constant. And you use
 manifest constants for most constants in D, with the caveat
 that for anything other than a string which involves an
 allocation, you probably don't want to use an enum. That's
 because enums are not variables, and their values are
 essentially copy-pasted wherever they're used. So, if you do
 something like

      enum foo = [1, 2, 3];

 everywhere that you use foo, it'll be the same as if you used
 [1, 2, 3] directly. And because [1, 2, 3] allocates a new
 array, that means that each use of the enum allocates a new
 array. In such a situation, using a static variable would be
 better, e.g.

     static immutable foo = [1, 2, 3];

 That does create a variable, so wherever you use foo, the array
 is sliced (so you get two arrays referring to the same piece of
 memory) rather than resulting in a new allocation.

 [. . .]
Somehow I missed all of these responses. Thank you. It seems that in some cases static immutable is preferred, so why not use that always then, rather than having to keep two cases in my head?
You can do whatever you want, but static immutable variables are variables, and enums are not, so they behave differently. And if you don't understand the differences, you could have problems understanding code that other people write or understanding why the compiler lets you do something in one case but not another. In any case, the normal way in D to declare a string constant is to use enum. So, that's primarily what you're going to see in most code. Whether you choose to do that in your own code is up to you. - Jonathan M Davis
Mar 17
parent Ian <ian iangarcia.net> writes:
On Monday, 17 March 2025 at 08:27:17 UTC, Jonathan M Davis wrote:
 In any case, the normal way in D to declare a string constant 
 is to use enum. So, that's primarily what you're going to see 
 in most code. Whether you choose to do that in your own code is 
 up to you.

 - Jonathan M Davis
Hi Jonathan, That all makes sense. enum it is, with the caveat for allocations. Just asking. Thanks, Ian
Mar 17
prev sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Sunday, 16 March 2025 at 15:22:04 UTC, Ian wrote:
 It seems that in some cases static immutable is preferred, so 
 why not use that always then, rather than having to keep two 
 cases in my head?
Enum is the indispensable one, immutable isnt important just theres a subsection of the community that has 12 words for safety, and needs to write at least 1 a line.
Mar 17
prev sibling parent reply cc <us86kj+3rxcwe3ebdv7w grr.la> writes:
On Monday, 24 February 2025 at 16:07:07 UTC, Ian wrote:
 Hello,

 What's the recommended D way to declare a string constant? Say, 
 for example, for a path used inside a class constructor? I've 
 seen const string, immutable, enum etc...

 Is this the place for these kinds of questions? Is there a D 
 stack overflow?

 Cheers,
  Ian
I got in the habit of using `static immutable` whenever possible as enum just can't be trusted to use CTFE. ```d enum string RfuncName = fullyQualifiedName!... enum string funcName = RfuncName.crc32Of.toHexString(); // Oops! Allocates on runtime every frame this is referenced ```
Mar 26
parent FeepingCreature <feepingcreature gmail.com> writes:
On Thursday, 27 March 2025 at 06:20:25 UTC, cc wrote:
 I got in the habit of using `static immutable` whenever 
 possible as enum just can't be trusted to use CTFE.

 ```d
 enum string RfuncName = fullyQualifiedName!...
 // Oops! Allocates on runtime every frame this is referenced
 enum string funcName = RfuncName.crc32Of.toHexString();
 ```
Woah! I was like "this surely can't be right" but it is... array literal per use because of the implicit string conversion, wow. File a bug for that? Amusingly, this works correctly: `enum string funcName = RfuncName.crc32Of.toHexString().idup;`
Mar 30