为什么memset的第二个参数不把int替换成char

时间:2021-11-14 21:49:47

memset是一个经常被用来初始化数组的函数,其定义如下:

1
void * memset ( void * ptr, int value, size_t num );

它的效果大致是把以ptr为起始地址,长度为num个字节的内存区间内,每个字节的值都设值成value。

这里就有一个奇怪的现象了,为什么value的类型被声明成了int,但却只用到了最低位的那个字节?或者说为什么memset只需要一个字节的值来做填充,但却需要用户传入一个int?

这还要从C89标准说起,据说在C89标准出来之前,C的代码中并不强制函数原型的声明,如果一个函数的调用出现在了它的声明之前,编译器会去假设一个声明。比如说:

1
2
3
4
5
6
7
void bar() {
  int a = foo(5);
}
int foo(int x) {
  return x + 1;
}

在这段代码中,foo在bar中被调用,但是声明却在其之后,现在的编译器是会给出编译错误的,但是在C89之前,编译器会根据函数调用的语句,int a = foo(5)来猜出foo的函数原型,比如传入的值是5,就是一个int,返回值也是一个int。

所以说,在一些古老的代码中,memset的调用可以发生在它被声明之前。但在C89之后,函数声明变成了必须的,于是memset就一定要被先声明出来,这时候为了照顾已有的代码,如

1
void * memset ( array, 0, sizeof(array) );

即使是对char数组赋值的memset,如

1
void * memset ( array, 'a', sizeof(array) );

字符常量(如’a')在C语言中也被认为成int类型,于是memset的原型就只能也使用int了……

就是说,它在接受‘a’类型的字符时,实际上的类型是int

reference:

http://*.com/questions/5919735/why-does-memset-take-an-int-instead-of-a-char

https://leonax.net/p/3037/why-memset-takes-int-as-its-second-parameter-instead-of-char/