Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should library expose c_int to consumers or force i32 compatibility

Tags:

I'm writing a simple Rust wrapper over C++ library. And this library is written using native int type. And I don't know what's the best approach to expose these API via rust. Here we have two considerations:

  1. Library is just a wrapper over C++ code and it's not our responsability to check int size. Thus, just expose c_int in our high level interfaces.

  2. High level interfaces must use native Rust types such as i32 so we use it everywhere while statically checking that int is i32 via some healthcheck like

#[allow(unused)]
fn assert_32_bit() {
    let _: c_int = 0_i32;
}

The latter just forbid user to use this library anywhere int is not i32.

I have read nomicon opinion about this problem (link), and its opinion is:

The raw C API needs to be wrapped to provide memory safety and make use of higher-level concepts like vectors.

But all examples with safe wrappers are using int32_t and similar types, that are easy to map on Rust type system.

Which approach should I take, and why? What's the official community position about this question?

For example, here is sample C++ function:

int sum(int a, int b);

Should I write

fn high_level_api_sum(a: c_int, b: c_int) { unsafe {sum(a, b)} }

or

fn high_level_api_sum(a: i32, b: i32) { unsafe {sum(a, b)} }

#[allow(unused)]
fn assert_32_bit() {
    let _: c_int = 0_i32;
}
like image 780
Alex Zhukovskiy Avatar asked Feb 14 '18 13:02

Alex Zhukovskiy


1 Answers

I don't think there is anything remotely like an "official" position on this. What follows is opinion... perhaps suggesting this question isn't suitable for SO in the first place.

If the correct type is c_int, use c_int. Rust programmers shouldn't be so very fragile that they curl into the fetal position just because you use a C type in an interface to a C/C++ library.

Ask yourself this: do your users benefit from you locking out any and all potential platforms where c_int is not i32 (e.g. embedded platforms)?

If the answer is "they don't", then don't do it. If they do benefit somehow, well, you'll have to weigh that against locking out platforms yourself. Maybe the use of c_int imposes some kind of wider interface issue.

like image 88
DK. Avatar answered Sep 20 '22 13:09

DK.