More technical details are described in PATH_MAX Is Tricky

For porting guidelines, see guidelines

Is it really standard not to define them?

These macros are indeed optional in Posix, so not defining them remains standard-compliant.

Their definition was actually not completely clear, Posix 1990 was ambiguous about it including \0 or not, it was made clear later on that it does include it, but some software still add +1. Sometimes PATH_MAX is even understood as the filename sections of paths, which is actually NAME_MAX, which is indeed limited by filesystems constraints, but then it is filesystem-dependent, and even depend on its revision, so to be rather queried at runtime with pathconf.

But it's really convenient! Isn't allocating dynamically much more complex?

FOO_MAX constants are most often used as “reasonable size to allocate a path”. On Linux it is typically 4096, which is not that reasonable (a whole memory page, thus a TLB lookup) when manipulating a lot of paths. Allocating dynamically would use much less memory.

Most often interfaces can be made to properly allocate dynamically. Notably, since Posix 2008 realpath(path, NULL) and getcwd(NULL, 0) allocate the path dynamically.

In general, using FOO_MAX in source code (with a large value) leads to code that is not actually checking against overflows. PATH_MAX being 4096 is actually "wrong" on Linux:

$ printf '#include <limits.h>\nPATH_MAX' | cpp -P
$ d=0123456789; for i in `seq 1 1000`; do mkdir $d; cd $d 2>/dev/null; done
$ pwd | wc -c

Using such paths lead to various broken software, we could for instance notice:

  • nautilus crashes because of unhandled signal 8, arithmetic exception
  • tar can create an archive containing such paths, but cannot untar it
  • filelight just ignores the path
  • gdb refuses to work

Using a large PATH_MAX value just hides these bugs under the carpet. Attackers will happily try to exploit them.

Can't it just be defined to PTRDIFF_MAX?

A lot of programs which blindly use FOO_MAX as allocation size would then just at best either not compile or at worse compile but fail or segfault at execution.

These also imply ABI problems

Exposing a hardcoded limitation like FOO_MAX also means hard-defining them into binaries, making them part of the ABI, and then a hell to change. See for instance Windows which has been stuck with MAX_PATH being 260. Some libraries (e.g. libusb1) even expose them in their own ABI, thus making the increase a very nasty flag-day.