[Issue 12936] Some more @nogc cases for immediately iterated array literal

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Thu May 19 06:05:57 PDT 2016


https://issues.dlang.org/show_bug.cgi?id=12936

Kenji Hara <k.hara.pg at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull
           Hardware|x86                         |All
                 OS|Windows                     |All

--- Comment #2 from Kenji Hara <k.hara.pg at gmail.com> ---
(In reply to bearophile_hugs from comment #0)
> 
> struct F { int x; }
> void main() @nogc {
>     foreach (       a; [F(1)]) {}           // Case#1 OK
>     foreach (int[1] a; [[1]]) {}            // Case#2 Error
>     foreach (const ref int[1] a; [[1]]) {}  // Case#3 Error
>     foreach (       a; [[1]]) {}            // Case#4 Error
> }

For case#2, it's possible enhancement because int[1] a is a copy of iterated
array literal element.

For case#3, it's not safe because an address of stack allocated array literal
can escape out of the lifetime.

    const(int)* p;
    foreach (const ref int[1] a; [[1]]) { p = &a[0]; }
    // After the foreach, p wold point invalid stack address.

Note that similar situation is properly rejected.

    void foo(ref int[1] sa) {}
    void main() {
        foo([1]);   // array literal never become stack allocated because
                    // its address can escape out via the ref parameter.
    }

For case#4 supporting it would cause inconsistent type inference result.

    void foo() {
        foreach (a; [[1]]) { pragma(msg, typeof(a)); }  // prints int[]
    }
    void bar() @nogc {
        foreach (a; [[1]]) { pragma(msg, typeof(a)); }  // prints int[] or
int[1]?
    }

I opened a compiler improvement for case#2:
https://github.com/dlang/dmd/pull/5795

--


More information about the Digitalmars-d-bugs mailing list