Why does memset
take an int
as the second argument instead of a char
, whereas wmemset
takes a wchar_t
instead of something like long
or long long
?

- 205,094
- 128
- 528
- 886
-
1@Default: Haha actually I know it doesn't work, but I think it makes it easier to read visually, doesn't it? – user541686 May 07 '11 at 07:39
-
Nope, not to me. And to be picky, memset could also be `code` :) – default May 07 '11 at 07:40
-
If `wmemset` was symmetrical it would take a `wint_t`, which is the type defined to be the `int` to `wchar_t`'s `char`. (Hint: several functions in the standard library take `int` arguments that are cast to characters. The (C) standard says that character literals are of type `int`, not `char`.) – Chris Lutz May 07 '11 at 07:42
-
@Default: Haha ok, I thought it might be more readable. :) @Chris: Wait, what?? I thought chars are characters?! – user541686 May 07 '11 at 07:43
-
`'\n'` is of type `int` in C (not in C++). Unless I'm badly mistaken. I'm typing this from my iPhone or I'd give a more comprehensive answer. – Chris Lutz May 07 '11 at 07:45
-
@Chris: Interesting, I had no idea, thanks. But then again, couldn't it be implicitly converted to `char`, since it fits in? (Feel free to respond later, I know it's not easy to type on a phone, haha.) – user541686 May 07 '11 at 07:45
-
What's strange is that `memset(ptr, 0xFEBADE23, 1);` is valid, but will only affect *one* bytes. The int I pass as argument is 4 bytes! What happens then? – Gui13 May 07 '11 at 07:47
-
@Gui13: Exactly, that's pretty much my question. :) – user541686 May 07 '11 at 07:48
-
You should edit your question then, to make this appear more clearly. – Gui13 May 07 '11 at 07:49
3 Answers
memset
predates (by quite a bit) the addition of function prototypes to C. Without a prototype, you can't pass a char
to a function -- when/if you try, it'll be promoted to int
when you pass it, and what the function receives is an int
.
It's also worth noting that in C, (but not in C++) a character literal like 'a'
does not have type char
-- it has type int
, so what you pass will usually start out as an int
anyway. Essentially the only way for it to start as a char and get promoted is if you pass a char
variable.
In theory, memset
could probably be modified so it receives a char
instead of an int
, but there's unlikely to be any benefit, and a pretty decent possibility of breaking some old code or other. With an unknown but potentially fairly high cost, and almost no chance of any real benefit, I'd say the chances of it being changed to receive a char
fall right on the line between "slim" and "none".
The value memset
writes into the destination is the value of its second argument converted to an unsigned char
.

- 195,579
- 13
- 168
- 312

- 476,176
- 80
- 629
- 1,111
-
9Wait, there existed a version of C without function prototypes?! =O – user541686 May 07 '11 at 07:56
-
10Yes -- prototypes were added during the C89 standardization. Before that, there were only function declarations, which specified the return type, but not the number or type(s) of parameter(s). – Jerry Coffin May 07 '11 at 07:58
-
2For an example of breaking old code, if `memset` suddenly took a `char` then code following the usual idiom of passing `(unsigned char)some_int` would become non-strictly-conforming, since it wouldn't work on a (very rare) implementation where `char` is signed and values greater than `CHAR_MAX` don't convert to `char` as you'd hope. – Steve Jessop Apr 03 '13 at 21:52
-
7Also, `memset` doesn't *by definition* use the `CHAR_BIT` least significant bits of the value. It's defined to convert the value to `unsigned char`, which on a 2's complement representation amounts to the same thing, but on other (very rare) implementations not so much. – Steve Jessop Apr 03 '13 at 21:54
-
1I've been using C++ for so long, I'd forgotten that `'a'` in C is an `int` and not a `char`. – Adrian McCarthy May 22 '14 at 17:32
Probably the same reason why the functions in <ctypes.h>
take ints
and not chars
.
On most platforms, a char
is too small to be pushed on the stack by itself, so one usually pushes the type closest to the machine's word size, i.e. int
.
As the link in @Gui13's comment points out, doing that also increases performance.

- 1
- 1

- 258,201
- 41
- 486
- 479
-
1There's an interesting answer here: http://www.programmersheaven.com/mb/embedCpp/359784/359784/memset-function/ , which confirms what you're saying :) What's interesting to confirm is what's the behaviour of `memset(ptr, 0xFEBADE23, 1);`? Which part of the int gets written? – Gui13 May 07 '11 at 07:52
-
@Frederic: Great explanation, but why doesn't the same thing apply to `wmemset`? Isn't a `wchar_t` also too small to be pushed onto the stack on many platforms too (often 16 bytes)? – user541686 May 07 '11 at 07:59
-
3The functions in `
` take `int`s for the same reason that `getc`, `fgetc`, etc., *return* `int` -- to accommodate `EOF`, which needs to be distinct from any value of `char` (or `signed char` or `unsigned char`). – Jerry Coffin May 07 '11 at 08:02 -
@Mehrdad, that depends. `wchar_t` [is 32 bits wide](http://gcc.gnu.org/ml/gcc/1998-08/msg00747.html) on Linux systems :) – Frédéric Hamidi May 07 '11 at 08:05
-
@Frederic: But it's 16 bits on Windows systems... :P (I think you meant `bits` not `bytes`) – user541686 May 07 '11 at 08:06
-
While the "efficiency" argument probably isn't right about `
` functions, it probably *is* a fairly reasonable guess of why the original design of C promoted all smaller types to `int` when being passed as parameters. As such, I'd call it at least half right in any case. – Jerry Coffin May 07 '11 at 08:08 -
-
The URL which @Gui13 provided should be [this](https://programmersheaven.com/discussion/359784/memset-function) now. – Feng. Ma Sep 15 '20 at 07:25
See fred's answer, it's for performance reasons.
On my side, I tried this code:
#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;
}
And it gives me this on a 64bits Mac:
Before: c = 0x00
After: c = 0x54
So as you see, only the last byte gets written. I guess this is dependent on the architecture (endianness).

- 12,993
- 17
- 57
- 104
-
6The value written is independent of the endianness of the architecture. The value written is the value passed in converted to an `unsigned char` which means modulo `2^CHAR_BIT` arithmetic. This means the least significant `CHAR_BIT` bits whatever the endianness of the machine. – CB Bailey May 07 '11 at 08:02