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 and 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...
Related
How to #define a function to be replaced by another?
For example, if I have a function Stuff(int numbers) and would like to replace it with Stuff2(int numbers, int otherNumbers).
So, when Stuff() is called, Stuff2() is used instead.
Using #define is a basic global text replacement.
#define Stuff(number) Stuff2(number,0)
The zero is here for illustration; replace it with whatever the appropriate default is. If necessary, you could even call a function or use more macro magic to compute it.
Update
So, following the commentary, OP is trying to redirect main().
This is a technique with a highly-specific use-case. The first thing to remember is that main() is not a normal function. That’s right, main() is special.
As a result, you cannot just replace main() and expect things to work happily. There must be a main(), and it must be declared according to one of your compiler’s accepted variations. (IMO, you should prefer to use one of the two variations required by the C Standard.)
Intercepting the user’s main()
The technique is commonly used by libraries that want to have an app-level control over your application, but want you to think that everything is normal.
They do this by declaring main() in the library’s code, and #defining main to something else in the header so that when you write "main()" it is actually a different function. For example:
// quuxlib.c
int main( int argc, char** argv )
{
int exit_code = 0;
// library does initializations here
...
// call the user's main(), LOL
exit_code = UsersMain( argc, argv );
// perform cleanup
...
return exit_code;
}
The library's header:
// quuxlib.h
#define main UsersMain
...
And now the user’s code looks normal:
#include "quuxlib.h"
int main( int argc, char** argv ) // This is actually UsersMain()!
{
// Use quuxlib without any further thought
}
Caveats and Best Practices
This technique is, IMHO, bad design. It seeks to obscure what is actually happening. A better library design would be explicit, and either:
Require you to properly initialize and finalize the library in your main()
Expect you to use an explicit entry procedure
The former is preferred, as it gets along with all kinds of stuff better. For example, Tcl hooks things properly. Here you simply create an interpreter, use it, and terminate normally.
#include "tcl.h"
int main()
{
Tcl_Interp* interp = Tcl_CreateInterp();
int status = Tcl_Eval( interp, "puts {Hello world!}" );
return 0;
}
Tcl also goes one step further, providing Tcl_Main and Tcl_AppInit to make life very easy. See an example here.
Using an explicit entry procedure is the very same thing as the main() replacement trick, just without pretending anything:
#include "quuxlib.h"
int AppMain() // required by QuuxLib
{
// my main program here
...
return 0;
}
The problems
To finish, the problems with re#defining main are:
it obscures what is really happening
it uses a global macro replacement
Good design doesn't try to hide things from you. A global macro replacement is also bad. In this case, "main" is not a reserved word. You could have a valid local identifier called "main". Using a global macro replacement obviates that possibility.
Finally, having a library provide explicit initialization and finalization procedures rather than take over main increases the flexibility available to the user. A library that takes your main() cannot be used with another library that does the same, nor can it really be trusted to handle things that can go wrong (IMHO) as well as a library the provides proper and explicit hooks for the library user to handle that kind of stuff.
The trade-off is pretty for common cases vs versatility.
Well, I think I’m pretty firmly into rambling now, so it’s time to stop...
I'm coding a program in C, and I'd like it to detect its own name. I'll explain :
I want it to do a specific action, depending of its name. Let's say :
if (!strcmp(myName, "Program1"))
printf("I am program 1!");
else
printf("I am someone else !");
This code is contained in Program1.c, and is compiled with :
gcc Program1.c -o Program1
And I'd execute it with :
./Program1
But I'm not able to find the code that would allow me to get the value "Program1" (the name of the executable file), which would be the variable myName in the code I gave.
Can someone help me please?
The name of the output from gcc is not stored anywhere in the file by default, and I don't know of a way to inject it into the binary. But is this what you really want?
The name that the program is invoked as is available as argv[0]. That may be different if the executable has been renamed after compilation.
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("My name is %s\n", argv[0]);
return 0;
}
Argument 0 is chosen by the calling program. It can be a full path with directory information (it typically depends whether the caller performed PATH lookup or invoked the executable from an explicit location), so if you want to act based on that, you should probably strip the path information (e.g. with basename on Unix/POSIX platforms).
Argument 0 is chosen by the caller, so it's a matter of convention. But it's a pretty much universally followed convention, except when the caller has a good reason not to respect it. Most platforms have a way to locate the executable. For example, on Linux, /proc/self/exe is a symbolic link to the executable. But in most cases, if the caller passes a different name, that means that the caller wants your program to behave as that different name, so argv[0] is what you should use.
argv[0] can be NULL if the program is invoked without arguments (i.e. if argc is 0). That's rare, but for robustness your program should do something sensible in that case.
is it possible to access variable value through other variable, as below
char var[30];
char buffer[30];
strcpy(buffer, "ABC");
/*variable var is holding the "buffer" variable name as string*/
strcpy(var,"buffer")
is there a way to access the buffer variable value "ABC", through variable var. ?
Not in any practical way in C, and you don't really want to anyway. Tying your program logic to the names of your variables is a horrible idea. Typically I see people attempt this when what they really need is some sort of collection type (and array, a map, whatever).
How about filling us in on the problem you are trying to solve with this?
Per your comment:
I need to have dynamic debug messages, I have a file which contain each function variables that I want to print.
Use stringification in a macro:
#define str(s) #s
int main() {
int bar;
str(bar) /* replaced by "bar" */
}
Not without significant boiler plate code. Variable names are eliminated at compile-time.
In theory, you could store a map from variable names to a pointer to a variable.
No, you can't. If you want indirect access, then declare a pointer and assign var to it.
char *forVar = var;
// Now you can access/modify via [] operator.
You can try using a union
For example:
union example {
char var[40];
char buffer[40];
} e1;
strcpy(e1.var, "ABC");
printf("%s is same as %s", e1.var, e1.buffer);
So basically you want to log some variables when they are written to/read from/passed to functions etc?
Doing this with compiled C is difficult, as mentioned, especially if you are optimising your executable (-0n on the compile statement), in which case some of the variables can disappear completely, or get re-used by other variables.
Using GDB
Having said that, I know gdb can log variable access and that sort of stuff. If you were to write a python script (see http://sourceware.org/gdb/onlinedocs/gdb/Python.html), you should be able to write a script to log variable content.
See this question for more: Do specific action when certain breakpoint hits in gdb
On demand only, using pre-compiler scripting
Alternatively, if you just wanted to do it on demand, you'd be better off using a pre-processing script to add in custom macro's or similar, using a csv file as input:
for each line in CSV:
read variable_name, file_name, variable_type
find all occurrences of variable_name in file_name
for each occurrence
insert printf(....)
On demand only, using macros
Good luck. There isn't a nice way to do it, because you'd generally need some sort of lookup, and you'd need a way of selectively outputting variables to your print function. In some cases you could do something like:
static char _LOGGED_VAR_001 = 'z';
static char _LOGGED_VAR_002 = 'z';
#define cMyVar _LOGGED_VAR_001
#define LOG_ALL_VARS() printf("Vals: %c, %c", _LOGGED_VAR_001, _LOGGED_VAR_002)
void myFunc()
{
char cMyVar; // Gets macro'd to _LOGGED_VAR_001 with LOCAL scope
cMyVar = 'a'; // LOCAL scope _LOGGED_VAR_001 becomes 'a'
LOG_ALL_VARS(); // At this point you print out the LOCAL _LOGGED_VAR_001
// and the global _LOGGED_VAR_002
}
You would get Vals: a, z
This is pretty ugly, would only work for variables with local scope, messes round with memory consumption, could be error prone and is generally a bad idea.
On demand, heap/stack dump
If you have enough storage, you could dump all your memory on demand to a file. This probably wouldn't be very portable, depending on how it was done. I'm not sure how to do it though, in a reliable manner.
Recommendation
Use GDB for design-time diagnostics. It's what it's designed for :)
For (e.g.) analysing released code (automated bug reports), a full dump and then analysis at will might be relevant.
I am writing a C program which is a frontend to a myriad tools. This fronted will be launched like this:
my-frontend --action <AN ACTION>
As all the tools have the same prefix, let say for this example this prefix is "foo". I want to concatenate "AN ACTION" to this prefix and exec this (if the tool exists).
I have written something but my implementation uses strcmp to test that "AN ACTION" is a valid action. Even if this works, I do not like it. So I am looking for a nicer solution that would do the same. The list of possibilities is pretty small (less than 10) and static (the list is "hardcoded") but I am sure there is a more "C-ish" way to do this (using a struct or something like that). As I am not a C expert, I am asking for your help.
Regards
Take a look at getopt_long. Its part of the standard C library. For full documentation on how C programs are supposed to handle arguments in a standard UNIX way, check this.
The above should give you the argument. But I see your problem is more than that. Dealing with multiple back-ends can be done like this:
struct cmds {
char *name;
void (*cmd)(int argc, char **argv);
};
You could declare a cmd_table like this:
struct cmds cmd_table[] = {
{ "backend1", backend1_exec },
{ "backend2", backend2_exec },
...
};
backend1_exec() and backend2_exec() are just functions which really do the grunt work for executing the real backend for you.
Then in your main() function just loop over the entries comparing each entry in the cmd_table with the argument, and then calling the corresponding backend function like this:
if (strcmp(cmdname, cmd_table[i].name)) {
*(cmd_table[i].cmd)(argc, argv);
}
Yeah, there's nothing wrong with using strcmp() if you just got 10 entries in the table. Its not a performance critical section of your program, so I wouldn't worry too much about that. This method is a popular way of handling this, from what I have seen (that does not make it authoritative, but might help reassure you, that you're not doing anything wrong).
Is there any way to access the command line arguments, without using the argument to main? I need to access it in another function, and I would prefer not passing it in.
I need a solution that only necessarily works on Mac OS and Linux with GCC.
I don't know how to do it on MacOS, but I suspect the trick I will describe here can be ported to MacOS with a bit of cross-reading.
On linux you can use the so called ".init_array" section of the ELF binary, to register a function which gets called during program initilization (before main() is called). This function has the same signature as the normal main() function, execept it returns "void".
Thus, you can use this function to remember or process argc, argv[] and evp[].
Here is some code you can use:
static void my_cool_main(int argc, char* argv[], char* envp[])
{
// your code goes here
}
__attribute__((section(".init_array"))) void (* p_my_cool_main)(int,char*[],char*[]) = &my_cool_main;
PS: This code can also be put in a library, so it should fit your case.
It even works, when your prgram is run with valgrind - valgrind does not fork a new process, and this results in /proc/self/cmdline showing the original valgrind command-line.
PPS: Keep in mind that during this very early program execution many subsystem are not yet fully initialized - I tried libc I/O routines, they seem to work, but don't rely on it - even gloval variables might not yet be constructed, etc...
In Linux, you can open /proc/self/cmdline (assuming that /proc is present) and parse manually (this is only required if you need argc/argv before main() - e.g. in a global constructor - as otherwise it's better to pass them via global vars).
More solutions are available here: http://blog.linuxgamepublishing.com/2009/10/12/argv-and-argc-and-just-how-to-get-them/
Yeah, it's gross and unportable, but if you are solving practical problems you may not care.
You can copy them into global variables if you want.
I do not think you should do it as the C runtime will prepare the arguments and pass it into the main via int argc, char **argv, do not attempt to manipulate the behaviour by hacking it up as it would largely be unportable or possibly undefined behaviour!! Stick to the rules and you will have portability...no other way of doing it other than breaking it...
You can. Most platforms provide global variables __argc and __argv. But again, I support zneak's comment.
P.S. Use boost::program_options to parse them. Please do not do it any other way in C++.
Is there some reason why passing a pointer to space that is already consumed is so bad? You won't be getting any real savings out of eliminating the argument to the function in question and you could set off an interesting display of fireworks. Skirting around main()'s call stack with creative hackery usually ends up in undefined behavior, or reliance on compiler specific behavior. Both are bad for functionality and portability respectively.
Keep in mind the arguments in question are pointers to arguments, they are going to consume space no matter what you do. The convenience of an index of them is as cheap as sizeof(int), I don't see any reason not to use it.
It sounds like you are optimizing rather aggressively and prematurely, or you are stuck with having to add features into code that you really don't want to mess with. In either case, doing things conventionally will save both time and trouble.