Просто так, для красоты )) в реализации оно приводится к unsigned char
memset.c glibc
/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */memset (void *dstpp, int c, size_t len)
{
longint dstp = (longint) dstpp;
if (len >= 8)
{
size_t xlen;
op_t cccc;
cccc = (unsignedchar) c;
cccc |= cccc << 8;
cccc |= cccc << 16;
if (OPSIZ > 4)
/* Do the shift in two steps to avoid warning if long has 32 bits. */
cccc |= (cccc << 16) << 16;
...
В musl тоже приводят
#include<string.h>#include<stdint.h>void *memset(void *dest, int c, size_t n)
{
unsignedchar *s = dest;
size_t k;
/* Fill head and tail with minimal branching. Each
* conditional ensures that all the subsequently used
* offsets are well-defined and in the dest region. */if (!n) return dest;
s[0] = s[n-1] = c;
if (n <= 2) return dest;
s[1] = s[n-2] = c;
s[2] = s[n-3] = c;
if (n <= 6) return dest;
s[3] = s[n-4] = c;
if (n <= 8) return dest;
/* Advance pointer to align it at a 4-byte boundary,
* and truncate n to a multiple of 4. The previous code
* already took care of any head/tail that get cut off
* by the alignment. */
k = -(uintptr_t)s & 3;
s += k;
n -= k;
n &= -4;
#ifdef __GNUC__typedefuint32_t __attribute__((__may_alias__)) u32;
typedefuint64_t __attribute__((__may_alias__)) u64;
u32 c32 = ((u32)-1)/255 * (unsignedchar)c;
Я не пишу на C, так что мне не надо (Почему я лезу не в свою тему - уже другой вопрос ;D).
А 4 байта у char литерала, а не у char, да. Я просто помню что с C++ была какая-то разница, но в чём она заключалась - не помню.
И это в той или иной степени объясняет почему там int.
Я думаю, это заговор масонов. Сделано специально, чтобы было легче перепутать второй и третий аргумент. А хитрые евреи зарабатывают на этом, занимаясь написанием статей типа "Самая опасная функция в мире С/С++" и продавая несчастным PVS-Studio.
И правильно делаю, не полез бы - не узнал что не прав.
И раз уж я такой неграмотный в С, то что будет если я передам значение, которое не влезает в 8 бит?
И раз уж я такой неграмотный в С, то что будет если я передам значение, которое не влезает в 8 бит?
Вам же вроде говорили, что это обычное дело, когда работают с типами аргументов шире, чем тип самих данных. Раз обещают заполнять байтами, значит до байта и обрежут. Я вам открою страшную тайну - такого в С очень много, начиная с putchar(c), ну или при printf(«%f», (float)f) - на самом деле в стек будет помещен double. Это пошло с тех времён изобретения С, когда почти все машины не допускали невыровненную адресацию.
Да я к тому что memset хочет int не потому что так едйствительно надо, а потому что просто удобнее видеть славный и красивый int в параметрах функции, а не char который сразу навевает мысли разные, int универсальнее так как в мыслях сразу число, а не символ и его размер был бы char появлялись бы вопросы в стиле эпик на стаковерфлове мол, а чё нельзя wchar_t совать и мол какая разница между ними, а тут int как int )))))
Если я бред написал, забыдь и выплюнь я не спал трое суток лалайй-лалаааай :D