12

On Fedora Core 7, I'm writing some code that relies on ARG_MAX. However, even if I #include <limits.h>, the constant is still not defined. My investigations show that it's present in <sys/linux/limits.h>, but this is supposed to be portable across Win32/Mac/Linux, so directly including it isn't an option. What's going on here?

Stu Thompson
  • 38,370
  • 19
  • 110
  • 156
Josh Matthews
  • 12,816
  • 7
  • 36
  • 39

3 Answers3

8

The reason it's not in limits.h is that it's not a quantity giving the limits of the value range of an integral type based on bit width on the current architecture. That's the role assigned to limits.h by the ISO standard.

The value in which you're interested is not hardware-bound in practice and can vary from platform to platform and perhaps system build to system build.

The correct thing to do is to call sysconf and ask it for "ARG_MAX" or "_POSIX_ARG_MAX". I think that's the POSIX-compliant solution anyway.

Acc. to my documentation, you include one or both of unistd.h or limits.h based on what values you're requesting.

One other point: many implementations of the exec family of functions return E2BIG or a similar value if you try to call them with an oversized environment. This is one of the defined conditions under which exec can actually return.

Thomas Kammeyer
  • 4,457
  • 21
  • 30
1

ARG_MAX is defined in /usr/include/linux/limits.h. My linux kernel version is 3.2.0-38.

Jingguo Yao
  • 7,320
  • 6
  • 50
  • 63
  • The accepted answer explains it pretty well, you should not rely on this value for your build as it might vary from system to system. This is only interesting for a build which is specialized to your particular system and probably filled in by your configure script. – scravy Feb 20 '20 at 20:59
  • 1
    This is a helpful answer that is also factually correct, since the OP refers to `` but does not reference the exact filesystem path. If that warrants downvotes, then I guess I still don't understand downvoting. Yes, `sysconf` is the "right" way to report this, but the level of "I understand C/C++ well enough to go looking for this value in `/some/path/to/limits.h`", this is exactly what I wanted to know. Came here trying to discover why [this method of discovering ARG_MAX on your system](https://porkmail.org/era/unix/arg-max.html) didn't work for modern Linux. – TheDudeAbides Oct 18 '21 at 08:47
1

For the edification of future people like myself who find themselves here after a web search for "arg_max posix", here is a demonstration of the POSIXly-correct method for discerning ARG_MAX on your system that Thomas Kammeyer refers to in his answer:

cc -x c <(echo '
  #include <unistd.h>
  #include <stdio.h>
  int main() { printf("%li\n", sysconf(_SC_ARG_MAX)); }
')

This uses the process substitution feature of Bash; put the same lines in a file and run cc thefile.c if you are using some other shell.

Here's the output for macOS 10.14:

$ ./a.out
262144

Here's the output for a RHEL 7.x system configured for use in an HPC environment:

$ ./a.out
4611686018427387903

$ ./a.out | numfmt --to=iec-i  # 'numfmt' from GNU coreutils
4.0Ei

For contrast, here is the method prescribed by https://porkmail.org/era/unix/arg-max.html, which uses the C preprocessor:

cpp <<HERE | tail -1
#include <limits.h>
ARG_MAX
HERE

This does not work on Linux for reasons still not entirely clear to me—I am not a systems programmer and not conversant in the POSIX or ISO specs—but probably explained above.

TheDudeAbides
  • 1,821
  • 1
  • 21
  • 29
  • Yes, I _do_ see that this question is tagged `linux`. Noted. Regardless, this answer is a top result for the search terms stated above. – TheDudeAbides Oct 18 '21 at 09:21