Why does this code use * char as a buffer pointer?

Looking for a circular buffer code for reuse, I came across using char, which confuses me

typedef struct CircularBuffer { void *buffer; // data buffer void *buffer_end; // end of data buffer size_t capacity; // maximum number of items in the buffer size_t count; // number of items in the buffer size_t sz; // size of each item in the buffer void *head; // pointer to head void *tail; // pointer to tail } CircularBuffer; void cb_push_back(CircularBuffer *cb, const void *item) { if(cb->count == cb->capacity) // handle error memcpy(cb->head, item, cb->sz); ////////////// here the part I don't understand ////////// cb->head = (char*)cb->head + cb->sz; ////////////////////////////////////////////////////////// if(cb->head == cb->buffer_end) cb->head = cb->buffer; cb->count++; } 

Why cast this pointer to a void char? Is this some kind of C-idiom (I have very limited C experience)? A simple convenient way to increase the pointer, perhaps?

Using char for a position indicator reappears in another buffer:

 /**< Circular Buffer Types */ typedef unsigned char INT8U; typedef INT8U KeyType; typedef struct { INT8U writePointer; /**< write pointer */ INT8U readPointer; /**< read pointer */ INT8U size; /**< size of circular buffer */ KeyType keys[0]; /**< Element of ciruclar buffer */ } CircularBuffer; 

Again, this looks like some sort of handy trick that C programmers know about, something that pointers are easy to manipulate if they are characters. But I'm really just thinking.

+4
source share
4 answers

Casting to char * is to do the pointer arithmetic correctly if you want to move the pointer in single-byte steps; this always works because char have, by definition, a size of 1 byte. Pointer arithmetic with void * pointers is not defined by the C standard instead, because void does not specify a size for a single element.

Another common C-idiom (associated with this) is to use unsigned char * when you want to access some memory as "raw bytes" ( unsigned type allows you to access the unsigned value of each byte without casting); it is often used also by typedef ed (something like strings typedef unsigned char byte; ), so that it is superfluous to understand that you do not want to interpret memory as characters, but as raw bytes.

+6
source

A char is one byte in size, so it (either signed char or unsigned char ) is used when you want to manipulate a certain area of ​​memory just like an array of bytes.

+5
source

Void pointers point to a value and have no type information. Thus, it is not possible to add to void pointers. Casting it to some other type is necessary for pointer arithmetic. Here's casting void * to char *, and then adding cb-> sz, moving forward in byte size, provided that the size of char is 1.

+3
source

Listing allows pointer arithmetic; without it, since cb->head is of type void* , the expression cb->head + cb->sz does not make sense.

After the pointer is converted to char* , adding the pointer (char*)cb->head + cb->sz means "the address of the object cb->size bytes, where cb->head points to.

+1
source

Source: https://habr.com/ru/post/1337707/


All Articles