c - ejemplo - ¿El tamaño de(enum)== sizeof(int), siempre?
typedef enum c (5)
Es el sizeof (enum) == sizeof (int), siempre
El estándar ANSI C dice:
Cada tipo enumerado debe ser compatible con caracteres, un tipo entero con signo o un tipo entero sin signo. La elección del tipo está definida por la implementación. (6.7.2.2 Enumerationspecifiers)
Entonces tomaría eso para decir que no.
Si este es el caso, #DEFINE no será mejor ya que salvaría la memoria.
¿De qué manera el uso define guardar memoria sobre el uso de una enumeración? Una enumeración es simplemente un tipo que le permite proporcionar más información al compilador. En el ejecutable resultante real, simplemente se convierte en un entero, del mismo modo que el preprocesador convierte una macro creada con #define en su valor.
¿Cuál es la práctica habitual? Yo si tengo que transportar estos tipos de devolución a través de una red y algún procesamiento debe hacerse en el otro extremo
Si planea transportar valores a través de una red y procesarlos en el otro extremo, debe definir un protocolo. Decide el tamaño en bits de cada tipo, la endianess (en qué orden son los bytes) y asegúrate de cumplirlo tanto en el código del cliente como del servidor. Además, no asuma que porque funciona, lo hace bien. Puede ser que la endianess, por ejemplo, en las plataformas de cliente y servidor elegidas coincida, pero puede que ese no sea siempre el caso.
¿El tamaño de (enum) == sizeof (int), siempre?
- ¿O es dependiente del compilador?
- ¿Es incorrecto decir que, como el compilador está optimizado para las longitudes de palabra (alineación de memoria), es decir, yint es el tamaño de palabra en un compilador en particular? ¿Significa que no hay penalización de procesamiento si uso enumeraciones, ya que serían palabras alineadas?
- ¿No es mejor si pongo todos los códigos de retorno en una enumeración, ya que claramente no me preocupo por los valores que obtiene, solo los nombres mientras verifico los tipos de devolución? Si este es el caso, #DEFINE no será mejor ya que salvaría la memoria.
¿Cuál es la práctica habitual? Si tengo que transportar estos tipos de devolución a través de una red y debe hacerse algún procesamiento en el otro extremo, ¿qué prefieres enum / # define / const ints?
EDITAR: solo verificando en la red, como el compilador no vincula simbólicamente macros, ¿cómo se depura la gente entonces, se compara el valor entero con el archivo de encabezado?
De las respuestas: agrego esta línea a continuación, ya que necesito aclaraciones,
"Así que está definido por la implementación, y sizeof (enum) podría ser igual a sizeof (char), es decir, 1".
- ¿No significa que el compilador verifica el rango de valores en enumeraciones y luego asigna memoria? No lo creo, por supuesto que no sé. ¿Puede alguien por favor explicarme qué es "podría ser"?
C99, 6.7.2.2p4 dice
Cada tipo enumerado debe ser compatible con caracteres, un tipo entero con signo o un tipo entero sin signo. La elección del tipo está definida por la implementación, 108) pero debe ser capaz de representar los valores de todos los miembros de la enumeración. [...]
La nota al pie 108 agrega
Una implementación puede retrasar la elección de qué tipo de enteros hasta que se hayan visto todas las constantes de enumeración.
Por lo tanto, está definido por la implementación, y sizeof (enum) podría ser igual a sizeof (char), es decir, 1.
Al elegir el tamaño de un pequeño rango de enteros, siempre hay una penalización. Si lo haces pequeño en la memoria, probablemente haya una penalización de procesamiento; si lo haces más grande, hay una penalización de espacio. Es una compensación de tiempo-espacio.
Los códigos de error suelen ser #defines, porque deben ser extensibles: diferentes bibliotecas pueden agregar nuevos códigos de error. No puedes hacer eso con enumeraciones.
En algunos compiladores, el tamaño de una enumeración depende de cuántas entradas hay en Enum. (menos de 255 Entrys => Byte, más de 255 Entrys int) Pero esto depende del compilador y de la configuración del compilador.
Es dependiente del compilador y puede diferir entre enumeraciones. La siguiente es la semántica
enum X { A, B };
// A has type int
assert(sizeof(A) == sizeof(int));
// some integer type. Maybe even int. This is
// implementation defined.
assert(sizeof(enum X) == sizeof(some_integer_type));
Tenga en cuenta que "algún tipo de entero" en C99 también puede incluir tipos enteros extendidos (que la implementación, sin embargo, tiene que documentar, si los proporciona). El tipo de enumeración es de algún tipo que puede almacenar el valor de cualquier enumerador ( A
y B
en este caso).
No creo que haya ninguna penalización en el uso de enumeraciones. Los enumeradores también son expresiones constantes integrales (por lo tanto, puede usarlo para inicializar variables estáticas o de alcance de archivo, por ejemplo), y las prefiero a macros siempre que sea posible.
Los enumeradores no necesitan memoria de tiempo de ejecución. Solo cuando crea una variable del tipo de enumeración, puede usar la memoria de tiempo de ejecución. Solo piense en los enumeradores como constantes de tiempo de compilación.
Solo usaría un tipo que pueda almacenar los valores del enumerador (debería conocer el rango aproximado de valores de antemano), emitirlo y enviarlo a través de la red. Preferiblemente, el tipo debe ser de ancho fijo, como int32_t
, por lo que no entra en conflicto cuando se trata de máquinas diferentes. O imprimiría el número y lo escanearía por el otro lado, lo que eliminaría algunos de estos problemas.
Respuesta a Editar
Bueno, el compilador no está obligado a usar ningún tamaño. Una cosa fácil de ver es que el signo de los valores importantes: los tipos sin firmar pueden tener un importante aumento del rendimiento en algunos cálculos. El siguiente es el comportamiento de GCC 4.4.0
en mi caja
int main(void) {
enum X { A = 0 };
enum X a; // X compatible with "unsigned int"
unsigned int *p = &a;
}
Pero si asigna un -1
, entonces GCC elige usar int
como el tipo con el que X
es compatible
int main(void) {
enum X { A = -1 };
enum X a; // X compatible with "int"
int *p = &a;
}
Usando la opción --short-enums
de GCC, eso hace que use el tipo más pequeño que todavía se ajusta a todos los valores.
int main() {
enum X { A = 0 };
enum X a; // X compatible with "unsigned char"
unsigned char *p = &a;
}
No.
Ejemplo: el compilador CodeSourcery
Cuando defines una enumeración como esta:
enum MyEnum1 {
A=1,
B=2,
C=3
};
// will have the sizeof 1 (fits in a char)
enum MyEnum1 {
A=1,
B=2,
C=3,
D=400
};
// will have the sizeof 2 (doesn''t fit in a char)
Details de su lista de correo