Run-time initialised static variables
dekevin
dekevin at student.ethz.ch
Wed Feb 7 12:10:38 UTC 2018
On Wednesday, 7 February 2018 at 00:31:01 UTC, Jonathan M Davis
wrote:
> On Tuesday, February 06, 2018 23:50:52 dekevin via
> Digitalmars-d-learn wrote:
>> Thanks a lot! I will change all my initialisations to static
>> constructors now.
>
> I should point out that the downside to static constructors is
> that if you have modules that recursively depend on each other,
> the program throws an Error at startup, because the runtime
> can't determine the correct order of initialization. So, while
> static constructors can be very useful, you do have to be
> careful with them.
>
>> The only additional problem I have, is that ℚInf has a
>> disabled default constructor.
>
> D does not have default constructors. What you're really
> disabling is default initialization. This is an important
> distinction in understanding how objects are initialized in D.
> The init value is known at compile time and can't involve
> runtime stuff, whereas a default constructor would be able to
> run arbitrary code at runtime.
>
>> Is there a way to allow shared static constructors, but not the
>> default constructor?
>> struct ℚInf {
>> ℚ qval;
>> immutable static ℚInf zero;
>> @disable this();
>> shared static this() {
>> zero.qval = ℚ(0);
>> }
>> this(long num, long den) {
>> qval = ℚ(num,den); //this initialisation requires
>> dynamically linked code
>> }
>> }
>
> If you're initializing an immutable variable, you have to
> initialize it in one go. What you're doing is letting it be
> default initialized (which results in a compilation error,
> because default initialiaztion is disabled for that type) and
> then assigning to one of its members. If the default
> initialization weren't disabled, you'd get an error about not
> being able to mutate an immutable variable, whereas the fact
> that you disabled default initialization but did not explicitly
> initialize the variable results in a compilation error about
> not initializing the variable.
>
> If you want zero to be immutable, you must initialize the
> entire object at once. e.g.
>
> zero = QInf(0, 0);
>
> or whatever makes sense. If you need zero to be initialized
> differently from other QInfs, then you could make a private
> constructor that just takes the value for qval. But it either
> has to be default initialized with whatever the init type is
> (which you clearly don't want, since you disabled that), or it
> needs to be explicitly given a value.
>
> - Jonathan M Davis
Ah I see the distinction between initialisation and construction
now.
Disabling default initialisation was necessary, because part of
the code of the initialisation code of ℚ is linked at runtime
(mainly to initialise ℤ, which relies on gmp_init which is linked
at runtime).
But even if I initialise it in one go, the compiler still
complains and wants to initialise posinf (complains that default
construction is disabled).
I also tested it with a static constructor and a non-immutable
type and that didn't work either.
Here is a stripped down version of the important bits:
struct ℚInf {
ℚ qval;
enum Inf {
negInf=-1,
nonInf=0,
posInf=+1,
}
Inf inf;
immutable static ℚInf posinf; //at this line the compiler
complains that default construction is disabled for type
immutable(ℚInf)
@disable this();
shared static this() {
posinf = ℚInf(Inf.posInf);
//neginf = ℚInf(Inf.negInf);
}
private this(Inf inf) {
assert(inf != nonInf);
this.inf = inf;
qval = ℚ(0,1);
}
this(long num, long den) {
inf=Inf.nonInf;
qval = ℚ(num,den);
}
}
struct ℚ{
ℤ num, den; //cannot call constructors on these, since they
require gmp_init, which requires runtime code
//Default initialiser disabled, since else num=0,den=0
@disable this();
this(long num){
this(num.ℤ);
}
this(ℤ num){
this.num=ℤ(num);
this.den = 1;
}
this(ℤ num,ℤ den){
assert(den != ℤ(0)); //Disable this for speed
if(den<0){ num=-num; den=-den; }
auto d=gcd(abs(num),den);
num/=d, den/=d;
this.num=num;
this.den=den;
}
this(long num, long den) {
this(ℤ(num),ℤ(den));
}
}
More information about the Digitalmars-d-learn
mailing list