-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Open
Labels
use caseDescribes a real use case that is difficult or impossible, but does not propose a solution.Describes a real use case that is difficult or impossible, but does not propose a solution.
Milestone
Description
This code attempts to square a complex number i² -> -1. When computing z = z.mul(z), the compiler decides to pass both values z1 and z2 by reference, however copy elision seems to modify z in place causing the incorrect value to be computed.
const std = @import("std");
const print = std.debug.warn;
const Complex = struct {
x: f32 = 0,
y: f32 = 0,
pub fn mul(z1: Complex, z2: Complex) Complex {
return Complex {
.x = z1.x*z2.x - z1.y*z2.y,
.y = z1.x*z2.y + z1.y*z2.x, // new value of .x gets used here
};
}
};
pub fn main() void {
var c = Complex{ .x=0.0, .y=1.0 };
var i: usize = 0;
var z: Complex = undefined;
print("incorrect:\n", .{});
z = c;
z = z.mul(z);
print("z: {d:.2} {d:.2}\n", .{ z.x, z.y });
z = c;
z = z.mul(c);
print("z: {d:.2} {d:.2}\n", .{ z.x, z.y });
z = c;
z = c.mul(z);
print("z: {d:.2} {d:.2}\n", .{ z.x, z.y });
// These examples produce the correct output
print("correct:\n", .{});
z = c.mul(c);
print("z: {d:.2} {d:.2}\n", .{ z.x, z.y });
z = c;
var res = z.mul(z);
print("z: {d:.2} {d:.2}\n", .{ res.x, res.y });
}
Output:
incorrect:
z: -1.00 -2.00
z: -1.00 -1.00
z: -1.00 -1.00
correct:
z: -1.00 0.00
z: -1.00 0.00
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
use caseDescribes a real use case that is difficult or impossible, but does not propose a solution.Describes a real use case that is difficult or impossible, but does not propose a solution.