Подтвердить что ты не робот

Почему memset принимает int вместо char?

Почему memset принимает int как второй аргумент вместо char, тогда как wmemset принимает wchar_t вместо чего-то вроде long или long long?

4b9b3361

Ответ 1

memset предшествует (довольно немного) добавлению прототипов функций к C. Без прототипа вы не можете передать char функции - когда/если вы попытаетесь, он будет повышен до int когда вы передадите его, и то, что получает функция, является int.

Стоит также отметить, что в C (но не в C++) символьный литерал, такой как 'a', не имеет тип char - он имеет тип int, поэтому то, что вы передаете, обычно в любом случае начинается как int. По сути, единственный способ начать его как символ и получить повышение - это передать переменную типа char.

В теории, memset, вероятно, может быть модифицирован таким образом, он получает char вместо int, но вряд ли какая - либо польза, и довольно приличная возможность нарушения какой - то старый кода или другого. С неизвестной, но потенциально довольно высокой стоимостью и практически без шансов на реальную выгоду, я бы сказал, что шансы на ее изменение, чтобы получить char падают прямо на границу между "тонким" и "ничем".

Редактировать ( в ответ на комментарии): CHAR_BIT наименее значимые биты int используются в качестве значения для записи цели.

Ответ 2

Вероятно, по той же причине, почему функции в <ctypes.h> принимают ints, а не chars.

На большинстве платформ char слишком мал, чтобы нажимать на стек сам по себе, поэтому обычно подталкивает тип, ближайший к размеру машинного слова, т.е. int.

Как указывает ссылка в комментарии @Gui13, выполнение этого также повышает производительность.

Ответ 3

См. ответ fred, по соображениям производительности.

На моей стороне я пробовал этот код:

#include <stdio.h>
#include <string.h>

int main (int argc, const char * argv[])
{
    char c = 0x00;

    printf("Before: c = 0x%02x\n", c);
    memset( &c, 0xABCDEF54, 1);
    printf("After:  c = 0x%02x\n", c);

    return 0;
}

И это дает мне это на 64-битном Mac:

Before: c = 0x00
After:  c = 0x54

Итак, как вы видите, записывается только последний байт. Я предполагаю, что это зависит от архитектуры (endianness).