0

According to Pointer arithmetic for void pointer in C, arithmetic with void pointers is not allowed. Yet, the iovec structure looks like so:

struct iovec {
    void *iov_base;
    size_t iov_len;
};

This is defined in the POSIX standard, and the iov_len field is described as the somewhat vague "The size of the memory pointed to by iov_base". Since iovec is just a data structure, I wondered if the functions that accept it as input parameters define how they use the iov_len field, but both readv and writev desribe it, again vaguely, as "the length of an area of memory."

For some functions, the meaning of the iov_len field does seem to be explicitly defined. For example, the recvmsg specification says the "iov_len field gives [the storage area's] size in bytes". Additionally, recv, which accepts a void pointer and length, properly defines the length parameter as the length of the buffer in bytes.

My question: Is the meaning of the iov_len field well-defined in these cases where it's defined as the length of a buffer?

jezza
  • 331
  • 2
  • 13
  • 1
    Is your beef with `iov_len` that it is a bit under-specified and doesn't tell you that the size is supposed to be in bytes, or is there something else? Also, the fact that pointer arithmetics is not allowed for `void*` seems to be irrelevant to the overall question. – SergeyA Mar 30 '21 at 20:01
  • I guess I'm being pedantic, but I would have thought pedantry is important when writing a standard... Also, if `void*` arithmetic was allowed (i.e. if `void` was a complete type), then the length could be naturally assumed to be the number of `void` elements in the buffer. As it stands, because `void` is an incomplete type, `iov_len` has no units, so to refer to it as a length is technically meaningless. – jezza Mar 30 '21 at 22:04
  • But I'm also wondering if I'm missing a subtlety. For instance the term 'size' or 'length' may be defined elsewhere in the standard to mean size in bytes. – jezza Mar 30 '21 at 22:06

2 Answers2

2

I believe you're just overthinking here. "Size" here definitely means "size in bytes", and in the cases you mention I don't think there's any meaningful difference between the words "size" and "length". There's no subtlety that you're missing.

It might be a tiny bit sloppy that they didn't say "in bytes" as they do in many other places, and you could file a defect report if you really want, but I don't see much room for confusion as there's really no other sensible interpretation.

Nobody is claiming that void has a size, but it's very common to use void * as a pointer to a generic buffer whose size is denominated in bytes; using void * instead of unsigned char * makes it convenient for you to pass a pointer to some other type without casting.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
0

That's pretty common to deal with void * along with explicit size. It allows you to forget the type of object you are referencing and thus reuse same the same void * field to store different types of data without unions at all.

The reason why you need size is typically for memcpy, which copies continuous memory. That way you are able not to only keep your data in a void * (you know desired size, so you can malloc it safely), but also pass it over.

Of course, you can always get back to typed world by casting your void * to some other type, for example size_t *.


void * are often used to implement "generic" data structures in C or for higher order functions. For example here is qsort definition:

void qsort(
   void *base,
   size_t number,
   size_t width,
   int (__cdecl *compare )(const void *, const void *)
);
Zazaeil
  • 3,900
  • 2
  • 14
  • 31