digitalmars.D.bugs - [Issue 5279] New: Function-static associative arrays
- d-bugmail puremagic.com (163/163) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (14/14) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (20/25) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (13/13) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (18/23) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (12/17) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (29/29) Nov 26 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5279
- d-bugmail puremagic.com (28/28) Apr 27 2012 http://d.puremagic.com/issues/show_bug.cgi?id=5279
http://d.puremagic.com/issues/show_bug.cgi?id=5279
Summary: Function-static associative arrays
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: DMD
AssignedTo: nobody puremagic.com
ReportedBy: bearophile_hugs eml.cc
I'd like DMD to support the definition of static associative arrays, that
become initialized only once at module start:
void foo() {
static string[string] map1 = ["bar" : "spam"];
static const string[string] map2 = ["bar" : "spam"];
static immutable string[string] map3 = ["bar" : "spam"];
}
void main() {}
That is similar to a static this() initialization of those maps, but with
visibility limited to foo().
--------------------------
Just for reference this is how DMD 2.050 compiles various kinds of AAs
literals, in all cases but fifth_function() the AA seems created again at each
function call (I think there is already a bug report about the enum AAs, but I
don't remember its number, please add it below if you remember it):
string first_function(string k) {
immutable string[string] map1 = ["bar" : "spam"];
return map1[k];
}
string second_function(string k) {
const string[string] map2 = ["bar" : "spam"];
return map2[k];
}
string third_function(string k) {
enum string[string] map3 = ["bar" : "spam"];
return map3[k];
}
string fourth_function(string k) {
static enum string[string] map4 = ["bar" : "spam"];
return map4[k];
}
immutable string[string] map5;
static this() {
map5 = ["bar" : "spam"];
}
string fifth_function(string k) {
return map5[k];
}
void main() {}
Compiled with:
DMD 2.050, -O -release -inline
_D5test314first_functionFAyaZAya comdat
L0: push EAX
mov EAX,offset FLAT:_D11TypeInfo_Aa6__initZ
mov ECX,offset FLAT:_D16TypeInfo_HAyayAa6__initZ
push dword ptr 0Ch[ESP]
push dword ptr 0Ch[ESP]
push 8
push EAX
push dword ptr FLAT:_DATA[01Ch]
push dword ptr FLAT:_DATA[018h]
push dword ptr FLAT:_DATA[0Ch]
push dword ptr FLAT:_DATA[08h]
push 1
push ECX
call near ptr __d_assocarrayliteralT
add ESP,018h
push EAX
call near ptr __aaGetRvalue
mov EDX,4[EAX]
mov EAX,[EAX]
add ESP,014h
pop ECX
ret 8
_D5test315second_functionFAyaZAya comdat
L0: push EAX
mov EAX,offset FLAT:_D11TypeInfo_Aa6__initZ
mov ECX,offset FLAT:_D17TypeInfo_HAyaxAya6__initZ
push dword ptr 0Ch[ESP]
push dword ptr 0Ch[ESP]
push 8
push EAX
push dword ptr FLAT:_DATA[01Ch]
push dword ptr FLAT:_DATA[018h]
push dword ptr FLAT:_DATA[0Ch]
push dword ptr FLAT:_DATA[08h]
push 1
push ECX
call near ptr __d_assocarrayliteralT
add ESP,018h
push EAX
call near ptr __aaGetRvalue
mov EDX,4[EAX]
mov EAX,[EAX]
add ESP,014h
pop ECX
ret 8
_D5test314third_functionFAyaZAya comdat
L0: push EAX
mov EAX,offset FLAT:_D11TypeInfo_Aa6__initZ
mov ECX,offset FLAT:_D16TypeInfo_HAyaAya6__initZ
push dword ptr 0Ch[ESP]
push dword ptr 0Ch[ESP]
push 8
push EAX
push dword ptr FLAT:_DATA[01Ch]
push dword ptr FLAT:_DATA[018h]
push dword ptr FLAT:_DATA[0Ch]
push dword ptr FLAT:_DATA[08h]
push 1
push ECX
call near ptr __d_assocarrayliteralT
add ESP,018h
push EAX
call near ptr __aaGetRvalue
mov EDX,4[EAX]
mov EAX,[EAX]
add ESP,014h
pop ECX
ret 8
_D5test315fourth_functionFAyaZAya comdat
L0: push EAX
mov EAX,offset FLAT:_D11TypeInfo_Aa6__initZ
mov ECX,offset FLAT:_D16TypeInfo_HAyaAya6__initZ
push dword ptr 0Ch[ESP]
push dword ptr 0Ch[ESP]
push 8
push EAX
push dword ptr FLAT:_DATA[01Ch]
push dword ptr FLAT:_DATA[018h]
push dword ptr FLAT:_DATA[0Ch]
push dword ptr FLAT:_DATA[08h]
push 1
push ECX
call near ptr __d_assocarrayliteralT
add ESP,018h
push EAX
call near ptr __aaGetRvalue
mov EDX,4[EAX]
mov EAX,[EAX]
add ESP,014h
pop ECX
ret 8
_D5test314fifth_functionFAyaZAya comdat
L0: push EAX
mov EAX,offset FLAT:_D11TypeInfo_Aa6__initZ
push dword ptr 0Ch[ESP]
push dword ptr 0Ch[ESP]
push 8
push EAX
push dword ptr _D5test34map5yHAyaAa
call near ptr __aaGetRvalue
mov EDX,4[EAX]
mov EAX,[EAX]
add ESP,014h
pop ECX
ret 8
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279
Jonathan M Davis <jmdavisProg gmx.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jmdavisProg gmx.com
PST ---
I would expect that this problem would be solved together with however being
able to use Objects with CTFE and dynamic memory in general is solved. Since, I
believe that it's essentially the same problem that won't allow you to
initialize a global variable which is a class type to anything other than null.
CTFE can't handle the heap yet. Once it can, AAs should work.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279I would expect that this problem would be solved together with however being able to use Objects with CTFE and dynamic memory in general is solved. Since, I believe that it's essentially the same problem that won't allow you to initialize a global variable which is a class type to anything other than null. CTFE can't handle the heap yet. Once it can, AAs should work.In DMD 2.050 this code works, so this enhancement request asks for those foo_map* to be visible inside foo() only: string[string] foo_map1; const string[string] foo_map2; immutable string[string] foo_map3; static this() { foo_map1 = ["bar" : "spam"]; foo_map2 = ["bar" : "spam"]; foo_map3 = ["bar" : "spam"]; } void foo() { // here use foo_map1, foo_map2, foo_map3 } void main() {} -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279 PST --- So essentially, you want static local variables to have access to a static constructor like all of the other variables with global lifetime do. Given that that breaks the scoping rules, I'm not sure that it's exactly a good idea. Perhaps allowing for a static constructor which is a nested function? That seems a bit like overkill, but it could theoretically work. If CTFE were properly advanced though, I don't think that it would be an issue. You'd either assign the variable an AA literal, or you'd write a function which created one and returned it, and you'd initialize the variable with that. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279
nfxjfg gmail.com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |nfxjfg gmail.com
Wouldn't that lead exactly to the same race condition prone crap C++ is doing
when it comes to initialization of static variables inside functions?
Just say no.
Immutable data (or de-facto immutable data only accessible through const) is
another story, though.
I would expect that this problem would be solved together with however being
able to use Objects with CTFE and dynamic memory in general is solved. Since, I
believe that it's essentially the same problem that won't allow you to
initialize a global variable which is a class type to anything other than null.
CTFE can't handle the heap yet. Once it can, AAs should work.
It's not that easy. The AA has to be allocated in the heap (to deal with later
write accesses to the AA). How can CTFE allocate heap memory at the program's
runtime? Obviously this doesn't work.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279So essentially, you want static local variables to have access to a static constructor like all of the other variables with global lifetime do. Given that that breaks the scoping rules, I'm not sure that it's exactly a good idea.I don't fully understand what you say, but I think you have misunderstood me. Surely I have never asked to break scoping rules. ----------------------Wouldn't that lead exactly to the same race condition prone crap C++ is doing when it comes to initialization of static variables inside functions?I don't know. If are sure that happens then please close this enhancement request. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279
PST ---
nfxjfg
It's going to have to be able to do it for objects eventually. Yes, it's a
thorny problem, but it _can_ be done. The fact that it's a thorny problem is
the reason why it hasn't been done _yet_, but it will be done eventually.
Bearophile
What I gathered what you were saying is that you were looking for a way to have
a static constructor initialize static local variables. Doing that would break
scoping rules.
However, re-reading your initial comment, it looks like what you want to have
happen is for the compiler to effectively set up a static constructor within
the function automatically which is not visible to the programmer. The compiler
would simply be smart enough to know that
static string[string] map1 = ["bar" : "spam"];
translates to something like
static string[string] map1;
static this()
{
string[string] map1_temp;
map1_temp["bar"] = "spam";
map1 = map1_temp;
}
That's not an entirely bad idea, but it seems to me that since CTFE has to be
fixed to be able to handle this situation anyway, we might as well just fix
CTFE rather than have the compiler special case this situation.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 26 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5279
SomeDude <lovelydear mailmetrash.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lovelydear mailmetrash.com
PDT ---
The following program doesn't compile with 2.059:
import std.stdio, std.container, std.range;
string[char] aa = ['f':"foo", 'b':"bar"];
void main(){
foreach (ch, str; aa) {
writefln("[%s]: [%s]", ch, str);
}
}
It gives:
PS E:\DigitalMars\dmd2\samples> rdmd -O -inline bug.d
bug.d(3): Error: non-constant expression ['f':"foo",'b':"bar"]
PS E:\DigitalMars\dmd2\samples>
This also happens with the following:
const string[char] aa = ['f': "foo",'b': "bar"];
static const string[char] aa = ['f': "foo",'b': "bar"];
immutable string[char] aa = ['f': "foo",'b': "bar"];
static immutable string[char] aa = ['f': "foo",'b': "bar"];
Only this compiles:
enum string[char] aa = ['f': "foo",'b': "bar"];
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 27 2012









d-bugmail puremagic.com 