why clang++ behaves differently from clang since the former is a symbol link of the latter?
Question
I have a C program that tries to modify a const string literal. As now I learned that this is not allowed.
When I compile the code with clang test.c
the compiler gives no warning. But when I compile it with clang++ test.c
it gives a warning:
test.c:6:15: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings] char *s = "hello world"; ^
The problem is that it turns out clang++
is just a symbol link of clang
:
ll `which clang++`
lrwxr-xr-x 1 root admin 5 Jan 1 12:34 /usr/bin/clang++@ -> clang
So my question is how could clang++
behaves differently from clang
given that it's a symbol link of clang
?
Solution
Clang is looking at its argv[0]
and altering its behavior depending on what it sees. This is an uncommon and discouraged, but not rare, trick going at least as far back as 4.2BSD ex
and vi
, which were the same executable, and probably farther.
In this case, clang
is compiling your .c
file as C, and clang++
is compiling it as C++. This is a historical wart which you should not rely on; use the appropriate compiler command and make sure that your file extension reflects the true contents of the file.
OTHER TIPS
By convention, the name by which a command is invoked is passed as argv[0]
; it is not especially unusual for programs to change their behavior based on this. (Historically, ln
, cp
, and mv
were hardlinks to the same executable on Research Unix and used argv[0]
to decide which action to do. Also, most shells look for a leading -
in argv[0]
to decide if they should be a login shell.) Often there is also some other way to get the same effect (options, environment variables, etc.); you should in general use this instead of playing argv[0]
games.
There are reasons to do this, but in most cases it's not a good idea to rely on it or to design programs around it.