Description
pub extern fn main() {
let num = 1.0;
if num > 0.0 {}
}
The above code (and any other code that uses f64, implicitly or explicitly) fails linking:
error: linking with `avr-gcc` failed: exit code: 1
|
= note: "avr-gcc" "-Os" "-mmcu=atmega328p" "-L" "/home/serenity/.xargo/lib/rustlib/avr-atmega328p/lib" "/home/serenity/rust-avr/float-bug-testcase/bug_2/target/avr-atmega328p/debug/deps/float_bug_testcase-d40b13363c5ce825.0.o" "-o" "/home/serenity/rust-avr/float-bug-testcase/bug_2/target/avr-atmega328p/debug/deps/float_bug_testcase-d40b13363c5ce825.elf" "-Wl,--gc-sections" "-L" "/home/serenity/rust-avr/float-bug-testcase/bug_2/target/avr-atmega328p/debug/deps" "-L" "/home/serenity/rust-avr/float-bug-testcase/bug_2/target/debug/deps" "-L" "/home/serenity/.xargo/lib/rustlib/avr-atmega328p/lib" "-Wl,-Bstatic" "/home/serenity/.xargo/lib/rustlib/avr-atmega328p/lib/libcore-3a5a5f891c3076ed.rlib" "-Wl,-Bdynamic" "-Wl,--gc-sections" "-flto" "-fuse-linker-plugin" "-Os" "-w"
= note: /home/serenity/rust-avr/float-bug-testcase/bug_2/target/avr-atmega328p/debug/deps/float_bug_testcase-d40b13363c5ce825.0.o: In function `main':
float_bug_testcase.cgu-0.rs:(.text.main+0x5e): undefined reference to `__gtdf2'
collect2: error: ld returned 1 exit status
error: aborting due to previous error
__gtdf2
is used for 64-bit floats, which are not supported by avr-gcc/avr-libc.
avr-gcc has sizeof(float) == sizeof(double) == 4, so there are no 64-bits floats in AVR C/C++.
If we tell the compiler to use f32, in whatever way we choose (explicit type annotation on num
or using the f32
suffix on either integer literal, the code compiles successfully.
Using f32 by default seems like the best course of action IMO, if that's a reasonable change.
Even then, though, the question about how to deal with f64 when used explicitly remains.
It could be entirely disallowed, support could be added (but that would likely involve hand-writing all the necessary 64-bit soft float code in assembly), or (ugh) f64 could be 32 bits wide.