Po połączeniu sąsiednich literałów łańcuchowych

17

C i C ++ kompilują sąsiednie literały łańcuchowe jako jeden literał łańcuchowy. Na przykład to:

"Some text..." "and more text"

jest równa:

"Some text...and more text"

W innych językach rodziny C, takich jak C # lub Java, jest to błąd składniowy (co jest w porządku BTW).

Jaki jest uzasadnienie / historyczny powód, dla którego C i C ++ to robią?

sampathsris
źródło

Odpowiedzi:

24

Oryginalny język C został zaprojektowany w latach 1969–1972, kiedy w komputerach nadal dominowała 80-kolumnowa karta perforowana. Jego projektanci wykorzystali 80 urządzeń kolumnowych, takich jak typ ASR-33. Urządzenia te nie zawijały automatycznie tekstu, więc istniała zachęta do przechowywania kodu źródłowego w obrębie 80 kolumn. Fortran i Cobol mieli do tego wyraźne mechanizmy kontynuacji, zanim w końcu przeszli na format swobodny.

Dennis Ritchie (przypuszczam) był genialnym uderzeniem błyskotliwości, aby zdać sobie sprawę, że w gramatyce nie było dwuznaczności i że długie łańcuchy ASCII można dopasować do 80 kolumn dzięki prostemu celowi nakłonienia kompilatora do połączenia sąsiednich łańcuchów literalnych. Niezliczona liczba programistów C była wdzięczna za tę małą funkcję.

Po włączeniu tej funkcji dlaczego miałaby być kiedykolwiek usunięta? Nie powoduje żalu i często jest przydatny. Dla jednego chciałbym mieć więcej języków. Współczesnym trendem jest rozszerzanie ciągów znaków z potrójnymi cudzysłowami lub innymi symbolami, ale prostota tej funkcji w C nigdy nie została przełamana.

david.pfx
źródło
8
Innym powodem jest to, że pozwala on na łączenie makr preprocesora zdefiniowanych jako literały łańcuchowe, np. #define FOO "foo-value"Później"FOO's value is " FOO "."
Blrfl
3
@Blrfl: Właśnie tak. Ważne jest, aby zdawać sobie sprawę, że konkatenacja łańcuchów ma miejsce po zakończeniu podstawiania makr.
david.pfx
7

C nie ma określonego operatora łączenia łańcuchów ( +), takiego jak C # i Java. W języku C # lub Java, gdy kompilator widzi

"a" + "b"

może skompilować kod dokładnie tak, jakby

"ab"

zostały zapisane w kodzie źródłowym. Jednak w C nie ma podobnie łatwej składni opisującej konkatenację łańcuchów, którą kompilator może rozpoznać i wstępnie obliczyć. Więc projektanci C dekad temu wybrali to

"a" "b"

oznaczałoby dokładnie to samo, co

"ab"

Naturalnie C ++ odziedziczył tę samą konwencję. Podczas gdy standardowa biblioteka C ++ przeciąża +się, std::stringaby oznaczać konkatenację łańcuchów, kompilator nie próbuje się łączyć, "a" + "b"ponieważ jest to w rzeczywistości błąd (nie można dodać dwóch const char *wskaźników razem).

Greg Hewgill
źródło
1
C również nie ma określonego typu łańcucha, zamiast tego wybiera wskaźniki do znaków w pamięci. Nie możesz dodawać wskaźników, a nawet jeśli +zostały one stworzone w taki sposób, by oznaczały konkatenację, nadal musisz rozwiązać problem, gdzie w pamięci znajduje się połączony łańcuch.
Blrfl,