Jump to page: 1 2
Thread overview
Auto keyword with const variable
Jul 24, 2013
Alex H
Jul 24, 2013
bearophile
Jul 24, 2013
dennis luehring
Jul 24, 2013
bearophile
Jul 24, 2013
monarch_dodra
Jul 24, 2013
Artur Skawina
Jul 24, 2013
monarch_dodra
Jul 24, 2013
Artur Skawina
Jul 24, 2013
MGW
Jul 24, 2013
Mike Parker
Jul 25, 2013
bsd
Jul 25, 2013
Dicebot
Jul 25, 2013
Jonathan M Davis
July 24, 2013
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.
July 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
July 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
July 24, 2013
Am 24.07.2013 11:39, schrieb bearophile:
> 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.

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?



July 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
July 24, 2013
On Wednesday, 24 July 2013 at 10:01:14 UTC, bearophile wrote:
> 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

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.
July 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.
July 24, 2013
On Wednesday, 24 July 2013 at 10:37:40 UTC, Artur Skawina wrote:
> 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)

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
}
//----
July 24, 2013
On 07/24/13 12:54, monarch_dodra wrote:
> On Wednesday, 24 July 2013 at 10:37:40 UTC, Artur Skawina wrote:
>> 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)
> 
> Nope. Stop. Wrong. Qualification is transitive in D, unlike in C++. Even when copying, stripping qualification is not safe:

"*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).

artur
July 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;
« First   ‹ Prev
1 2