rust-cpp icon indicating copy to clipboard operation
rust-cpp copied to clipboard

Align and size assertion failures

Open EarthyOrange opened this issue 3 years ago • 7 comments

cpp!{{
    #include <stdlib.h>
    #include <errno.h>
}}

fn as_cstr_ptr(str: &str) -> Result<*const u8> {

    let c_string: *const u8 = CString::new(str)?.as_bytes_with_nul().as_ptr();
    Ok(c_string)
}

pub fn set_env_variable(name: &str, value: &str, overwrite: i32) -> Result<i32> {
    let c_name_ptr = as_cstr_ptr(name)?;
    let c_value_ptr = as_cstr_ptr(value)?;
    let ret_val: i32 = cpp!(
        unsafe [
            c_name_ptr as "const char *",
            c_value_ptr as "const char *",
            overwrite as "int"
        ] -> i32 as "int"
        {
            return setenv(c_name_ptr, c_value_ptr, overwrite) != 0 ? errno : 0;
        }
    );
    match ret_val {
        0 => Ok(0),
        code => Err(StdlibError::from(code)),
    }
}

I have the above code snippet, where I am simply trying to call C++'s setenv method. For each of the argument passed to the macro, I see the assertion failure messages (from cpp_macros-0.5.5/src/lib.rs) of the following format.

"size_of for argument `{}` does not match between c++ and rust"
"align_of for argument `{}` does not match between c++ and rust"

Can some light be please shown on:

  • when/why these assertions fail?
  • how to fix them?
  • what is the impact of the size and alignment mismatch?

EarthyOrange avatar Jan 28 '21 01:01 EarthyOrange

let c_string: *const u8 = CString::new(str)?.as_bytes_with_nul().as_ptr();

This is not related to the assertion, but this does not sounds correct, because CString::new() will allocate a copy of the string, and then it will go out of scope because the CString is just a temporary. You need to keep the CString alive.

I don't know what is causing this assert because the arguments seems alright. The assert should contain the name of the wrong argument. It happens when trying to pass an argument which we can detect is of the wrong size, for example a i16 as a "int" or a const dyn Foo as a "const void"

ogoffart avatar Jan 28 '21 08:01 ogoffart

Excellent point with the illegal borrow there. Maybe the compilation didn't fail because it was just checking the Result's movability and ignored the pointer it contains.

I see these asserts fail for all three arguments. The integer arg should not be failing the asserts, correct?

EarthyOrange avatar Jan 28 '21 16:01 EarthyOrange

What's your compiler and platform ?

ogoffart avatar Jan 28 '21 17:01 ogoffart

Actually, the size assertion should in theory never be triggered because there is also a compile check just before. Could you debug and see what are the values of the alignment and size and why they don't match?

ogoffart avatar Jan 28 '21 18:01 ogoffart

I am cross-compiling on windows for linux OS using the gcc-linaro-arm-linux-gnueabihf v4.7 toolchain.

rustc: 1.48.0

EarthyOrange avatar Jan 28 '21 18:01 EarthyOrange

Ah, cross-compilation ... That is probably the reason. I never tried that. Is the C++ compiler is also running in cross compilation mode? Normally the cc crate should take care of that.

ogoffart avatar Jan 28 '21 18:01 ogoffart

For the string "Hello World!!!", size_of returns 15aö>Ln and align_of returns 1. I am not sure why the unicode characters are getting appended to the size_of value.

I don't have to compile any c++ code. I am just dynamically linking the shared objects which I assume have been created using the same g++ compiler.

EarthyOrange avatar Jan 28 '21 19:01 EarthyOrange