Thread overview
Dude! Where's my string constant?
Jan 23, 2007
kris
Jan 23, 2007
Frits van Bommel
Jan 24, 2007
kris
Jan 24, 2007
Frits van Bommel
Jan 24, 2007
kris
January 23, 2007
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?

January 23, 2007
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.
January 23, 2007
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
January 24, 2007
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



January 24, 2007
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?)
January 24, 2007
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