www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Runtime constant definitions

reply Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Hi,

I'm trying to define a couple of constants that I want to be computed at 
run time. I have written the following code:

---

/// Square root of real-number precision.
final real REAL_EPSILON_SQRT;

/// Cube root of real-number precision.
final real REAL_EPSILON_CBRT;


static this()
{
     REAL_EPSILON_SQRT = sqrt(real.epsilon);
     REAL_EPSILON_CBRT = cbrt(real.epsilon);
}

---

Compiling this, I get the errors

scid/core.d:21: Error: cannot modify final variable 'REAL_EPSILON_SQRT'
scid/core.d:22: Error: cannot modify final variable 'REAL_EPSILON_CBRT'

where the lines 21 and 22 are the ones inside the curly braces. What's 
wrong?


Thanks,
Lars
Sep 11 2008
next sibling parent reply "Bill Baxter" <wbaxter gmail.com> writes:
On Fri, Sep 12, 2008 at 3:14 PM, Lars Kyllingstad
<public kyllingen.nospamnet> wrote:
 Hi,

 I'm trying to define a couple of constants that I want to be computed at run
 time. I have written the following code:

 ---

 /// Square root of real-number precision.
 final real REAL_EPSILON_SQRT;

 /// Cube root of real-number precision.
 final real REAL_EPSILON_CBRT;


 static this()
 {
    REAL_EPSILON_SQRT = sqrt(real.epsilon);
    REAL_EPSILON_CBRT = cbrt(real.epsilon);
 }

 ---

 Compiling this, I get the errors

 scid/core.d:21: Error: cannot modify final variable 'REAL_EPSILON_SQRT'
 scid/core.d:22: Error: cannot modify final variable 'REAL_EPSILON_CBRT'

 where the lines 21 and 22 are the ones inside the curly braces. What's
 wrong?

D1 or D2? Does something in the spec lead you to believe that static this() should get around final's restrictions? It does seem like there should be some way to make a module-level constant that requires some computation. But I'd say just make 'em non final. Or use CTFE cbrt/sqrt functions. Or just precompute the value. --bb
Sep 11 2008
parent Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Bill Baxter wrote:
 On Fri, Sep 12, 2008 at 3:14 PM, Lars Kyllingstad
 <public kyllingen.nospamnet> wrote:
 Hi,

 I'm trying to define a couple of constants that I want to be computed at run
 time. I have written the following code:

 ---

 /// Square root of real-number precision.
 final real REAL_EPSILON_SQRT;

 /// Cube root of real-number precision.
 final real REAL_EPSILON_CBRT;


 static this()
 {
    REAL_EPSILON_SQRT = sqrt(real.epsilon);
    REAL_EPSILON_CBRT = cbrt(real.epsilon);
 }

 ---

 Compiling this, I get the errors

 scid/core.d:21: Error: cannot modify final variable 'REAL_EPSILON_SQRT'
 scid/core.d:22: Error: cannot modify final variable 'REAL_EPSILON_CBRT'

 where the lines 21 and 22 are the ones inside the curly braces. What's
 wrong?

D1 or D2?

D1, using GDC.
 Does something in the spec lead you to believe that static this()
 should get around final's restrictions?

None other than the fact that the following compiles perfectly: class Foo { final real bar; this() { bar = 1.0; } } I thought the whole point of a final variable was that it becomes constant AFTER the first time one assigns a value to it.
 It does seem like there should be some way to make a module-level
 constant that requires some computation.

Agreed.
 But I'd say just make 'em non final.  Or use CTFE cbrt/sqrt functions.
  Or just precompute the value.

The best would of course be to calculate the values at compile time. I didn't know that's possible in D. How do I do this? Since real is an architecture-dependent type, I don't want to precompute the values. -Lars
Sep 12 2008
prev sibling parent reply Frank Benoit <keinfarbton googlemail.com> writes:
I think 'const' should work.
Sep 12 2008
next sibling parent Lars Kyllingstad <public kyllingen.NOSPAMnet> writes:
Frank Benoit wrote:
 I think 'const' should work.

It works! Thanks! :) But isn't this the opposite of the intended behaviour? I thought consts were evaluated at compile time, and finals and static this() blocks at run time. At least that's how I've interpreted the D1 specs. -Lars
Sep 12 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Fri, Sep 12, 2008 at 4:20 AM, Lars Kyllingstad
<public kyllingen.nospamnet> wrote:
 Frank Benoit wrote:
 I think 'const' should work.

It works! Thanks! :) But isn't this the opposite of the intended behaviour? I thought consts were evaluated at compile time, and finals and static this() blocks at run time. At least that's how I've interpreted the D1 specs. -Lars

http://www.digitalmars.com/d/1.0/attribute.html#const "A const declaration without an initializer must be initialized in a constructor (for class fields) or in a static constructor (for static class members, or module variable declarations). " To be honest I'm not sure if the "un-reassignable" property of "final" is documented anywhere. There is a mention in the 1.011 changelog that "final for variables now works" but I don't know what "works" means.
Sep 12 2008
prev sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Fri, Sep 12, 2008 at 9:49 PM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
 On Fri, Sep 12, 2008 at 4:20 AM, Lars Kyllingstad
 <public kyllingen.nospamnet> wrote:
 Frank Benoit wrote:
 I think 'const' should work.

It works! Thanks! :) But isn't this the opposite of the intended behaviour? I thought consts were evaluated at compile time, and finals and static this() blocks at run time. At least that's how I've interpreted the D1 specs. -Lars

http://www.digitalmars.com/d/1.0/attribute.html#const "A const declaration without an initializer must be initialized in a constructor (for class fields) or in a static constructor (for static class members, or module variable declarations). " To be honest I'm not sure if the "un-reassignable" property of "final" is documented anywhere. There is a mention in the 1.011 changelog that "final for variables now works" but I don't know what "works" means.

Sounds like a bug then. If there's a loophole for const to init in static this() there should be the same loophole for final vars. Almost certainly just an oversight. --bb
Sep 12 2008