¿Cuál es el tamaño de una enumeración en C?


La mejor respuesta

Un enigma muy espinoso, cuando uno tiene que hacer coincidir las compensaciones de estructura a través de los límites de la máquina o los protocolos de red . La especificación dice que el tamaño debe ser el mínimo requerido para representar el valor más grande que puede tomar. Por lo tanto, una enumeración de estado de máquina de estado típica, por ejemplo, podría requerir solo un byte.

Hay AFAIK solo tres formas de controlar el tamaño:

algunos (pero no todos) compiladores tienen un modificador de compilador para forzar el tamaño a sizeof (int) o a 32 bits. La sintaxis de cambio no es la misma entre, por ejemplo, MSC y gccc / clang.

La segunda forma, si necesita completar, por ejemplo, un campo de 16 bits, es definir un valor máximo ficticio que requiera ese tamaño.

La otra forma es usar estilos int regulares en las definiciones de estructuras, pero luego se renuncia a la conveniencia del depurador de que muestre el valor por el nombre de enumeración, y en su lugar solo obtenga números enteros.

Entonces, probablemente será necesario especificar que la estructura que contiene la enumeración está empaquetada, no rellenada.

Respuesta

Si no forma parte de alguna variable x es const o volatile, y x no es del tipo de matriz, luego la declaración…

x = x;

… prácticamente no hace nada. Está bien formado. Suponiendo que x se inicializó de antemano, ¹ también está bien definido. La asignación no lo hace Realmente cambia el estado del programa, con un par de posibles excepciones (ver más abajo).

Esto es cierto incluso si x tiene un struct tipo.

struct foo {

char buf[42];

int x;

};

struct foo x = { "Hello World", 18 };

x = x; // no big deal.

Entonces, ¿cuál es el «error»? No es un código útil , pero hay bastante código que se ajusta a esa descripción. «Es sólo un error si su objetivo era hacer otra cosa y no lo logró.

[Anexo: Dada la inutilidad de esta asignación, los compiladores están dispuestos a advertir sobre ello, ya que es bastante probable que lo hiciera significa otra cosa.]

¿Por qué tanto sobre const y volatile? La restricción en const es simple: significa «sólo lectura», por lo que no puede escribir en él. Al menos, no con una simple asignación.

El de volatile es más complicado. Esa palabra clave dice que el valor calificado por ella podría modificarse de formas no visibles para la implementación, y que la escritura en ella podría tener efectos secundarios. Sin ahondar en una ratonera aquí, en la práctica, las únicas operaciones razonablemente bien definidas que puede realizar en un objeto volátil se ven así:

volatile int v;

int i;

i = v; // reads from v once, places into i.

v = i; // writes to v once with the contents of i.

Puedes hacer un poco más que eso con cordura con volatile, pero solo un poco. Ese es un tema para otro día. Hay una razón por la que C ++ 20 desaprueba todos los usos de volatile excepto unos pocos. Sus cambios parecen bastante sensatos.

Mencioné un par de posibles excepciones anteriormente. Jonas Oberhauser me recordó que cualquier relleno en un struct es no necesariamente preservado por esa asignación.

Además, teóricamente es posible que la representación subyacente de los objetos cambie debido a la asignación, si el mismo valor se puede representar de varias formas.

Con suerte, su programa es insensible a ambas posibilidades. Sin embargo, si alguna vez observa la representación subyacente del objeto, podría ver diferencias. Funciones como memcmp pueden notar, por ejemplo. Del mismo modo, si utiliza juegos de palabras de tipo.

¹ Y si no fue así, bienvenido a comportamiento indefinido, ya que probablemente se encuentre en conflicto con uno de estos:

  • El valor de un objeto con duración de almacenamiento automático se usa cuando es indeterminado ( 6.2 .4 , 6.7.9 , 6.8 ).
  • Un lvalue que designa un objeto de duración de almacenamiento automático que podría haber sido declarado con la clase de almacenamiento de registro se usa en un contexto que requiere la valor del objeto designado, pero el objeto no está inicializado. ( 6.3.2.1 ).

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *