¿Por qué memset toma un int en lugar de un char?

5 minutos de lectura

avatar de usuario
usuario541686

Por que memset toma un int como el segundo argumento en lugar de un charmientras que wmemset toma una wchar_t en lugar de algo como long o long long?

  • @Default: jaja, en realidad sé que no funciona, pero creo que hace que sea más fácil de leer visualmente, ¿no es así?

    – usuario541686

    7 de mayo de 2011 a las 7:39


  • No, no a mí. Y para ser exigente, memset también podría ser code 🙂

    – por defecto

    7 de mayo de 2011 a las 7:40

  • Si wmemset fuera simétrico, tomaría un wint_tque es el tipo definido para ser el int para wchar_t‘s char. (Sugerencia: varias funciones en la biblioteca estándar toman int argumentos que se lanzan a los personajes. El estándar (C) dice que los caracteres literales son del tipo intno char.)

    – Chris Lutz

    7 de mayo de 2011 a las 7:42

  • @Default: Haha ok, pensé que podría ser más legible. 🙂 @Chris: Espera, ¿qué? ¡¿Pensé que los chars son personajes?!

    – usuario541686

    7 de mayo de 2011 a las 7:43


  • '\n' es de tipo int en C (no en C++). A menos que esté muy equivocado. Estoy escribiendo esto desde mi iPhone o daría una respuesta más completa.

    – Chris Lutz

    7 de mayo de 2011 a las 7:45

avatar de usuario
ataúd de jerry

memset es anterior (bastante) a la adición de prototipos de funciones a C. Sin un prototipo, usted hipocresía pasar un char a una función — cuando/si lo intenta, será promovida a int cuando lo pasas, y lo que recibe la función es un int.

También vale la pena señalar que en C, (pero no en C++) un carácter literal como 'a' lo hace no tener tipo char — tiene tipo intentonces lo que pase será generalmente comenzar como un int de todos modos. Esencialmente, la única forma de que comience como char y sea promovido es si aprueba un char variable.

En teoria, memset probablemente podría modificarse para que reciba un char en lugar de un int, pero es poco probable que haya algún beneficio, y una posibilidad bastante decente de romper algún código antiguo u otro. Con un costo desconocido pero potencialmente bastante alto, y casi ninguna posibilidad de ningún beneficio real, diría que las posibilidades de que se cambie para recibir un char caer justo en la línea entre “delgado” y “ninguno”.

Editar (respondiendo a los comentarios): El CHAR_BIT partes menos significativas del int se utilizan como el valor para escribir en el destino.

  • Espera, ¿existía una versión de C sin prototipos de funciones? =O

    – usuario541686

    7 de mayo de 2011 a las 7:56


  • Sí, se agregaron prototipos durante la estandarización del C89. Antes de eso, solo había declaraciones de funciones, que especificaban el tipo de retorno, pero no el número o tipo(s) de parámetro(s).

    – Jerry Ataúd

    7 de mayo de 2011 a las 7:58

  • Para ver un ejemplo de descifrar código antiguo, si memset de repente tomó un char luego codifique siguiendo el idioma habitual de pasar (unsigned char)some_int se volvería no estrictamente conforme, ya que no funcionaría en una implementación (muy rara) donde char está firmado y los valores son mayores que CHAR_MAX no convertir a char como esperarías.

    –Steve Jessop

    03/04/2013 a las 21:52


  • También, memset no por definición utilizar el CHAR_BIT bits menos significativos del valor. Está definido para convertir el valor a unsigned charque en una representación en complemento a 2 equivale a lo mismo, pero en otras implementaciones (muy raras) no tanto.

    –Steve Jessop

    03/04/2013 a las 21:54


  • He estado usando C++ durante tanto tiempo que lo había olvidado 'a' en C es un int y no un char.

    – Adrián McCarthy

    22 mayo 2014 a las 17:32

avatar de usuario
Frederic Hamidi

Probablemente la misma razón por la que las funciones en <ctypes.h> llevar ints y no chars.

En la mayoría de las plataformas, un char es demasiado pequeño para colocarse en la pila por sí mismo, por lo que generalmente se inserta el tipo más cercano al tamaño de palabra de la máquina, es decir int.

Como señala el enlace en el comentario de @ Gui13, hacer eso también aumenta el rendimiento.

  • Hay una respuesta interesante aquí: programrsheaven.com/mb/embedCpp/359784/359784/memset-function lo que confirma lo que estás diciendo 🙂 Lo que es interesante confirmar es cuál es el comportamiento de memset(ptr, 0xFEBADE23, 1);? ¿Qué parte del int se escribe?

    – Gui13

    7 de mayo de 2011 a las 7:52


  • @Frederic: Gran explicación, pero ¿por qué no se aplica lo mismo a wmemset? no es un wchar_t también demasiado pequeño para ser empujado a la pila en muchas plataformas también (a menudo 16 bytes)?

    – usuario541686

    7 de mayo de 2011 a las 7:59

  • Las funciones en <ctype.h> llevar ints por la misma razón que getc, fgetcetc regreso int — para acomodar EOFque debe ser distinto de cualquier valor de char (o signed char o unsigned char).

    – Jerry Ataúd

    7 de mayo de 2011 a las 8:02


  • @Mehrdad, eso depende. wchar_t tiene 32 bits de ancho en sistemas Linux 🙂

    – Frederic Hamidi

    7 de mayo de 2011 a las 8:05


  • @Frederic: Pero son 16 bits en sistemas Windows… 😛 (Creo que te referías a bits no bytes)

    – usuario541686

    7 de mayo de 2011 a las 8:06


Vea la respuesta de Fred, es por razones de rendimiento.

Por mi parte, probé este código:

#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;
}

Y me da esto en un Mac de 64bits:

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

Entonces, como puede ver, solo se escribe el último byte. Supongo que esto depende de la arquitectura (endianness).

  • El valor escrito es independiente del endianismo de la arquitectura. El valor escrito es el valor pasado convertido a un unsigned char que significa modulo 2^CHAR_BIT aritmética. Esto significa que el menos significativo CHAR_BIT bits sea cual sea el endianness de la máquina.

    –CB Bailey

    7 de mayo de 2011 a las 8:02

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad