C中main的参数数量限制

C中main的参数数量限制,c,language-lawyer,C,Language Lawyer,在C语言中传递给main()的参数数量是否有限制?众所周知,它被定义为intmain(intargc,char*argv[]) 当我调用程序时,我可以这样传递参数: $ prog.exe arg1 arg2 arg3.....argn 我们可以用这种方式提供给main()的参数数量是否有上限?我不这么认为。虽然理论上可能没有限制,但计算机可能无法处理150万个参数。你有什么特别的原因需要知道这一点吗?我不建议对选项、文件参数等以外的对象使用命令行参数…根据POSIX规范,有一个定义了参数+环境

在C语言中传递给
main()
的参数数量是否有限制?众所周知,它被定义为
intmain(intargc,char*argv[])

当我调用程序时,我可以这样传递参数:

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

我们可以用这种方式提供给
main()
的参数数量是否有上限?

我不这么认为。虽然理论上可能没有限制,但计算机可能无法处理150万个参数。你有什么特别的原因需要知道这一点吗?我不建议对选项、文件参数等以外的对象使用命令行参数…

根据POSIX规范,有一个定义了参数+环境变量的最大字节数的宏
ARG\u MAX


但是,由于C没有定义任何与此相关的内容,因此不存在固有的跨平台限制。如果操作系统手册没有定义宏,您必须查阅操作系统手册。

不,ISO C99标准没有限制。如果您使用的是“受祝福的”
main
表单(其中有两种):

然后将限制为有符号整数的最大大小(取决于实现,但保证至少为215-1或32767)

当然,您甚至可以拥有更多,因为该标准特别允许非受祝福的
main
表单(例如,以
long
作为计数的表单)

该标准规定了参数的存储方式以及
argv[argc]
等内容必须为NULL,但它没有直接限制数量

当然,在实践中会有限制,但这将完全取决于实施和环境。然而,如果你不得不问,那么你很可能是在问

大多数工具都会将大量参数放入响应文件(比如
args.txt
),然后传递单个参数,如:

my_prog @args.txt

它绕过了参数数量和大小的任意限制。

C本身没有明确的限制。这是一个未在语言中定义的行为示例,而是在实现中定义的行为示例。请记住,语言本身与它的实现、后续库、IDE等不同。

这是因为我与一位同事进行了讨论。我的同事在一次采访中被问到这个问题。我想知道它是否会受到堆栈大小的限制,或者像andrew提到的那样受到int的大小的限制,但我不确定其中任何一个。@Ravi:它们不在堆栈上。它更可能受到进程内存布局或其他操作系统配置的限制。从理论上讲,您可以实现一个新的C环境,而不是具有更多功能的本机平台ABI。@Potatoswatter:参数空间通常在进程的初始堆栈上分配。把它们放在那里很容易,因为操作系统无论如何都必须设置这个区域,并且它允许参数的大小在操作系统的未来版本中变化或增长,因为它不依赖于参数的大小。所谓“不受祝福”是指标准允许实现在没有操作系统的情况下“工作”吗?不,不完全是这样。即使没有传入任何参数,您仍然可以在非OS环境中使用这两种规范形式之一
main
通常不是起始点,因此启动代码可以在调用
main
之前推送零
argc
和空
argv[0]
。我的意思是,ISO允许main的其他变体,例如从UNIX传入环境的
{argc,argv,envp}
变体。+1用于提供一些Windows答案@pmg:不,这意味着该标准允许操作系统/环境为
main
定义其他非便携格式。啊,好的。ISO允许
main
的变体,但“以其他实现定义的方式”,因此通过使用不同的
main
原型,您将自己锁定到特定的实现。是的,编译器至少必须提供两种规范形式。其他任何内容都是可选的,并且实现是定义的,因此您是正确的-您可能会将自己绑定到该实现(或兼容的实现)。re:
exec()
syscall。OSs只是出于理智的原因,限制了它们必须从旧进程内存映像传输到正在创建的新进程内存映像的内存量。由于传输发生在内核中,因此必须有限制以避免用户进程耗尽内核内存(想象一下。在Windows上,这本不重要,因为旧进程仍然存在,但IIRC也将其限制在32K。由
limit.h
提供的值可能低于操作系统支持的实际值,可能被用作表示“好吧,我们知道它至少可以这么大”的方式。在为
exec
设置参数时,这可能已经足够好了,但我不会依赖该值来确定操作系统实际可以传递的参数的大小。另请参阅。
my_prog @args.txt