"a" == "a"
Wyrażenie to może przynieść true
lub false
; nie ma żadnych gwarancji. Dwa literały literowe "a"
mogą zajmować to samo miejsce lub mogą istnieć w dwóch różnych miejscach w pamięci.
Uważam, że najbliższym językiem w standardzie C++ jest: "Czy wszystkie ciągi znaków są odrębne (to znaczy są przechowywane w nienakładających się obiektach), to implementacja jest zdefiniowana" (C++ 11 §2.14.5/12). Nie ma żadnych innych wymagań ani ograniczeń, więc wynik pozostaje nieokreślony.
"a" != "b"
Wyrażenie to musi ustąpić false
ponieważ nie ma możliwości, że te dwa literały łańcuchowe mogą zajmować tę samą lokalizację w pamięci: "a"[0] != "b"[0]
.
Porównując literały łańcuchowe w ten sposób, faktycznie porównujesz wskaźniki do początkowych elementów w tablicach.
Ponieważ jesteśmy porównując wskaźniki, relacyjnych porównań (<
, >
, <=
i >=
) są jeszcze bardziej problematyczne niż porównań równości (==
i !=
), ponieważ tylko ograniczony zestaw porównań wskaźnik może być wykonywane przy użyciu relacyjnej porównania. Dwa wskaźniki mogą być porównywane tylko wtedy, gdy oba wskaźniki znajdują się w tej samej tablicy lub wskaźniki w tym samym obiekcie.
Jeżeli oba "a"
literałami łańcuch zajmują to samo położenie w pamięci, a następnie "a" < "a"
będzie dobrze zdefiniowany i przyniesie false
, ponieważ oba wskaźniki wskazują elementu początkowego ('a'
) w tym samym układzie.
Jednakże, jeśli obie "a"
literały ciągów znaków zajmują różne miejsca w pamięci, wynik "a" < "a"
jest nieokreślona, ponieważ oba wskaźniki są całkowicie niepowiązanych do punktu obiektów porównywane.
Ponieważ "a"
i "b"
nigdy nie zajmują tej samej lokalizacji w pamięci, zawsze ma niezdefiniowane zachowanie. To samo dotyczy innych operatorów porównań relacyjnych.
Jeśli z jakiegoś powodu chcesz porównać ze sobą dwa ciągi literałów i uzyskasz dobrze zdefiniowane wyniki, możesz użyć porównywalnika std::less
, który zapewnia ścisłe i słabe porządkowanie wszystkich wskaźników. Istnieją również porównywarki std::greater
, std::greater_equal
i std::less_equal
.Biorąc pod uwagę, że literały łańcuchowe o tej samej zawartości mogą nie porównywać równości, nie wiem, dlaczego ktoś chciałby to zrobić, ale można.
Dlaczego miałbyś to zrobić? Aby uzyskać gwarantowaną wartość false, spróbuj 'assert (!" Wiadomość idzie tutaj ");' – chris
@chris: Ciekawość dla jednego. Także w przypadku pomysłu implementacji klasy podobnej do enum. –
możliwy duplikat [Różnica wyjściowa w gcc i turbo C] (http://stackoverflow.com/questions/3289354/output-difference-in-gcc-and-turbo-c) – kennytm