Domanda

Dai un'occhiata a questa citazione da qui , verso il fondo della pagina. (Credo che il commento citato su const si applichi anche a invarianti )

  

Le enumerazioni differiscono dai cons in quanto non occupano spazio   nell'oggetto / libreria / eseguibile finale emesso, mentre i cons fanno.

Quindi apparentemente value1 gonferà l'eseguibile, mentre value2 viene trattato come un valore letterale e non viene visualizzato nel file oggetto.

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

Indietro in C ++ Ho sempre pensato che fosse per motivi legacy e vecchi compilatori che non potevano ottimizzare le costanti. Ma se questo è ancora vero in D, ci deve essere una ragione più profonda dietro questo. Qualcuno sa perché?

È stato utile?

Soluzione

Proprio come in C ++, un enum in D sembra essere un intero letterale "conservato". ( modifica : sorprendente, D2 supporta persino float e stringhe ). I suoi enumeratori non hanno posizione. Sono semplicemente irrilevanti come valori senza identità.

Inserire enum è una novità in D2. Definisce innanzitutto una nuova variabile. Non è un lvalue (quindi anche tu non puoi prendere il suo indirizzo). An

enum int a = 10; // new in D2

È come

enum : int { a = 10 }

Se posso fidarmi della mia scarsa conoscenza di D. Quindi, a qui non è un lvalue (nessuna posizione e non puoi prendere il suo indirizzo). Una const, tuttavia, ha un indirizzo. Se si dispone di una variabile const globale (non si sa se si tratta della giusta terminologia D), il compilatore di solito non può ottimizzarla, perché non sa a quali moduli può accedere quella variabile o potrebbe prendere il suo indirizzo. Quindi deve allocare memoria per questo.

Penso che se hai una const locale, il compilatore può comunque ottimizzarlo come in C ++, perché il compilatore sa esaminando il suo ambito se qualcuno è interessato al suo indirizzo o se tutti ne prendono semplicemente il valore.

Altri suggerimenti

La tua vera domanda; perché enum / const è lo stesso in D come in C ++; sembra essere senza risposta. Purtroppo non esiste una buona ragione per questa scelta. Credo che questo sia stato solo un effetto collaterale non intenzionale in C ++ che è diventato un modello di fatto. In D era necessario lo stesso modello, e Walter Bright decise che doveva essere fatto come in C ++ in modo tale che quelli provenienti da quel luogo avrebbero riconosciuto cosa fare ... In effetti, prima di questa decisione piuttosto sciocca dell'IMHO, veniva usata la parola chiave manifest invece di enum per questo caso d'uso.

Penso che un buon compilatore / linker dovrebbe comunque rimuovere la costante. È solo che con l'enum, in realtà è garantito nelle specifiche. La differenza è principalmente una questione di semantica. (Ricorda anche che 2.0 non è ancora completo)

Il vero scopo di enum essere espanso sintatticamente per supportare singole costanti manifest, da quello che capisco, è che Don Clugston, un guru del modello D, stava facendo cose folli con i modelli. Ha continuato a correre per lunghi tempi di costruzione, ridicolo utilizzo della memoria del compilatore, ecc. Perché il compilatore continuava a creare strutture di dati interne per variabili const. Una cosa fondamentale delle variabili const / immutabili rispetto agli enum è che le variabili const / immutabili sono valori e che possono essere presi il loro indirizzo. Questo significa che c'è un sovraccarico aggiuntivo per il compilatore. Questo di solito non ha importanza, ma quando si eseguono metaprogrammi di compilazione molto complicati, anche se le variabili const sono ottimizzate, questo è comunque un sovraccarico significativo al momento della compilazione.

Sembra che verrà usato il valore enum " inline " nelle espressioni in cui la const occuperà effettivamente la memoria e qualsiasi espressione che fa riferimento caricherà il valore dalla memoria.

Questo suono è simile alla differenza tra const vs. readonly in C #. La prima è una costante di compilazione e la successiva è una costante di runtime. Ciò ha sicuramente influito sul controllo delle versioni degli assembly (poiché gli assembly che fanno riferimento a un readonly riceveranno una copia in fase di compilazione e non otterrebbero una modifica al valore se l'assembly di riferimento è stato ricostruito con un valore diverso).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top