Re: How to create instance of class that get data from 2 another instance?
What I am doing wrong? http://www.everfall.com/paste/id.php?iwh4qdcqv6zi Well, there's no `parseconfig` there. Do you expect the `parseconfig` from line 30 or line 193 to be available in line 170? From line 30. In line 193 I am get in instance of class instance of parseconfig to be able to use config inside MySQL class. What I should to do in situation where for creation of class I should pass to constructor data instances from 2 different classes?
Re: Scoped external function declaration
Thanx Daniel, thanx Ketmar. I just thinked that this is some sort of bug. May be DMD should not change mangled name of external function... Bit i dont know.
Re: Scoped external function declaration
On Fri, 02 Jan 2015 10:40:22 + novice2 via Digitalmars-d-learn wrote: > Thanx Daniel, thanx Ketmar. > > I just thinked that this is some sort of bug. > May be DMD should not change mangled name of external function... > Bit i dont know. with `extern(C)` it didn't. what you probably not realised is that D has nested functions, so extern which declared inside other function becomes right this: an extern nested function. that's why D compiler mangles it's name. there are no nested functions in C, but D is not C. ;-) signature.asc Description: PGP signature
Re: getting current DateTime
On Wednesday, December 31, 2014 19:07:13 bitwise via Digitalmars-d-learn wrote: > > Why do you need DateTime and not SysTime? > > > > I'm actually surprised it doesn't have that too... > > > > -Steve > > Initially I was looking for something that would be the > equivalent to DateTime in C#. This now appears to be SysTime, not > DateTime in D. > > It seems the only real reason to use DateTime is as an > optimization. > > From DateTime docs: > "It is optimized for calendar-based operations and has no concept > of time zone." That and it gets used internally by SysTime for any calendar-based operations that it has to do, so it encapsulates that functionality, but if what you're looking for is something that represents the time from the system rather than a date and time on a calendar, you want SysTime. The main places that code is likely to use DateTime is if it needs to operate on dates and times separately from any connection to the system's time or time zones and when you want to get the separate pieces of the date and time (year, month, etc.) efficiently, because converting to DateTime calculates that information once, whereas calling each individual property on SysTime results in having to do some of the calculations multiple times if you want to access multiple of the properties (which sometimes makes me think that I never should have put those properties on SysTime in the first place, but it's convenient if you don't care about the small loss of efficiency when duplicating some of the calculations to get multiple of the properties or you only need one or two of the properties). - Jonathan M Davis
Re: How to create instance of class that get data from 2 another instance?
I looked at my code and it's seems that I can create instance of MySQL in main. void main() { auto parseconfig = new parseConfig(); auto mysql = new MySQL(parseconfig, seismodownload); } In parseConfig I am creation instance of seismoDownload: class parseConfig { if (checkLinkCode(emsc_csem) == 200) { auto seismodownload = new seismoDownload(emsc_csem); seismodownload.parse(); } } So I should be able to call it in main ( I talk about "auto mysql = new MySQL(parseconfig, seismodownload);") But I am getting error: Error: undefined identifier seismodownload, did you mean class seismoDownload?
Re: Can the order in associative array change when keys are not midified?
On Thursday, 1 January 2015 at 18:58:04 UTC, Andrej Mitrovic via Digitalmars-d-learn wrote: On 1/1/15, Tobias Pankrath via Digitalmars-d-learn wrote: You could implement an OrderedMap!(Key, Value) via RedBlackTree!(Tuple!(Key, Value), (a,b) => a[0] < b[0]). We could add this as an alias into Phobos or perhaps as just a documentation line on the website. Will do. Going to submit some documentation PRs anyway.
What exactly shared means?
I always think that shared should be use to make variable global across threads (similar to __gshared) with some synchronize protection. But this code doesn't work (app is stuck on _aaGetX or _aaRehash ): shared double[size_t] logsA; void main() { auto logs = new double[1_000_000]; foreach(i, ref elem; parallel(logs, 4)) { elem = log(i + 1.0); logsA[i]= elem; } } But when I add synchronized block it is OK: shared double[size_t] logsA; void main() { auto logs = new double[1_000_000]; foreach(i, ref elem; parallel(logs, 4)) { elem = log(i + 1.0); synchronized { logsA[i]= elem; } } }
Re: What exactly shared means?
On Friday, 2 January 2015 at 11:47:47 UTC, Daniel Kozak wrote: I always think that shared should be use to make variable global across threads (similar to __gshared) with some synchronize protection. But this code doesn't work (app is stuck on _aaGetX or _aaRehash ): But when I add synchronized block it is OK: I am not aware of any changes since the following thread (see the second post): http://forum.dlang.org/thread/brpbjefcgauuzguyi...@forum.dlang.org#post-mailman.679.1336909909.24740.digitalmars-d-learn:40puremagic.com So AFAIK "shared" is currently nothing more than a compiler hint (despite the documentation suggesting otherwise (Second to last paragraph of "__gshared" doc compares it to "shared", see http://dlang.org/attribute.html). My current understanding is that you either use "__gshared" and do your own synchronisation, or you use thread local storage, i.e. do not use "shared", but I would be happy to be proven wrong on that point. BTW, you can use the following search to find more information (It is was I used to find the above linked thread): https://www.google.com/?#q=site:forum.dlang.org+shared
Re: What exactly shared means?
On Friday, January 02, 2015 11:47:46 Daniel Kozak via Digitalmars-d-learn wrote: > I always think that shared should be use to make variable global > across threads (similar to __gshared) with some synchronize > protection. But this code doesn't work (app is stuck on _aaGetX > or _aaRehash ): > > shared double[size_t] logsA; > > void main() { > > auto logs = new double[1_000_000]; > > foreach(i, ref elem; parallel(logs, 4)) { > elem = log(i + 1.0); > logsA[i]= elem; > } > } > > > But when I add synchronized block it is OK: > > shared double[size_t] logsA; > > void main() { > > auto logs = new double[1_000_000]; > > foreach(i, ref elem; parallel(logs, 4)) { > elem = log(i + 1.0); > synchronized { > logsA[i]= elem; > } > } > } Objects in D default to being thread-local. __gshared and shared both make it so that they're not thread-local. __gshared does it without actually changing the type, making it easier to use but also dangerous to use, because it makes it easy to violate the compiler's guarantees, because it'll treat it like a thread-local variable with regards to optimizations and whatnot. It's really only meant for use with C global variable declarations, but plenty of folks end up using it for more, because it avoids having the compiler complain at them like it does with shared. Regardless, if you use __gshared, you need to make sure that you protect it against being accessed by multiple threads at once using mutexes or synchronized blocks or whatnot. shared does not add any more synchronization or automatic mutex-locking or anything like that than __gshared does (IIRC, there is some talk in TDPL about shared adding memory barriers - which __gshared wouldn't do - but that hasn't been implemented and probably never would be, because it would be too expensive with regards to efficiency). However, unlike __gshared, shared _does_ alter the type of the variable, so the compiler will treat it differently. That way, it won't do stuff like optimize code under the assumption that the object is thread-local like it can do with non-shared objects. It makes it clear which objects are thread-local and which aren't and enforces that with the type system. In principle, this is great, since it clearly separates thread-local and non-thread local objects and protects you against treating a non-thread local object as if it were thread-local. And as long as you're writing code which operates specifically on shared variables rather than trying to use "normal" code with them, it works great. The problem is that you inevitably want to do things like use a function that takes thread-local variables on a shared object - e.g. if a type is written to be used as thread-local, then none of its member functions are shared, and none of them can be used by a shared object, which obviously makes using such a type as shared to be a bit of a pain. In principle, D is supposed to provide ways to safely convert shared objects to thread-local ones - i.e. when the compiler can guarantee that the object is protected by a mutex or synchronized block or whatnot. The main way that this was proposed is what TDPL describes with regards to synchronized classes. The member variables of a synchronized class would be shared, and protected by the class, since all of its member functions would be synchronized, and no direct access to the member variables would be allowed, guaranteeing that any time the member variables were accessed, it would be within a synchronized function, meaning that the compiler could guarantee that all access to the member variables was protected by a mutex. So, the compiler would then be able to safely strip away the outermost layer of shared, allowing you to theoretically use the member variables with normal functions. However, that only strips away the outermost layer (since that's all the compiler could guarantee was protected), which frequently wouldn't be enough, and it requires creating entire synchronized types just to use shared objects. So, the efficacy of the idea is questionable IMHO, much as the motivation is a good one (only removing shared when the compiler can guarantee that only one thread can access it). However, synchronized classes have yet to be implemented (only synchronized functions), so we don't currently have the ability to have the outermost layer of shared be stripped away like that. There is currently no place in the language where the compiler is able to guarantee that a shared object is sufficiently protected against access from multiple threads at once for it to be able to automatically remove shared under any circumstances. The _only_ way to strip it away at this point is to cast it away explicitly. So, right now, what you're forced to do is something like shared T foo = funcThatReturnsSharedT(); synchronized(someObj) { // be sure at this point that all other code that access foo // also synchr
Re: Can the order in associative array change when keys are not midified?
On 1/1/15 7:32 AM, Idan Arye wrote: If I have an associative array and I only modify it's values, without changing the keys, can I assume that the order won't change? I would never make that assumption. An AA is free to rehash at any time, for whatever reason. What I would say is that you can probably safely assume an AA will iterate in the same order as long as it hasn't been changed. If you need guaranteed ordering, use an array or a RedBlackTree. -Steve
Re: getting current DateTime
On 1/2/15 6:21 AM, Jonathan M Davis via Digitalmars-d-learn wrote: The main places that code is likely to use DateTime is if it needs to operate on dates and times separately from any connection to the system's time or time zones and when you want to get the separate pieces of the date and time (year, month, etc.) efficiently, because converting to DateTime calculates that information once, whereas calling each individual property on SysTime results in having to do some of the calculations multiple times if you want to access multiple of the properties (which sometimes makes me think that I never should have put those properties on SysTime in the first place, but it's convenient if you don't care about the small loss of efficiency when duplicating some of the calculations to get multiple of the properties or you only need one or two of the properties). Not sure if you saw it, but I think a question for you Jonathan, is why DateTime ignores subsecond data? Wouldn't it be trivial to include that too? It seems to be a conflict to say, either I want to efficiently work with components, or I want subsecond resolution. Even if subseconds was a single value to deal with (like a Duration). I personally have not used DateTime, as SysTime fits my needs quite well. -Steve
Re: getting current DateTime
On Friday, January 02, 2015 08:31:11 Steven Schveighoffer via Digitalmars-d-learn wrote: > On 1/2/15 6:21 AM, Jonathan M Davis via Digitalmars-d-learn wrote: > > > The main places that code is likely to use DateTime is if it needs to > > operate on dates and times separately from any connection to the system's > > time or time zones and when you want to get the separate pieces of the > > date and time (year, month, etc.) efficiently, because converting to > > DateTime calculates that information once, whereas calling each individual > > property on SysTime results in having to do some of the calculations > > multiple times if you want to access multiple of the properties (which > > sometimes makes me think that I never should have put those properties on > > SysTime in the first place, but it's convenient if you don't care about the > > small loss of efficiency when duplicating some of the calculations to get > > multiple of the properties or you only need one or two of the properties). > > Not sure if you saw it, but I think a question for you Jonathan, is why > DateTime ignores subsecond data? Wouldn't it be trivial to include that too? > > It seems to be a conflict to say, either I want to efficiently work with > components, or I want subsecond resolution. Even if subseconds was a > single value to deal with (like a Duration). It could be added, but IIRC, I decided that it didn't make sense, because the primary reason for DateTime was for calendar-based operations, and subsecond resolution doesn't make any sense for those. Those only make sense for when you're dealing with the actual system time. They _do_ make some sense when using DateTime strictly for holding the separate pieces of the date/time rather than accessing each of the properties on SysTime directly, but it's also cheaper to get the subseconds than any of the properties that DateTime currently holds. > I personally have not used DateTime, as SysTime fits my needs quite well. For most situations, it's what you need, since most code isn't looking to deal with dates and times without tying them to the system time and time zone somehow. Regardless of my original intentions, I think that the primary use case for DateTime, Date, and TimeOfDay has ended up simply being to hold those properties for SysTime rather than calculating each of them individually. But they'll still come in handy for anyone who actually needs to be able to do date/time calculations for calendar stuff without getting time zones and whatnot involved. - Jonathan M Davis
Re: How to create instance of class that get data from 2 another instance?
On Friday, 2 January 2015 at 11:21:08 UTC, Suliman wrote: I looked at my code and it's seems that I can create instance of MySQL in main. void main() { auto parseconfig = new parseConfig(); auto mysql = new MySQL(parseconfig, seismodownload); } In parseConfig I am creation instance of seismoDownload: class parseConfig { if (checkLinkCode(emsc_csem) == 200) { auto seismodownload = new seismoDownload(emsc_csem); seismodownload.parse(); } } So I should be able to call it in main ( I talk about "auto mysql = new MySQL(parseconfig, seismodownload);") But I am getting error: Error: undefined identifier seismodownload, did you mean class seismoDownload? Anything declared in main() is local to main and not a global.
Re: How to create instance of class that get data from 2 another instance?
Anything declared in main() is local to main and not a global. Ok! So I need create multiple instances of the parseconfig? Or please suggest me any solution, I really can't understand how to be in such situation...
Re: How to create instance of class that get data from 2 another instance?
On Friday, 2 January 2015 at 14:50:54 UTC, Suliman wrote: Anything declared in main() is local to main and not a global. Ok! So I need create multiple instances of the parseconfig? Or please suggest me any solution, I really can't understand how to be in such situation... Have you ever used a C-like programming language or are you a bloody beginner? So that I can figure out how basic the explanation has to be. Basically every pair of {} introduces a scope. And you can only refer to things declared in the current or a parent scope. { int x; { // x available here } } // x not available anymore For your example this means that void main() { auto parseconfig = new parseConfig(); } // parseConfig unavaiable since here class whatever { // cannot use parseconfig } What you can do is to declare the config outside any braces and make it a module global. But you'll need a module constructor (look them up in the docs). They are declared with this() outside of any scope in a module. parseConfig parseconfig; this() { parseconfig = new parseConfig(...); } void main() { /* can use parseconfig */ } class SomeClass { /* should be able to as well */ } ---
Re: How to create instance of class that get data from 2 another instance?
Thanks! I will try! D is my first compilable language, I wrote only some scripts without OO before. So in my case your suggestion is best practice? Or there is any more simple way to pass config and data to MySQL class?
Re: How to create instance of class that get data from 2 another instance?
On Friday, 2 January 2015 at 15:33:06 UTC, Suliman wrote: Thanks! I will try! D is my first compilable language, I wrote only some scripts without OO before. So in my case your suggestion is best practice? Or there is any more simple way to pass config and data to MySQL class? I think it's fine to have a global config instance. Alternatively you can pass the config to both the seismoDownlead and MySqlWhatever classes. // there ist enforce(cond, msg) for this in std.exception/std.conv, dunno. if (!exists(confpath)) throw new Exception("ERROR: config.ini do not exists"); // it becomes enforce(exists(confpath), "ERROR: config.ini does not exist");
Re: How to create instance of class that get data from 2 another instance?
I think it's fine to have a global config instance. Alternatively you can pass the config to both the seismoDownlead and MySqlWhatever classes. // there ist enforce(cond, msg) for this in std.exception/std.conv, dunno. if (!exists(confpath)) throw new Exception("ERROR: config.ini do not exists"); // it becomes enforce(exists(confpath), "ERROR: config.ini does not exist"); Not fully understand. How I need to declare global config instance? void main() { } this() { auto parseconfig = new parseConfig(); } But how this() will be called in nothing in main? And I can't understand how to pass the config to both the seismoDownlead and MySqlWhatever classes. I know how to pass, but I do not understand how to do it with current situation with scopes. Here is current version of my code. I am not asking to do work for me, but could you show what and where I should move http://www.everfall.com/paste/id.php?oscnkeq740ue ?
vibe.d mongodb connections
I'm currently trying around with vibe.d and I'm confused about the MongoDB example: import vibe.d; MongoClient client; void test() { auto coll = client.getCollection("test.collection"); foreach (doc; coll.find(["name": "Peter"])) logInfo("Found entry: %s", doc.toJson()); } shared static this() { client = connectMongoDB("127.0.0.1"); } "client" is TLS but is initialized within a shared module consturctor, meaning that only the main thread will have a initialized db-connection. http://vibed.org/api/vibe.db.mongo.mongo/connectMongoDB says: "Thus, the MongoClient instance can - and should - be shared among all fibers in a thread by storing in in a thread local variable." So wouldn't it make more sense that the MongoDB example initializes the "client" variable in a "static this()" instead of a "shared static this()" ? Kind Regards Benjamin Thaut
Re: How to create instance of class that get data from 2 another instance?
class parseConfig { string dbname; string dbuser; string dbpass; string dbhost; string dbport; uint status; this() { auto checkLinkCode(string link) // we need to check all links to be sure if they are alive { return status; } . if (checkLinkCode(emsc_csem) == 200) { auto seismodownload = new seismoDownload(emsc_csem, this); //here seismodownload.parse(); } } } I know that in С# I can pass to function, and this would be point of class from where it's call (Here is parseConfig). Is it's possible to do something similar in D?
Example usage of the core.sync classes
I'm trying to write a small 3D engine, and wanted to place the physics in a separate thread to the graphics, using events, possibly std.concurrency, to communicate between them. How, then, do I pass large amounts of data between threads? I'm thinking the physics world state (matrix for each object, object heirarchies, etc) being passed to the graphics thread for rendering. I'd assumed that I would use Mutex, or ReadWriteMutex, but I have no idea how to build code using these classes, if this is even the right way to go about this. I would really appreciate any pointers you can give. Many thanks
vibe.d + dub dynamic library
Is it possible to get dub to build vibe.d into a dynamic library? Or is it at least possible to make dub link against the shared version of phobos? I found this blog post about dynamic linktimes, unfortunately it does not describe how to actually make dub use the dynamic version of phobos. https://code.dawg.eu/reducing-vibed-turnaround-time-part-1-faster-linking.html (I'm on linux) Kind Regards Benjamin Thaut
Re: Example usage of the core.sync classes
On Friday, 2 January 2015 at 17:39:19 UTC, Matt wrote: I'm trying to write a small 3D engine, and wanted to place the physics in a separate thread to the graphics, using events, possibly std.concurrency, to communicate between them. How, then, do I pass large amounts of data between threads? I'm thinking the physics world state (matrix for each object, object heirarchies, etc) being passed to the graphics thread for rendering. I'd assumed that I would use Mutex, or ReadWriteMutex, but I have no idea how to build code using these classes, if this is even the right way to go about this. I would really appreciate any pointers you can give. Many thanks My personal favorite method is to use the primitives in core.atomic with a double or triple buffer. To double buffer, keep two buffers in an array (data[][] or something) and an integer index that points to the active buffer, then use atomicStore to update active buffer index when you want to swap. Triple buffering can improve runtime performance at the cost of more memory, and in this case you will need two indices and two swap methods, one for the producer and another for the consumer. I use cas with a timed sleep to update the indices in this case. Take it with a grain of salt, I'm far from a pro, but this has worked well for me in the past. I can post some example code if you need it.
Re: Example usage of the core.sync classes
Am 02.01.2015 um 19:45 schrieb Vlad Levenfeld: My personal favorite method is to use the primitives in core.atomic with a double or triple buffer. To double buffer, keep two buffers in an array (data[][] or something) and an integer index that points to the active buffer, then use atomicStore to update active buffer index when you want to swap. Triple buffering can improve runtime performance at the cost of more memory, and in this case you will need two indices and two swap methods, one for the producer and another for the consumer. I use cas with a timed sleep to update the indices in this case. Take it with a grain of salt, I'm far from a pro, but this has worked well for me in the past. I can post some example code if you need it. I have to agree with Vlad here. The usual way is to do double buffering. So you have two buffers which hold all the data that the physics simulation passes to the game logic. While the physics simulation is computing the next frame, the game logic can use the results from the last frame. The only point where sinchronisation is neccessary is when swapping the buffers. You have to ensure that both the game logic and the physics thread are done with their current buffer and then sawp them. The only downside of this approach is, that you will get a small delay (usually the time taken for 1 frame) into the data you pass this way. Sometimes this approach is called the "exractor pattern". I use it to pass data from the game simulation to the renderer, so the renderer can render in paralell with the game simulation computing the next frame. You can find a example of my double buffered solution here: https://github.com/Ingrater/Spacecraft/blob/master/game/sources/renderer/extractor.d I had tripple buffering up and running at some point, but I went back to double buffering, because tripple buffering can cause micro lags and you don't want that. Kind Regards Benjamin Thaut
Re: What exactly shared means?
On Friday, 2 January 2015 at 13:14:14 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: Objects in D default to being thread-local. __gshared and shared both make it so that they're not thread-local. __gshared does it without actually changing the type, making it easier to use but also dangerous to use, because it makes it easy to violate the compiler's guarantees, because it'll treat it like a thread-local variable with regards to optimizations and whatnot. I'm pretty sure that's not true. __gshared corresponds to C-style globals, which are *not* assumed to be thread-local (see below). shared does not add any more synchronization or automatic mutex-locking or anything like that than __gshared does (IIRC, there is some talk in TDPL about shared adding memory barriers - which __gshared wouldn't do - but that hasn't been implemented and probably never would be, because it would be too expensive with regards to efficiency). However, unlike __gshared, shared _does_ alter the type of the variable, so the compiler will treat it differently. That way, it won't do stuff like optimize code under the assumption that the object is thread-local like it can do with non-shared objects. Are you sure about all this optimisation stuff? I had (perhaps wrongly) assumed that __gshared and shared variables in D guaranteed Sequential Consistency for Data Race Free (SCDRF) and nothing more, just like all normal variables in C, C++ and Java. Thread-local variables (i.e. everything else in D ) could in theory be loosened up to allow some *extra* optimisations that C/C++/Java etc. don't normally support (because they would risk violating SCDRF), but I don't know how much of this is taken advantage of currently. If I'm correct, then the advice to users would be "Use __gshared and pretend you're writing C/C++/Java, or use shared and do exactly the same but with type-system support for your convenience/frustration".
Re: What exactly shared means?
On 1/2/15 2:47 PM, John Colvin wrote: Are you sure about all this optimisation stuff? I had (perhaps wrongly) assumed that __gshared and shared variables in D guaranteed Sequential Consistency for Data Race Free (SCDRF) and nothing more, just like all normal variables in C, C++ and Java. There is nothing special about __gshared other than where it is put. Real simple test: __gshared int x; void main() { int xlocal; int *xp = (rand() % 2) ? &x; &xlocal; *xp = 5; } tell me how the compiler can possibly know anything about what type of data xp points at? But with shared, the type itself carries the hint that the data is shared between threads. At this point, this guarantees nothing in terms of races and ordering, which is why shared is so useless. In fact the only useful aspect of shared is that data not marked as shared is guaranteed thread local. If I'm correct, then the advice to users would be "Use __gshared and pretend you're writing C/C++/Java, or use shared and do exactly the same but with type-system support for your convenience/frustration". Use __gshared for accessing C globals, and otherwise only if you know what you are doing. There are many aspects of D that make assumptions based on whether a type is shared or not. -Steve
Re: How to create instance of class that get data from 2 another instance?
Oh mama mia! I did it! http://www.everfall.com/paste/id.php?a5pp73ns1e4k auto seismodownload = new seismoDownload(emsc_csem, this); then: auto mysql = new MySQL(parseconfig,eqs); So could anybody show me better way? As I said I did not fully understand how use global class instance...
Re: What exactly shared means?
On Friday, 2 January 2015 at 20:32:51 UTC, Steven Schveighoffer wrote: On 1/2/15 2:47 PM, John Colvin wrote: Are you sure about all this optimisation stuff? I had (perhaps wrongly) assumed that __gshared and shared variables in D guaranteed Sequential Consistency for Data Race Free (SCDRF) and nothing more, just like all normal variables in C, C++ and Java. There is nothing special about __gshared other than where it is put. Real simple test: __gshared int x; void main() { int xlocal; int *xp = (rand() % 2) ? &x; &xlocal; *xp = 5; } tell me how the compiler can possibly know anything about what type of data xp points at? But with shared, the type itself carries the hint that the data is shared between threads. At this point, this guarantees nothing in terms of races and ordering, which is why shared is so useless. In fact the only useful aspect of shared is that data not marked as shared is guaranteed thread local. If I'm correct, then the advice to users would be "Use __gshared and pretend you're writing C/C++/Java, or use shared and do exactly the same but with type-system support for your convenience/frustration". Use __gshared for accessing C globals, and otherwise only if you know what you are doing. There are many aspects of D that make assumptions based on whether a type is shared or not. -Steve Perhaps a more precise statement of affairs would be this: All variables/data are SC-DRF with the exception of static variables and globals, which are thread-local. `shared` exists only to express via the type-system the necessity of thread-safe usage, without prescribing or implementing said usage. Hmm. I went in to writing that thinking "shared isn't so bad". Now I've thought about it, it is pretty damn useless. What's the point of knowing that data is shared without knowing how to safely use it? I guess it protects against completely naive usage. Couldn't we have thread-safe access encapsulated within types a-la std::atomic?
Re: What exactly shared means?
On Friday, 2 January 2015 at 21:06:03 UTC, John Colvin wrote: Hmm. I went in to writing that thinking "shared isn't so bad". Now I've thought about it, it is pretty damn useless. What's the point of knowing that data is shared without knowing how to safely use it? I guess it protects against completely naive usage. The real issue with "shared" is that objects may change status during runtime based on the state of the program. What you really want to know is when a parameter is "local", that is, guaranteed to not be accessed by another thread during the execution of the function. If so you open up for optimizations.
Re: What exactly shared means?
On Friday, 2 January 2015 at 22:10:36 UTC, Ola Fosheim Grøstad wrote: On Friday, 2 January 2015 at 21:06:03 UTC, John Colvin wrote: Hmm. I went in to writing that thinking "shared isn't so bad". Now I've thought about it, it is pretty damn useless. What's the point of knowing that data is shared without knowing how to safely use it? I guess it protects against completely naive usage. The real issue with "shared" is that objects may change status during runtime based on the state of the program. What you really want to know is when a parameter is "local", that is, guaranteed to not be accessed by another thread during the execution of the function. If so you open up for optimizations. What significant optimisations does SC-DRF actually prevent?
Re: What exactly shared means?
On Friday, January 02, 2015 19:47:50 John Colvin via Digitalmars-d-learn wrote: > On Friday, 2 January 2015 at 13:14:14 UTC, Jonathan M Davis via > Digitalmars-d-learn wrote: > > Objects in D default to being thread-local. __gshared and > > shared both make > > it so that they're not thread-local. __gshared does it without > > actually > > changing the type, making it easier to use but also dangerous > > to use, > > because it makes it easy to violate the compiler's guarantees, > > because it'll > > treat it like a thread-local variable with regards to > > optimizations and > > whatnot. > > I'm pretty sure that's not true. __gshared corresponds to C-style > globals, which are *not* assumed to be thread-local (see below). No, the type system will treat __gshared like a thread-local variable. It gets put in shared memory like a C global would be, but __gshared isn't actually part of the type, so the compiler has no way of knowing that it's anything other than a thread-local variable - which is precisely why it's so dangerous to use it instead of shared. For instance, __gshared int* foo; void main() { foo = new int; int* bar = foo; } will compile just fine, whereas if you used shared, it wouldn't. - Jonathan M Davis
Re: What exactly shared means?
On Friday, January 02, 2015 15:32:51 Steven Schveighoffer via Digitalmars-d-learn wrote: > In fact the > only useful aspect of shared is that data not marked as shared is > guaranteed thread local. That and the fact that you're supposed to be able to know which portions of your program are operating on shared data quite easily that way, as opposed to it potentially being scattered everywhere through a program like it can be in languages like C++ or Java. But it definitely doesn't provide any of the kinds of compiler guarantees that we all wanted it to. The result is that it's arguably a bit like C++'s const in that it helps, but it really doesn't ultimately provide strong guarantees. Personally, I think that we're still far better off using shared the way it is than using __gshared or being stuck with what C++ and the like have, but there's no question that it's not where we want it to be. - Jonathan M Davis
Re: What exactly shared means?
On Friday, 2 January 2015 at 23:26:57 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: On Friday, January 02, 2015 19:47:50 John Colvin via Digitalmars-d-learn wrote: On Friday, 2 January 2015 at 13:14:14 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: > Objects in D default to being thread-local. __gshared and > shared both make > it so that they're not thread-local. __gshared does it > without > actually > changing the type, making it easier to use but also dangerous > to use, > because it makes it easy to violate the compiler's > guarantees, > because it'll > treat it like a thread-local variable with regards to > optimizations and > whatnot. I'm pretty sure that's not true. __gshared corresponds to C-style globals, which are *not* assumed to be thread-local (see below). No, the type system will treat __gshared like a thread-local variable. It gets put in shared memory like a C global would be, but __gshared isn't actually part of the type, so the compiler has no way of knowing that it's anything other than a thread-local variable - which is precisely why it's so dangerous to use it instead of shared. For instance, __gshared int* foo; void main() { foo = new int; int* bar = foo; } will compile just fine, whereas if you used shared, it wouldn't. - Jonathan M Davis I understand that. As far as optimisations and codegen go, that is not the same as being able to assume that something is thread-local, far from it. The rule (in C(++) at least) is that all data is assumed to be visible and mutable from multiple other threads unless proved otherwise. However, given that you do not write a race, the compiler will provide full sequential consistency. If you do write a race though, all bets are off. Are you telling me that D does not obey the C(++) memory model? That would be a fatal hole in our C(++) interoperability. AFAIK, the only data in D that the compiler is allowed to assume to be thread-local is data that it can prove is thread-local. The trivial case is TLS, which is thread-local by definition.
Re: What exactly shared means?
On Friday, 2 January 2015 at 23:10:46 UTC, John Colvin wrote: What significant optimisations does SC-DRF actually prevent? By "SC-DRF" I assume you mean the Java memory model. AFAIK SCDRF just means that if you syncronize correctly (manually) then you will get sequential consistency (restriction on the compiler). Getting rid of the restrictions on the compiler and eliding programmer-provided syncronization allows for more optimizations on loads, writes, reordering, syncronization/refcounting...?
Re: What exactly shared means?
On Friday, January 02, 2015 23:51:04 John Colvin via Digitalmars-d-learn wrote: > AFAIK, the only data in D that the compiler is allowed to assume > to be thread-local is data that it can prove is thread-local. The > trivial case is TLS, which is thread-local by definition. In D, if a type is not marked as shared, then it is by definition thread-local, and the compiler is free to assume that it's thread-local. If it's not actually thread-local (e.g. because you cast away shared), then it's up to you to ensure that no other threads access that data while it's being referred to via a reference or pointer that's typed as thread-local. The only exception is immutable, in which case it's implicitly shared, because it can never change, and there's no need to worry about multiple threads accessing the data at the same time. - Jonathan M Davis
Re: What exactly shared means?
On Friday, 2 January 2015 at 23:51:05 UTC, John Colvin wrote: The rule (in C(++) at least) is that all data is assumed to be visible and mutable from multiple other threads unless proved otherwise. However, given that you do not write a race, the compiler will provide full sequential consistency. If you do write a race though, all bets are off. The memory is visible and mutable, but that's pretty much the only guarantee you get. Without synchronization, there's no guarantee a write made by thread A will ever be seen by thread B, and vice versa. Analogously in D, if a thread modifies a __gshared variable, there's no guarantees another thread will ever see that modification. The variable isn't thread local, but it's almost as if the compiler to treat it that way. These relaxed guarantees allow the compiler to keep variables in registers, and re-order memory writes. These optimizations are crucial to performance.
cannot modify struct with immutable members
I get the following error from the code below: (dmd2.066.1, linux) test.d(26): Error: cannot modify struct myTest1 Test with immutable members Is this expected? If so, how can I achieve this result - being able to set (a new) initial value of myTest1 from within an nested function ? thanks ! ted code: struct A { int someInt; } struct Test { this( ref const(A) arg ) { mA = arg; } private: const(A) mA; } void main() { Test myTest1; A topA; void _someFunc( ref const(A) myA ) { myTest1 = Test(myA); } Test myTest2 = Test(topA); // is ok as expected _someFunc( topA );// error. }
Re: cannot modify struct with immutable members
On Sat, 03 Jan 2015 13:25:31 +1030 ted via Digitalmars-d-learn wrote: > > I get the following error from the code below: (dmd2.066.1, linux) > test.d(26): Error: cannot modify struct myTest1 Test with immutable members > > Is this expected? > > If so, how can I achieve this result - being able to set (a new) initial > value > of myTest1 from within an nested function ? > > thanks ! > ted > > > code: > struct A > { > int someInt; > } > > struct Test > { > this( ref const(A) arg ) > { > mA = arg; > } > > private: > const(A) mA; > } > > void main() > { > Test myTest1; > A topA; > > void _someFunc( ref const(A) myA ) > { > myTest1 = Test(myA); > } > > Test myTest2 = Test(topA); // is ok as expected > _someFunc( topA ); // error. > } the question is: "why do you want `mA` to be const?" leaving aside compiler complaints this is the one and important question. let's try to fix your code instead of devising workarounds to beat the compiler. ;-) please remember that D `const` is not the same as C/C++ `const`, so my question is not so stupid as it may look. p.s. you can use `in A myA` instead of `ref const A myA`, in most cases compiler is intelligent enough to use "pass-by-reference" for `in` args. signature.asc Description: PGP signature
Re: cannot modify struct with immutable members
Hi, thanks for the reply...to answer your direct question, the original code looked like: struct A { int someInt; } struct Test { @property { const(A) getA() { return mA; } } this( ref const(A) arg ) { mA = arg; } private: A mA; } void main() { Test myTest1; A topA; void _someFunc( ref const(A) myA ) { myTest1 = Test(myA); } Test myTest2 = Test(topA); // is ok as expected _someFunc( topA ); // later on A foo = myTest1.getA(); } which compiles. However, I think I exercised some other compiler-related bug when I added a field to another structure in the module, and the compiler started complaining about the construct above... 'Error: cannot implicitly convert expression (arg) of type const(A) to A' in the constructor of Test (I'm unable to recreate this error in this simple code example). (I am prototyping something, so the code I'm producing is very badly structured, and I have nested functions within delegates within and I have also hit some odd scoping errors - definite compiler issues - (notwithstanding the horrible code structure)). so (given my D knowledge is limited) I then wondered why it accepted (nonconst)mA=(const)arg in the first place, hence the const()...hence the original question. I am assuming that the ref const(A) myA means that _someFunc (and below) is unable to alter any fields of myA. This may be my basic error. thanks ! ketmar via Digitalmars-d-learn wrote: > On Sat, 03 Jan 2015 13:25:31 +1030 > ted via Digitalmars-d-learn wrote: > >> >> I get the following error from the code below: (dmd2.066.1, linux) >> test.d(26): Error: cannot modify struct myTest1 Test with immutable members >> >> Is this expected? >> >> If so, how can I achieve this result - being able to set (a new) initial >> value of myTest1 from within an nested function ? >> >> thanks ! >> ted >> >> >> code: >> struct A >> { >> int someInt; >> } >> >> struct Test >> { >> this( ref const(A) arg ) >> { >> mA = arg; >> } >> >> private: >> const(A) mA; >> } >> >> void main() >> { >> Test myTest1; >> A topA; >> >> void _someFunc( ref const(A) myA ) >> { >> myTest1 = Test(myA); >> } >> >> Test myTest2 = Test(topA); // is ok as expected >> _someFunc( topA ); // error. >> } > > the question is: "why do you want `mA` to be const?" leaving aside > compiler complaints this is the one and important question. let's try > to fix your code instead of devising workarounds to beat the > compiler. ;-) > > please remember that D `const` is not the same as C/C++ `const`, so my > question is not so stupid as it may look. > > p.s. you can use `in A myA` instead of `ref const A myA`, in most cases > compiler is intelligent enough to use "pass-by-reference" for `in` args.
Re: cannot modify struct with immutable members
Well, I just cleared up some of my misunderstanding. I did not realise the mA (within struct Test) would be a _copy_ of arg, not a reference (pointer) to arg. So the more correct code snippet would be: struct A { int someInt; } struct Test { @property { const(A) getA() { return *mA; } } this( in A arg ) { mA = &arg; } private: const A* mA; } void main() { Test myTest1; A topA; topA.someInt = 100; void _someFunc( in A myA ) { myTest1 = Test(myA); } Test myTest2 = Test(topA); // is ok as expected _someFunc( topA ); } which fails to compile for the same reason (test.d(30): Error: cannot modify struct myTest1 Test with immutable members) (I have been able to work around my original issue by removing @safe from Test, and then cast()ing ... but this is ugly) This code snippet is me trying to understand whether I have a fundamental misunderstanding with const, or whether it is an issue with the compiler (I agree with your view that 'fixing my code' is the correct approach, btw - I'm still curious). (The reason for this basic structure is that _someFunc is a callback from another module, and myTest1 contains state information that is created/adjusted via the callback. And (to be safe) myTest1 contains references to other structures that it should not adjust - hence the const()). and I can't use @safe and pointers.. So, it appears I need to do what I want with classes, not structs: i.e. import std.stdio; class A { int someInt; } @safe class Test { @property { const(A) getA() { return mA; } } this( in A arg ) { mA = arg; } private: const A mA; } void main() { Test myTest1; A topA = new A; topA.someInt = 100; void _someFunc( in A myA ) { myTest1 = new Test(myA); } Test myTest2 = new Test(topA); // is ok as expected _someFunc( topA ); writeln( "topA: ", topA.someInt ); writeln( "myTest1.A: ", myTest1.getA.someInt ); } I'm happy I've got a workaround (which seems to safely preserve the const'dness), but I still don't understand why the compiler barfs on the struct version as it should be 'replacing' the higher scoped variable anyway...thanks for your response.apologies for the streaming conciousness of this reply...
Re: cannot modify struct with immutable members
On Sat, 03 Jan 2015 14:45:24 +1030 ted via Digitalmars-d-learn wrote: > Well, I just cleared up some of my misunderstanding. > > I did not realise the mA (within struct Test) would be a _copy_ of arg, not > a reference (pointer) to arg. > > So the more correct code snippet would be: > > struct A > { > int someInt; > } > > struct Test > { > @property { const(A) getA() { return *mA; } } > this( in A arg ) > { > mA = &arg; > } > > private: > const A* mA; > } > > void main() > { > Test myTest1; > A topA; > > topA.someInt = 100; > > void _someFunc( in A myA ) > { > myTest1 = Test(myA); > } > > Test myTest2 = Test(topA); // is ok as expected > _someFunc( topA ); > > > } nonononono! ;-) please, don't use pointers like this. try to avoid pointers altogether, they are VERY dangerous. as for your sample: it is already invalid. see: this (in A arg) { mA = &arg; } you are storing the address of *local* *var* *from* *stack* here. then local will go out of scope and... BANG! everyone is dead. > This code snippet is me trying to understand whether I have a fundamental > misunderstanding with const, or whether it is an issue with the compiler seems that you didn't get D `const`. it's deffers from C/C++ `const`. in most cases you don't need to use it at all. the funny thing of D const is that const "variable" cannot be changed in any way after assigning. that's why compiler complains: you're trying to change variable with `const` part, which is forbidden. structure instance with const fields can be initialized only once, upon creation. so did `Test myTest1;` -- you initialized `myTest1` with default values. you can't reinitialize it later. in C++ constness on member doesn't impose such restrictions. this is confusing for newcomers with C/C++ expirience. the best advice here is "don't use `const` in D unless you are fully understand what you are doing and how it work in D". > I'm happy I've got a workaround (which seems to safely preserve the > const'dness), but I still don't understand why the compiler barfs on the > struct version as it should be 'replacing' the higher scoped variable you don't need `const` here at all. as far as i can see you want to tell the compiler that `mA` must not be changed after creating a struct. to achieve that you'd better move your struct to separate module and provide read-only getter. you need to move your struct to separate module 'cause `private` modifier will not affect the code in the same module. one of the D rules is that the code in one module can access anything that was declared in the same module, including "private" members of structs/classes. C++ tries to achieve that with "friend" members, but as D has full-fledged module system, it doesn't need such tricks. tl;dr: don't use `const` here, provide an accessor and stop worrying/helping the compiler. ;-) signature.asc Description: PGP signature
Re: cannot modify struct with immutable members
On Sat, 03 Jan 2015 14:45:24 +1030 ted via Digitalmars-d-learn wrote: p.s. also please note that structs in D are always passed by value and copied (until you not explicitly ask for something another). so: MyStruct a; MyStruct b; b = a; actually does `memcpy()` (with postblit if there is any). and it's forbidden to overwrite `const` variable contents. that's why compiler complains: by assigning to `mA` you are trying to overwrite contents of `const` variable. signature.asc Description: PGP signature
Re: cannot modify struct with immutable members
ketmar via Digitalmars-d-learn wrote: > On Sat, 03 Jan 2015 14:45:24 +1030 > ted via Digitalmars-d-learn wrote: > >> Well, I just cleared up some of my misunderstanding. >> >> I did not realise the mA (within struct Test) would be a _copy_ of arg, >> not a reference (pointer) to arg. >> >> So the more correct code snippet would be: >> >> struct A >> { >> int someInt; >> } >> >> struct Test >> { >> @property { const(A) getA() { return *mA; } } >> this( in A arg ) >> { >> mA = &arg; >> } >> >> private: >> const A* mA; >> } >> >> void main() >> { >> Test myTest1; >> A topA; >> >> topA.someInt = 100; >> >> void _someFunc( in A myA ) >> { >> myTest1 = Test(myA); >> } >> >> Test myTest2 = Test(topA); // is ok as expected >> _someFunc( topA ); >> >> >> } > nonononono! ;-) > please, don't use pointers like this. try to avoid pointers altogether, > they are VERY dangerous. as for your sample: it is already invalid. see: > > this (in A arg) { mA = &arg; } > > you are storing the address of *local* *var* *from* *stack* here. then > local will go out of scope and... BANG! everyone is dead. Oops...true (*blush*) - should have noticed this. > >> This code snippet is me trying to understand whether I have a >> fundamental misunderstanding with const, or whether it is an issue with >> the compiler > seems that you didn't get D `const`. it's deffers from C/C++ `const`. > in most cases you don't need to use it at all. the funny thing of D > const is that const "variable" cannot be changed in any way after > assigning. that's why compiler complains: you're trying to change > variable with `const` part, which is forbidden. > > structure instance with const fields can be initialized only once, upon > creation. so did `Test myTest1;` -- you initialized `myTest1` with > default values. you can't reinitialize it later. > > in C++ constness on member doesn't impose such restrictions. this is > confusing for newcomers with C/C++ expirience. the best advice here is > "don't use `const` in D unless you are fully understand what you are > doing and how it work in D". Ironically, I'm trying to use const in an effort to understand it...but there seems to be an unusual amount of pain until I grok it. > >> I'm happy I've got a workaround (which seems to safely preserve the >> const'dness), but I still don't understand why the compiler barfs on the >> struct version as it should be 'replacing' the higher scoped >> variable > you don't need `const` here at all. as far as i can see you want to > tell the compiler that `mA` must not be changed after creating a > struct. to achieve that you'd better move your struct to separate > module and provide read-only getter. > > you need to move your struct to separate module 'cause `private` > modifier will not affect the code in the same module. one of the D > rules is that the code in one module can access anything that was > declared in the same module, including "private" members of > structs/classes. C++ tries to achieve that with "friend" members, but > as D has full-fledged module system, it doesn't need such tricks. > > tl;dr: don't use `const` here, provide an accessor and stop > worrying/helping the compiler. ;-) Yeah.its one of those cases where the prototype code is getting too ugly, and a refactorisation is required.but no time !! many thanks, ted
Re: cannot modify struct with immutable members
On Sat, 03 Jan 2015 15:56:58 +1030 ted via Digitalmars-d-learn wrote: > Ironically, I'm trying to use const in an effort to understand it...but > there seems to be an unusual amount of pain until I grok it. just remember that `const` "infects" everything down to the bytes when it's applied. and it's forbidden to overwrite `const` vars with different values. in your canse it "infects" your `A` struct, effectively converting it to `const A` (with `const int someInt`). and as you can't change "consted" value, and structs are `memcpy()`ed... compiler tracked that down and refused to do it. so you don't really need `const` fields in D. you can make getters `const` though, so that they can be used on `const MyStruct` instances. so two rules should help you here: 1. it's forbidden to overwrite `const` vars with new values. 2. `const` will infect everything down to bytes. maybe this will help you like it helps me. ;-) signature.asc Description: PGP signature
Re: cannot modify struct with immutable members
ketmar via Digitalmars-d-learn wrote: > On Sat, 03 Jan 2015 15:56:58 +1030 > ted via Digitalmars-d-learn wrote: > >> Ironically, I'm trying to use const in an effort to understand it...but >> there seems to be an unusual amount of pain until I grok it. > just remember that `const` "infects" everything down to the bytes when > it's applied. and it's forbidden to overwrite `const` vars with > different values. > > in your canse it "infects" your `A` struct, effectively converting it > to `const A` (with `const int someInt`). and as you can't change > "consted" value, and structs are `memcpy()`ed... compiler tracked that > down and refused to do it. > > so you don't really need `const` fields in D. you can make getters > `const` though, so that they can be used on `const MyStruct` instances. > > so two rules should help you here: > 1. it's forbidden to overwrite `const` vars with new values. > 2. `const` will infect everything down to bytes. > > maybe this will help you like it helps me. ;-) Thanks for your helpbesides the issues that you pointed out, I had forgotten that structs are always copied (I'm so used to thinking in pointers (if you ignore the fubar from my earlier example) - and a world where copying data structures is an expensive exercise to be avoided)... I'm now taking the view that const is there for the compiler to optimise code on the basis that nothing can alter it once set (and can only be set on initialisation). So I see your point that it would not be used very often in general defensive code - better to provide access restrictions (getters) for most cases. I am refactoring the code to use getters/setters One of the really good things about D is that it is relatively painless to refactor when you have to - much less boilerplate to have to move around ! thanks again, regards, ted
Re: cannot modify struct with immutable members
On Sat, 03 Jan 2015 16:40:14 +1030 ted via Digitalmars-d-learn wrote: > I'm now taking the view that const is there for the compiler to optimise > code on the basis that nothing can alter it once set (and can only be set > on initialisation). So I see your point that it would not be used very > often in general defensive code - better to provide access restrictions > (getters) for most cases. exactly! ;-) > thanks again, you're welcome. hope you will keep enjoying D, it's great. ;-) signature.asc Description: PGP signature