2009-03-04 16 views
6

Echa un vistazo a esta cita de here, hacia la parte inferior de la página. (Creo que el comentario citado sobre const s aplican a invariant s también)const vs enum en D

enumeraciones difieren de consts en cuanto a que no consumen ningún espacio en la final de objeto/biblioteca/ejecutable emitida, mientras que consts hacen.

Así que al parecer value1 se hinchan el ejecutable, mientras value2 se trata como un literal y no aparece en el archivo de objeto.

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

De nuevo en C++ que siempre supone que esto era por razones de compatibilidad, y compiladores antiguos que no podrían optimizar distancia 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é?

Respuesta

4

Al igual que en C++, una enumeración de D parece ser un "número entero conservado literal" (edición: increíble, D2 incluso soporta floats and strings). Sus enumeradores no tienen ubicación. Simplemente son inmateriales como valores sin identidad.

La colocación de enum es nueva en D2. Primero define una nueva variable. No es un valor 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 D. Entonces, a aquí no es un valor l (no hay ubicación y no puede tomar su dirección). Un const, sin embargo, tiene una dirección. Si tiene una variable const global (no estoy seguro si esta es la terminología D correcta), el compilador usualmente no puede optimizarla, porque no sabe qué módulos pueden acceder a esa variable o tomar su dirección. Por lo tanto, tiene que asignarle espacio de almacenamiento.

Creo que si tienes un const local, el compilador aún puede optimizarlo igual que en C++, porque el compilador sabe mirando su alcance si a alguien le interesa su dirección o si todo el mundo simplemente toma su valor .

1

Parece que el valor enum se usará "en línea" en las expresiones donde el const se almacenará realmente y cualquier expresión que haga referencia cargará el valor del almacenamiento de la memoria.

Este sonido es similar a la diferencia entre const vs. readonly en C#. El primero es una constante en tiempo de compilación y el último es una constante en tiempo de ejecución. Esto definitivamente afectó el control de versiones de los ensambles (ya que los ensamblados que hacen referencia a un archivo de solo lectura recibirían una copia en tiempo de compilación y no obtendrían un cambio en el valor si el ensamblado al que se hace referencia se reconstruyera con un valor diferente).

3

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 hay que tener en cuenta que 2.0 no está completo aún)

+1

Pero ese deseo asume que el compilador siempre tiene toda la fuente relevante. – larsivi

+0

¿Qué sucede si desea otorgar acceso a bibliotecas de terceros a esa variable const? ¿Qué pasa si se trata de una instancia de clase completa que se ha hecho const? – Marenz

+0

Nota: dije "compilador/* enlazador *". Además, D tiene que ser capaz de ver el valor de la variable en tiempo de compilación de todos modos (para plegado constante y otras cosas), por lo que hay incluso menos sentido en almacenarla físicamente en alguna parte, en cualquier situación donde sea necesaria _necesita_ la fuente disponible de todos modos. (No conozco ningún compilador que desmonte internamente el código de objeto de una ejecución anterior) – FeepingCreature

4

Su pregunta real; por qué enum/const es lo mismo en D que en C++; parece ser sin respuesta. Lamentablemente, no existe una buena razón para esta elección en absoluto. Creo que esto fue solo un efecto secundario involuntario en C++ que se convirtió en un patrón de facto.En D, se necesitaba el mismo patrón, y Walter Bright decidió que debería hacerse como en C++, de modo que aquellos que venían de ese lugar pudieran reconocer qué hacer ... De hecho, antes de esta decisión en mi humilde opinión, se utilizó el manifiesto de palabras clave. en lugar de enum para este uso.

+2

Es desafortunado que 'enum' significa constante manifiesta. Sin embargo, D solo quiere cambiar lo que se rompe expresamente, todo lo demás sigue las normas establecidas para los lenguajes de algol. Estoy seguro de que si realmente se desvivía, podría encontrar muchas palabras clave y sintaxis raras que podrían haberse hecho mejor, por ejemplo, asignación/igualdad, valor de retorno enumerado antes del nombre de la función, estructura/agregado, etc. –

2

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