2015-11-16 17 views
5

Il compilatore Clang genera un avviso che compila questo snippet di codice e non riesco a capire perché.restituisce riferimento all'oggetto temporaneo locale sul puntatore dereferenziamento

const int* Get() { 
    static const int ARRAY[4] = {1, 2, 3, 4}; 
    return &ARRAY[0]; 
} 

const int& Test() { 
    const auto& p = Get(); 
    return (*p); 
} 

warning: returning reference to local temporary object [-Wreturn-stack-address] 
    return (*p); 

GCC non presenta avvisi su questo codice. posso fissare il frammento di come questo: const auto p = Get(); Ma io voglio sapere se c'è qualche oggetto temporaneo e il problema è più profondo

+0

@ 101010 "oggetto temporaneo"? Forse potresti essere un po 'più chiaro? Possiamo sicuramente fare riferimenti a variabili non const nello stack. –

+4

Mentre 'p' è temporaneo,' * p' è valido. Immagino sia un falso positivo di Clang. – Jarod42

+1

@JonathanMee: [Informazioni sui provvisori] (http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/) –

risposta

4

Questo avviso è un falso positivo, dal momento che la pointee di p non è una temporanea, nonostante p riferimento a uno. Vi sono più scenari in cui tale avvertimento viene prodotto spurio; Vedi per es. Bug 21218, che utilizza

char * f() { 
    typedef char* t; 
    const t & r = new char[5]; 
    return r; 
} 

Presumibilmente, se il tipo restituito è un riferimento, Clang cerca i const riferimenti (che sono stati legati a provvisori) nell'espressione restituita, senza considerare come vengono utilizzati.

1

Risposta: L'avviso di Clang non è corretto. passo

Let attraverso quello che succede qui:

  1. static const int ARRAY[4] = {1, 2, 3, 4}; costruisce una matrice globale di int s
  2. return &ARRAY[0]; restituisce un puntatore al primo elemento della matrice globale
  3. const auto& p = Get() memorizza un riferimento a un puntatore al primo elemento di un array globale
  4. return (*p); crea un riferimento al lvalue del primo elemento dell'array globale

è il difficile. Clang sembra erroneamente pensare che *p sia un valore locale, quando in realtà sappiamo che è globale.

Fondamentale per questa dimostrazione è the fact that *p returns an lvalue.

+0

_ "È facile da fare" _ perché lo dice chiaramente nello standard. –

+0

@LightnessRacesinOrbit Non ho una copia dello standard e non riesco a trovare alcuna informazione online che confermi che l'operatore di dereferenziazione ha restituito un lvalue. Se puoi indicarmi una fonte, mi piacerebbe includerla piuttosto che un esempio per dimostrare la mia risposta. –

+1

https://en.wikipedia.org/wiki/Dereference_operator seconda frase –

Problemi correlati