Description
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 <[email protected]>"]
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.