Stream: general

Topic: ffi for [T; N] args


Luca Barbato (May 20 2020 at 09:02, on Zulip):

Recently we had a this PR that produced something faulty, I reduced it to this, is it a cbindgen problem or something that should be addressed in rustc ?

LeSeulArtichaut (May 20 2020 at 09:09, on Zulip):

it's kinda ugly, but such is C interop

:heart: :laughing:

Luca Barbato (May 20 2020 at 09:12, on Zulip):

I have few ideas on how to fix it on the cbindgen side (not accepting [T; 3] arguments when generating bindings), but now I'm wondering if there is something broken on the rustc side.

Luca Barbato (May 20 2020 at 09:13, on Zulip):

Incidentally f(a: *const [T; N]) on the rust side called as T foo[N] = ...; f(foo) on the C side, seems working ...

LeSeulArtichaut (May 20 2020 at 09:16, on Zulip):

I think you'll be more likely to find an answer by asking cbindgen folks what's the expected behaviour in cbindgen. I might be wrong though, I never did C bindings in rust :eyes:

Luca Barbato (May 20 2020 at 09:17, on Zulip):

the code generated by cbindgen is faulty. That's sure.

Luca Barbato (May 20 2020 at 09:20, on Zulip):

But then, what extern "C" fn foo(my_array: [T; N]) is supposed to produce ^^; ?

Hanna Kruppe (May 20 2020 at 09:34, on Zulip):

I think this is a bug in the improper_ctypes lint: passing arrays by value has no C equivalent, so we should warn about it when an array is used as "top level" type. Similar to how passing PhantomData directly is considered "improper", but having PhantomData occur in repr(C) structs isn't.

Hanna Kruppe (May 20 2020 at 09:34, on Zulip):

I vaguely recall discussing this before

Luca Barbato (May 20 2020 at 09:35, on Zulip):

you can by having this map [T; N] -> typedef struct TN { T a[N] } TN;

Hanna Kruppe (May 20 2020 at 09:35, on Zulip):

Oh, I found it and it turns out someone fixed the bug I was thinking of and the lint does complain nowadays: #66305

Luca Barbato (May 20 2020 at 09:36, on Zulip):

but not by default, I guess ^^

Hanna Kruppe (May 20 2020 at 09:37, on Zulip):

Luca Barbato said:

you can by having this map [T; N] -> typedef struct TN { T a[N] } TN;

This is not passing an array by value, it's passing a struct by value. The Rust equivalent for that is a repr(C) struct containing an array.

Luca Barbato (May 20 2020 at 09:37, on Zulip):

C does not have arrays :P

Luca Barbato (May 20 2020 at 09:38, on Zulip):

array notation as argument is just sugar for the pointer notation ^^

Hanna Kruppe (May 20 2020 at 09:38, on Zulip):

I don't know what point you're trying to make.

Luca Barbato (May 20 2020 at 09:38, on Zulip):

that it should be probably either an hard error or a default on lint

Hanna Kruppe (May 20 2020 at 09:44, on Zulip):

Oh, right. The improper_ctypes lint in general (not just for by-value arrays) doesn't currently run on C-ABI functions defined in Rust, only in declarations from extern {} blocks. This is https://github.com/rust-lang/rust/issues/66220

Luca Barbato (May 20 2020 at 09:49, on Zulip):

I see

Gary Guo (May 20 2020 at 23:14, on Zulip):

C does not have arrays

That's an incorrect statement. C does have arrays, but it "decays" when it is used as a rvalue, and that's what happened in function parameters.

Gary Guo (May 20 2020 at 23:14, on Zulip):

This is likely a cbindgen bug.

Josh Triplett (May 21 2020 at 07:49, on Zulip):

Right, you can tell if something is an array or pointer via typeof.

Josh Triplett (May 21 2020 at 07:49, on Zulip):

There's a macro in the Linux kernel that checks for arrayness.

Connor Horman (May 25 2020 at 23:51, on Zulip):

typeof? What is this gnu extension nonsense. sizeof however does work.

Last update: May 29 2020 at 18:00UTC