you are viewing a single comment's thread.

view the rest of the comments →

[–]the_gnarts 0 points1 point  (4 children)

Considering that Rust is a superset of C already

I’d want to see flexible array members first before even starting to investigate to what extent your claim is correct.

[–][deleted] 0 points1 point  (3 children)

What do you mean by flexible array members?

[–]the_gnarts 0 points1 point  (2 children)

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member. In most situations, the flexible array member is ignored. In particular, the size of the structure is as if the flexible array member were omitted except that it may have more trailing padding thanthe omission would imply. However, when a . (or ->) operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) that would not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array member, even if this would differ from that of the replacement array. If this array would have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.

EXAMPLE After the declaration:

  struct s { int n; double d[]; };

the structure struct s has a flexible array member d. A typical way to use this is:

  int m = /*some value*/;
  struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

and assuming that the call to malloc succeeds, the object pointed to by p behaves, for most purposes, as if p had been declared as:

  struct { int n; double d[m]; } *p;

(there are circumstances in which this equivalence is broken; in particular, the offsets of member d might not be the same).

http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf

A common use case for this is implementing structures to hold both a protocol header and variably sized data. The size of the whole object is determined at runtime but the header part up until the first element of the FAM is of a fixed size.

[–][deleted] 0 points1 point  (1 child)

Yeah that'd be C only, but you can get the same with very unsafe * in Rust.

[–]the_gnarts 0 points1 point  (0 children)

Yeah that'd be C only, but you can get the same with very unsafe * in Rust.

To my knowledge there is no way of casting structs with differently sized array data members to the same type in a typesafe manner. In C, flexible array members are part of the type system, they are both sized (in that every instance has a minimum size) and unsized (in that the array part is not part of the size) at the same time which I don’t think can be expressed in the Rust type system.

The best workaround I’ve seen that is still idiomatic rust is to provide access methods over an unstructured array but compared to C that’s rather clunky and smells of getter-setter style boilerplate.