tags:

views:

104

answers:

5

Is there a limit on the number of arguments that we pass to main() in C? As you all know, it is defined as int main(int argc, char *argv[]).

When I call the program, I can pass arguments like so:

$ prog.exe arg1 arg2 arg3.....argn

Is there an upper bound in the number of argument that we may supply to main() in this way?

A: 

I think it's basically limited to the size of an int (2^32). You'll hit a limit of your command shell before you hit a limit in C.

Andrew Cooper
+1  A: 

I wouldn't think so. While there may not be a theoretical limit, the computer probably can't handle 1.5 million arguments. Is there any particular reason you need to know this? I wouldn't recommend using command line arguments for thing other than options, file parameters, ect...

Alexander Rafferty
It was because of this discussion I was having with a collegue of mine. My collegue was asked this question in an interview. I was wondering if it might be limited by the size of the stack or by the size of an int as andrew mentioned but I ain't sure of any of those.
RaviPathak
@Ravi: They don't go on the stack. It's more likely limited by the process memory layout or other OS configuration. You could theoretically implement a *new* C environment other than the native platform ABI with more capabilities.
Potatoswatter
@Potatoswatter: The space for arguments is often allocated on the process's initial stack. It's easy to put them there because the OS has to set up this area anyway, and it does allow the size of the arguments to vary or grow in future versions of the OS because it doesn't rely on the size of the arguments.
nategoose
+8  A: 

According to the POSIX spec for exec, there is a macro ARG_MAX defined in <limits.h> which defines the maximum number of bytes for the arguments + environment variables.

But since C doesn't define anything about that, no, there isn't an inherent cross-platform limit. You have to consult your OS manual if it doesn't define that macro.

Potatoswatter
Re: `exec()` syscall. OSs simply for sanity reasons limit how much memory they would have to transfer from the old process memory image into the new one being created. Since the transfer happens in kernel, there has to be limit to avoid user processes depleting kernel memory (imagine the [fork/shell bomb](http://en.wikipedia.org/wiki/Fork_bomb#Example_fork_bombs)). On Windows that shouldn't matter, since the old process remains, but IIRC they limit it too to 32K.
Dummy00001
The value provided by `limit.h` could be lower than the actual value supported by the OS and may be intended to be used as a way of saying "well, we know that it can be at least this big". When setting up arguments for `exec` this may be good enough, but I wouldn't rely on that value for the size of the arguments that a program could actually be passed by the OS.
nategoose
+3  A: 

No, there is no limit imposed by the ISO C99 standard. If you're using the "blessed" main form (of which there are two):

int main (int argc, char *argv[]);

then you will be limited to the maximum size of a signed integer (implementation-dependent but guaranteed to be at least 215-1 or 32,767).

Of course, you could even have more than that since the standard specifically allows for non-blessed main forms (for example, one that takes a long as the count).

The standard mandates how the arguments are stored and things like argv[argc] having to be NULL, but it does not directly limit the quantity.

Of course, there will be a limit in practice but this will depend entirely on the implementation and environment. However, if you have to ask, then you're probably doing something wrong.

Most tools would place a truly large number of arguments into a response file (say args.txt) then pass a single argument like:

my_prog @args.txt

which gets around arbitrary limits on argument quantity and size.

paxdiablo
By "non-blessed" do you mean the Standard allows for implementations to 'work' without an Operating System?
pmg
No, not entirely. You can still use one of the two canonical forms in a non-OS environment even if there are no arguments passed in. `main` isn't usually the start point so the startup code could push a zero `argc` and NULL `argv[0]` before calling `main`. I mean that ISO allows for other variants of main, for example the `{argc, argv, envp}` variant from UNIX where the environment is passed in as well.
paxdiablo
+1 for providing some Windows answers. @pmg: No, it means the Standard allows OSes/environments to define other non-portable formats for `main`.
Potatoswatter
Ah ok. ISO allows variants of `main` but "in some other implementation-defined manner", so by using a different `main` prototype you're locking yourself to a specific implementation.
pmg
Yes, at a bare minimum, a compiler must provide the two canonical forms. Anything else is optional and implementation-defined so you're right - you'll probably be tying yourself to that implementation (or compatible ones).
paxdiablo
A: 

There is no limit explicit in C itself. This is an example of a behavior not defined in the language but rather the implementation. Remember that the language itself is different than it's implementation, subsequent libraries, IDE's, etc.

Old McStopher