double solve(double a[]) {
      return 0[a] + 1[a] + 2[a] + 3[a];
    }

    solve((double[]){1, 2, 3, 4});
The cast in the invocation can be macro-ed away. And the best thing is, the actual stack layout and data movement/shuffling is pretty much identical to the approach with <stdargs.h>, and with no UB or compiler intrinsics.

That's a compound literal, not a cast.