In latest nightly observing a to-be returned variable changes its value.
Code
I have not been able to reproduce this with pure c code. I found this while working with cgo+rust, and managed to make a small-ish reproducible setup.
I tried this code:
lib.rs
use softposit::{P32, P16}; #[no_mangle] pub extern "C" fn positdiv32(a: u32, b:u32) -> u32{ let a = P32::from_bits(a); let b = P32::from_bits(b); let c = a/b; let x = c.to_bits(); // if x >> 31 == 0{ // print!("hey!\n"); // } // print!("{:}\n",x); x }
toml file
[package] name = "positrs" version = "0.1.0" authors = ["jaap aarts <jaap.aarts1@gmail.com>"] edition = "2018" [lib] crate-type = ["cdylib"] [dependencies] softposit = "0.3.9"
positrs.h
#include <stdarg.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> uint32_t positdiv32(uint32_t a, uint32_t b);
c file
#include <stdio.h> #include <stdint.h> #include "positrs.h" void binprintf(uint32_t v) { unsigned int mask=1<<((sizeof(int)<<3)-1); while(mask) { printf("%d", (v&mask ? 1 : 0)); mask >>= 1; } } void main(){ uint32_t a = 0b11000100001110111011110011001000; uint32_t b = 0b01011111011001010011000111110001; uint32_t c = positdiv32(a,b); binprintf(c); }
run
cargo build --release
cp target/release/libpositrs.so .
gcc -g main.c -o call_rust -L. -lpositrs
LD_LIBRARY_PATH=. ./call_rust
And you will see that this prints 00011110000111010100101001000110⏎
This is (to me) clearly wrong since dividing a negative number with a positive number should be a negative number, and this is a positive number.
So I tried to print the variable in rust, see where it went wrong...
Uncomment the printf!(...) line and run the following commands
cargo build --release
cp target/release/libpositrs.so .
LD_LIBRARY_PATH=. ./call_rust
and this luckely prints the exact same binary value....
3789731258
11100001111000101011010110111010⏎
oh.
somehow adding the print statement changes the return value of the function when exported to C.
The second one is correct, the first is not.
I also tried just observing x, without actually printing it, using the if statement above the print! and it had the same result as the print!
I expected to see this happen:
I expected the value to be the same no-matter what if the value is being observed, and this to be the correct value of 0b11100001111000101011010110111010
Instead, this happened: explanation
Instead I got the wrong number after updating to the latest nightly.
Version it worked on
Currently I know for sure it works on rustc 1.52.0-beta.6 (f97769a2b 2021-04-27)
It also previously worked on nightly, but I dont think I can see the version history.
Version with regression
current broken nightly version: rustc 1.53.0-nightly (42816d61e 2021-04-24)
rustc --version --verbose:
rustc 1.52.0-beta.6 (f97769a2b 2021-04-27)
binary: rustc
commit-hash: f97769a2b7bc5a6b3d8f7140613cf26352f2b518
commit-date: 2021-04-27
host: x86_64-unknown-linux-gnu
release: 1.52.0-beta.6
LLVM version: 12.0.0
The compiler did not crash.