Best practice when referring to a program's name in C
What is considered best practice when referring to a program's name? I've seen:
#define PROGRAM_NAME "myprog"
printf("this is %s\n", PROGRAM_NAME);
as well as:
printf("this is %s\n", argv[0]);
I know, that the second approach will give me ./myprog
rather than myprog
when the program is not called from $PATH
an开发者_运维问答d that the first approach will guarantee consistence regarding the program's name.
But is there anything else, that makes one approach superior to the other?
The second approach is superior when you have multiple links. In *nix systems, sometimes behavior depends on how you call a program. So hard coding the program name would clearly be a problem -- it could never check that.
I tried to take the best of both worlds:
char const * program_name;
int main(int argc, char **argv) {
program_name = argv[0];
//...
}
If you need program_name to be available in some other file you can declare it like this:
extern char const * program_name;
I declare "char const *" because I want it to be a pointer which points to const data. I'm not sure if I did right this part.
I usually use argv[0]
, or basename(argv[0])
if possible. From the user's POV, I think if they rename or hardlink an executable (or somebody else does that for them), then they want messages from it to appear under the name they're using, not under some other name it was compiled as, that they may or may not know about.
Similarly if you discover in future that you want to compile your program under different names with different options, to give different versions, do you want to wrap an #ifndef
around that #define
and make sure that it's defined via the compiler command line: -DPROGRAM_NAME=myprog_demo
, or do you just want to do it and it works?
The exception might be that if your usage instructions are an extract from a manpage or other documentation, then possibly you do want to hardwire the program name into that. But then you probably wouldn't use the #define
either.
Implementations needn't provide argv[0]
, though, so for best portable practices handle that case too. Then again, if your system doesn't provide it then probably the user isn't actually going to see messages on any kind of terminal, either.
By the way:
#define PROGRAM_NAME "myprog"
puts("this is " PROGRAM_NAME);
The second approach could give you also strings like /usr/bin/myprog
if you executed it that way; basename should give the name of the executable (that you could think of as the name of your program)... unless it is symlinked... (in that case, you have the name of the link... that could be used to do choices of some kind in the program behaviour).
The first approach "fixes" the program name to what the programmer wanted, no matter how the user renamed the executable file or symlinked (or even hardlinked)
It doesn't exactly answer your question for programming best practices, but I think you should also keep in mind what's best for the user.
I personally prefer programs refering to themselves using argv[0]
, i.e. the command I was calling, and not some random name that the coder hardcoded in the program. A few examples where a hardcoded name is annoying or at least not helpful:
- I've created a link to a program
- I've renamed the binary for some reason
- I have multiple executables with the same basenames in different directories in my
$PATH
- A program gives me hints about other ways to call it, e.g. in "usage" messages
The only situation where I'd prefer a hardcoded program name is when I'm using GUI applications. I wouldn't want to see "~/foo/bar.pl" as a window title.
The former is superior to the later when your don't have argv
at hand.
#define PROGRAM_NAME "myprog"
void salute()
{
// no argv available
printf("Hello from %s\n", PROGRAM_NAME );
}
void main( int argc, char** argv )
{
salute();
}
Depends whether argv
is in scope or not...
精彩评论