2015-06-10 11 views
6

Il risultato di alcuni cast di puntatore è descritto come non specificato. Ad esempio, [expr.static.cast]/13:Come si comporta una conversione puntata non specificata in C++ 14?

Un prvalue di tipo “puntatore a CV1 vuoto” può essere convertito in un prvalue di tipo “puntatore a cv2 T,” [...] Se il valore del puntatore originale rappresenta l'indirizzo A di un byte in memoria e A soddisfa il requisito di allineamento di T, quindi il valore del puntatore risultante rappresenta lo stesso indirizzo del valore del puntatore originale, ovvero A. Il risultato di qualsiasi altro puntatore del genere la conversione non è specificata.

La mia domanda è: nel caso in cui l'allineamento è non soddisfatti, quali sono i possibili risultati?

Ad esempio, sono consentiti i seguenti risultati?

  • un puntatore nullo
  • un valore di puntatore valido (ossia puntatore che non punta memoria allocata di dimensioni T)
  • un puntatore valido per un T in una parte completamente separata della memoria

esempio di codice di riferimento:

#include <iostream> 

int main(int argc, char **argv) 
{ 
    int *b = (int *)"Hello, world"; // (1) 

    *b = -1;       // (2) 
    std::cout << argc << '\n'; 
} 

Linea (1) innesca il mio sopra citazione da [expr.static.cast]/13, perché è un reinterpret_cast che è coperto da [expr.reinterpret.cast]/7 che definisce la conversione in termini di static_cast ing attraverso void *.

Se il risultato non specificato può essere un valore di puntatore non valido, la riga (1) potrebbe causare un trap hardware. (Riferimento: N4430 che chiarisce una formulazione simile in C++ 14 e C++ 11).

Domanda corollario: c'è qualche caso in cui la riga 1 causerebbe un comportamento non definito? (Non lo penso in questa fase, dal momento che la lettura del valore del puntatore C++ 14 non valida è definita dall'implementazione o causa una trappola hardware).


Anche interessante è quella linea (2) sarebbe in molti casi essere indefinito comportamento causa rigoroso violazione aliasing (e forse altre ragioni), se il risultato non specificato può essere &argc allora questo programma può emettere -1 senza attivare indefinito comportamento!

+6

Err, viene non specificato. – EJP

+1

"... allora questo programma potrebbe emettere" -1 "senza attivare un comportamento indefinito" è strano - e direi sbagliato - modo per esprimerlo. La linea (2) ha come risultato un comportamento indefinito, sempre. "Comportamento indefinito" significa semplicemente che qualsiasi comportamento del programma sarebbe conforme alle specifiche, incluso il comportamento dell'output di -1. Un "valore non specificato" è un valore (non un comportamento) che le specifiche non vincolano e l'implementazione non deve documentare. – Nemo

+0

@Nemo come fa la riga 2 in UB (se 'b' ha il valore' & argc') –

risposta

3

La mia domanda è: nel caso in cui l'allineamento non è soddisfatto, quali sono i possibili risultati?

Per quanto posso dire, N4303: Pointer safety and placement new risponde parzialmente a questa domanda, anche se un po 'indirettamente. Questo documento si riferisce a CWG issue 1412: Problems in specifying pointer conversions che ha comportato le modifiche a [expr.static.pressofuso]/13 che si fa riferimento, in particolare aggiungendo:

[...] Se il valore del puntatore originario rappresenta l'indirizzo A di un byte in memoria e A soddisfa il requisito di allineamento T, allora il puntatore risultante valore rappresenta lo stesso indirizzo il valore del puntatore originale, cioè, A. il risultato di qualsiasi altra tale conversione puntatore è specificato. [...]

In riferimento a questo cambiamento N4303 dice (sottolineatura mia):

Prima dell'adozione della risoluzione per DR 1412 [CWG1412], il valore di bp non è specificato al momento della sua inizializzazione e il suo successivo passaggio all'operatore new tramite la nuova espressione. Detto puntatore può essere nullo, non sufficientemente allineato o altrimenti pericoloso da usare.

Quindi una conversione non specificato può risultati in:

  • Un puntatore nullo
  • Un puntatore sufficientemente allineato
  • Un puntatore che è pericoloso utilizzare
+0

"un puntatore pericoloso da usare" sembra essere prudente. "valore del puntatore non valido" è sicuramente un puntatore pericoloso da usare; quali altre possibilità ci sono? –

+0

"Un puntatore insufficientemente allineato" - per quanto posso vedere non c'è altro testo, oltre alla regola di aliasing rigorosa, che impedirebbe l'uso di un puntatore del genere. Solo questa clausola di cui stiamo discutendo per impedire potenzialmente che un puntatore venga creato in primo luogo. Quindi, presumibilmente, su macchine che applicano l'allineamento dell'hardware non è possibile restituire un puntatore non allineato in modo insufficiente. –

+0

@MattMcNabb: Solo per citare alcune altre possibilità: un puntatore che non si confronta uguale a se stesso, o un puntatore per il quale l'aritmetica del puntatore si rompe (cioè p + 1-1! = P) – MSalters