2012-11-08 16 views
10

Ecco un codice di esempio:Le costanti statiche della funzione in linea sono univoche?

enum Foo // or enum class whatever 
{ BAR 
, STUFF 
}; 

inline const char* to_string(const Foo& foo) 
{ 
    static const char* const NAMES[] = 
    { "BAR" 
    , "STUFF" 
    }; 
    // let's assume I have some boundary checks here, it's not the point 
    return NAMES[foo]; 
}; 

Questa funzione è in linea, è in un'intestazione utilizzato in diverse unità di compilazione. L'obiettivo qui è di fare in modo che il compilatore non faccia nulla se non si usa questa funzione.

Domande:

  1. Fa garanzia standard di C++ che nomi saranno esiste in un solo file oggetto, o è lasciato al compilatore di decidere o non garantisce che ogni file oggetto avrà è la copia?
  2. Se ci saranno più copie, sarà un problema di collegamento (presumo che non possa testare un numero sufficiente di compilatori per verificarlo).
  3. Gcc, msvc e clang ottimizzeranno questo caso rendendo il binario finale con una sola istanza di NAMES?
+1

Una domanda per domanda, per favore. –

+2

@LightnessRacesinOrbit: "Sì, ho sentito che ti piacciono le domande, quindi ho posto domande nella mia domanda in modo che tu possa rispondere mentre rispondi ..." – Mehrdad

+4

Direi che queste domande sono sufficientemente connesse per essere pubblicate in una singola domanda. – leftaroundabout

risposta

7

Sì, lo standard garantisce che ci sarà un solo oggetto. Da C++ 03 §7.1.2/4:

[...] Un static variabile locale in una funzione extern inline riferisce sempre allo stesso oggetto. Una stringa letterale in una funzione in linea extern è lo stesso oggetto in diverse unità di traduzione.

(Si noti che una funzione extern inline è una funzione inline con collegamento esterno, cioè una funzione inline non contrassegnati come static.)

Esattamente quali oggetto file appare nel dipenderà dal compilatore, ma ciò che il sospetto capita è che ogni file oggetto che lo usa avrà una copia, e il linker sceglierà arbitrariamente uno dei simboli e scarterà il resto.

+0

Cosa succede se è contrassegnato come statico? – imreal

+1

@Nick: quindi lo standard non fornisce garanzie. –

+0

@Nick: presumibilmente con "it" intendi la funzione. –

1

Lo standard garantisce che una sola copia sarà utilizzata. Non garantisce che non ci saranno copie inutilizzate che occupano spazio nel codice.

Il linker è generalmente responsabile del consolidamento di tutti i riferimenti per utilizzare la stessa istanza.

Problemi correlati