www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - union initalization

reply Rufus Smith <RufusSmith indi.com> writes:
I would like to combine two types


template Foo(A, B = 4)
{
     union
     {
        byte b = B;
        int a = A << 8;
     }
}

This packs a and b together in to an int bytes, saving an 
int(rather than storing a and b in an int each) and makes it 
easier to access.

I get an error about overlapping default initialization. They 
don't actually overlap in this case because of the shift.
Jul 21 2016
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 07/21/2016 06:48 PM, Rufus Smith wrote:
 I would like to combine two types


 template Foo(A, B = 4)
 {
      union
      {
         byte b = B;
         int a = A << 8;
      }
 }

 This packs a and b together in to an int bytes, saving an int(rather
 than storing a and b in an int each) and makes it easier to access.
Bitfields may actually be useful in this case: https://dlang.org/phobos/std_bitmanip.html#.bitfields
 I get an error about overlapping default initialization. They don't
 actually overlap in this case because of the shift.
The following at least compiles: struct Foo(int A, byte B = 4) { union { byte b = void; int a = void; uint __both = (A << 8) | B; } } void main() { auto f = Foo!(42)(); } Ali
Jul 21 2016
parent reply Rufus Smith <RufusSmith indi.com> writes:
On Friday, 22 July 2016 at 02:08:06 UTC, Ali Çehreli wrote:
 On 07/21/2016 06:48 PM, Rufus Smith wrote:
 I would like to combine two types


 template Foo(A, B = 4)
 {
      union
      {
         byte b = B;
         int a = A << 8;
      }
 }

 This packs a and b together in to an int bytes, saving an
int(rather
 than storing a and b in an int each) and makes it easier to
access. Bitfields may actually be useful in this case: https://dlang.org/phobos/std_bitmanip.html#.bitfields
They don't allow default assignment though?
 I get an error about overlapping default initialization. They
don't
 actually overlap in this case because of the shift.
The following at least compiles: struct Foo(int A, byte B = 4) { union { byte b = void; int a = void; uint __both = (A << 8) | B; } } void main() { auto f = Foo!(42)(); } Ali
Maybe... I don't like extra member. Bitfields seem like it would be the best way but I require default initialization. I want to hide as details of the work on unpacking as possible.
Jul 21 2016
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 07/21/2016 08:00 PM, Rufus Smith wrote:

 Bitfields may actually be useful in this case:

   https://dlang.org/phobos/std_bitmanip.html#.bitfields
They don't allow default assignment though?
A factory function can help: import std.bitmanip; struct S(int a_init, byte b_init) { mixin (bitfields!(int, "a", 24, byte, "b", 8)); disable this(); } auto makeS(int a_init, byte b_init = 4)() { auto s = S!(a_init, b_init).init; s.a = a_init; s.b = b_init; return s; } void main() { const s = makeS!42(); assert(s.a == 42); assert(s.b == 4); }
 The following at least compiles:

 struct Foo(int A, byte B = 4)
 {
     union
     {
         byte b = void;
         int a = void;
         uint __both = (A << 8) | B;
     }
 }

 void main() {
     auto f = Foo!(42)();
 }

 Ali
Maybe... I don't like extra member.
Me neither. Besides, 'b' coincides with a different part of 'a' depending on the endianness of the system. Ali
Jul 21 2016
prev sibling parent Johannes Pfau <nospam example.com> writes:
Am Fri, 22 Jul 2016 01:48:52 +0000
schrieb Rufus Smith <RufusSmith indi.com>:

 I would like to combine two types
 
 
 template Foo(A, B = 4)
 {
      union
      {
         byte b = B;
         int a = A << 8;
      }
 }
 
 
 I get an error about overlapping default initialization. They 
 don't actually overlap in this case because of the shift.
To be pedantic about this: The initializers actually do overlap. As A << 8 shifts in zeroes, these bits are initialized as well. I think there's no idiomatic way to initialize only part of an integer.
Jul 22 2016