Dlaczego b [2] jest fałszywe?

11
string s;
bool b[] = {s=="",  s==s.c_str(),  s.c_str()==""};

zestawy

b[] = {true, true, false};

dlaczego b[2]fałsz?

Jeśli A==Bi A==Cczy nie powinno to oznaczać B==C?

NoComprende
źródło
Teraz widzę swój błąd i mam poczucie deja vu, ponieważ nie pierwszy raz pomyliłem się, porównując wskaźniki.
NoComprende

Odpowiedzi:

14

W tym wyrażeniu

s.c_str()==""

porównywane są dwa wskaźniki (adresy). Pierwszy to wskaźnik zwracany przez, s.c_str()a drugi to wskaźnik do pierwszego znaku (kończącego znak zero) literału łańcucha "".

Oczywiste jest, że adresy są różne (należy również pamiętać, że literał łańcuchowy ma statyczny czas przechowywania).

Aby uzyskać oczekiwany wynik, powinieneś napisać zamiast tego

std::strcmp( s.c_str(), "" ) == 0

Co do tych dwóch wyrażeń

s==""

i

s==s.c_str()

następnie porównywane są łańcuchy, ponieważ standardowa klasa std :: string przeciąża operator == dla właściwego operandu.

Vlad z Moskwy
źródło
Czy norma gwarantuje, że wskaźniki będą inne, w ostatnim przypadku? Rozumiem, że mogą.
Jeffrey
Można jedynie dodać, że powinien to być UB. „porównanie z literałem łańcuchowym skutkuje nieokreślonym zachowaniem”
Roout
@Jeffrey To gwarancja, ponieważ przynajmniej łańcuch jest pusty. :) Ale w każdym razie klasa std :: string używa kopii argumentu swojego konstruktora.
Vlad z Moskwy
1
@Roout - „UB” oznacza niezdefiniowane zachowanie. ”Oznacza to, że definicja języka nie mówi, jakie jest zachowanie programu ** . Program o niezdefiniowanym zachowaniu nie jest prawidłowym programem C ++.„ Nieokreślone zachowanie ”oznacza, że istnieje kilka alternatyw, a standard nie mówi, która z nich zostanie wybrana. Program jest ważny, a wdrożenie może wybrać dowolną z alternatyw
Pete Becker
@PeteBecker program z UB jest nadal poprawnym programem C ++ (przynajmniej w tym sensie, że pomyślnie się kompiluje i można go uruchomić).
trolley813 18.10.19