Summary
On x86 we evaluate function arguments right to left, but Rust evaluates them left to right. Method calls and overloaded operators go through the same path, so a() + b() on a user type runs b() first too. The gimplifier evaluates call arguments in the target's push order, which is reversed on x86.
Reproducer
I tried this code:
#![feature(no_core)]
#![no_core]
static mut N: i32 = 0;
fn tick() -> i32 {
unsafe {
N += 1;
N
}
}
fn three(a: i32, b: i32, c: i32) -> i32 {
a * 100 + b * 10 + c
}
fn main() -> i32 {
// rustc gives 123
three(tick(), tick(), tick()) - 123
}
Does the code make use of any (1.49) nightly feature ?
Godbolt link
No response
Actual behavior
three gets 3, 2, 1, so the program exits with a non-zero code.
Expected behavior
three gets 1, 2, 3 and the program exits with 0.
GCC Version
36b5a15
Summary
On x86 we evaluate function arguments right to left, but Rust evaluates them left to right. Method calls and overloaded operators go through the same path, so
a() + b()on a user type runsb()first too. The gimplifier evaluates call arguments in the target's push order, which is reversed on x86.Reproducer
I tried this code:
Does the code make use of any (1.49) nightly feature ?
Godbolt link
No response
Actual behavior
threegets 3, 2, 1, so the program exits with a non-zero code.Expected behavior
threegets 1, 2, 3 and the program exits with 0.GCC Version
36b5a15