Lo que determina sizeof (int)

7

Con respecto a los tipos de datos estándar, ¿cuál es el tamaño de un entero en los controladores ATmega? ¿Y qué determina el tamaño, es solo el compilador? ¿O está en el diseño de hardware del controlador y, por lo tanto, todos los compiladores de ATmega tienen que cumplir con ese tamaño? Y si está en el hardware, ¿por qué en una PC puede tener dos compiladores diferentes que dan resultados diferentes para sizeof (int) incluso si se ejecutan en el mismo procesador?

    
pregunta Aelgawad

3 respuestas

11

int es un tipo C. Los ATMega no tienen idea de eso, solo funcionan con bytes de 8 bits (porque tienen CPUs AVR de 8 bits).

El compilador convierte cualquier operación en tipos int a las operaciones equivalentes requeridas para realizar esa operación al nivel de tamaño requerido por la arquitectura de la CPU: para un AVR, se convierte para realizar operaciones a nivel de byte, para una CPU de 16 bits , se haría a nivel de 16 bits, etc.

En avr-gcc y int el tipo se define simplemente en el compilador como un entero de 2 bytes . El hecho de que cambie en función de la plataforma significa que es mejor utilizar los tipos <stdint.h> , como uint16_t , si desea estar seguro del tamaño en el código que debe ser portátil. Hay tipos definidos para todos los tamaños de enteros estándar (8,16,32,64) en ambos con signo y sin signo.

Hay otras definiciones para los llamados tipos _fast que se garantiza que tienen al menos el tamaño requerido, pero producirán el código más rápido basado en la plataforma, por ejemplo, los procesadores de 32 bits tienden a realizar operaciones en números de 32 bits más eficientemente que diga los números de 8 bits, por lo que uint_fast8_t en una plataforma de 32 bits sería un entero de 32 bits (es al menos 8 bits, pero es más rápido de manejar).

La instrucción sizeof() se realiza en tiempo de compilación, y se convierte a una constante, no es ejecutada por el procesador. avr-gcc sabe cuán grande ha definido un int como, por lo que sabe con qué constante reemplazar la llamada sizeof() .

    
respondido por el Tom Carpenter
6

Los tamaños de int , short int , long int , etc. son decididos por las personas que escriben el compilador. Las reglas de C son que short int < = int < = long int , pero eso deja mucho espacio para los escritores del compilador.

Los escritores de compiladores analizan las capacidades de los procesadores e intentan tomar decisiones razonables para esa CPU. A menudo, los indicadores de la línea de comando obligan a que int tenga un tamaño específico para que sea más fácil portar el código entre los procesadores.

El compilador genera diferentes secuencias de código para manejar diferentes tamaños de int; la CPU está controlada por el código y, por lo tanto, implementa el tamaño definido por la salida de los compiladores.

Los Atmega's usan la arquitectura de CPU de AVR. En su mayoría procesa 8 bits de datos a la vez. Así que el compilador tiene que generar código para implementar aritmética de múltiples bytes.

Los espacios de direcciones subyacentes de la mayoría de los ATmege son de 16 bits, por lo que es muy conveniente tener una aritmética que pueda acceder a todo eso. Por lo tanto, por defecto, un int es de 16 bits. En los "días antiguos" de x86 con memoria segmentada, donde las direcciones pueden ser de 16 o 32 bits, y el compilador dirigido a generar cde para un "modelo" en particular, el compilador generalmente genera un código para un tamaño de int que mantenga el tamaño del puntero para ese 'modelo de memoria'.

Si usa un compilador para el mismo procesador, puede generar código para dos (o más) tamaños diferentes de int ( int , no short int , long int , solo int ), eso es exactamente lo que hará en respuesta a las banderas apropiadas (o pragma).

El compilador 'sabe' para qué tamaño de int está generando el código, por lo que sizeof(int) será reemplazado por el valor correcto, en tiempo de compilación, por el compilador.

    
respondido por el gbulmer
5

Los tamaños de los tipos de datos C estándar están determinados por la implementación del compilador. Según el estándar , un int debe ser capaz de contener valores en el rango de -32767 a 32767 (16 bits), pero puede ser mayor. El tamaño de un int suele ser el valor más natural para la CPU: el tamaño de palabra o el tamaño de un registro de CPU.

La única forma de saberlo con certeza es consultar el manual del compilador o escribir el código de prueba. Es una buena idea tener una copia del manual para un compilador incorporado, ya que es más probable que los aspectos específicos de la alineación y el almacenamiento de datos importen en la programación integrada. Las extensiones de compilador (por ejemplo, para soporte de interrupciones) también son más importantes.

Si tienes un compilador compatible con C99, es más fácil usar los tipos uintX_t definidos para obtener el tamaño que deseas.

Para referencia, aquí están los tamaños mínimos para otros tipos de datos tomados de la sección 5.2.4.2.1 de la norma C99. Tenga en cuenta que no se requiere la aritmética del complemento de dos, aunque no conozco el complemento de ninguna persona o las máquinas de magnitud de signo fuera de mi cabeza.

char (tamaño byte): sizeof (char) siempre es igual a 1. Los caracteres firmados deben contener valores en el rango de -127 a 127. Los caracteres sin signo deben contener valores en el rango de 0 a 255. La norma también especifica el número mínimo de bits en un char / byte, que es 8.

corto: -32767 a 32767 para firmado, 0 a 65535 para sin firmar. Equivalente a 16 bits.

int: Igual que el corto.

largo: -2147483647 a 2147483647 para firmado, 0 a 4294967295 para sin firmar. Equivalente a 32 bits.

long long: -9223372036854775807 a 9223372036854775807 para firmado, de 0 a 18446744073709551615 para sin firmar. Equivalente a 64 bits.

puntero: Implementación definida. El estándar permite diferentes "requisitos de representación y alineación" para los punteros a diferentes tipos de datos, pero nunca lo he visto en la práctica.

    
respondido por el Adam Haun

Lea otras preguntas en las etiquetas