11

The documentation for glibc stays they are integer types (no narrower than unsigned int), but I'm not finding a standards reference that says they have to be an integer type (see also time_t).

So in the end, the question becomes: Is

#include <stdio.h>
#include <stdint.h>
struct stat st;

if (stat("somefile", &st) == 0) {
        printf("%ju %ju\n", (uintmax_t)st.st_dev, (uintmax_t)st.st_ino);
}

portable.

alk
  • 69,737
  • 10
  • 105
  • 255
John Hascall
  • 9,176
  • 6
  • 48
  • 72
  • 1
    "see also time_t" --> In C, `time_t` may be an integer: signed or unsigned (this is uncommon), or floating point type. I suspect with POSIX, it it limited to signed integer types. – chux - Reinstate Monica Jan 09 '18 at 14:47

2 Answers2

11

POSIX standard requires dev_t to be an integer type and ino_t to be an unsigned integer.

dev_t shall be an integer type.

fsblkcnt_t, fsfilcnt_t, and ino_t shall be defined as unsigned integer types.

Since intmax_t and uintmax_t are supposed to be the "greatest width" integers, your code is safe. Just to be sure in case st_dev happens to be negative, you could write it as:

    printf("%jd %ju\n", (intmax_t)st.st_dev, (uintmax_t)st.st_ino);

Otherwise, your code is safe.

P.P
  • 117,907
  • 20
  • 175
  • 238
4

From the current POSIX specifications:

dev_t shall be an integer type.

[...]

ino_t shall be defined as unsigned integer types

alk
  • 69,737
  • 10
  • 105
  • 255