On Friday, 28 January 2022 at 18:02:27 UTC, Iain Buclaw wrote:
>For example, druntime depends on this behaviour.
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:
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?
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 = [];
}
}