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.
Within the kernel, the dev_t type (defined in <linux/types. h>) is used to hold device numbers—both the major and minor parts. As of Version 2.6. 0 of the kernel, dev_t is a 32-bit quantity with 12 bits set aside for the major number and 20 for the minor number.
Greatest-width integer typesEdit intmax_t and uintmax_t is a signed and unsigned integer which are of the greatest supported width. They are, in other words, the integer types which have the greatest limits.
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.
From the current POSIX specifications:
dev_t shall be an integer type.
[...]
ino_t shall be defined as unsigned integer types
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With