In some cases a program can be run in different ways and exhibit different behavior on how it is called. If you call vim
as vi
, it runs in a compatibility mode. Sometimes it is to try to maintain one version of several related programs - for example mailq
and newaliases
on many unix systems are a link to sendmail
so that these programs stay in sync)
Java programs are typically invoked as:
% java -jar foo.jar args
% java Foo args
The first version is where you have a Manifest file that indicates the main class, the second version runs the main method in the class Foo
found in the class path.
The information presented for Java is either a path to the jar or the name of the class being invoked.
The location of the jar isn't important enough to be something to code from (and was actually not part of the original spec). A Jar can be named anything really, and often includes version numbers. Whats more, there's no guarantee that the class was even stored in a .jar (it could have been extracted).
Invoking a Java application with -jar
has only one way to enter it - the class defined in the Manifest. There's no renaming that can be done.
The other option, of invoking it with the class name points directly to the execution unit. Furthemore, it can't be named multiply - you can't have Bar.class
be the code for class Foo
it just doesn't work that way.
This should show that there's really no point to passing the information of argv[0]
in the C sense to a Java application - its either going to be java
, meaningless and arbitrary, or the name of the class that is being invoked (that you are already executing code out of (you could do something like getClass().getEnclosingClass().getName()
if you were desperate...)).
There is a point here, you can define multiple Main methods in classes in a .jar or on the class path. And you could have them behave differently just as if there was a series of if statements based on what argv[0]
was.
I have in the past had code akin to java -cp Foo.jar com.me.foo.Test
which invoked the Test
class's Main method rather than the one defined in the one defined in the Manifest.
My first guess for the reason was simply because of performance and memory saving reasons, and for the ease of compiler implementation as well (especially for the kind of computers at the time when C was invented). Passing huge arrays "by value" seemed to have a huge impact at the stack, it needs a full array copy operation for each function call, and probably the compiler must be smarter to output the correct assembly code (though the last point is debatable). It would also be more difficult to treat dynamically allocated arrays the same way as statically allocated arrays (from the viewpoint of the language's syntax).
EDIT: after reading some parts from this link, I think the real reason (and the reason why arrays in structs are treated as value types, while sole arrays are not) is the backward compatibility to C's predecessor B. Here is the cite from Dennis Ritchie:
[...} The solution constituted the crucial jump in the evolutionary chain
between typeless BCPL and typed C. It eliminated the materialization
of the pointer in storage, and instead caused the creation of the
pointer when the array name is mentioned in an expression. The rule,
which survives in today's C, is that values of array type are
converted, when they appear in expressions, into pointers to the first
of the objects making up the array.
This invention enabled most existing B code to continue to work,
despite the underlying shift in the language's semantics. [..]
Best Answer
Argv is basically like this:
On the left is the argument itself--what's actually passed as an argument to main. That contains the address of an array of pointers. Each of those points to some place in memory containing the text of the corresponding argument that was passed on the command line. Then, at the end of that array there's guaranteed to be a null pointer.
Note that the actual storage for the individual arguments are at least potentially allocated separately from each other, so their addresses in memory might be arranged fairly randomly (but depending on how things happen to be written, they could also be in a single contiguous block of memory--you simply don't know and shouldn't care).