www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Partially initialized structs?

reply Arredondo <arm.plus gmail.com> writes:
Is it possible to declare a partially initialized struct?

I would have thought that doing it like this would work:

```
struct S {
     int[100] a = void;
     int b = 0;
}

```

But when I declare a variable of type `S`, the array `a` is 
initialized, so it seems that the `= void` is not playing any 
role here.

Of course `S s = void;` works for `a`, but then `b` is not 
initialized. I tried doing:

```
struct S {
	 disable this ();
	auto this(int b) {
		this.b = b;
		a = void;
	}
	
     int[100] a;
     int b = 0;
}
```
But that doesn't even compile.


I'm currently settling for something like:
```
auto placeS(string name)() => iq{
	S $(name) = void;
	$(name).b = 0;
}.text;
```
and then declare with `mixin(placeS!"s");`.

Is there a better way?

Cheers!
Arredondo.
Feb 25
next sibling parent reply Hipreme <msnmancini hotmail.com> writes:
On Wednesday, 26 February 2025 at 03:47:32 UTC, Arredondo wrote:
 Is it possible to declare a partially initialized struct?

 I would have thought that doing it like this would work:

 ```
 struct S {
     int[100] a = void;
     int b = 0;
 }

 ```

 But when I declare a variable of type `S`, the array `a` is 
 initialized, so it seems that the `= void` is not playing any 
 role here.

 Of course `S s = void;` works for `a`, but then `b` is not 
 initialized. I tried doing:

 ```
 struct S {
 	 disable this ();
 	auto this(int b) {
 		this.b = b;
 		a = void;
 	}
 	
     int[100] a;
     int b = 0;
 }
 ```
 But that doesn't even compile.


 I'm currently settling for something like:
 ```
 auto placeS(string name)() => iq{
 	S $(name) = void;
 	$(name).b = 0;
 }.text;
 ```
 and then declare with `mixin(placeS!"s");`.

 Is there a better way?

 Cheers!
 Arredondo.
I highly recommend you don't do that. I've been using D for more than 5 years and that led me to a bug which took me some time to solve that quite recently. The proper way to to do it is creating an implementation of a void init instead: ```d struct S { int[100] a; int b = 0; static S defaultInit(int b) { S s = void; s.b = b; return s; } } ``` Having `void` initialization on fields would be really unsafe and could break your code at any moment and that would be really hard to identify. With that you'll be able at least to fix that issue.
Feb 26
parent reply Arredondo <arm.plus gmail.com> writes:
On Wednesday, 26 February 2025 at 10:19:17 UTC, Hipreme wrote:
     ```d
     struct S
     {
         int[100] a;
         int b = 0;
         static S defaultInit(int b)
         {
            S s = void;
            s.b = b;
            return s;
         }
     }
     ```
Thank you for this Hipreme. I do have a question though, wouldn't this create two copies of S? one at construction and then another at the call site after defaultInit returns? Regarding safety, I'm well aware I'm playing with fire here. For now I'm just experimenting to see if something like this is even worth it performance-wise. Cheers! Arredondo.
Feb 26
parent reply Hipreme <msnmancini hotmail.com> writes:
On Wednesday, 26 February 2025 at 23:47:41 UTC, Arredondo wrote:
 On Wednesday, 26 February 2025 at 10:19:17 UTC, Hipreme wrote:
     ```d
     struct S
     {
         int[100] a;
         int b = 0;
         static S defaultInit(int b)
         {
            S s = void;
            s.b = b;
            return s;
         }
     }
     ```
Thank you for this Hipreme. I do have a question though, wouldn't this create two copies of S? one at construction and then another at the call site after defaultInit returns? Regarding safety, I'm well aware I'm playing with fire here. For now I'm just experimenting to see if something like this is even worth it performance-wise. Cheers! Arredondo.
Yes, that is definitely worth performance wise. Specially if you wish to start using an array of `S`, this could be a huge toll. And no, it won't create 2 copies. D has a thing called Return Value Optimization. Since that local variable is returned, it has no need to copy it.
Feb 26
parent reply Arredondo <arm.plus gmail.com> writes:
On Thursday, 27 February 2025 at 01:22:07 UTC, Hipreme wrote:
 And no, it won't create 2 copies. D has a thing called Return 
 Value Optimization. Since that local variable is returned, it 
 has no need to copy it.
That's great to know. Thank you!
Feb 26
parent reply bkoie <blaa some.com> writes:
On Thursday, 27 February 2025 at 02:09:29 UTC, Arredondo wrote:
 On Thursday, 27 February 2025 at 01:22:07 UTC, Hipreme wrote:
 And no, it won't create 2 copies. D has a thing called Return 
 Value Optimization. Since that local variable is returned, it 
 has no need to copy it.
That's great to know. Thank you!
```d template Model(T, T n = 100) // where n: length with Type of T { auto voidStackArr(inout bool _void = true) { T[n] arr = void; assert(!_void); arr = 0; return arr; } } alias voidStackArrInt = Model!int; void main() { import std.stdio: writeln; // err we are reading garb values auto arr = voidStackArrInt.voidStackArr; arr.writeln; // ok auto arr2 = voidStackArrInt.voidStackArr(false); arr2.writeln; } ``` and we're back to c++ u guys should really stop doing things like this
Feb 26
parent monkyyy <crazymonkyyy gmail.com> writes:
On Thursday, 27 February 2025 at 06:15:38 UTC, bkoie wrote:
 template Model(T, T n = 100) // where n: length with Type of T
spoiler alert: there is fun to be had here; your going to want to clear your sleep sch, stock up on caffine, digging into this syntax is a wild ride of some of the best compiler bugs d can offer 10/10
Feb 26
prev sibling parent reply bkoie <blaa some.com> writes:
On Wednesday, 26 February 2025 at 03:47:32 UTC, Arredondo wrote:
 Is it possible to declare a partially initialized struct?

 I would have thought that doing it like this would work:

 ```
 struct S {
     int[100] a = void;
     int b = 0;
 }

 ```
stuff like this is not even necessary if you dont need it now dont delcare an easy workaround is use some copy dictionary.
Feb 26
next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Wednesday, 26 February 2025 at 15:11:47 UTC, bkoie wrote:
  stuff like this is not even necessary if you dont need it now 
 dont delcare an easy workaround is use some copy dictionary.
It's not that simple. I found the following code very sympathetic. You can use the same method for structures that contain dynamic arrays and can be customized as needed... ```d alias MSS(T) = My_Static_Struct!T; struct My_Static_Struct(Type) { Type id = 0; Type[8] arr; alias T = typeof(this); disable this (); static init(Type id) { T that = void; that.id = id; return that; } } alias MDS(T) = My_Dynamic_Struct!T; struct My_Dynamic_Struct(Type) { Type id; Type[] arr; alias T = typeof(this); disable this (); static init(Type id, size_t length) { alias R = Type[]; import std.range : uninitializedArray; T that = void; that.id = id; that.arr = length.uninitializedArray!R; return that; } } import std.stdio; void main() { alias T = ubyte; MSS!T[] m1; with(MSS!T) { m1 = [ init(41), init(42) ]; } m1.writefln!"%-(%s\n%)"; MDS!T[] m2; with(MDS!T) { m2 = [ init(41, 4), init(42, 8) ]; } m2.writefln!"%-(%s\n%)"; } /* PRINTS: My_Static_Struct!ubyte(41, [0, 0, 0, 0, 0, 0, 0, 0]) My_Static_Struct!ubyte(42, [0, 0, 0, 0, 0, 0, 0, 0]) My_Dynamic_Struct!ubyte(41, [16, 32, 216, 47]) My_Dynamic_Struct!ubyte(42, [32, 32, 216, 47, 100, 127, 0, 0]) */ ``` SDB 79
Feb 26
next sibling parent reply bkoie <blaa some.com> writes:
On Wednesday, 26 February 2025 at 16:38:20 UTC, Salih Dincer 
wrote:
 My_Static_Struct!ubyte(41, [0, 0, 0, 0, 0, 0, 0, 0])
 My_Static_Struct!ubyte(42, [0, 0, 0, 0, 0, 0, 0, 0])
 My_Dynamic_Struct!ubyte(41, [16, 32, 216, 47])
 My_Dynamic_Struct!ubyte(42, [32, 32, 216, 47, 100, 127, 0, 0])
 */
 ```
code doing a bunch of undefined runtime magic if you think this is valid then you will enjoy c++.
Feb 26
parent Salih Dincer <salihdb hotmail.com> writes:
On Wednesday, 26 February 2025 at 19:34:24 UTC, bkoie wrote:
 On Wednesday, 26 February 2025 at 16:38:20 UTC, Salih Dincer 
 wrote:
 My_Static_Struct!ubyte(41, [0, 0, 0, 0, 0, 0, 0, 0])
 My_Static_Struct!ubyte(42, [0, 0, 0, 0, 0, 0, 0, 0])
 My_Dynamic_Struct!ubyte(41, [16, 32, 216, 47])
 My_Dynamic_Struct!ubyte(42, [32, 32, 216, 47, 100, 127, 0, 0])
 */
 ```
code doing a bunch of undefined runtime magic if you think this is valid then you will enjoy c++.
I hate CPP. If we had done something similar by relying on him, we would probably have struggled too hard. Cheers with :D AI (DeepSeek) generated the following code that did not work in response: ```CPP #include <array> #include <vector> #include <memory> #include <iostream> template <typename Type> struct My_Static_Struct { Type id; std::array<Type, 8> arr; My_Static_Struct() = delete; static My_Static_Struct init(Type id_val) { return {id_val, {}}; } }; template <typename Type> struct My_Dynamic_Struct { Type id; std::unique_ptr<Type[]> arr; size_t arr_length; My_Dynamic_Struct() = delete; static My_Dynamic_Struct init(Type id_val, size_t length) { return {id_val, std::unique_ptr<Type[]>(new Type[length]), length}; } }; int main() { using T = unsigned char; // My_Static_Struct kullanımı using MSS = My_Static_Struct<T>; std::vector<MSS> m1 = { MSS::init(41), MSS::init(42) }; for (const auto& elem : m1) { std::cout << "MSS id: " << static_cast<int>(elem.id) << " | arr: "; for (auto val : elem.arr) { std::cout << static_cast<int>(val) << " "; } std::cout << std::endl; } // My_Dynamic_Struct kullanımı using MDS = My_Dynamic_Struct<T>; std::vector<MDS> m2 = { MDS::init(41, 4), MDS::init(42, 8) }; for (const auto& elem : m2) { std::cout << "MDS id: " << static_cast<int>(elem.id) << " | arr: "; for (size_t i = 0; i < elem.arr_length; ++i) { std::cout << static_cast<int>(elem.arr[i]) << " "; } std::cout << std::endl; } return 0; } ``` SDB 79
Feb 26
prev sibling parent user1234 <user1234 12.de> writes:
On Wednesday, 26 February 2025 at 16:38:20 UTC, Salih Dincer 
wrote:
 On Wednesday, 26 February 2025 at 15:11:47 UTC, bkoie wrote:
  stuff like this is not even necessary if you dont need it now 
 dont delcare an easy workaround is use some copy dictionary.
It's not that simple. I found the following code very sympathetic. You can use the same method for structures that contain dynamic arrays and can be customized as needed... ```d alias MSS(T) = My_Static_Struct!T; struct My_Static_Struct(Type) { Type id = 0; Type[8] arr; alias T = typeof(this); disable this (); static init(Type id) { T that = void; that.id = id; return that; } } alias MDS(T) = My_Dynamic_Struct!T; struct My_Dynamic_Struct(Type) { Type id; Type[] arr; alias T = typeof(this); disable this (); static init(Type id, size_t length) { alias R = Type[]; import std.range : uninitializedArray; T that = void; that.id = id; that.arr = length.uninitializedArray!R; return that; } } import std.stdio; void main() { alias T = ubyte; MSS!T[] m1; with(MSS!T) { m1 = [ init(41), init(42) ]; } m1.writefln!"%-(%s\n%)"; MDS!T[] m2; with(MDS!T) { m2 = [ init(41, 4), init(42, 8) ]; } m2.writefln!"%-(%s\n%)"; } /* PRINTS: My_Static_Struct!ubyte(41, [0, 0, 0, 0, 0, 0, 0, 0]) My_Static_Struct!ubyte(42, [0, 0, 0, 0, 0, 0, 0, 0]) My_Dynamic_Struct!ubyte(41, [16, 32, 216, 47]) My_Dynamic_Struct!ubyte(42, [32, 32, 216, 47, 100, 127, 0, 0]) */ ``` SDB 79
after exit valgrind is very happy with that code. Simple main: ``` =24625== Memcheck, a memory error detector ==24625== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==24625== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info ==24625== Command: /tmp/temp_7F2438E29F90 ==24625== ==24625== ==24625== HEAP SUMMARY: ==24625== in use at exit: 72 bytes in 2 blocks ==24625== total heap usage: 101 allocs, 99 frees, 9,040 bytes allocated ==24625== ==24625== LEAK SUMMARY: ==24625== definitely lost: 0 bytes in 0 blocks ==24625== indirectly lost: 0 bytes in 0 blocks ==24625== possibly lost: 0 bytes in 0 blocks ==24625== still reachable: 72 bytes in 2 blocks ==24625== suppressed: 0 bytes in 0 blocks ==24625== Rerun with --leak-check=full to see details of leaked memory ==24625== ==24625== For lists of detected and suppressed errors, rerun with: -s ==24625== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` Your program: ``` ==24746== Memcheck, a memory error detector ==24746== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==24746== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info ==24746== Command: /tmp/temp_7F2438E29F90 ==24746== ==24746== Conditional jump or move depends on uninitialised value(s) ==24746== at 0x45DC79: std.format.internal.write.formatValueImplUlong!(std.stdio.Fil .LockingTextWriter, char).formatValueImplUlong(ref std.stdio.File.LockingTextWriter, ulong, in bool, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:193) ==24746== by 0x45DA91: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, ubyte, char).formatValueImpl(ref std.stdio.File.LockingTextWriter, const(ubyte), scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:173) ==24746== by 0x45D95B: std.format.write.formatValue!(std.stdio.File.LockingTextWriter, ubyte, char).formatValue(ref std.stdio.File.LockingTextWriter, ref ubyte, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1239) ==24746== by 0x45D8E0: std.format.internal.write.formatElement!(std.stdio.File.LockingTextWriter, ubyte, char).formatElement(ref std.stdio.File.LockingTextWriter, ref ubyte, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:3218) ==24746== by 0x46047B: std.format.internal.write.formatRange!(std.stdio.File.LockingTextWriter, ubyte[], char).formatRange(ref std.stdio.File.LockingTextWriter, ref ubyte[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1497) ==24746== by 0x4603E4: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, ubyte[], char).formatValueImpl(ref std.stdio.File.LockingTextWriter, ubyte[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1281) ==24746== by 0x4603B9: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, ubyte[8], char).formatValueImpl(ref std.stdio.File.LockingTextWriter, ref ubyte[8], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1230) ==24746== by 0x46036F: std.format.write.formatValue!(std.stdio.File.LockingTextWriter, ubyte[8], char).formatValue(ref std.stdio.File.LockingTextWriter, ref ubyte[8], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1239) ==24746== by 0x4602F8: std.format.internal.write.formatElement!(std.stdio.File.LockingTextWriter, ubyte[8], char).formatElement(ref std.stdio.File.LockingTextWriter, ref ubyte[8], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:3218) ==24746== by 0x45D896: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, char).formatValueImpl(ref std.stdio.File.LockingTextWriter, ref temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:2557) ==24746== by 0x45D7F3: std.format.write.formatValue!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, char).formatValue(ref std.stdio.File.LockingTextWriter, ref temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1239) ==24746== by 0x45D296: std.format.internal.write.formatRange!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct[], char).formatRange(ref std.stdio.File.LockingTextWriter, ref temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1545) ==24746== ==24746== Conditional jump or move depends on uninitialised value(s) ==24746== at 0x49F836C: _IO_new_file_xsputn (fileops.c:1218) ==24746== by 0x49F836C: _IO_file_xsputn GLIBC_2.2.5 (fileops.c:1196) ==24746== by 0x49ED596: fwrite (iofwrite.c:39) ==24746== by 0x45C961: std.stdio.trustedFwrite!(char).trustedFwrite(shared(core.stdc.stdio._IO_FILE)*, const(char[])) (stdio.d:4751) ==24746== by 0x45F4A3: std.stdio.File.LockingTextWriter.put!(char[]).put(scope char[]) (stdio.d:3211) ==24746== by 0x45F45A: std.range.primitives.doPut!(std.stdio.File.LockingTextWriter, char[]).doPut(ref std.stdio.File.LockingTextWriter, ref char[]) (primitives.d:307) ==24746== by 0x45F42C: std.range.primitives.put!(std.stdio.File.LockingTextWriter, char[]).put(ref std.stdio.File.LockingTextWriter, char[]) (primitives.d:410) ==24746== by 0x45F067: std.format.internal.write.writeAligned!(std.stdio.File.LockingTextWriter, char[], char[], immutable(char)[], immutable(char)[], char).writeAligned(ref std.stdio.File.LockingTextWriter, char[], char[], immutable(char)[], immutable(char)[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec), std.format.internal.write.PrecisionType) (write.d:3464) ==24746== by 0x45E7FE: std.format.internal.write.writeAligned!(std.stdio.File.LockingTextWriter, char[], char[], immutable(char)[], char).writeAligned(ref std.stdio.File.LockingTextWriter, char[], char[], immutable(char)[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec), bool) (write.d:3316) ==24746== by 0x45E038: std.format.internal.write.formatValueImplUlong!(std.stdio.Fil .LockingTextWriter, char).formatValueImplUlong(ref std.stdio.File.LockingTextWriter, ulong, in bool, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:224) ==24746== by 0x45DA91: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, ubyte, char).formatValueImpl(ref std.stdio.File.LockingTextWriter, const(ubyte), scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:173) ==24746== by 0x45D95B: std.format.write.formatValue!(std.stdio.File.LockingTextWriter, ubyte, char).formatValue(ref std.stdio.File.LockingTextWriter, ref ubyte, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1239) ==24746== by 0x45D8E0: std.format.internal.write.formatElement!(std.stdio.File.LockingTextWriter, ubyte, char).formatElement(ref std.stdio.File.LockingTextWriter, ref ubyte, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:3218) ==24746== ==24746== Syscall param write(buf) points to uninitialised byte(s) ==24746== at 0x4A70324: write (write.c:26) ==24746== by 0x49F7D2C: _IO_file_write GLIBC_2.2.5 (fileops.c:1180) ==24746== by 0x49F70CF: new_do_write (fileops.c:448) ==24746== by 0x49F8D98: _IO_do_write GLIBC_2.2.5 (fileops.c:425) ==24746== by 0x49F83DD: _IO_new_file_xsputn (fileops.c:1243) ==24746== by 0x49F83DD: _IO_file_xsputn GLIBC_2.2.5 (fileops.c:1196) ==24746== by 0x49ED596: fwrite (iofwrite.c:39) ==24746== by 0x45C961: std.stdio.trustedFwrite!(char).trustedFwrite(shared(core.stdc.stdio._IO_FILE)*, const(char[])) (stdio.d:4751) ==24746== by 0x45C893: std.stdio.File.LockingTextWriter.put!(const(char)[]).put(scope const(char)[]) (stdio.d:3211) ==24746== by 0x45C84A: std.range.primitives.doPut!(std.stdio.File.LockingTextWriter, const(char)[]).doPut(ref std.stdio.File.LockingTextWriter, ref const(char)[]) (primitives.d:307) ==24746== by 0x45C81C: std.range.primitives.put!(std.stdio.File.LockingTextWriter, const(char)[]).put(ref std.stdio.File.LockingTextWriter, const(char)[]) (primitives.d:410) ==24746== by 0x45D3D7: std.format.internal.write.formatRange!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct[], char).formatRange(ref std.stdio.File.LockingTextWriter, ref temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1575) ==24746== by 0x45D004: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct[], char).formatValueImpl(ref std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct[], scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1281) ==24746== Address 0x4b60c5c is 28 bytes inside a block of size 1,024 alloc'd ==24746== at 0x484380F: malloc (vg_replace_malloc.c:442) ==24746== by 0x49EC273: _IO_file_doallocate (filedoalloc.c:101) ==24746== by 0x49F9E9F: _IO_doallocbuf (genops.c:347) ==24746== by 0x49F9E9F: _IO_doallocbuf (genops.c:342) ==24746== by 0x49F9237: _IO_file_overflow GLIBC_2.2.5 (fileops.c:744) ==24746== by 0x49F83DD: _IO_new_file_xsputn (fileops.c:1243) ==24746== by 0x49F83DD: _IO_file_xsputn GLIBC_2.2.5 (fileops.c:1196) ==24746== by 0x49ED596: fwrite (iofwrite.c:39) ==24746== by 0x45C961: std.stdio.trustedFwrite!(char).trustedFwrite(shared(core.stdc.stdio._IO_FILE)*, const(char[])) (stdio.d:4751) ==24746== by 0x45D4DB: std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(scope immutable(char)[]) (stdio.d:3211) ==24746== by 0x45D492: std.range.primitives.doPut!(std.stdio.File.LockingTextWriter, immutable(char)[]).doPut(ref std.stdio.File.LockingTextWriter, ref immutable(char)[]) (primitives.d:307) ==24746== by 0x45D464: std.range.primitives.put!(std.stdio.File.LockingTextWriter, immutable(char)[]).put(ref std.stdio.File.LockingTextWriter, immutable(char)[]) (primitives.d:410) ==24746== by 0x45D850: std.format.internal.write.formatValueImpl!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, char).formatValueImpl(ref std.stdio.File.LockingTextWriter, ref temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:2528) ==24746== by 0x45D7F3: std.format.write.formatValue!(std.stdio.File.LockingTextWriter, temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, char).formatValue(ref std.stdio.File.LockingTextWriter, ref temp_7F2438E29F90.My_Static_Struct!(ubyte).My_Static_Struct, scope ref const(std.format.spec.FormatSpec!(char).FormatSpec)) (write.d:1239) ==24746== My_Static_Struct!ubyte(41, [0, 0, 0, 0, 0, 0, 0, 0]) My_Static_Struct!ubyte(42, [0, 0, 0, 0, 0, 0, 0, 0]) My_Dynamic_Struct!ubyte(41, [16, 96, 245, 4]) My_Dynamic_Struct!ubyte(42, [32, 96, 245, 4, 0, 0, 0, 0]) ==24746== Conditional jump or move depends on uninitialised value(s) ==24746== at 0x4A79B7: core.internal.gc.impl.conservative.gc.Gcx.mark!(false, false, false).mark(core.internal.gc.impl.conservative.gc.Gcx.ScanRang !(false).ScanRange) (in /tmp/temp_7F2438E29F90) ==24746== by 0x4A7915: core.internal.gc.impl.conservative.gc.Gcx.markConservative!(false).mar Conservative(void*, void*) (in /tmp/temp_7F2438E29F90) ==24746== by 0x4A23BF: core.thread.threadbase.thread_scanAll(scope void(void*, void*) nothrow delegate).__lambda2!(core.thread.threadbase.ScanType, void*, void*).__lambda2(core.thread.threadbase.ScanType, void*, void*) (in /tmp/temp_7F2438E29F90) ==24746== by 0x4A7F3F: core.thread.threadbase.scanAllTypeImpl(scope void(core.thread.threadbase.ScanType, void*, void*) nothrow delegate, void*) (in /tmp/temp_7F2438E29F90) ==24746== by 0x4A7E7C: core.thread.threadbase.thread_scanAllType(scope void(core.thread.threadbase.ScanType, void*, void*) nothrow delegate).__lambda2!(void*).__lambda2(void*) (in /tmp/temp_7F2438E29F90) ==24746== by 0x494C1B: core.thread.osthread.callWithStackShell(scope void(void*) nothrow delegate) (in /tmp/temp_7F2438E29F90) ==24746== by 0x4A7E51: thread_scanAllType (in /tmp/temp_7F2438E29F90) ==24746== by 0x4A2385: thread_scanAll (in /tmp/temp_7F2438E29F90) ==24746== by 0x49FFBE: core.internal.gc.impl.conservative.gc.Gcx.markAll!(core.internal.gc.impl.conservative.gc.Gcx.markConservative!(false).mar Conservative(void*, void*)).markAll() (in /tmp/temp_7F2438E29F90) ==24746== by 0x49ADD1: core.internal.gc.impl.conservative.gc.Gcx.fullcollect(bool, bool) (in /tmp/temp_7F2438E29F90) ==24746== by 0x49FA93: core.internal.gc.impl.conservative.gc.ConservativeGC.runLocked!(core.internal.gc.impl.conservative.gc.ConservativeGC.fullCollect().go(core.internal.gc.impl.co servative.gc.Gcx*), core.internal.gc.impl.conservative.gc.Gcx*).runLocked(ref core.internal.gc.impl.conservative.gc.Gcx*) (in /tmp/temp_7F2438E29F90) ==24746== by 0x497B43: core.internal.gc.impl.conservative.gc.ConservativeGC.fullCollect() (in /tmp/temp_7F2438E29F90) ==24746== ==24746== ==24746== HEAP SUMMARY: ==24746== in use at exit: 56 bytes in 2 blocks ==24746== total heap usage: 113 allocs, 111 frees, 45,560 bytes allocated ==24746== ==24746== LEAK SUMMARY: ==24746== definitely lost: 0 bytes in 0 blocks ==24746== indirectly lost: 0 bytes in 0 blocks ==24746== possibly lost: 32 bytes in 1 blocks ==24746== still reachable: 24 bytes in 1 blocks ==24746== suppressed: 0 bytes in 0 blocks ==24746== Rerun with --leak-check=full to see details of leaked memory ==24746== ==24746== Use --track-origins=yes to see where uninitialised values come from ==24746== For lists of detected and suppressed errors, rerun with: -s ==24746== ERROR SUMMARY: 107 errors from 4 contexts (suppressed: 0 from 0) ```
Feb 26
prev sibling parent Arredondo <arm.plus gmail.com> writes:
On Wednesday, 26 February 2025 at 15:11:47 UTC, bkoie wrote:
 stuff like this is not even necessary if you dont need it now 
 dont delcare an easy workaround is use some copy dictionary.
I'm not sure that would work for me with the way I'm iteratively building these objects, but I'll think about it. Thank you for the suggestion.
Feb 26