При определении функции, которая будет работать с памятью, правильнее ли передавать адреса как void * или uint8 *?

#c #pointers #syntax #types #casting

#c #указатели #синтаксис #типы #Кастинг

Вопрос:

Большинство существующих функций памяти во время выполнения принимают или возвращают void*, что позволяет передавать аргументы без явного приведения типов указателей. Должен ли этот шаблон реплицироваться при создании пользовательских функций памяти?

Другими словами, что из следующего является более правильным и почему:

 int read_bytes( void * dest, size_t count );
 

или

 int read_bytes( uint8_t * dest, size_t count );
 

?

Ответ №1:

Я бы рекомендовал использовать void* . В противном случае каждый вызов функции будет выглядеть как:

 int n = read_bytes((uint8_t*)amp;myVar, sizeof(myVar));
 

вместо того, чтобы просто

 int n = read_bytes(amp;myVar, sizeof(myVar));
 

Ответ №2:

void* — это указатель общего назначения в C / C . Он используется в тех случаях, когда вы не хотите, чтобы определенный тип указывался с данными, и позволяет избежать необходимости приведения указателя. Это также указатель, который вы хотите использовать с необработанными адресами.

Вы бы использовали uint_t, где вы хотите указать, что вы действительно имеете дело с целыми числами без знака.

Ответ №3:

Если вы обрабатываете память только как необработанную, непрозрачную память, а не как последовательность байтов, то void * это подходящий тип. Это может быть идиоматическим, например, при использовании placement-new для создания объекта в памяти. Существуют также некоторые традиционные API-интерфейсы C, которые используют указатели void для ссылок на память, например memcpy or memchr , поэтому иногда может быть удобно использовать один и тот же тип.

С другой стороны, если вы думаете о памяти как о массиве байтов, и особенно если вы хотите получить доступ к случайным байтам в памяти (т. Е. Выполнить арифметику указателя или итератора), вам обязательно следует использовать тип указателя char . Существует определенная дискуссия о том, какой из них лучше; как правило, для ввода-вывода вам нужен простой char как «тип данных системного ввода-вывода» (например, ввод-вывод чтения / записи). С другой стороны, если вы хотите оперировать арифметическими байтовыми значениями, unsigned char это более уместно. Однако эти два типа совместимы с макетом, так что не стесняйтесь относиться к одному как к другому, если это необходимо.