why clang++ behaves differently from clang since the former is a symbol link of the latter?
Asked Answered
A

2

11

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?

Anomaly answered 28/4, 2012 at 0:58 Comment(0)
F
13

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.

Fisherman answered 28/4, 2012 at 1:1 Comment(4)
Do you mean that bash is looking at argv[0] and altering the behavior? So it's hard coded in bash that clang++ behaves differently from clang?Anomaly
Sorry, I didn't think enough. It's hard coded in clang. Thank you:)Anomaly
Could I get a citation on this technique being "uncommon and discouraged"? Not meaning to bash, just curious.Aga
I'm not aware of citations for the 'uncommon' part, but here's one fairly influential place where it's discouraged with the rationale that you never know when the end user might want to rename a program without changing its behavior, e.g. because you have two different compilers and they can't both be /usr/bin/cc.Fisherman
H
5

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.

Hacienda answered 28/4, 2012 at 1:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.