Thread overview
(Manifest) constants inside structs
Jan 22, 2008
Sönke Ludwig
Jan 23, 2008
Sönke Ludwig
Jan 23, 2008
Robert Fraser
Jan 23, 2008
Walter Bright
Jan 23, 2008
Sönke Ludwig
Jan 23, 2008
Walter Bright
January 22, 2008
I'm currently trying to upgrade from DMD 2.008 to 2.010. There's one problem I could not find a work-around. There are a bunch of structs which have constants defined inside:

  struct S {
    static const S some_const1 = {0};
    static const S some_const2 = {1};

    int member;
  }

This works fine, until there is a second struct, which uses on of these constants in an equivalent initializer:

  struct T {
    static const T dependent_constant = {S.some_const1};
    // <- error: cannot convert const(S) to S

    S member;
  }

I've tried to use an enum instead, but that causes a segfault in the compiler:

  struct S {
    enum S some_const1 = {0}; // compiler segfault without error message
  }

A possible solution would be to put the constants outside of the struct. However, the actual structs look more like:

  template(S, int N) Vector {
    static const S zero = {...};
    static const S one = {...};
  }
  alias Vector!(int, 2) Vec2i;

  // in code used as Vec2i.one

Since the types used for S are not known, putting the constants outside of the struct is not possible.

I think the semantics should be changed to allow assignment of const values to non-const variables, as long as the specific struct does not contain a reference 
 /pointer of some form (directly or indirectly).

Also manifest constants inside structs using enum would be nice.

Does anybody have another idea how to sidestep this issue for now?
I think I'm running out of ideas after also having tried a bunch of other things.
January 23, 2008
Finally found a dirty hack that works:

T ct_strip_const_helper(T)( const(T)[] t ){ return (cast(T[])t)[0]; }
T ct_strip_const(T)( const(T) t ){ return ct_strip_const_helper([t]); }

struct S {
  static const S ess_const = {1};

  int member;
}


struct T {
  static const T tee_const = {ct_strip_const(S.ess_const)};

  S member;
}
January 23, 2008
Sönke Ludwig wrote:
> Finally found a dirty hack that works:
> 
> T ct_strip_const_helper(T)( const(T)[] t ){ return (cast(T[])t)[0]; }
> T ct_strip_const(T)( const(T) t ){ return ct_strip_const_helper([t]); }
> 
> struct S {
>   static const S ess_const = {1};
> 
>   int member;
> }
> 
> 
> struct T {
>   static const T tee_const = {ct_strip_const(S.ess_const)};
> 
>   S member;
> }

Eww! Here's to hoping the enum-in-structs thing gets fixed.
January 23, 2008
Both of these should go into bugzilla: http://d.puremagic.com/issues/
January 23, 2008
Walter Bright wrote:
> Both of these should go into bugzilla: http://d.puremagic.com/issues/

Done.


Also I just noticed that the crash only applies to the specific case where the same struct is used as the enum type, in which it is declared:

struct S { enum S s_const = ...; }
January 23, 2008
Sönke Ludwig wrote:
> Done.

Thanks.