On Friday, 28 January 2022 at 18:02:27 UTC, Iain Buclaw wrote:
For example, druntime depends on this behaviour.

Template: https://github.com/dlang/druntime/blob/a0ad8c42c15942faeeafb016e81a360113ae1b6b/src/rt/config.d#L46-L58

Ouch. From where I stand, this looks like some really ugly hack abusing both the template keyword and mangle pragma. Presumably intended to implement this part of the spec: https://dlang.org/library/rt/config.html

Moreover, these are even global variables rather than functions. Wouldn't it make more sense to use a special "weak" attribute for this particular use case? I see that there was a related discussion here: https://forum.dlang.org/post/rgmp5d$198g$1...@digitalmars.com

Regular symbol: https://github.com/dlang/druntime/blob/a17bb23b418405e1ce8e4a317651039758013f39/test/config/src/test19433.d#L1

If we can rely on instantiated symbols to not violate ODR, then you would be able to put symbols in the .link-once section. However all duplicates must also be in the .link-once section, else you'll get duplicate definition errors.

Duplicate definition errors are surely better than something fishy silently happening under the hood. They can be solved when/if we encounter them. That said, I can confirm that GDC 10 indeed fails with `multiple definition of 'rt_cmdline_enabled'` linker error when trying to compile:

```D
extern(C) __gshared bool rt_cmdline_enabled = false;
void main() { }
```

But can't GDC just use something like this in `rt/config.d` to solve the problem?
```D
version(GNU) {
    import gcc.attribute;
pragma(mangle, "rt_envvars_enabled") @attribute("weak") __gshared bool rt_envvars_enabled_ = false; pragma(mangle, "rt_cmdline_enabled") @attribute("weak") __gshared bool rt_cmdline_enabled_ = true; pragma(mangle, "rt_options") @attribute("weak") __gshared string[] rt_options_ = [];
    bool rt_envvars_enabled()() { return rt_envvars_enabled_; }
    bool rt_cmdline_enabled()() { return rt_cmdline_enabled_; }
    bool rt_options()() { return rt_options_; }
} else {
// put each variable in its own COMDAT by making them template instances
    template rt_envvars_enabled()
    {
pragma(mangle, "rt_envvars_enabled") __gshared bool rt_envvars_enabled = false;
    }
    template rt_cmdline_enabled()
    {
pragma(mangle, "rt_cmdline_enabled") __gshared bool rt_cmdline_enabled = true;
    }
    template rt_options()
    {
pragma(mangle, "rt_options") __gshared string[] rt_options = [];
    }
}
```

Reply via email to