Jump to page: 1 2
Thread overview
Partially initialized structs?
Feb 26
Arredondo
Feb 26
Hipreme
Feb 26
Arredondo
Feb 27
Hipreme
Feb 27
Arredondo
Feb 27
bkoie
Feb 27
monkyyy
Feb 26
bkoie
Feb 26
bkoie
Feb 26
user1234
Feb 26
Arredondo
February 26

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.

February 26

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.

February 26

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.

February 26

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...

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

February 26

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++.

February 26

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...

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.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)
February 26

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.

February 26

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.

February 27

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.

February 27

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!

« First   ‹ Prev
1 2