2015-08-02 18 views
6

Il C++ linguaggio di programmazione 3a edizione da Stroustrup afferma che,Il confronto tra puntatori è un comportamento non definito o non specificato in C++?

sottrazione di puntatori è definito solo quando entrambi i puntatori indicano elementi dello stesso array (anche se la lingua non ha modo veloce di garantire che è il Astuccio). Quando sottraendo un puntatore da un altro, il risultato è il numero di elementi dell'array tra i due puntatori (un intero). Si può aggiungere un intero a un puntatore o sottrarre un intero da un puntatore; in entrambi i casi, il risultato è un valore puntatore. Se tale valore non indica un elemento dello stesso array come il puntatore originale o uno là, il risultato dell'utilizzo di tale valore è indefinito.

Ad esempio:

void f() 
{ 
    int v1 [10]; 
    int v2 [10]; 
    int i1 = &v1[5] - &v1[3]; // i1 = 2 
    int i2 = &v1[5] - &v2[3]; // result undefined 
} 

stavo leggendo unspecified behavior su Wikipedia. Si dice che

In C e C++, il confronto dei puntatori agli oggetti è definito solo se i puntatori puntano a membri dello stesso oggetto o elementi della stessa matrice.

Esempio:

int main(void) 
{ 
    int a = 0; 
    int b = 0; 
    return &a < &b; /* unspecified behavior in C++, undefined in C */ 
} 

Così, mi sono confuso. Quale è corretto? Wikipedia o il libro di Stroustrup? Cosa dice lo standard C++ a riguardo?

mi corregga se sto malinteso qualcosa.

+0

Non vedo i 2 estratti come in conflitto. Puoi chiarire la tua confusione? – Amit

+3

Stroustrup si riferisce al puntatore * sottrazione * (chiamato anche puntatore * differenza *), e l'esempio mostra il calcolo della differenza. L'articolo che stai citando da Wiki si riferisce al puntatore logico * confronto *. – WhozCraig

risposta

10

Si noti che il puntatore sottrazione e confronto puntatore sono diverse operazioni con regole diverse.

C++ 14 5,6/6, su puntatori sottraendo:

Se entrambi i puntatori indicano elementi dello stesso oggetto array o uno dopo l'ultimo elemento dell'array dell'oggetto, il comportamento è indefinito.

C++ 14 5,9/3-4:

Confrontando puntatori a oggetti è definito come segue:

  • Se due puntatori scegliere diversi elementi dello stesso vettore, o ai suoi oggetti su se stessi, il puntatore all'elemento con l'indice più alto si confronta meglio.

  • Se un puntatore punta a un elemento di una matrice, oa un suo sottooggetto, e un altro puntatore punta a uno oltre l'ultimo elemento dell'array, quest'ultimo punta a un confronto maggiore.

  • Se due puntatori puntano a diversi membri di dati non statici della stessa oggetto oppure oggetti secondari di tali organi, ricorsivamente, il puntatore all'elemento dichiarata successivamente confronta maggiore fornito i due elementi hanno lo stesso controllo di accesso e forniti la loro classe non è un'unione.

Se due operandi p e q risultano uguali (5,10), e p<=qp>=q sia cedere true e p<q e p>q entrambi cedere falsa. Altrimenti, se un puntatore p confronta maggiore di un puntatore q, p>=q, p>q, q<=p e q<p tutto cedere true e p<=q, p<q, q>=p e q>p tutti cedere false. In caso contrario, il risultato di ciascuno degli operatori non è specificato.

+0

Nell'ultima frase "Altrimenti, il risultato di ciascuno degli operatori non è specificato." Perché dovrebbe essere non specificato anziché non definito? è perché lo standard definisce che i possibili risultati sono solo Veri di Falso, quindi nessun altro comportamento può accadere? –

+0

@LorenzoBelli "undefined" è un errore molto più grave di "non specificato", letteralmente tutto può succedere, incluso il blocco del programma. Con un comportamento non specificato, l'unico problema è che non si sa se il risultato sarà 'true' o' false' - e il compilatore è libero di specificare che il comportamento è più rigoroso di quanto richiesto dallo standard. Generalmente gli autori delle specifiche vogliono consentire programmi ben educati e solo specificare comportamenti non definiti quando assolutamente necessari. –

+0

@LorenzoBelli Inoltre, l'operatore deve restituire lo stesso valore se il confronto viene eseguito due volte in caso di comportamento Non specificato. Ma con UB, ogni confronto può restituire vero/falso indipendentemente. –

Problemi correlati