Почему clang++ ведет себя иначе, чем clang, поскольку первая является символьной ссылкой последнего?

У меня есть программа на C, которая пытается изменить строковый литерал const. Как теперь я узнал, что это запрещено.

Когда я компилирую код с clang test.c, компилятор не дает никаких предупреждений. Но когда я компилирую его с помощью clang++ test.c, он дает предупреждение:

test.c: 6: 15: предупреждение: преобразование из строкового литерала в 'char *' устарело       [-Wdeprecated перезаписываемые-строки]      char * s = "привет мир";               ^

Проблема заключается в том, что оказывается, что clang++ является просто ссылкой на символ clang:

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

Итак, мой вопрос: как clang++ ведет себя иначе, чем clang, учитывая, что это ссылка на символ clang?

Ответ 1

Clang смотрит на свой argv[0] и изменяет его поведение в зависимости от того, что он видит. Это необычный и неудобный, но не редкостный трюк, по крайней мере, еще в 4.2BSD ex и vi, которые были одинаковыми исполняемыми и, вероятно, дальше.

В этом случае clang компилирует ваш файл .c как C, а clang++ компилирует его как С++. Это историческая бородавка, на которую вы не должны полагаться; используйте соответствующую команду компилятора и убедитесь, что расширение вашего файла отражает истинное содержимое файла.

Ответ 2

По соглашению имя, с которым вызывается команда, передается как argv[0]; для программ не особенно необычно менять свое поведение на основе этого. (Исторически ln, cp и mv были жесткими ссылками на один и тот же исполняемый файл в Research Unix и использовали argv[0], чтобы решить, какое действие нужно сделать. Кроме того, большинство оболочек ищут ведущий - в argv[0] решить, должны ли они быть оболочкой входа.) Часто есть и другой способ получить тот же эффект (параметры, переменные среды и т.д.); вы должны использовать это вместо игры argv[0].

Есть причины сделать это, но в большинстве случаев это не очень хорошая идея полагаться на него или на разработку программ вокруг него.