Search code examples
c++charcommand-line-argumentsprogram-entry-point

C++ - Should argv[] in the int main be always of the type char* (or char** if argv is used)?


I understand that since argc is the number of arguments, it can be an int. But why should argv be of char pointer type? Does this mean I cannot pass an integer argument and use argv[1] in mathematical operations?

Edit: To make it more clear, is it possible to write something like int* argv[] . Is argv already defined as char* type such that it cannot be changed?


Solution

  • Actually there are two valid definitions for main:

    int main() { /* ... */ }
    

    and

    int main(int argc, char *argv[]) { /* ... */ }
    

    or equivalent. (Note that, as a parameter, char *argv[] is equivalent to char **argv, which is a more accurate representation of what it is, a pointer to pointer to char.)

    Implementations can, but are not required to, support other forms; for example some systems support an additional char *envp[] parameter.

    What's unusual about main isn't that it doesn't have just a single valid definition. It's that, unlike other user-defined functions, it doesn't have infinitely many. For example, you can define a function named foo any way you like. The definition of main is restricted because it's your program's entry point, and the calling environment has to know how to call it.

    This is covered in more detail in section 3.6.1 of the ISO C++ standard. N4296 is a draft of the 2014 edition.

    If you want to pass integers as command-line arguments, pass them as strings and then parse them. (The atoi() function is one of the simplest ways to do this, but it doesn't do any error checking. The std::stoi() function, defined in the <string> header starting with C++11, is better.)

    The main function takes a list of strings (strictly speaking a char** pointer to the initial element of an array of char* pointers, each of which points to the beginning of a string) because it's an extremely flexible data structure and yet it isn't overly complicated. (Note that a "string" here is a C-style string, a sequence of characters terminated by a '\0' null character -- not to be confused with the std::string type defined by the C++ standard library.)

    There are various open-source libraries for parsing command-line arguments. For example, Unix-like systems have a getopt() function; see its documentation for more details.

    See also this related question.