2009-10-19 20 views

Odpowiedz

25

Na czas przechowywania:

2.13.4 Zwykli literały ciągów znaków UTF-8 i literały łańcuchowe są również określane jako wąskie napisowych. Wąski Łańcuch znaków ma typ „układ n const karbonizatu”, w którym n oznacza wielkość łańcuchu, jak zdefiniowano poniżej i miał długość statyczne pamięci

czytać w połączeniu z 3.7.1

3.7.1.

Wszystkie obiekty, które nie mają czasu przechowywania dynamicznego, nie mają czasu przechowywania wątków i są , a nie lokalne mają czas przechowywania statycznego. Przechowywanie tych obiektów powinno trwać przez cały czas trwania programu (3.6.2, 3.6.3).

typu:

Załącznik C

podrozdziale 2.13.4:

Zmień: literały łańcuchowe wykonane const Rodzaj ciąg jest dosłowny zmieniono z "array of char" na "array of const char." Typ łańcuch literowy char16_t został zmieniony z "array of a-integer-type" na "array of const char16_t." Typ literałowy char32_t został zmieniony z "array of a-integer-type" na "array of const char32_ - t.”Rodzaj szerokiego łańcucha dosłownym zmienia się z«tablicy wchar_t»na«tablicy const wchar_t»

Uzasadnienie:. W ten sposób unika wywoływania niepoprawnych przeciążony funkcję, która może oczekiwać, aby móc modyfikować jego argument.

Wpływ na oryginalną funkcję: Zmiana na semantykę dobrze zdefiniowanej funkcji. Trudności z konwersją: Prosta transformacja składniowa, ponieważ literały łańcuchowe można konwertować na znak *; (4.2). Najczęstsze przypadki są obsługiwane przez nową, ale przestarzałą standardową konwersję: char * p = "abc"; // poprawny w C, przestarzały w C++ char * q = expr? "abc": "de"; // ważne w C, C++ nieważny w

Jak powszechnie stosowane: programy, które mają uzasadniony powód do traktowania literały ciągów znaków jako wskaźniki do potencjalnie pamięci modyfikowalny są prawdopodobnie rzadko.

dynamicznie przydzielane (słowo „kupa” nigdy nie jest używany w kontekście obszaru pamięci AFAIK w standardzie) Pamięć wymaga wywołania funkcji, które mogą zdarzyć się tak wcześnie, jak main dużo po pamięć statyczna jest przydzielona.

+0

+1 dla poprawnej odpowiedzi, ale twoja oferta z Standardu nie jest dokładna (co najmniej 2.13.4). –

+0

Przydatny może być również cytat dotyczący standardowego użycia C-stringów. W świecie C bardziej standardowym jest zwracanie wskaźnika char *, który został przydzielony dynamicznie, a zatem wymagane jest zwolnienie. Jeśli nie zastosujesz się do tej konwencji, twój kod nie będzie działał dobrze z istniejącymi bibliotekami, które zakładają tę konwencję. –

+1

@ Kirir V. Lyadvinsky: Pochodzi z projektu C-0x 0x N-4411 (wspomnianego w komentarzu przeze mnie). – dirkgently

13

Ten kod jest całkowicie poprawny i zgodny. Jedynym "gotcha" byłoby zapewnienie, że dzwoniący nie próbuje zwolnić ciąg.

+0

"Ten kod jest całkowicie poprawny i zgodny". Czemu? –

+0

Nie ma potrzeby. Literały to "const char []", które nigdy nie są przydzielane do sterty. Zwrócony wskaźnik będzie ważny podczas wykonywania całego programu. –

+1

Nie ma "" const char [] "" –

11

Ten kod jest ważny i zgodny z normą.

Literały łańcuchowe są zapisywane w pamięci tylko do odczytu, a funkcja po prostu otrzymuje adres wybranego ciągu znaków.

standard C++ (2.13.4) mówi:

Zwykły łańcuch dosłowne ma typ „tablicę n const char” i statyczny czas trwania przechowywania

one kluczem do zrozumienia problemu tutaj jest czas przechowywania statycznego: literały łańcuchowe są przydzielane podczas uruchamiania programu i trwają przez czas trwania programu. Twoja funkcja dostaje adres i zwraca go.

5

Technicznie Tak, jest ważny.
Struny mają durata do przechowywania statycznego.

Ale to nie wszystko.

Są to C-ciągi. Konwencja w C-bibliotekach i funkcjach polega na zwrocie dynamicznie przydzielonego łańcucha, który powinien zostać zwolniony. Oznacza to, że zwracany wskaźnik niejawnie przekazuje własność z powrotem do osoby wywołującej (jak zwykle w C występują również wyjątki).

Jeśli nie zastosujesz się do tych konwencji, możesz pomylić wielu doświadczonych programistów C, którzy oczekiwaliby tej konwencji. Jeśli nie zastosujesz się do tego standardowego oczekiwania, to powinno być dobrze udokumentowane w kodzie.

Również jest to C++ (jak na twoje tagi). Więc bardziej konwencjonalne jest zwracanie std :: string. Powodem tego jest to, że przekazanie prawa własności za pomocą wskaźników jest tylko dorozumiane (a to doprowadziło do wielu błędów w kodzie C, gdy powyższe oczekiwania zostały złamane, ale udokumentowane, niestety dokumentacja ta nigdy nie została odczytana przez użytkownika kodu). Używając std :: string przechodzisz przez obiekt i nie ma już żadnych kwestii własności (wynik jest przekazywany jako wartość, a zatem twoja), ale ponieważ jest to obiekt, nie ma pytań ani problemów z alokacją zasobów .

Jeśli martwisz się o skuteczność, myślę, że to jest fałszywa sprawa.

Jeśli chcesz to do drukowania za pośrednictwem strumieni jest już standardem konwencja, aby to zrobić:

std::cout << std::boolalpha << false << std::endl; 
std::cout << std::boolalpha << true << std::endl; 
Powiązane problemy