18

I would like to implement this C code which uses a flexible array member (sometimes called the struct hack) in Rust:

struct test {
  int key;
  int dataSize;
  int data[];
};
struct test* t = malloc(sizeof(struct test) + sizeOfData)

The empty array at the end of structure allows you to allocate your meta fields and data all at once. Unfortunately, I can't figure out how to do such thing in Rust.

3
  • 4
    users.rust-lang.org/t/… Commented Jun 23, 2018 at 23:17
  • 2
    I think you could achieve this on nightly with the allocator API and a decent amount of unsafe. But I'm not familiar enough with how it works in C. What if the alignment of the data array is bigger than the size of the header -- are padding bytes counted in the sizeof, or do we just rely on malloc allocating more than necessary to satisfy the maximum possible alignment? Commented Jun 24, 2018 at 0:14
  • @MatthieuM. Probably my fault because you can't avoid padding bytes like I said, both sizeof and offsetof must produce the same size for FAM. Commented Oct 30, 2018 at 8:33

1 Answer 1

2

The Rust equivalent of this struct would use a slice:

struct test {
  key: i32,
  dataSize: i32,
  data: [i32],
}

however, these types are not really convenient to use at the moment as there is no safe way to construct them.

A more practical way to do this is to use a generic:

struct test<T: ?Sized> {
  key: i32,
  dataSize: i32,
  data: T,
}

and then to make sure that you only use test when T is an array or a slice (which you could only create through coercion).

See also:

Sign up to request clarification or add additional context in comments.

5 Comments

no it's wrong, slice contains their len, FAM doesn't. There is no equivalent of FAM in Rust ATM.
@Stargateur [T] does not contain the length. You are talking about &[T] which is a fat pointer to a slice: that contains the length. But not the unsized [T] itself.
@JL2210 A fat pointer is a pointer + some extra data, for example &[T] is a fat pointer, as it contains the address to the first element + the size, and &dyn Trait is a fat pointer as it contains a pointer to the data + a pointer to the vtable.
@LukasKalbertodt but this would not make sense in Rust, [T] need to know its size somehow, if you need unsafe this would not be Rust for me. Say [T] is the equivalent of FAM is wrong for me, at least for now.
Hoi! Could this be the correct solution to all of this? At least pointers to structs with an extern type as last field are not fat pointers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.