prendendo l’indirizzo di un object temporaneo

§5.3.1 Operatori unari, sezione 3

Il risultato di unario e operatore è un puntatore al suo operando. L’operando deve essere un lvalue o un id qualificato.

Che cosa significa esattamente “deve essere” significa in questo contesto? Significa che è un errore prendere l’indirizzo di un temporaneo? Mi stavo solo chiedendo, perché g ++ mi dà solo un avvertimento, mentre comeau si rifiuta di compilare il seguente programma:

#include  int main() { &std::string("test"); } 

avvertimento g ++: taking address of temporary

errore di comando: expression must be an lvalue or a function designator

Qualcuno ha un compilatore Microsoft o altri compilatori e può testare questo programma, per favore? Grazie in anticipo.

La parola “deve” nella lingua standard significa un requisito rigoroso. Quindi, sì, il tuo codice è mal formato (è un errore) perché tenta di applicare l’operatore address-of a un non-lvalue.

Tuttavia, il problema qui non è un tentativo di prendere l’indirizzo di un temporaneo . Il problema è, ancora una volta, prendere l’indirizzo di un non-lvalue . L’object temporaneo può essere lvalue o non-lvalue a seconda dell’espressione che produce quel temporaneo o fornisce l’accesso a tale temporaneo. Nel tuo caso hai std::string("test") – un cast di stile funzionale a un tipo non di riferimento, che per definizione produce un non-valore. Quindi l’errore.

Ad esempio, se volessi prendere l’indirizzo di un object temporaneo, avresti potuto aggirare la restrizione facendo ciò

 const std::string &r = std::string("test"); &r; // this expression produces address of a temporary 

il puntatore risultante rimane valido finché esiste il temporaneo. Esistono altri modi per ottenere legalmente l’indirizzo di un object temporaneo. È solo che il tuo metodo specifico è illegale.

Quando la parola “deve” è usata nello standard C ++, significa “deve morire di pena” – se un’implementazione non obbedisce a questa, è difettosa.

È consentito in MSVC con l’opzione deprecata / Ze (estensioni abilitate). Era consentito nelle precedenti versioni di MSVC. Genera una diagnostica con tutti gli avvisi abilitati:

avviso C4238: estensione non standard utilizzata: valore di class utilizzato come valore l.

A meno che non venga utilizzata l’opzione / Za (applica la compatibilità ANSI), quindi:

errore C2102: ‘&’ richiede il valore-l

Lo standard C ++ è effettivamente un requisito per le implementazioni C ++ conformi. In alcuni punti è scritto per distinguere tra codice che le implementazioni conformi devono accettare e codice per il quale le implementazioni conformi devono fornire una diagnosi.

Quindi, in questo caso particolare, un compilatore conforms deve dare una diagnosi se viene preso l’indirizzo di un valore. Entrambi i compilatori lo fanno, quindi sono conformi a questo riguardo.

Lo standard non vieta la generazione di un eseguibile se un determinato input causa una diagnostica, cioè gli avvertimenti sono una diagnostica valida.

&std::string("test"); sta chiedendo l’indirizzo del valore di ritorno della chiamata di funzione (ignoreremo come irrilevante il fatto che questa funzione sia un ctor). Non aveva un indirizzo finché non lo assegni a qualcosa. Quindi è un errore.

Non sono un esperto di standard, ma sicuramente mi sembra un errore. molto spesso g ++ dà solo un avvertimento per cose che sono veramente errori.