digitalmars.D.learn - [static] [shared] [const|immutable]
- Lionello Lunesu (53/53) May 14 2009 I like shared/const/immutable as much as the next guy, but there are now...
- Christopher Wright (9/13) May 14 2009 The decision to make a variable a static class or module member is
- Lionello Lunesu (14/27) May 14 2009 You're right, of course. I realize now that "static" is a storage class
- Christopher Wright (18/54) May 14 2009 Immutable is threadsafe. Shared implies automatic locking, I believe;
- Lionello Lunesu (5/48) May 18 2009 So one has to wonder what code will be generated for "shared
- Christopher Wright (6/8) May 18 2009 If that happens, Walter will get a bug report, and he'll change it so
- BCS (11/20) May 14 2009 // without lookin up the details of threading
- BCS (11/20) May 14 2009 // without lookin up the details of threading
- Lionello Lunesu (7/31) May 18 2009 :O Indeed, that works! Which is scary, since the compiler did not detect...
- BCS (12/30) May 14 2009 static global is redundent
I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post. Surely, some combinations should/can be disallowed? * What's the point of "shared immutable"? * What about a locally declared "shared" variable? (The stack is implicit TLS anyway.) * Come to think of it, what's the difference between a "const int" and a "immutable int"? (Is "const" only meant to be used in a function's argument list?) L. (From the results it's apparent that "static" on the global level does not actually do anything (probably kept for C/C++ compatibility where it's used to mean "private") and that "static" used locally declares the variable as if it were global. This makes sense.) //The code: int f = 0xDEAD0001; //0678 const int cf = 0xDEAD0002; //068d immutable int _if = 0xDEAD0003; //068d shared int sf = 0xDEAD0011; //068d shared const int scf = 0xDEAD0012; //068d shared immutable int sif = 0xDEAD0013; //068d static int Sf = 0xDEAD0101; //0678 static const int Scf = 0xDEAD0102; //068d static immutable int Sif = 0xDEAD0103; //068d static shared int Ssf = 0xDEAD0111; //068d static shared const int Sscf = 0xDEAD0112; //068d static shared immutable int Ssif = 0xDEAD0113; //068d int main() { int f_ = 0xDEAD1001; //073c** const int cf_ = 0xDEAD1002; //073c* immutable int if_ = 0xDEAD1003; //073c* shared int sf_ = 0xDEAD1011; //073c** shared const int scf_ = 0xDEAD1012; //073c* shared immutable int sif_ = 0xDEAD1013; //073c* static int Sf_ = 0xDEAD1101; //0678 static const int Scf_ = 0xDEAD1102; //068d static immutable int Sif_ = 0xDEAD1103; //068d static shared int Ssf_ = 0xDEAD1111; //068d static shared const int Sscf_ = 0xDEAD1112; //068d static shared immutable int Ssif_ = 0xDEAD1113; //068d // prevent optimization return f+cf+_if+sf+scf+sif+Sf+Scf+Sif+Ssf+Sscf+Ssif+ f_+cf_+if_+sf_+scf_+sif_+Sf_+Scf_+Sif_+Ssf_+Sscf_+Ssif_; } // The numbers in comments represent the sections as printed by dumpbin: //0678 LED386 (TLS?) //068d LED386 (global) //073c CMD386 (code) //* only appears in obj when compiled with -g //** does not appear in obj when compiled with -O
May 14 2009
Lionello Lunesu wrote:I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post.The decision to make a variable a static class or module member is independent of whether to make it shared or not. Shared and const-level have to do with controlling access to the variable. An immutable variable does not need to be declared shared. Shared const is for publish-subscribe sort of deals. Shared mutable is for cooperative writing to the variable. The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble.
May 14 2009
"Christopher Wright" <dhasenan gmail.com> wrote in message news:gugs7b$70p$1 digitalmars.com...Lionello Lunesu wrote:You're right, of course. I realize now that "static" is a storage class (when used locally) not a type modifier.I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post.The decision to make a variable a static class or module member is independent of whether to make it shared or not.Shared and const-level have to do with controlling access to the variable. An immutable variable does not need to be declared shared.So, immutable implies shared.Shared const is for publish-subscribe sort of deals.You mean one thread can change the value, but for another thread it's constant? I can see how it would be useful using reference types, but I don't understand how it would work with value types..Shared mutable is for cooperative writing to the variable.This one I understood :)The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble.As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please? Thanks, L.
May 14 2009
Lionello Lunesu wrote:"Christopher Wright" <dhasenan gmail.com> wrote in message news:gugs7b$70p$1 digitalmars.com...Immutable is threadsafe. Shared implies automatic locking, I believe; immutable variables do not need any locking.Lionello Lunesu wrote:You're right, of course. I realize now that "static" is a storage class (when used locally) not a type modifier.I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post.The decision to make a variable a static class or module member is independent of whether to make it shared or not.Shared and const-level have to do with controlling access to the variable. An immutable variable does not need to be declared shared.So, immutable implies shared.Shared const doesn't really work for value types; it ends up being the same as immutable. Unless you have a mutable pointer to the value, in which case you can write to the value through that pointer. That is not safe -- the compiler is free to see that this variable is const and a value type, which means you can't ever write to it, and then put it in read-only memory. Const that doesn't boil down to immutable works a fair bit better with object-oriented code. You wrap your value in a class, create a mutable instance, and send it to a bunch of other functions or objects or threads expecting a const object. They can't use the mutators, but they can use the accessors.Shared const is for publish-subscribe sort of deals.You mean one thread can change the value, but for another thread it's constant? I can see how it would be useful using reference types, but I don't understand how it would work with value types..By reference. int i; shared int* j = &i; sendToManyThreads(j);Shared mutable is for cooperative writing to the variable.This one I understood :)The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble.As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please?
May 14 2009
Christopher Wright wrote:Lionello Lunesu wrote:So one has to wonder what code will be generated for "shared immutable".. an immutable with (useless) locking?"Christopher Wright" <dhasenan gmail.com> wrote in message news:gugs7b$70p$1 digitalmars.com...Immutable is threadsafe. Shared implies automatic locking, I believe; immutable variables do not need any locking.Lionello Lunesu wrote:You're right, of course. I realize now that "static" is a storage class (when used locally) not a type modifier.I like shared/const/immutable as much as the next guy, but there are now 2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the variable globally or locally (stack), we end up with 24 possible declaration. See the code at the end of this post.The decision to make a variable a static class or module member is independent of whether to make it shared or not.Shared and const-level have to do with controlling access to the variable. An immutable variable does not need to be declared shared.So, immutable implies shared.Got it. Thanks.. L.Shared const doesn't really work for value types; it ends up being the same as immutable. Unless you have a mutable pointer to the value, in which case you can write to the value through that pointer. That is not safe -- the compiler is free to see that this variable is const and a value type, which means you can't ever write to it, and then put it in read-only memory. Const that doesn't boil down to immutable works a fair bit better with object-oriented code. You wrap your value in a class, create a mutable instance, and send it to a bunch of other functions or objects or threads expecting a const object. They can't use the mutators, but they can use the accessors.Shared const is for publish-subscribe sort of deals.You mean one thread can change the value, but for another thread it's constant? I can see how it would be useful using reference types, but I don't understand how it would work with value types..
May 18 2009
Lionello Lunesu wrote:So one has to wonder what code will be generated for "shared immutable".. an immutable with (useless) locking?If that happens, Walter will get a bug report, and he'll change it so that shared immutable variables are silently converted to non-shared immutable variables. That currently happens with incompatible type modifiers and storage classes, I believe.
May 18 2009
Hello Lionello,"Christopher Wright" <dhasenan gmail.com> wrote in message// without lookin up the details of threading void main() { int i; with(new Thread({i++;})) { Start(); Wait(); } }The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble.As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please?
May 14 2009
Hello Lionello,"Christopher Wright" <dhasenan gmail.com> wrote in message// without lookin up the details of threading void main() { int i; with(new Thread({i++;})) { Start(); Wait(); } }The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble.As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please?
May 14 2009
BCS wrote:Hello Lionello,:O Indeed, that works! Which is scary, since the compiler did not detect the access to 'i' from another thread. In this case the code is safe, but only because of the Wait/join at the end.. This looks like a hole in the shared/tls system and there's nothing the compiler can do about it. :( L."Christopher Wright" <dhasenan gmail.com> wrote in message// without lookin up the details of threading void main() { int i; with(new Thread({i++;})) { Start(); Wait(); } }The point of a shared local variable is to pass it to another thread or set of threads, which will then be able to mutate it without trouble.As before, how can an int (value type) on the stack ever be shared with another thread? It would always have to be copied... Can you give me an example please?
May 18 2009
Hello Lionello,//The code:immutable need not be sharedshared immutable int sif = 0xDEAD0013; //068dstatic global is redundentstatic int Sf = 0xDEAD0101; //0678 static const int Scf = 0xDEAD0102; //068d static immutable int Sif = 0xDEAD0103; //068d static shared int Ssf = 0xDEAD0111; //068d static shared const int Sscf = 0xDEAD0112; //068d static shared immutable int Ssif = 0xDEAD0113; //068dint main() {I'm not shure what this would be used forshared const int scf_ = 0xDEAD1012; //073c*immutable need not be sharedshared immutable int sif_ = 0xDEAD1013; //073c*I'm not shure what this would be used forstatic const int Scf_ = 0xDEAD1102; //068dI think this is redundentstatic immutable int Sif_ = 0xDEAD1103; //068dI'm not shure what this would be used forstatic shared const int Sscf_ = 0xDEAD1112; //068dimmutable need not be sharedstatic shared immutable int Ssif_ = 0xDEAD1113; //068dBy my count 13 of the 24 cases are never needed in paractace as they end up redundent. FWIW, I like the current setup.
May 14 2009