【发布时间】:2008-09-05 19:39:37
【问题描述】:
在 Fedora Core 7 上,我正在编写一些依赖于 ARG_MAX 的代码。但是,即使我#include <limits.h>,仍然没有定义常量。我的调查表明它存在于<sys/linux/limits.h> 中,但它应该可以跨 Win32/Mac/Linux 移植,因此不能直接包含它。这是怎么回事?
【问题讨论】:
在 Fedora Core 7 上,我正在编写一些依赖于 ARG_MAX 的代码。但是,即使我#include <limits.h>,仍然没有定义常量。我的调查表明它存在于<sys/linux/limits.h> 中,但它应该可以跨 Win32/Mac/Linux 移植,因此不能直接包含它。这是怎么回事?
【问题讨论】:
它不在limits.h中的原因是它不是一个基于当前架构上的位宽给出整数类型值范围限制的量。这是 ISO 标准分配给 limits.h 的角色。
您感兴趣的值在实践中不受硬件限制,并且可能因平台而异,也可能因系统构建而异。
正确的做法是致电sysconf 并询问“ARG_MAX”或“_POSIX_ARG_MAX”。我认为无论如何这都是符合 POSIX 的解决方案。
累加。在我的文档中,根据您请求的值,您可以包含 unistd.h 或 limits.h 之一或两者。
另外一点:如果您尝试在超大环境中调用 exec 系列函数的许多实现,它们会返回 E2BIG 或类似的值。这是 exec 可以实际返回的已定义条件之一。
【讨论】:
为了教育像我这样在网络搜索“arg_max posix”后发现自己在这里的未来人,这里演示了在您的系统上识别 ARG_MAX 的 POSIXly-correct 方法,Thomas Kammeyer 在他的回答中提到:
cc -x c <(echo '
#include <unistd.h>
#include <stdio.h>
int main() { printf("%li\n", sysconf(_SC_ARG_MAX)); }
')
这使用了 Bash 的process substitution 功能;如果您使用的是其他 shell,请将相同的行放入文件中并运行 cc thefile.c。
这是 macOS 10.14 的输出:
$ ./a.out
262144
以下是配置为在 HPC 环境中使用的 RHEL 7.x 系统的输出:
$ ./a.out
4611686018427387903
$ ./a.out | numfmt --to=iec-i # 'numfmt' from GNU coreutils
4.0Ei
作为对比,这里是https://porkmail.org/era/unix/arg-max.html规定的方法,使用了C预处理器:
cpp <<HERE | tail -1
#include <limits.h>
ARG_MAX
HERE
这在 Linux 上不起作用,原因我仍然不完全清楚——我不是系统程序员,也不熟悉 POSIX 或 ISO 规范——但可能在上面解释过。
【讨论】:
linux。著名的。无论如何,这个答案是上述搜索词的最佳结果。
ARG_MAX 在 /usr/include/linux/limits.h 中定义。我的linux内核版本是3.2.0-38。
【讨论】:
<sys/linux/limits.h>,但没有引用确切的文件系统路径。如果这需要反对票,那么我想我仍然不明白反对票。是的,sysconf 是报告这个问题的“正确”方式,但是“我对 C/C++ 的理解足够好,可以在/some/path/to/limits.h 中寻找这个值”的水平,这正是我想知道的。来到这里试图找出为什么 this method of discovering ARG_MAX on your system 不适用于现代 Linux。