Closed Yeaseen closed 2 months ago
c4go gives the same output as gcc
and clang
do. So, the error is in c2rust
Might this be due to the order of operations in an expression (for final
) being unspecified? Rust does fn1(q_q)
first, but C may do either first, and it might be doing fn1(p_p)
first.
I cross-checked this C code with c4go
which preserves the C order and gives the same output as GCC and Clang do.
I found the order in that translated go code by c4go
is the same as what c2rust gives here.
var final int32 = func() int32 {
tempVar2 := &(fn1(int32(q_q)))[0]
*tempVar2 += (fn1(p_p))[0]
return *tempVar2
}()
noarch.Printf([]byte("Result: %d\n\x00"), final)
I believe C has nothing to do with this, as I tested GCC and Clang with UBSan and Asan. No run time error was found.
Not sure about what error in c2rust
is causing this divergence.
As far as I am concerned, c2rust uses Clang-based LibTool as a front-end for the C input. It should even be c2rust's advantage to preserve this C operation. Yet, this divergence in output. The root cause is still unclear to me. If any direction, that would be great.
I believe C has nothing to do with this, as I tested GCC and Clang with UBSan and Asan. No run time error was found.
Order of evaluation is unspecified, not undefined. So it won't be flagged by UBSan, but it gives unspecified results.
yeah. Specification might be an issue. But I think Rust is doing 150 + 150
instead of 124 + 150
.
In the translated rust code, the following modification gives the perfect output 274
//*fresh0 += *fn1(p_p); // I believe this part is buggy
*fresh0 = *fresh0 + *fn1(p_p);
I think this needs special care to preserve equivalence. The same bug is also found in CxGo
@kkysen has already provided a satisfactory explanation for the results you observe @Yeaseen:
Order of evaluation is unspecified, not undefined. So it won't be flagged by UBSan, but it gives unspecified results.
You can read more about the order of evaluation in C here https://en.cppreference.com/w/c/language/eval_order.
I've copied your code example in to godbolt.org. Depending on what compiler you chose, the result of the computation, the result is either 274 or 300. For x64 msvc v19, it computes 300 just like the Rust compiler.
Input C code (test.c)
GCC+Clang Output with UBSan+Asan
Both GCC and Clang give the same output
Translated Rust code's output
Translated Rust Code
Warning while cargo build
I found this warning while building the above translated code by
c2rust
Modified Code to suppress the warning
To suppress the warning, I modified the translated rust code. Now, there's no warning. Still, the same output before the modification. and the output is still different from what
GCC
andClang
give.Output after Modification
This time
cargo build
doesn't show the previous warning.Possible Root cause
The likely cause of the discrepancy is the order of evaluation of
result
.