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!
Err, viene non specificato. – EJP
"... 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
@Nemo come fa la riga 2 in UB (se 'b' ha il valore' & argc') –