Partially initialized structs?

user1234 user1234 at 12.de
Wed Feb 26 22:22:26 UTC 2025


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 at 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.File.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.File.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.ScanRange!(false).ScanRange) (in /tmp/temp_7F2438E29F90)
==24746==    by 0x4A7915: 
core.internal.gc.impl.conservative.gc.Gcx.markConservative!(false).markConservative(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).markConservative(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.conservative.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)
```


More information about the Digitalmars-d-learn mailing list