Pregunta

Consulte esta cita de aquí , hacia el final de la página. (Creo que el comentario citado sobre const s se aplica también a invariant s)

  

Las enumeraciones difieren de los consts en que no consumen espacio   en el objeto / biblioteca / ejecutable finalizado, mientras que los consts sí.

Entonces, aparentemente value1 hinchará el ejecutable, mientras que value2 se trata como un literal y no aparece en el archivo objeto.

const int value1 = 0xBAD;
enum int value2 = 42;

En C ++ siempre asumí que esto era por razones heredadas y compiladores antiguos que no podían optimizar las constantes. Pero si esto sigue siendo cierto en D, debe haber una razón más profunda detrás de esto. Alguien sabe por qué?

¿Fue útil?

Solución

Al igual que en C ++, una enumeración en D parece ser un literal entero conservado " ( editar : increíble, D2 incluso admite flotadores y cadenas ). Sus enumeradores no tienen ubicación. Son simplemente inmateriales como valores sin identidad.

Colocar enum es nuevo en D2. Primero define una nueva variable. No es un valor de l (por lo que tampoco puede tomar su dirección). Un

enum int a = 10; // new in D2

Es como

enum : int { a = 10 }

Si puedo confiar en mi pobre conocimiento de D. Entonces, a aquí no es un lvalue (no hay ubicación y no puede tomar su dirección). Una constante, sin embargo, tiene una dirección. Si tiene una variable const global (no estoy seguro de si esta es la terminología D correcta), el compilador generalmente no puede optimizarla, porque no sabe qué módulos pueden acceder a esa variable o podrían tomar su dirección. Entonces tiene que asignar almacenamiento para ello.

Creo que si tiene un const local, el compilador aún puede optimizarlo como en C ++, porque el compilador sabe si mira su alcance si alguien está interesado en su dirección o si todos toman su valor.

Otros consejos

Tu pregunta real; por qué enum / const es lo mismo en D que en C ++; Parece no tener respuesta. Lamentablemente, no existe una buena razón para esta elección. Creo que esto fue solo un efecto secundario no intencional en C ++ que se convirtió en un patrón de facto. En D se necesitaba el mismo patrón, y Walter Bright decidió que debía hacerse como en C ++, de modo que los que vinieran de ese lugar reconocieran qué hacer ... De hecho, antes de esta decisión tonta en mi humilde opinión, se utilizó el manifiesto de palabras clave en lugar de enumeración para este caso de uso.

Creo que un buen compilador / enlazador aún debería eliminar la constante. Es solo que con la enumeración, en realidad está garantizado en la especificación. La diferencia es principalmente una cuestión de semántica. (También tenga en cuenta que 2.0 aún no está completo)

El verdadero propósito de que enum se expanda sintácticamente para admitir constantes de manifiesto único, por lo que entiendo, es que Don Clugston, un gurú de plantillas de D, estaba haciendo cosas locas con las plantillas. Siguió corriendo en tiempos de compilación largos, uso ridículo de la memoria del compilador, etc. porque el compilador seguía creando estructuras de datos internas para variables constantes. Una cosa clave sobre las variables constantes / inmutables en comparación con las enumeraciones es que las variables constantes / inmutables son valores y pueden tomar su dirección. Esto significa que hay una sobrecarga adicional para el compilador. Esto generalmente no importa, pero cuando está ejecutando metaprogramas de tiempo de compilación realmente complicados, incluso si las variables constantes están optimizadas, esto sigue siendo una sobrecarga significativa en tiempo de compilación.

Parece que se usará el valor enum " inline " en expresiones donde el const realmente tendrá almacenamiento y cualquier expresión que haga referencia a él cargará el valor del almacenamiento de memoria.

Esto suena similar a la diferencia entre const vs. readonly en C #. El primero es una constante de tiempo de compilación y el segundo es una constante de tiempo de ejecución. Esto definitivamente afectó el control de versiones de los ensamblajes (dado que los ensamblados que hacen referencia a un solo lectura recibirían una copia en el momento de la compilación y no obtendrían un cambio en el valor si el ensamblado referenciado se reconstruyera con un valor diferente).

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