promozione integrale quando passaggio e la restituzione argomento per riferimento?
-
02-10-2019 - |
Domanda
Sto leggendo qualcosa circa la risoluzione di sovraccarico e ho trovato qualcosa che mi preoccupa ... Nel seguente codice:
int const& MaxValue(int const& a, int const& b)
{
return a > b ? a : b;
}
void SomeFunction()
{
short aShort1 = 3;
short aShort2 = 1;
int const & r2 = MaxValue(aShort1, aShort2); // integral promotion
//is it safe to pass r2 around before function SomeFunction completes
// CallSomeOtherFunctionThatCallsSomethingElse(r2);
}
La mia comprensione è che due int di temporanei vengono creati e sono allocate sullo stack appartenente a SomeFunction. Così, quando i rendimenti MaxValue, r2 riferimento a una di quelle variabili temporanee (in questo caso, quello che contiene il valore 3). Così, è dovrebbero essere sicuri di passare r2 intorno.
La domanda è, se la mia comprensione va bene, questo è un comportamento standard (si prega di verificare)? In caso contrario, si prega di spiegare cosa sta succedendo nel codice di cui sopra.
Molte grazie
Soluzione
Risposta breve:. Non è sicuro
Le garanzie standard che una variabile temporanea può essere associato a una riferimento costante nel qual caso la durata delle espande temporanei per la durata del riferimento legato . Il problema nel vostro caso particolare è quello che è in realtà di riferimento vincolante temporaneo.
Quando si chiama MaxValue( s1, s2 )
, due variabili temporanee di tipo int vengono creati e legato agli argomenti dei parametri a
e b
in MaxValue
. Ciò significa che la durata di tali provvisori è esteso al completamento della funzione. Ora, nella dichiarazione di ritorno della funzione si sta assumendo un secondo riferimento ad uno dei provvisori e che secondo riferimento non si estenderà la durata. r2
non estendere ulteriormente la durata dell'oggetto, e si dispone di un riferimento penzoloni.
Si noti che a causa della compilazione separata, il compilatore non può assolutamente conoscere al di fuori del MaxValue
se il riferimento restituito è quello di uno degli argomenti o per un oggetto del tutto diverso che non è una temporanea:
int const & OtherMaxValue( int const & a, int const & b ) {
static int value = 0;
value = (a > b? a : b);
return value;
}
Quindi non può assolutamente immaginare se qualcuno, o che dei bisogni provvisori vita per essere esteso.
Come nota laterale, per piccoli oggetti (ad esempio tutti i tipi interi) passando per riferimento può essere effettivamente peggiore di passaggio per valore. Inoltre v'è già un modello std::max
che in realtà implementa questa funzionalità.
Altri suggerimenti
Benvenuti al motivo per cui cast impliciti schifo. Si dispone ora di un riferimento a una temporanea, che è stato distrutto. Spero che non volevi fare qualsiasi cosa con esso.
Sì, la vostra comprensione è fine e questo è il comportamento standard.
A parte questo:
In questo modo, è dovrebbe essere sicuro di passare r2 intorno.
, che non capisco.
// EDIT
Si dovrebbe usare puntatori invece di riferimenti qui per ottenere lo stesso, ma senza il problema. Utilizzando l'indirizzo di un argomento passato per riferimento const è OK solo all'interno della funzione perché può puntare a copia locale di un oggetto.
Si dovrebbe tornare e passare il valore per i tipi semplici.