www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Dude! Where's my string constant?

reply kris <foo bar.com> writes:
Does D have a compile-time string constants? One that doesn't wind up in 
the obj file when it is unused?

const char[] Foo = "foo";

Apparently resides in the object file, used or not. Just like const int 
does. For true compile-time integer constants, we're supposed to use 
enum -- but what of strings? Enum currently doesn't like char[] :)

Suggestions for faking it include:

* char[] Foo() { return "foo"; }
* template Foo { const Foo="foo"; }

The former *should* get removed by the linker as unused, while the 
latter apparently gets eliminated by way of lack-of-expansion.

However, going to these lengths is surely counter-intuitive?
Jan 23 2007
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
kris wrote:
 Does D have a compile-time string constants? One that doesn't wind up in 
 the obj file when it is unused?
 
 const char[] Foo = "foo";
 
 Apparently resides in the object file, used or not. Just like const int 
 does. For true compile-time integer constants, we're supposed to use 
 enum -- but what of strings? Enum currently doesn't like char[] :)
 
 Suggestions for faking it include:
 
 * char[] Foo() { return "foo"; }

Only works if *no* string constant in the module is used. They're all put into .rodata, which is only thrown away if it's not referenced *at all*.[1]
 * template Foo { const Foo="foo"; }

This string will not be created until Foo is instantiated, and is put into a separate linkonce section (which can be removed if unused)[1]. Good find :). Note: this won't happen if the member is declared char[], it needs to be the (automatically-deduced) static array.
 The former *should* get removed by the linker as unused, while the 

It isn't necessarily, as noted above.
 latter apparently gets eliminated by way of lack-of-expansion.

Yep.
 However, going to these lengths is surely counter-intuitive?

Yes it is. What happens for the second one when instantiated should really happen by default for all strings (i.e. be put into separate sections). [1]: Usual disclaimer: on Linux, using ld --gc-sections. I know not of OMF & optlink :P.
Jan 23 2007
parent reply kris <foo bar.com> writes:
Frits van Bommel wrote:
 kris wrote:

 However, going to these lengths is surely counter-intuitive?

Yes it is. What happens for the second one when instantiated should really happen by default for all strings (i.e. be put into separate sections).

Indeed; along with init-data for structs and so on. That would resolve the currently issue with the Win32 header bloat
Jan 23 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
kris wrote:
 Frits van Bommel wrote:
 kris wrote:

 However, going to these lengths is surely counter-intuitive?

Yes it is. What happens for the second one when instantiated should really happen by default for all strings (i.e. be put into separate sections).

Indeed; along with init-data for structs and so on. That would resolve the currently issue with the Win32 header bloat

Hmm... Not only would it fix the bloat, I think it would also remove the requirement to even link to the compiled headers. The only reason that was needed were struct initializers, right? (enums are used for constants?)
Jan 23 2007
parent kris <foo bar.com> writes:
Frits van Bommel wrote:
 kris wrote:
 
 Frits van Bommel wrote:

 kris wrote:

[snip]
 However, going to these lengths is surely counter-intuitive?

Yes it is. What happens for the second one when instantiated should really happen by default for all strings (i.e. be put into separate sections).

Indeed; along with init-data for structs and so on. That would resolve the currently issue with the Win32 header bloat

Hmm... Not only would it fix the bloat, I think it would also remove the requirement to even link to the compiled headers. The only reason that was needed were struct initializers, right? (enums are used for constants?)

Yep; that is how I understand it. But was hoping Walter would care to elaborate carefully in a reply to this very question posted earlier, in the related Win32 thread? BTW: this is how the POINT p = void; syntax manages to sneak under the linker radar -- there's no init_data needed for such decls
Jan 23 2007
prev sibling parent Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
kris wrote:
 Does D have a compile-time string constants? One that doesn't wind up in 
 the obj file when it is unused?
 
 const char[] Foo = "foo";
 
 Apparently resides in the object file, used or not. Just like const int 
 does. For true compile-time integer constants, we're supposed to use 
 enum -- but what of strings? Enum currently doesn't like char[] :)
 
 Suggestions for faking it include:
 
 * char[] Foo() { return "foo"; }
 * template Foo { const Foo="foo"; }
 
 The former *should* get removed by the linker as unused, while the 
 latter apparently gets eliminated by way of lack-of-expansion.
 
 However, going to these lengths is surely counter-intuitive?
 

Personally, I've always thought it would be useful if enums could take any type as base. So then you would just: enum : char[] { Foo = "foo"c } I vaguely recall posting about this a few years ago and getting a generally negative response. -- Chris Nicholson-Sauls
Jan 23 2007