Parameter passing does not work the way you appear to believe it does.
There are precisely two signatures for main
that are guaranteed to work:
int main()
and
int main(int argc, char *argv[])
The latter is the one you use when you want to parse command line arguments. Here argc
is the argument count, i.e. the number of passed arguments (including the name of the command itself) and the length of argv
. argv
is an array of C-style strings that holds the arguments.
So, when you call
./a.out 8
then argc
is 2, argv[0]
is "./a.out"
, argv[1]
is "8"
, and argv[2]
is a null pointer. If you want to use the first command line argument as a number, you have to parse argv[1]
with std::istringstream
or atoi
or similar, as in
#include <iostream>
#include <sstream>
int main(int argc, char *argv[]) {
if(argc < 2) {
std::cerr << "No argument was given.\n";
return -1;
}
std::istringstream parser(argv[1]);
int x;
if(parser >> x) {
std::cout << x << " * 2 = " << x * 2 << '\n';
} else {
std::cerr << "The argument was not a number.\n";
return -2;
}
}
As a side note, because this is not something you can depend upon, this also explains why you get the output 2
. When you write
int main(int x) {
x
takes the value of argc
, and what would have been argv
is ignored, for low-level reasons that have to do with the way the arguments are laid out in memory before the jump to main
. When you call the program with ./a.out 8
, that value is 2, and so x
is 2 in your code. This is not guaranteed to work by the C++ standard, but it is likely to happen on all platforms as it did on yours.