Thread overview
[Issue 1432] New: Bogus "overlapping initialization" error with structs, unions, and member initializers
Aug 19, 2007
d-bugmail
Apr 23, 2009
d-bugmail
Nov 27, 2011
Trass3r
Oct 01, 2013
Kenji Hara
Oct 01, 2013
Kenji Hara
August 19, 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1432

           Summary: Bogus "overlapping initialization" error with structs,
                    unions, and member initializers
           Product: D
           Version: 1.018
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: jarrett.billingsley@gmail.com


struct S
{
        int blah = 5;

        union
        {
                int x;
                T t;
                Object o;
        }
}

struct T
{
        int y;
}

Gives the error "dtest.d(26): struct dtest.S overlapping initialization for
struct S.blah"

If you remove the initializer for S.blah, or if you remove the t member from that union, or if you make the union named, it works.


-- 

April 23, 2009
http://d.puremagic.com/issues/show_bug.cgi?id=1432





------- Comment #1 from tomas@famolsen.dk  2009-04-22 21:33 -------
Another variation:

union S
{
    float[2] a;
    struct
    {
        union { float i = 1; float x; }
        union { float j = 2; float y; }
    }
}

$ dmd bar.d -c
bar.d(2): Error: union bar.S overlapping initialization for struct S.i
bar.d(2): Error: union bar.S overlapping initialization for struct S.j

If 'a' is moved below the anonymous struct it works. The spec does not mention this special case as far as I can tell. Explicit initialization of aggregate fields inside anonymous struct/union combinations should be documented.


-- 

November 27, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=1432


Trass3r <mrmocool@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mrmocool@gmx.de
           Platform|x86                         |All
         OS/Version|Windows                     |All


--- Comment #2 from Trass3r <mrmocool@gmx.de> 2011-11-27 06:08:55 PST ---
The first example compiles fine now.
Really not sure if the second should compile at all, but the order of
compilation dependence is definitely a bug.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 01, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1432



--- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-01 07:16:17 PDT ---
(In reply to comment #1)
> Another variation:
> 
> union S
> {
>     float[2] a;
>     struct
>     {
>         union { float i = 1; float x; }
>         union { float j = 2; float y; }
>     }
> }
> 
> $ dmd bar.d -c
> bar.d(2): Error: union bar.S overlapping initialization for struct S.i
> bar.d(2): Error: union bar.S overlapping initialization for struct S.j
> 
> If 'a' is moved below the anonymous struct it works. The spec does not mention this special case as far as I can tell. Explicit initialization of aggregate fields inside anonymous struct/union combinations should be documented.

More reduced test case.

union U1
{
    int a = 1;  // OK
    string b;
}
union U2
{
    int a;
    string b = "s";  // overlapping initialization for struct U2.b
}

I discovered this behavior while debugging other compiler bug. If there's overlapped fields, and the non-first field is explicitly initialized, compiler rejects it by "overlapping initialization".

As far as I see, the behavior seems to be intended by the current compiler code. However, normally D language semantics does not rely on the lexical order of declarations. I can agree that the behavior is contrary to the basic principle.

---

I'd propose more better semantics:

If exactly one field has an explicit initializer between overlapped fields, compiler should prefer it for default initialization.

U1 u1;  assert(u1.a == 1);
U2 u2;  assert(u2.b == "s");

If there's no explicitly initialized field between overlapped siblings, the first one is initialized at the default initialization.

union U3 { int a; char c; }    U3 u3;  assert(u3.a == 0);
union U4 { char c; int a; }    U4 u4;  assert(u4.c == 0xff);

If two or more fields have explicit initializers between overlapped siblings, it would cause compilation error.

union U5 { int a = 1, string b = "s" }
U5 u5;   // Error: overlapped initialization between U5.a and U5.b

How about that?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 01, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=1432


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|1.018                       |D2


--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2013-10-01 07:17:08 PDT ---
Change to D2 issue.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------