Quindi, operator[]
non dice direttamente che s[s.size()]
deve essere il carattere dopo s[s.size()-1]
nella memoria. Sembra formulato per evitare di fare questa affermazione.Can `std :: basic_string :: operator []` può restituire un terminatore nul "distante" protetto?
Ma s.data()
indica che s.data()+k == &s[k]
e s.data()
devono restituire un puntatore.
Ignorando il difetto livello apparente di utilizzare &
su CharT
sopra e non std::addressof
, è l'implementazione libera per restituire un diverso CharT
(ad esempio, uno su una pagina protetta, o in ROM) per s[s.size()]
prima della prima chiamata a s.data()
? (Chiaramente si potrebbe organizzare il buffer di porre fine ad una pagina di sola lettura con uno zero su di esso, sto parlando di una situazione diversa)
Per essere espliciti:
Per quanto posso dire, se s.data()
non viene mai chiamato (e il compilatore può provarlo), quindi s[s.size()]
non deve essere contiguo con il resto del buffer.
Può std::addressof(s[s.size()])
cambiamento dopo una chiamata al s.data()
e l'attuazione risulti conforme agli standard (fino a quando s.data()+k == &s[k]
ha .data()
valutati prima []
, ma il compilatore è libero di far rispettare quello). O ci sono requisiti di immutabilità che non riesco a vedere?
cppreference dice chiaramente che dal momento che C++ 11 'operator []' si comporta esattamente come si descrive per 'data().' Tuttavia, si dice anche che questo carattere non può essere modificato. – SergeyA
@SergeyA La dicitura precedente è la mia lettura dello standard (corrente bozza), piuttosto che basare l'interpretazione di qualcun altro (chiunque abbia modificato per ultimo, per esempio). Se vuoi, posso aggiungere citazioni dirette, ma non sono difficili da trovare (apri il tuo standard, cerca 'basic_string', vai ad esso dall'indice, cerca' operator ['e' data ('da lì). Mi chiedo se ci siano * altre * restrizioni che mi sono sfuggite (come inizialmente mi mancava la restrizione implicita '.data()' su '& s [s.size()]'). La maggior parte di quelle ovvie (basate sugli iteratori) don si applica, poiché '* s.end()' rimane UB. – Yakk
Lo standard indica effettivamente che 's [s.size()]' è ben definito e non UB? È oltre la fine della stringa dopo tutto e sarebbe UB per qualsiasi altro contenitore.In pratica è probabile che ogni implementazione tenga il null finale richiesto da 'c_str()' quindi è probabilmente un punto controverso –