const->immutable array argument?

Steven Schveighoffer schveiguy at yahoo.com
Tue Sep 20 05:35:07 PDT 2011


On Tue, 20 Sep 2011 07:33:20 -0400, bearophile <bearophileHUGS at lycos.com>  
wrote:

> In this bug report I have asked for better error messages:
> http://d.puremagic.com/issues/show_bug.cgi?id=6696
>
> But beside the error message, do you know why an immutable ref can't be  
> given to a function with a const ref argument? foo() can't change the  
> contents of the array a any way, so what's wrong in this code?
>
>
> void foo(const ref int[5] a) {}
> void main() {
>     immutable int[5] arr;
>     foo(arr); // Error?
> }

The complaint from the compiler is that cast(const(int[5u])) arr is not an  
lvalue.

So apparently, the compiler wants to *copy* arr (via cast), then ref that.

This smells like a bug, but could potentially be intended behavior.

There is a workaround, but it's UGLY and dangerous:

foo(*(cast(const(int[5])*)&arr));

I think the rules for implicit casting need to take into account whether  
it can use this kind of rewrite.

I'd file a bug, but note that it could possibly be an enhancement.

BTW, there are some funky things that happen with an immutable storage  
class.  For example:

void foo(ref const(int) a) {}
void bar(immutable int a) { foo(a); }
void main()
{
    immutable int a = 5;
    foo(a); // error, see below
    bar(a); // ok
}

The error for the foo(a) line is:
Error: constant 5 is not an lvalue

So the compiler is apparently replacing a with an enum.  But if it's a  
parameter, it gets storage on the stack.  That doesn't seem right.  I  
thought immutable data was supposed to live where you declare it, and  
that's why you use enum to force it to be a compile-time constant.

The same trick does not work with a fixed-size array, so I think  
definitely the original issue is a bug (behavior should be consistent with  
int).

-Steve


More information about the Digitalmars-d-learn mailing list