Differenza tra le due enumerazioni

2

Mi sono imbattuto in una definizione enum: -

typedef enum NSInteger {
    kBorderTypeNone   = 0,
    kBorderTypeLeft   = 1 << 0,
    kBorderTypeRight  = 1 << 1,
    kBorderTypeTop    = 1 << 2,
    kBorderTypeBottom = 1 << 3
} BorderType;

e anche (possibilmente) può essere equivalente a

typedef enum NSInteger {
    kBorderTypeNone   = 0,
    kBorderTypeLeft   = 1 ,
    kBorderTypeRight  = 2,
    kBorderTypeTop    = 4,
    kBorderTypeBottom = 8
} BorderType;

Quali sono le differenze interne (se esistono)? C'è qualche vantaggio l'uno rispetto all'altro? Quale è raccomandato?

Se entrambi sono uguali, come viene gestito dal compilatore? In quale fase del compilatore è ridotto allo stesso insieme di istruzioni?

    
posta TryinHard 21.01.2014 - 05:44
fonte

4 risposte

3

Sono identici e diversi nello stile del programmatore. Se stai guardando il codice compilato, sarà byte-per-byte lo stesso.

Non sei sicuro di quale teoria del compilatore stai cercando di ottenere, ma a un livello molto semplice i compilatori hanno generalmente due fasi:

  1. tokenize al file e crea un albero di analisi
  2. converti l'albero di parsing in istruzioni di livello inferiore

La semplificazione potrebbe teoricamente verificarsi in una delle fasi. Quando l'albero di analisi viene assemblato, se gli oggetti vengono rilevati come [const] [op] [const], a quel punto il compilatore dispone di informazioni sufficienti per creare semplicemente una costante che rappresenta il risultato dell'operazione. O immagino che potrebbe mettere ciecamente l'operazione come parte dell'albero di analisi e lasciare che la seconda fase faccia la semplificazione.

Ho avuto il piacere di scrivere un semplice compilatore come parte di una laurea in Informatica (molto tempo fa, ma mi piacerebbe pensare di ricordare qualcosa del college) e nel mio caso l'ho trovato semplificare la semplificazione immediata (ovvero il primo passaggio) e inserire la costante risultante come parte dell'albero di analisi. In questo modo, vari posti potrebbero gestire questa costante in modo uniforme (vale a dire se l'istruzione è in corso e le istruzioni dell'interruttore rispetto a quelle dei cicli). Nel momento in cui devi agire su ciò che ogni costrutto linguistico deve fare, tutti questi vari luoghi non dovrebbero preoccuparsi di eseguire il calcolo "1 < < 3" perché a quel punto sarebbe già un semplice numero intero.

    
risposta data 21.01.2014 - 06:03
fonte
2

Verranno compilati con lo stesso codice e l'unica differenza è la leggibilità. Tutto il compilatore moderno dovrebbe essere in grado di dedurre il valore di un'espressione costante e calcolarli in fase di compilazione.

È molto chiaro per me che il primo enum è usato come bandiera. per esempio. type = kBorderTypeLeft|kBorderTypeRight

Ma non è chiaro per la seconda versione di enum. Inoltre, se ne hai molti tipi, può essere difficile ottenere il giusto valore per ogni enum e alcune persone potrebbero pensare che il valore sia una specie di "numero magico".

    
risposta data 21.01.2014 - 06:05
fonte
0

La leggibilità

Il primo modulo indica al maintainer che i valori di quell'enumerazione possono rappresentare posizioni di bit in una variabile con più flag e possono essere usati come:

myCellBorders = kBorderTypeLeft | kBorderTypeTop | kBorderTypeBottom;

Indica anche che tutti i possibili valori sono già riservati e che non è possibile definire altri valori per quell'enumerazione, ad esempio:

kBorderTypeHalfSizedCenteredBottom = 3

La seconda forma implica che il maintainer è consapevole del fatto che le potenze successive di 2 sono 1, 2, 4, 8 ..., che ha notato questa specificità e che corrisponde all'intenzione del programmatore.

    
risposta data 21.01.2014 - 10:08
fonte
0

Riguardo allo stile di programmazione, penso che sia più idiomatico e dovrebbe essere usato

typedef NS_OPTIONS(NSInteger, RoundCorner) {
    RoundCornedNone   = 0,
    RoundCornerLeft   = 1 << 0,
    RoundCornerRight  = 1 << 1,
    RoundCornerTop    = 1 << 2,
    RoundCornerBottom = 1 << 3,
    RoundCornerAll = RoundCornerLeft | RoundCornerRight | RoundCornerTop | RoundCornerBottom,
};

quando si sta elencando un set di maschera di bit le cui possibili combinazioni rappresentano uno stato.

Considerando che, quando si sta elencando un insieme di stati mutuamente esclusivi

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
    UITableViewCellStyleDefault,
    UITableViewCellStyleValue1,
    UITableViewCellStyleValue2,
    UITableViewCellStyleSubtitle
};

NS_ENUM dovrebbe essere usato.

    
risposta data 23.02.2014 - 14:24
fonte

Leggi altre domande sui tag