2010-08-11 2 views
5

Alcune semplici domande.L'ordine dei dati nella memoria

const int gFirst; 
const int gSecond; 

struct Data 
{ 
    static int First; 
    static int Second; 

    int first; 
    int second; 
}; 

Data data; 

È garantito che le seguenti affermazioni sono vere?

  1. &gFirst < &gSecond
  2. &Data::First < &Data::Second
  3. &data.first < &data.second

risposta

8

1) Questo risultato non è specificato.
2) Questo risultato non è specificato. *
3) Sì.

La sezione pertinente nello standard è §5.9/2. confronto relazionali tra i puntatori p e q sono specificate solo quando:

  • p e q punto allo stesso oggetto o funzione, scegliere uno oltre l'estremità della stessa matrice o entrambi sono nulli. In questo caso, p <= q e p >= q sono veri e p < q e p > q sono falsi.
  • p e q puntare a membri di dati non statici dello stesso oggetto, il puntatore al membro dichiarato successivo confronta maggiore. (Nota, questo confronto non può essere tra gli specificatori di accesso.)
  • p e q puntare a elementi all'interno dello stesso array o uno oltre la fine dell'array, il puntatore all'elemento con il subscript più alto o ad uno oltre la fine di l'array è più grande.
  • p e q puntare a membri di dati dello stesso oggetto unione, nel qual caso vengono confrontati uguali.

In tutti gli altri casi, il risultato non è specificato.

* Poiché sono statici, non ottengono (ovviamente) le regole del "membro non statico". Saranno definiti in alcune unità di traduzione e quindi sono come qualsiasi altro puntatore. (Non specificato.)


Nota! C'è un modo per ottenere ordinamento totale, e che è via std::less<void*>

Questo è in §20.3.3/8 (e tutti gli altri oggetti funzione comparativi.):

Per i modelli greater, less , greater_equal e less_equal, le specializzazioni per qualsiasi tipo di puntatore generano un ordine totale, anche se gli operatori incorporati <, >, <=, >= no.

Così, mentre non si sa se è std::less<void*>(&gFirst, &gSecond)true o false, si sono garantiti:

std::less<void*>(&gFirst, &gSecond) == 
    std::greater<void*>(&gSecond, &gFirst); 
std::less<void*>(&Data::First, &Data::Second) == 
    std::greater<void*>(&Data::Second, &Data::First); 

che può rivelarsi utile.

6

La risposta:

1) Not guaranteed. 
    But probably. 
    But the order of initialization is guaranteed. 
2) No. 
    You just have the declaration here. 
    You need to to define the instances in a source file. 
    Then they will behave the same way as the objects in (1). 
3) Yes. 
+0

A 1) Penso che l'ordine di inizializzazione all'interno di un file sorgente sia garantito. L'ordine di inizializzazione di più file sorgente non è definito. –

+0

Ero sciatto con la domanda 2 per aver presupposto che avresti anche inizializzato i dati in un altro file nello stesso ordine in cui le variabili sono dichiarate qui. Colpa mia. Questo caso è in realtà quello a cui sono più interessato. – zeroes00