2015-03-26 13 views
11

regularny ciąg ciąg dosłowne ma następującą definicję:Dlaczego zwracanie odwołania do literału ciągu jest odwołaniem do tymczasowego?

Ordinary literały ciągów znaków i UTF-8 literały ciągów znaków są również określane jako wąskich napisowych. Wąskie wyrażenie literowe ma typ "array n const char", gdzie n jest rozmiarem łańcucha zdefiniowanego poniżej, i ma statyczny czas przechowywania (3.7).

Jestem zakładając, ponieważ ma statyczny czas przechowywania i że są one zwykle umieszczane w pamięci ROM, to naprawdę nie jest wielka sprawa, czy istnieje zwisające odniesienie do niej. Poniższy kod emituje ostrzeżenie

const char* const & foo() 
{ 
    return "Hello"; 
} 
// warning: returning reference to temporary [-Wreturn-local-addr] 

Ale to jest w porządku, nawet bez słowa kluczowego static

const char* const & foo() 
{ 
    const char* const & s = "Hello"; 
    return s; 
} 

Więc jaka jest różnica między nimi?

+3

Twój kod nie zwraca referencji do literału. Zwraca referencję do wskaźnika. Większość tego, co cytujesz, jest nieistotna dla kodu. –

+2

Skąd pochodzi twój cytat? Powinieneś go dodać. – dhein

+0

Dlaczego zwracasz odwołanie do wskaźnika-znaku zamiast samego wskaźnika-znaku? – CodesInChaos

Odpowiedz

8

Nie ma różnicy. W obu przypadkach zwracasz odwołanie do wskaźnika, który już nie istnieje.

To, że pointee (dane) nadal istnieje na zawsze, jest nieistotne.

10

Cytat mówi pan pisał, że

Wąski Łańcuch znaków ma typ „tablicę n const char”

Oznacza to, że rodzaj "Hello" jest const char[6].

Twój kod zwraca referencję do const char *. Oznacza to, że konwersja między tablicami i wskaźnikami musi być zastosowana do literału łańcuchowego, powodując wartość prvalue (= temporary) typu const char *. Następnie powiąż to z referencją i zwróć to odwołanie. Odwołanie staje się zwisające, gdy tylko zakres funkcji się kończy i wskaźnik tymczasowy zostanie zniszczony.

2
const char* const & s = "Hello"; 

Tutaj zmienna jest tworzona na stosie ... i że zmienna (co zdarza się wskaźnik) wskazuje na miejsce w pamięci, gdzie przechowywany jest string-dosłowne. Jesteś nie zwracając samą literał łańcuchowy; powrócisz, odniesienie do zmiennej zostanie wkrótce zniszczone w wyniku rozwijania stosu. Dlatego zwracanie odniesienia do takiej zmiennej jest niebezpieczne, ponieważ jest to obiekt tymczasowy.

Powiązane problemy