www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - `static` symbol needs to be `immutable` for compile-time access?

reply Shriramana Sharma <samjnaa_dont_spam_me gmail.com> writes:
Hello. This is a minimal abstraction of a part of my program:

int func(string s)
{
    static int [] i = [5, 6, 7];
    return i[2];
}
template temp(string s) { enum temp = func(s); }
void main() { static assert(temp!"str" == 7); }

With the above code I get:

<src>(4): Error: static variable i cannot be read at compile time
<src>(6):        called from here: func("str")
<src>(7): Error: template instance <src>.temp!"str" error instantiating

I find that if I either replace `static` by `immutable` or even just *add* 
`immutable` after `static`, the error goes away. Do all values which need to 
be readable at compile time need to be declared `immutable`?

In C/C++ the `static` here is used to avoid the array being created every 
time the function is entered; in D too it does the same thing, no? So if I 
have an array of constants in a function that I need to be accessible to a 
template at compile time, and I (for obvious reasons) don't want to be 
initialized at every function call, do I have to declare it `static 
immutable`?

-- 

Jan 22 2016
next sibling parent Kagamin <spam here.lot> writes:
Why do you declare mutable constants?
Jan 22 2016
prev sibling next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 22 January 2016 at 09:56:27 UTC, Shriramana Sharma 
wrote:

 In C/C++ the `static` here is used to avoid the array being 
 created every time the function is entered; in D too it does 
 the same thing, no? So if I have an array of constants in a 
 function that I need to be accessible to a template at compile 
 time, and I (for obvious reasons) don't want to be initialized 
 at every function call, do I have to declare it `static 
 immutable`?
A static variable is still a runtime variable. It's effectively the same as declaring a variable outside of the function scope at module scope, except that it's visible only in the current scope and the function name gets mangled into the symbol int i; void foo() { static int j; } j is no more a compile-time value than i is. If you want an array of constant values available at compile-time, then you need to declare the array as immutable.
Jan 22 2016
parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Friday, 22 January 2016 at 10:15:19 UTC, Mike Parker wrote:
 A static variable is still a runtime variable. It's effectively 
 the same as declaring a variable outside of the function scope 
 at module scope, except that it's visible only in the current 
 scope and the function name gets mangled into the symbol

 int i;

 void foo() {
    static int j;
 }

 j is no more a compile-time value than i is. If you want an 
 array of constant values available at compile-time, then you 
 need to declare the array as immutable.
To expand on this: As you noted, a `static` local variable is, with regards to its lifetime, effectively global. This means there could be code like the following: int func(string s) { int [] i = [5, 6, 7]; auto result = i[2]; i[2] = 42; return result; } I.e., the array could contain a different value depending on whether the function has already been run before. Functions evaluated at compile time need to be effectively pure, because the order of declarations in D is specified not to matter (modulo bugs). Making the variable immutable, or turning it into a normal local variable (even a mutable one!), guarantees that.
Jan 22 2016
prev sibling parent reply anonymous <anonymous example.com> writes:
On 22.01.2016 10:56, Shriramana Sharma wrote:
 Do all values which need to
 be readable at compile time need to be declared `immutable`?
Yes, `static immutable` or `enum`.
 In C/C++ the `static` here is used to avoid the array being created every
 time the function is entered; in D too it does the same thing, no?
Yes, it's the same in D. But without `immutable` you could make `func` return a different value per call, i.e. `func` would not be pure. Impure compile time calculations are not allowed. One reason for that is that it would require specifying an order in which they're done, which would be weird, especially with separate compilation of modules.
 So if I
 have an array of constants in a function that I need to be accessible to a
 template at compile time, and I (for obvious reasons) don't want to be
 initialized at every function call, do I have to declare it `static
 immutable`?
Yes, without `immutable` they're not constants to the compiler.
Jan 22 2016
parent reply Shriramana Sharma <samjnaa_dont_spam_me gmail.com> writes:
Thanks to all who replied.

anonymous wrote:
 Do all values which need to
 be readable at compile time need to be declared `immutable`?
Yes, `static immutable` or `enum`.
It would seem that in the case of arrays, the former is preferable to the latter, as per the para above this header: http://ddili.org/ders/d.en/const_and_immutable.html#ix_const_and_immutable.variable, %20immutable But a further question, if I don't declare them as `static immutable` but just as `immutable`, would that mean that those arrays are necessarily created (meaning memory allocation) every time the function is run? --
Jan 22 2016
parent anonymous <anonymous example.com> writes:
On 22.01.2016 15:33, Shriramana Sharma wrote:
 It would seem that in the case of arrays, the former is preferable to the
 latter, as per the para above this header:

 http://ddili.org/ders/d.en/const_and_immutable.html#ix_const_and_immutable.variable,
 %20immutable
The link doesn't work for me, but yes, `static immutable` is usually better for arrays than `enum`.
 But a further question, if I don't declare them as `static immutable` but
 just as `immutable`, would that mean that those arrays are necessarily
 created (meaning memory allocation) every time the function is run?
I guess compilers may reuse the same array for all calls, seeing that the value is a constant, but I don't think they're required to do so.
Jan 22 2016