2012-04-28 10 views
10

Mam program w języku C, który próbuje zmodyfikować literał ciąg stały. Jak teraz dowiedziałem się, że to nie jest dozwolone.dlaczego clang ++ zachowuje się odmiennie od klang, skoro ten pierwszy jest łączem symbolicznym tego ostatniego?

Podczas kompilacji kodu z clang test.c kompilator nie daje żadnego ostrzeżenia. Ale kiedy go skompilować z clang++ test.c daje ostrzeżenie:

test.c: 6: 15: ostrzeżenie: konwersja z ciągiem do dosłownego 'char *' jest przestarzała [-Wdeprecated zapisu-strings] char * s = "cześć świat"; ^

Problemem jest to, że okazuje się, clang++ jest tylko link symbolem clang:

ll `which clang++` 
lrwxr-xr-x 1 root admin 5 Jan 1 12:34 /usr/bin/[email protected] -> clang 

Więc moje pytanie brzmi: jak clang++ mógł zachowuje się inaczej od clang zważywszy, że jest to związek symbolem clang ?

Odpowiedz

11

Clang patrzy na swój argv[0] i zmienia jego zachowanie w zależności od tego, co widzi. Jest to rzadka i zniechęcająca, ale nie rzadka sztuczka, która przechodzi co najmniej aż 4.2BSD ex i vi, które były tym samym plikiem wykonywalnym i prawdopodobnie dalej.

W tym przypadku clang kompiluje plik .c jako C i clang++ kompiluje go jako C++. To jest historyczna brodawka, na którą nie powinieneś polegać; użyj odpowiedniej komendy kompilatora i upewnij się, że twoje rozszerzenie pliku odzwierciedla prawdziwą zawartość pliku.

+0

Czy masz na myśli to, że _bash_ patrzy na 'argv [0]' i zmienia zachowanie? Więc w bashie jest to zakodowane, że 'clang ++' zachowuje się inaczej niż 'clang'? – RockU

+1

Przepraszam, nie myślałem wystarczająco. Jest mocno zakodowany w 'clang'. Dziękuję :) – RockU

+1

Czy mógłbym cytować tę technikę jako "niecodzienną i zniechęconą"? Nie znaczy bash, po prostu ciekawy. –

5

Zgodnie z przyjętą konwencją nazwa wywołująca polecenie jest przekazywana jako argv[0]; nie jest czymś niezwykłym, że programy zmieniają swoje zachowanie w oparciu o to. (Dawniej ln, cp i mv były hardlinki do tego samego pliku wykonywalnego na Badawczego Unix i używane argv[0] zdecydować, które działania do zrobienia. Ponadto, większość muszli szukać wiodącego - w argv[0] zdecydować, czy powinny one być powłoką zgłoszeniową). Często istnieje również inny sposób uzyskania tego samego efektu (opcje, zmienne środowiskowe itp.); powinieneś generalnie używać tego zamiast grać w gry argv[0].

Istnieją powody, aby to zrobić, ale w większości przypadków nie jest dobrym pomysłem poleganie na nim lub projektowanie programów wokół niego.

+0

+1 za uprzedzenie mnie. – zwol