Skip to content

a = f(a, b); return value sometimes interfering with argument? #3696

@ghost

Description

This code is giving different results based on implementation of concatAll. The implementations look equivalent.

I have a feeling this has something to do with result locations. Is this how things are supposed to be?

Note: The matrix code here is not important - you can just run the different implementations and see that they output different results. Also, this is probably not the most efficient way to design a matrix library, but it's convenient (when it works).

const std = @import("std");

pub fn concat(a: [16]f32, b: [16]f32) [16]f32 {
    return .{
        a[0] * b[ 0] + a[4] * b[ 1] + a[ 8] * b[ 2] + a[12] * b[ 3],
        a[1] * b[ 0] + a[5] * b[ 1] + a[ 9] * b[ 2] + a[13] * b[ 3],
        a[2] * b[ 0] + a[6] * b[ 1] + a[10] * b[ 2] + a[14] * b[ 3],
        a[3] * b[ 0] + a[7] * b[ 1] + a[11] * b[ 2] + a[15] * b[ 3],
        a[0] * b[ 4] + a[4] * b[ 5] + a[ 8] * b[ 6] + a[12] * b[ 7],
        a[1] * b[ 4] + a[5] * b[ 5] + a[ 9] * b[ 6] + a[13] * b[ 7],
        a[2] * b[ 4] + a[6] * b[ 5] + a[10] * b[ 6] + a[14] * b[ 7],
        a[3] * b[ 4] + a[7] * b[ 5] + a[11] * b[ 6] + a[15] * b[ 7],
        a[0] * b[ 8] + a[4] * b[ 9] + a[ 8] * b[10] + a[12] * b[11],
        a[1] * b[ 8] + a[5] * b[ 9] + a[ 9] * b[10] + a[13] * b[11],
        a[2] * b[ 8] + a[6] * b[ 9] + a[10] * b[10] + a[14] * b[11],
        a[3] * b[ 8] + a[7] * b[ 9] + a[11] * b[10] + a[15] * b[11],
        a[0] * b[12] + a[4] * b[13] + a[ 8] * b[14] + a[12] * b[15],
        a[1] * b[12] + a[5] * b[13] + a[ 9] * b[14] + a[13] * b[15],
        a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
        a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15],
    };
}

fn meh(a: [16]f32) [16]f32 {
    return a;
}

fn concatAll(arr: []const [16]f32) [16]f32 {
    // this gives the correct result
    var result = concat(concat(arr[0], arr[1]), arr[2]);

    // this gives a wrong result!
    //var result = arr[0];
    //result = concat(result, arr[1]);
    //result = concat(result, arr[2]);

    // this gives the correct result...
    //var result = arr[0];
    //result = concat(meh(result), arr[1]);
    //result = concat(meh(result), arr[2]);

    return result;
}

pub fn main() void {
    const a = [16]f32 {
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 9, 1,
    };
    const b = [16]f32 {
        0, -1, 0, 0,
        1, 0, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1,
    };
    const c = [16]f32 {
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        7, 0, 0, 1,
    };
    const result = concatAll([_][16]f32 { a, b, c });
    std.debug.warn("{} {} {} {}\n", result[0], result[1], result[2], result[3]);
    std.debug.warn("{} {} {} {}\n", result[4], result[5], result[6], result[7]);
    std.debug.warn("{} {} {} {}\n", result[8], result[9], result[10], result[11]);
    std.debug.warn("{} {} {} {}\n", result[12], result[13], result[14], result[15]);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    use caseDescribes a real use case that is difficult or impossible, but does not propose a solution.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions