1

In "Accelerated C++: Practical Programming by Example", it says

Now that we understand pointers and character arrays, we can understand how to pass arguments to the main function. Most operating systems provide a way to pass a sequence of character strings to main as an argument, if the main function is willing to accept them. The way the author of main signals such willingness is by giving main two parameters: an int and a pointer to a pointer to char. Like any parameters, these can have arbitrary names, but programmers often call them argc and argv. The value of argv is a pointer to the initial element of an array of pointers, one for each argument. The value of argc is the number of pointers in the array of which argv points to the initial element. The initial element of that array always represents the name by which the program is called, so argc is always at least 1. The arguments, if any, occupy subsequent elements of the array.

As an example, this program writes its arguments, if any, with spaces between them:

int main(int argc, char** argv) { 

// if there are arguments, write them if (argc > 1) {
int i; 

// declare i outside the for because we need it after the loop finishes
for (i = 1; i < argc-1; ++i) 
  cout << argv[i] << " ";

cout << argv[i] << endl;

return 0; 
}
// write all but the last entry and a space // argv[i] is a char*
// write the last entry but not a space

what I don't understand is this sentence "The value of argc is the number of pointers in the array of which argv points to the initial element. The initial element of that array always represents the name by which the program is called, so argc is always at least 1. "

what is argv[0]?

5
  • 3
    "The initial element of that array always represents the name by which the program is called, so argc is always at least 1" - That is flat out wrong. It is possible to launch a program with an empty argv and argc being 0. It is also possible to put whatever string you want into argv[0] - it is purely a convention that it be the name of the program, you cannot rely on that. Commented Jul 27, 2020 at 17:29
  • @JesperJuhl oh... I think that probably answers my question... Commented Jul 27, 2020 at 17:39
  • 1
    C++ Standard on Jesper's comment: eel.is/c++draft/basic.start.main#2.2 .TL;DR: If argc isn't 0 you get either the invocation of the program or an empty string. Note invocation of the program doesn't necessarily mean the name of the program. Symlinks, for example can break your expectations very quickly. Commented Jul 27, 2020 at 17:40
  • 1
    There is another mistake in "The value of argc is the number of pointers in the array of which argv points to the initial element.", as the array argv is null-pointer-terminated, meaning it contains at least argc + 1 pointers (of which the first argc point to valid strings). Commented Jul 27, 2020 at 17:51
  • @user4581301 "If argc isn't 0 you get either the invocation of the program or an empty string" - Not quite. If I launch an executable with execv, execvp or execvpe (or equivalent Win32 functions), I get to specify argv, so I can make argv[0] be "hello world" or any other arbitrary string. Commented Jul 27, 2020 at 18:06

1 Answer 1

1

The value of argc cannot be negative, but it can be 0, which means no arguments were passed to the program. However, from the reference

If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (ntmbss) ([multibyte.strings]) and argv[0] shall be the pointer to the initial character of a ntmbs that represents the name used to invoke the program or "".

So in that case, argv[0] is either the name used to invoke the program, or an empty string.

Sign up to request clarification or add additional context in comments.

6 Comments

That's not a hard fact. Purely convention. If I launch your program foo via execv and put "xyzzy" into argv[0], that is still perfectly valid.
@JesperJuhl Hmm, interesting. I can't seem to find wording that says that's ok. Could you point me to that?
The man page I linked to has this wording "The execv(), execvp(), and execvpe() functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer." - note the use of the word "should", not "must". Also, annecdotal evidence; I've done that several times in real life and if you look into the implementation you'll see it accepts arbitrary content for argv.
@JesperJuhl Yes, but I mean't standard wording. Doesn't the link you shared refer to an implementation defined version of main?
Possible. I haven't dug into specifically what the standard says. All I know is that on at least Solaris, FreeBSD, Linux, AiX and Windows you can freely control argv[0].
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.