the commands point to the exact same binary, effectively making them duplicates
Yes, they're intended to be the same, and are actually the same single file on disk, given the inode number of them is the same
$ which cc c++ gcc g++ clang clang++ | xargs ls -li
1152921500312779808 -rwxr-xr-x 76 root wheel 167120 May 10 04:30 /usr/bin/c++
1152921500312779808 -rwxr-xr-x 76 root wheel 167120 May 10 04:30 /usr/bin/cc
1152921500312779808 -rwxr-xr-x 76 root wheel 167120 May 10 04:30 /usr/bin/clang
1152921500312779808 -rwxr-xr-x 76 root wheel 167120 May 10 04:30 /usr/bin/clang++
1152921500312779808 -rwxr-xr-x 76 root wheel 167120 May 10 04:30 /usr/bin/g++
1152921500312779808 -rwxr-xr-x 76 root wheel 167120 May 10 04:30 /usr/bin/gcc
On a typical *nix system symlinks are usually used instead of hard links like that
$ ls -al /usr/bin | grep 'vim'
lrwxr-xr-x 1 root wheel 3 May 10 04:30 ex -> vim
lrwxr-xr-x 1 root wheel 3 May 10 04:30 rview -> vim
lrwxr-xr-x 1 root wheel 3 May 10 04:30 rvim -> vim
lrwxr-xr-x 1 root wheel 3 May 10 04:30 vi -> vim
lrwxr-xr-x 1 root wheel 3 May 10 04:30 view -> vim
-rwxr-xr-x 1 root wheel 5056496 May 10 04:30 vim
lrwxr-xr-x 1 root wheel 3 May 10 04:30 vimdiff -> vim
-rwxr-xr-x 1 root wheel 2154 May 10 04:30 vimtutor
That said, in any case the command can be determined easily, regardless of the full executable file, a hard link or a symlink, by checking the command executed which is argv[0]
in a typical C or C++ program, or $0
in bash. This is extremely common and one notable usage of it is in BusyBox where almost all POSIX utilities are in a single busybox
binary and anything you run like ls
, mv
, test
, rm
... will eventually run busybox
But why is gcc and clang the same binary? It's another weird thing in macOS because Apple stopped using/including gcc for more than a decade ago due to licensing issues. They lie to others by telling "clang is gcc" and the only way you can know it is by running gcc --version