Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does it say "We must not include limits.h!" in dirent.h?

When we include <dirent.h> and <limits.h> to a c file, dirent structs' d_name variable shows We must not include limits.h! in the variable description in the ide. When I look at the file /usr/include/x86_64-linux-gnu/bits/dirent.h it contains the following code piece.

...
struct dirent
  {
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];       /* We must not include limits.h! */
  };
...

My question is why we must not include limits.h. I've searched online, but I couldn't find any satisfying answer.

like image 766
sipihr Avatar asked Oct 16 '19 20:10

sipihr


3 Answers

Each standard header has a specification for what it exposes or may expose. dirent.h exposes struct dirent, DIR, and the relevant functions, and reserves names starting with d_. Some headers are also permitted but not required to expose things exposed by certain other headers; dirent.h is not one of these. So indirectly including limits.h would be a violation of the namespace and would break conforming programs that assume they can use names that limits.h would expose for their own identifiers.

like image 156
R.. GitHub STOP HELPING ICE Avatar answered Nov 13 '22 01:11

R.. GitHub STOP HELPING ICE


The maximum number of characters in a file name (component) is NAME_MAX. The number 256 equals NAME_MAX + 1 (or is the maximum of that on any targeted system). Naturally using a bare magic number like this is generally frowned upon.

But that macro is defined only in <limits.h>. It cannot be included in <dirent.h> because the latter is not supposed to define any of these macros.


Additionally, values such as NAME_MAX may not be guaranteed to be defined.

Per POSIX <limits.h>(bolding mine):

The values in the following list may be constants within an implementation or may vary from one pathname to another. For example, file systems or directories may have different characteristics.

A definition of one of the values shall be omitted from the <limits.h> header on specific implementations where the corresponding value is equal to or greater than the stated minimum, but where the value can vary depending on the file to which it is applied. The actual value supported for a specific pathname shall be provided by the pathconf() function.

...

{PATH_MAX}

Maximum number of bytes in a pathname, including the terminating null character.

Minimum Acceptable Value: {_POSIX_PATH_MAX}

Minimum Acceptable Value: {_XOPEN_PATH_MAX}

As noted in the comments, Linux supports filesystems with different maximum pathname lengths.

like image 1
Andrew Henle Avatar answered Nov 13 '22 02:11

Andrew Henle