Pregunta

Cuando uso malloc y hago una manipulación de memoria similar, ¿puedo confiar en que sizeof (char) sea siempre 1?

Por ejemplo, necesito asignar memoria para N elementos de tipo char . Se está multiplicando por sizeof (char) necesario:

char* buffer = malloc( N * sizeof( char ) );

o puedo confiar en que sizeof (char) siempre es 1 y simplemente omitir la multiplicación

char* buffer = malloc( N );

Entiendo completamente que sizeof se evalúa durante la compilación y luego el compilador incluso puede compilar la multiplicación y, por lo tanto, la penalización de rendimiento será mínima y probablemente cero.

Estoy preguntando principalmente sobre la claridad y portabilidad del código. ¿Es esta multiplicación alguna vez necesaria para el tipo char ?

¿Fue útil?

Solución

Si bien no es necesario, considero una buena práctica dejar el tamaño de (char) porque hace que el código sea más legible y evita el uso de un número mágico. Además, si el código necesita cambiarse más tarde, de modo que en lugar de un carácter está mal ubicando el tamaño de algo en un puntero para ese objeto, es más fácil cambiar el código que si solo tiene un " 1 " ;.

Otros consejos

Por definición, sizeof (char) siempre es igual a 1. Un byte es el tamaño del carácter en C, cualquiera que sea el número de bits en un byte (8 en la CPU de escritorio común).

El ejemplo típico donde un byte no es 8 bits es el PDP-10 y otras arquitecturas antiguas tipo mini computadora con bytes de 9/36 bits. Pero los bytes que no son 2 ^ N se están volviendo extremadamente poco comunes, creo

Además, creo que este es un mejor estilo:

char* buf1;
double* buf2;

buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);

porque funciona sea cual sea el tipo de puntero.

sizeof (char) es siempre 1 sin importar el tipo de manipulación de memoria que realice.

Sin embargo, sizeof (TCHAR) puede variar según las opciones del compilador.

Lo considero una especie de antipatrón . Señala que el programador no sabía muy bien lo que estaba haciendo, lo que inmediatamente arroja el resto del código a la luz dudosa.

De acuerdo, no es (citando Wikipedia) "ineficaz", pero lo encuentro "lejos de ser óptimo". No cuesta nada en tiempo de ejecución, pero satura el código con basura innecesaria, todo el tiempo indicando que alguien lo consideró necesario.

Además, tenga en cuenta que la expresión no se analiza como una llamada de función: sizeof no es una función. No estás llamando a una función pasándole el símbolo mágico char . Está aplicando el operador de prefijo unario incorporado sizeof a una expresión, y su expresión es en este caso una conversión al tipo char , que en C se escribe como (char) .

Es perfectamente posible, y muy recomendable siempre que sea posible, usar sizeof en otras expresiones, entonces producirá el tamaño del valor de la expresión:

char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);

Esto imprimirá 1 , siempre, en todas las implementaciones de C conformes.

También estoy muy de acuerdo con David Cournapeau y considero repetir el tipo name en un malloc () -call para también ser una especie de antipatrón.

En lugar de

char *str;

str = malloc(N * sizeof (char));

que muchos escribirían para asignar un búfer de cadena con capacidad de N caracteres, iría con

char *str;

str = malloc(N * sizeof *str);

O (solo para cadenas) omita el sizeof como se indica arriba, pero esto, por supuesto, es más general y funciona igual de bien para cualquier tipo de puntero.

No es necesario. Consulte aquí (por ejemplo).

El estándar C define

sizeof(char) para que siempre sea 1 (byte). Tenga en cuenta que debido a que sizeof devuelve una cantidad de bytes , la cantidad de bits por byte es irrelevante (y en términos prácticos es 8 de todos modos).

Algo más a tener en cuenta es que el compilador sabe estáticamente que el valor de sizeof (char) es 1 y también sabe que multiplicar un número por un estático 1 implica que no es necesario hacer la multiplicación; el compilador lo optimizará. Las inquietudes sobre el rendimiento no deberían ser consideradas por estos motivos.

De " Nuevo estándar C. Un comentario económico y cultural " ;.

  1. Estadísticas: 2.0% de sizeof se toman de char y 1.5% - de unsigned char . Página 1033 en la versión 1.2 del libro.
  2. página 1037.
  

El número de bits en la representación de un tipo de carácter es   irrelevante. Por definición, el número   de bytes en byte es un tipo de carácter   uno.

     

Desarrolladores de pautas de codificación a veces   asociar un byte como siempre conteniendo   ocho bits En hosts donde el   tipo de caracteres es de 16 bits, esto puede   conducir a la suposición incorrecta de que   aplicando sizeof a un tipo de personaje   devolverá el valor 2.   Estos problemas se discuten en otra parte.

El uso de sizeof (char) hace que su código sea más legible y portátil.

En x86, todos sabemos que un carácter es 1 byte. Pero escribirlo explícitamente ayuda a aclarar sus intenciones, lo que siempre es bueno.

Además, ¿qué pasa si su código se coloca en otra plataforma donde un carácter no es de 1 byte? ¿Qué pasa si un personaje tenía solo 4 bits?

De acuerdo, no es necesario, pero no ralentiza el tiempo de ejecución y dará sus frutos en el raro caso de que necesite portar su código a una arquitectura diferente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top