When the return value is modified inside a scope(exit/success) block, the spec does not say what the semantics are.
A test program that demonstrates that the implementation exhibits different semantics depending on function call ABI (returned large structs are passed by ref):
```
import std.stdio;
struct Big {
ulong a;
ulong[4] b;
}
struct Small {
ulong a;
ulong b;
}
auto quirk(T)() {
T result;
scope(success)
{
result.a = 10;
}
return result;
}
void main() {
auto small = quirk!Small();
writeln(small);
auto big = quirk!Big();
writeln(big);
}
```
The issue is further complicated if the return expression also modifies the return value; i.e. we also need semantics for this testcase:
```
import std.stdio;
struct Big {
ulong a;
ulong[4] b;
}
struct Small {
ulong a;
ulong b;
}
auto ref addOne(T)(ref T t)
{
t.a += 1;
return t;
}
auto quirk(T)() {
T result;
scope(exit)
{
result.a = 10;
}
return addOne(result);
}
void main() {
auto small = quirk!Small();
writeln(small);
auto big = quirk!Big();
writeln(big);
}
```
Comment #1 by simen.kjaras — 2018-04-24T08:52:07Z
Worth noting: On win32, the Small struct used above is not small enough to be passed by value. The intended behavior shows up when Small.sizeof <= 8.
Comment #2 by robert.schadek — 2024-12-15T15:25:00Z