digitalmars.D.learn - Auto keyword with const variable
- Alex H (10/10) Jul 24 2013 This code:
- bearophile (6/15) Jul 24 2013 It's a bit annoying. I don't remember people discussing this
- dennis luehring (4/20) Jul 24 2013 should that be fixed - i don't think that any auto removal of
- bearophile (9/11) Jul 24 2013 You could write:
- monarch_dodra (24/35) Jul 24 2013 Definitly. Auto means "same type". I think it could be OK if it
- Artur Skawina (18/19) Jul 24 2013 No, it's a design bug. The head qualifier(s) should always be stripped
- monarch_dodra (39/45) Jul 24 2013 Nope. Stop. Wrong. Qualification is transitive in D, unlike in
- Artur Skawina (11/19) Jul 24 2013 "*Head* qualifier(s)". Why do I always end up quoting myself? ;)
- MGW (5/16) Jul 24 2013 There is no error. All right.
- Mike Parker (8/19) Jul 24 2013 This is the exact behavior I would expect. I think of auto as
- bsd (21/28) Jul 24 2013 +1
- Dicebot (5/12) Jul 25 2013 Casting is always an extreme measure, one that should be avoided
- Jonathan M Davis (6/20) Jul 24 2013 The behavior is correct and desirable. It would be a big problem for gen...
This code: void test(const int n) { auto j = n; j++; } Gives this error: cannot modify const expression j Is this considered a feature or a bug? I would assume most people wouldn't want new variables inheriting const.
Jul 24 2013
Alex H:void test(const int n) { auto j = n; j++; } Gives this error: cannot modify const expression j Is this considered a feature or a bug? I would assume most people wouldn't want new variables inheriting const.It's a bit annoying. I don't remember people discussing this small problem. I don't know if it's easy to "fix" it and what side effects such change could cause. Bye, bearophile
Jul 24 2013
Am 24.07.2013 11:39, schrieb bearophile:Alex H:should that be fixed - i don't think that any auto removal of const, immutable, shared or anything else should just happen silently and how would it look to preserve the const if auto would auto-rip it of?void test(const int n) { auto j = n; j++; } Gives this error: cannot modify const expression j Is this considered a feature or a bug? I would assume most people wouldn't want new variables inheriting const.It's a bit annoying. I don't remember people discussing this small problem. I don't know if it's easy to "fix" it and what side effects such change could cause.
Jul 24 2013
dennis luehring:and how would it look to preserve the const if auto would auto-rip it of?You could write: immutable j = n; For every default behavour you need a way to implement the other nicely :-) Currently for the problem of the OP you can use this: Unqual!(typeof(n)) j = n; Bye, bearophile
Jul 24 2013
On Wednesday, 24 July 2013 at 10:01:14 UTC, bearophile wrote:dennis luehring:Definitly. Auto means "same type". I think it could be OK if it followed IFTI rules? After all, in concept, it's kind of the same mechanism. I wouldn't go any further than that though. //---- void foo(T)(T t) { pragma(msg, T.stringof); } void main(string[] args) { immutable int[] i = [1, 2, 3]; foo(i); auto j = i; pragma(msg, typeof(j).stringof); } //---- immutable(int)[] immutable(int[]) //---- Problem: I don't really see a good usecase for making auto have special IFTI behavior. Keeping it to "same type, 100% of the time" seems like the best.and how would it look to preserve the const if auto would auto-rip it of?You could write: immutable j = n; For every default behavour you need a way to implement the other nicely :-) Currently for the problem of the OP you can use this: Unqual!(typeof(n)) j = n; Bye, bearophile
Jul 24 2013
On 07/24/13 12:09, monarch_dodra wrote:Keeping it to "same type, 100% of the time" seems like the best.No, it's a design bug. The head qualifier(s) should always be stripped when copying objects. Stripping is always fine (ie safe), not doing it just creates other problems, like the one in OP, or unnecessary template bloat. The IFTI special cases that are already there are just handling one of the symptoms. As you can always declare something as 'immutable' or 'const', instead of 'auto', the default would have to be head-mutable [1]. Ie, this would then work: const int a; immutable b = a; // immutable int const c = a; // const int auto d = a; // int Right now, you have to do `auto d = cast()a;` or use the Unqual hack... artur [1] If D had a `var` qualifier, then defaulting to 'const' might be better. But it doesn't.
Jul 24 2013
On Wednesday, 24 July 2013 at 10:37:40 UTC, Artur Skawina wrote:On 07/24/13 12:09, monarch_dodra wrote:Nope. Stop. Wrong. Qualification is transitive in D, unlike in C++. Even when copying, stripping qualification is not safe: //---- struct S { int* p; } void main() { immutable i = 1; auto a = immutable(S)(&i); auto b = cast(S)a; //Unsafe cast *b.p = 2; //This'll probably crash on a linux //Program corrupted by here. assert(i == *&i); //This fails (!!!) on my win32 } //---- Long story short, never cast to Unqual. Always to an implicit cast, and let the compiler complain if it is illegal: //---- struct S1 { int a; } struct S2 { int* p; } void main() { immutable i = 1; auto a1 = immutable(S1)(i); auto a2 = immutable(S2)(&i); S1 b1 = a1; //OK! S2 b2 = a2; //Error: cannot implicitly convert expression (a2) of type immutable(S2) to S2 } //----Keeping it to "same type, 100% of the time" seems like the best.No, it's a design bug. The head qualifier(s) should always be stripped when copying objects. Stripping is always fine (ie safe)
Jul 24 2013
On 07/24/13 12:54, monarch_dodra wrote:On Wednesday, 24 July 2013 at 10:37:40 UTC, Artur Skawina wrote:"*Head* qualifier(s)". Why do I always end up quoting myself? ;) Obviously, stripping is only fine for the copied object itself, not for any internal refs. const(int*) cpci; auto mpci = cast()cpci; // const(int)* Unqual!(typeof(cpci)) mpci2; // const(int)* This works already; it's just that having to drop the qualifiers explicitly is unnecessary and bug-prone (it's too easy to cast away a bit too much const). arturOn 07/24/13 12:09, monarch_dodra wrote:Nope. Stop. Wrong. Qualification is transitive in D, unlike in C++. Even when copying, stripping qualification is not safe:Keeping it to "same type, 100% of the time" seems like the best.No, it's a design bug. The head qualifier(s) should always be stripped when copying objects. Stripping is always fine (ie safe)
Jul 24 2013
On Wednesday, 24 July 2013 at 08:07:55 UTC, Alex H wrote:This code: void test(const int n) { auto j = n; j++; } Gives this error: cannot modify const expression j Is this considered a feature or a bug? I would assume most people wouldn't want new variables inheriting const.There is no error. All right. auto - the type expects the maximum transfer of properties from the context. int j = n; j++ // if change j
Jul 24 2013
On Wednesday, 24 July 2013 at 08:07:55 UTC, Alex H wrote:This code: void test(const int n) { auto j = n; j++; } Gives this error: cannot modify const expression j Is this considered a feature or a bug? I would assume most people wouldn't want new variables inheriting const.This is the exact behavior I would expect. I think of auto as "this variable is going to be the same type as that variable." Since in is const int, then j also is going to be const int. If you want to copy n into a nonconst variable, you have to cast away the const. int j = cast( int )n; auto j = cast( int )n;
Jul 24 2013
On Wednesday, 24 July 2013 at 11:26:32 UTC, Mike Parker wrote: ...This is the exact behavior I would expect. I think of auto as "this variable is going to be the same type as that variable." Since in is const int, then j also is going to be const int. If you want to copy n into a nonconst variable, you have to cast away the const. int j = cast( int )n; auto j = cast( int )n;+1 This works fine for pods, no cast required int j = n; ++j; ...and this does what one would expect too struct S { int* value; } void funky(const S s) { int* s1 = s.value; *s1 = 5; } /d535/f466.d(9): Error: cannot implicitly convert expression (s.value) of type const(int*) to int* void funky(const S s) { S s1 = s; *s1.value = 5; } /d297/f947.d(9): Error: cannot implicitly convert expression (s) of type const(S) to S
Jul 24 2013
On Wednesday, 24 July 2013 at 11:26:32 UTC, Mike Parker wrote:This is the exact behavior I would expect. I think of auto as "this variable is going to be the same type as that variable." Since in is const int, then j also is going to be const int. If you want to copy n into a nonconst variable, you have to cast away the const. int j = cast( int )n; auto j = cast( int )n;Casting is always an extreme measure, one that should be avoided in mundane code as much as possible. Despite the fact `auto` behaves as it should, this really highlights lack of `mutable` attribute in language.
Jul 25 2013
On Wednesday, July 24, 2013 10:07:54 Alex H wrote:This code: void test(const int n) { auto j = n; j++; } Gives this error: cannot modify const expression j Is this considered a feature or a bug? I would assume most people wouldn't want new variables inheriting const.The behavior is correct and desirable. It would be a big problem for generic code if the type of auto didn't match the right-hand side of the expression. In some cases, it might be okay if auto gave you the tail-const type, but even that could be problematic depending on the type. - Jonathan M Davis
Jul 24 2013