Wrapping_add and normal add difference on µc hardware

Hello,

I am testing the integer overflow in Rust & C, a little information - I am using a tc375 board with hightec rust compiler, with C and Rust being compiled together.

Consider the below code built in debug mode with opt-level = 2, when I call test() function from C (main.c) file. For normal_add() func, I was expecting it to have a UB and for wrapped_add, I was expecting the wrapped around value.

pub fn normal_add(a: Datatype, b: Datatype) -> Datatype 
{
    a + b
}

pub fn wrapped_add(a: Datatype, b: Datatype) -> Datatype 
{
    a.wrapping_add(b)
}

#[no_mangle]
pub extern "C" fn test()
{
    let x: Datatype = normal_add(65535, 10);
    let y: Datatype = wrapped_add(65535, 10);

    unsafe 
    {
        core::ptr::write_volatile(&mut 0u16 as *mut _, x);
        core::ptr::write_volatile(&mut 0u16 as *mut _, y);
    }
}

But, I don't see any UB for normal_add in debug mode. Instead a wrapped around value is returned for both.

Does the overflow checks get disabled, when you are compiling for FFI for your rust function called from C? If yes, why does Rust behave in that way?

Thanks

As a matter of principle, Rust does not have UB in safe code.

For addition, Rust defines overflow to panic in debug mode, and wrap in release mode.
(more precisely, it depends on the -C overflow-checks setting.)

2 Likes
  1. Rust doesn't have UB on overflow. The default behavior is to panic on debug builds and wrap on release builds, however, like opt-level, that's just a default.

    If not specified, debug assertions are automatically enabled only if the opt-level is 0

    So if you set opt-level and nothing else, you have disabled the panics.

  2. C doesn't have UB on unsigned overflow either, just signed. (You're example is testing unsigned.)

  3. What do you mean by "don't see any UB" anyway? Your program can contain UB but happen to compile down to something that doesn't crash;[1] that's one of the insidious things about UB.

    • If you meant you didn't see a panic, that's due to my note in (1).

I am unaware of your particular setup, so there may be some discrepancy between what Rust (or C) considers UB and what happens with that particular compiler, if it's exotic enough.


  1. today; maybe the next compilation will crash ↩︎

3 Likes

Yes, I was missing the overflow check flag in toml file and hence, I was not seeing the panic behaviour in debug mode. As I add this flag, the normal_add() func goes into panic. Thanks

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.