digitalmars.D.learn - Accessing members through pointers to structs (also, CTFE associative
- Ali (59/59) Dec 13 2016 Hi, Long time watcher and recently started playing with D a bit
- drug007 (2/23) Dec 13 2016 I'm sleepy, sorry for quick and probable wrong answer - try (*d.room).na...
- Ali (3/4) Dec 13 2016 Oh yeah, tried that too. That at least compiles but gives a
- bauss (wtf happend to my name took some old cached title LOL??) (3/7) Dec 13 2016 Try
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/8) Dec 13 2016 That is the address of the local variable room. You need to use 'ref' th...
- Ali (3/12) Dec 13 2016 Haha :)
- =?UTF-8?Q?Ali_=c3=87ehreli?= (38/39) Dec 13 2016 I'm not entirely sure whether this should work but I think the problem
- Ali (35/43) Dec 14 2016 I'm not sure I fully follow here. Because the variable in the
- =?UTF-8?Q?Ali_=c3=87ehreli?= (6/38) Dec 15 2016 Yeah, I think the compiler is confused because the function is called in...
- Stefan Koch (3/9) Dec 15 2016 You cannot Assign Associative Arrays at compile-time.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/15) Dec 15 2016 Thanks Stefan but at least there should be a better diagnostic instead
- Ali (3/23) Dec 17 2016 Ah kay. Confusing :)
Hi, Long time watcher and recently started playing with D a bit more. Ran in to a couple of snags that I'll combine in one post. It involves a data set that contains a list of strings. Each string represents a Room name. What I'm trying to do is pluck out the room names and also calculate the frequency each letter occurs in a name, per room. First problem is to do with pointers to structs. Here's the code: static immutable rooms = import("data.txt").split("\n").map!parse.array; static Tuple!(const(Room*), "room", int[char], "frequencies")[rooms.length] data; static this() { foreach (i, room; rooms) { data[i].room = &room; // Also calculate frequencies, but that's not important yet. } } void main() { foreach (d; data) { d.room.name.writeln; // <-- How do I access name here?? } } I've tried d.(*room).name but that didn't work. There's no arrow operator. I've tried making my tuple a ref Room instead, but that's a no go as well. I can copy the Room object directly in to the tuple, but since it's already there in static immutable data I'd rather just have a pointer to it. Is there a way to do that? Second problem is to do with associative arrays. At first the Room object had a frequencies object in it (ie: int[char] <- number of times a character appears in the name). In my parse function, if I add a foreach loop that loops through the letters in the room's name, and adds populates an associative array like so: Room parse(string line) { immutable name = // blah int[char] frequencies; foreach (letter; name) { frequencies[letter] += 1 } return Room(name, frequencies); } pragma(msg, rooms); // <- this works! In the above case the pragma actually prints out all the Room objects, with their respective frequencies calculated correctly. But *after* it has printed it out, then a whole list of compilation errors that all look like this: Error: non-constant expression ['d':1, 'r':3, 'x':1, 'e':1, 'v':2, 'k':2, 'z':1, 't':1, 'u':1, 'p':2, 'c':1, 's':1, 'f':2, 'i':2] But it seems that it was calculated correctly, it just can't be assigned to the actual variable. My current workaround includes taking frequencies out of the Room struct and calculating them inside a module constructor (hence the first question on the Tuple and Room *) Are there other workarounds? Cheers, and thanks for any help! - Ali
Dec 13 2016
On 13.12.2016 23:30, Ali wrote:Hi, Long time watcher and recently started playing with D a bit more. Ran in to a couple of snags that I'll combine in one post. It involves a data set that contains a list of strings. Each string represents a Room name. What I'm trying to do is pluck out the room names and also calculate the frequency each letter occurs in a name, per room. First problem is to do with pointers to structs. Here's the code: static immutable rooms = import("data.txt").split("\n").map!parse.array; static Tuple!(const(Room*), "room", int[char], "frequencies")[rooms.length] data; static this() { foreach (i, room; rooms) { data[i].room = &room; // Also calculate frequencies, but that's not important yet. } } void main() { foreach (d; data) { d.room.name.writeln; // <-- How do I access name here?? } } I've tried d.(*room).name but that didn't work. There's no arrowI'm sleepy, sorry for quick and probable wrong answer - try (*d.room).name
Dec 13 2016
On Tuesday, 13 December 2016 at 21:08:31 UTC, drug007 wrote:(*d.room).nameOh yeah, tried that too. That at least compiles but gives a runtime exception (bad address).
Dec 13 2016
On Tuesday, 13 December 2016 at 21:21:34 UTC, Ali wrote:On Tuesday, 13 December 2016 at 21:08:31 UTC, drug007 wrote:Try (*cast(Room*)(d.room)).name(*d.room).nameOh yeah, tried that too. That at least compiles but gives a runtime exception (bad address).
Dec 13 2016
On 12/13/2016 12:30 PM, Ali wrote:foreach (i, room; rooms) { data[i].room = &room;That is the address of the local variable room. You need to use 'ref' there: foreach (i, ref room; rooms) {- AliAli "the real one :o)"
Dec 13 2016
On Tuesday, 13 December 2016 at 21:33:11 UTC, Ali Çehreli wrote:On 12/13/2016 12:30 PM, Ali wrote:Ahh true!! Cheers. Now about that second part of my problem ....foreach (i, room; rooms) { data[i].room = &room;That is the address of the local variable room. You need to use 'ref' there: foreach (i, ref room; rooms) {- AliAli "the real one :o)"Haha :)
Dec 13 2016
On 12/13/2016 01:36 PM, Ali wrote:Now about that second part of my problem ....I'm not entirely sure whether this should work but I think the problem is with mutating the 'frequencies' member of an immutable element of 'rooms'. The error message means that those non-const expressions cannot be shared by a member of an immutable AA. I moved the frequencies to 'data' and hte following worked. Used 'shared static this' so that the data is populated per application instead of per thread. Additionally, the 'd.room.name.writeln' expression works just fine with DMD64 D Compiler v2.072.1. import std.algorithm: splitter, map; import std.array: array; import std.typecons: Tuple; import std.stdio: writeln; static immutable Room[] rooms = import("data.txt").splitter.map!parse.array; struct Room { string name; } static Tuple!(const(Room*), "room", int[char], "frequencies")[rooms.length] data; shared static this() { foreach (i, ref room; rooms) { data[i].room = &room; foreach (letter; room.name) { data[i].frequencies[letter]++; } } } Room parse(string line) pure { immutable name = line; return Room(name); } void main() { foreach (d; data) { d.room.name.writeln; d.frequencies.writeln; } } Ali
Dec 13 2016
On Tuesday, 13 December 2016 at 23:29:31 UTC, Ali Çehreli wrote:On 12/13/2016 01:36 PM, Ali wrote:I'm not sure I fully follow here. Because the variable in the parse function is not immutable and the frequencies member is not "created" yet, so to say. So after I create the frequencies object, I assign it to the member of a Room object. The following illustrates this more clearly I think: struct A { int x; } struct B { int[char] x; } auto f1() { int x; x = 3; return A(x); } auto f2() { int[char] x; x['A'] = 2; return B(x); } static immutable a = f1(); static immutable b = f2(); pragma(msg, a); pragma(msg, b); This fails to compile with "Error: non-constant expression ['A':2]". But, the pragma(msg) prints out the correct information for both a and b. What's the deal with static immutable associative arrays and D anyway? Is there some kind of roadmap somewhere or bugs that need to be fixed before they work properly in D? I'm confused because it seems like the data actually gets inside the struct object that has an AA as a member, but then the compiler just decides "nah, just kidding, this ain't actually ok. bye".Now about that second part of my problem ....I'm not entirely sure whether this should work but I think the problem is with mutating the 'frequencies' member of an immutable element of 'rooms'. The error message means that those non-const expressions cannot be shared by a member of an immutable AA.I moved the frequencies to 'data' and hte following worked.Yeah that is indeed the workaround I mentioned and hence the need for the pointer to room problem I was having :p This does work. But I guess I'm just looking for a more ideal solution. Thanks for all the help so far! :)
Dec 14 2016
On 12/14/2016 04:02 AM, Ali wrote:On Tuesday, 13 December 2016 at 23:29:31 UTC, Ali Çehreli wrote:Yeah, I think the compiler is confused because the function is called in a non-const context during the initialization of an immutable object. I would open an issue: https://issues.dlang.org/enter_bug.cgi?product=D AliOn 12/13/2016 01:36 PM, Ali wrote:I'm not sure I fully follow here. Because the variable in the parse function is not immutable and the frequencies member is not "created" yet, so to say. So after I create the frequencies object, I assign it to the member of a Room object. The following illustrates this more clearly I think: struct A { int x; } struct B { int[char] x; } auto f1() { int x; x = 3; return A(x); } auto f2() { int[char] x; x['A'] = 2; return B(x); } static immutable a = f1(); static immutable b = f2(); pragma(msg, a); pragma(msg, b); This fails to compile with "Error: non-constant expression ['A':2]". But, the pragma(msg) prints out the correct information for both a and b.Now about that second part of my problem ....I'm not entirely sure whether this should work but I think the problem is with mutating the 'frequencies' member of an immutable element of 'rooms'. The error message means that those non-const expressions cannot be shared by a member of an immutable AA.
Dec 15 2016
On Thursday, 15 December 2016 at 19:30:08 UTC, Ali Çehreli wrote:Yeah, I think the compiler is confused because the function is called in a non-const context during the initialization of an immutable object. I would open an issue: https://issues.dlang.org/enter_bug.cgi?product=D AliYou cannot Assign Associative Arrays at compile-time. Because those are defined by druntime have no stable ABI.
Dec 15 2016
On 12/15/2016 05:30 PM, Stefan Koch wrote:On Thursday, 15 December 2016 at 19:30:08 UTC, Ali Çehreli wrote:Thanks Stefan but at least there should be a better diagnostic instead of the confusing current situation that Ali experienced. AliYeah, I think the compiler is confused because the function is called in a non-const context during the initialization of an immutable object. I would open an issue: https://issues.dlang.org/enter_bug.cgi?product=D AliYou cannot Assign Associative Arrays at compile-time. Because those are defined by druntime have no stable ABI.
Dec 15 2016
On Friday, 16 December 2016 at 01:48:59 UTC, Ali Çehreli wrote:On 12/15/2016 05:30 PM, Stefan Koch wrote:Ah kay. Confusing :) Thanks again!On Thursday, 15 December 2016 at 19:30:08 UTC, Ali Çehreli wrote:Thanks Stefan but at least there should be a better diagnostic instead of the confusing current situation that Ali experienced. AliYeah, I think the compiler is confused because the function is called in a non-const context during the initialization of an immutable object. I would open an issue: https://issues.dlang.org/enter_bug.cgi?product=D AliYou cannot Assign Associative Arrays at compile-time. Because those are defined by druntime have no stable ABI.
Dec 17 2016