44

On Linux systems (either 32- or 64-bit), what is the size of pid_t, uid_t, and gid_t?

Joe Shaw
  • 22,066
  • 16
  • 70
  • 92

3 Answers3

74
#include <stdio.h>
#include <sys/types.h>

int main()
{
    printf("pid_t: %zu\n", sizeof(pid_t));
    printf("uid_t: %zu\n", sizeof(uid_t));
    printf("gid_t: %zu\n", sizeof(gid_t));
}

EDIT: Per popular request (and because, realistically, 99% of the people coming to this question are going to be running x86 or x86_64)...

On an i686 and x86_64 (so, 32-bit and 64-bit) processor running Linux >= 3.0.0, the answer is:

pid_t: 4
uid_t: 4
gid_t: 4
Johannes Overmann
  • 4,914
  • 22
  • 38
Dave
  • 5,133
  • 21
  • 27
  • 6
    The answers are portable to all Linux targets as far as I know. They're all 4. – R.. GitHub STOP HELPING ICE Jul 05 '11 at 00:16
  • 20
    Actually, the code was not portable, because the format specifier was `%d` but `sizeof` returns a `size_t`, which is unsigned and not necessarily the size of an `int`. The correct portable format specifier is `%zu`. I have fixed it. – rob mayoff Apr 03 '14 at 21:58
  • 3
    Would be nice to also include the results for at least one example architecture. – Pavel Šimerda Jan 04 '15 at 20:28
  • 1
    does 4 mean 4 bytes? – Zap Aug 31 '19 at 18:06
  • 1
    @Zap yes (long pedantic answer: it means four `char`s, and a single `char` is the closest thing C has to a byte... of course a "byte" is *usually* an octet (8 bits), but it originally meant *smallest individually addressable unit of memory* - on some hardware that's a different size than 8 bits, but C requires a `char`/byte to be *at least* 8 bits, and anything else is rather rare unless you're writing bare metal code for DSPs). – mtraceur Jul 01 '23 at 03:25
28

On intel architectures, sizes are defined in /usr/include/bits/typesizes.h:

#define __UID_T_TYPE            __U32_TYPE
#define __GID_T_TYPE            __U32_TYPE
#define __PID_T_TYPE            __S32_TYPE

In other words, uid_t and gid_t are unsigned 32-bit integers and pid_t is a signed 32-bit integer. This applies for both 32- and 64-bits.

I am not sure what they are on other architectures offhand as I don't have any available at the moment, but the definitive way is to compile a program which prints the output of sizeof(uid_t), etc.

Joe Shaw
  • 22,066
  • 16
  • 70
  • 92
  • `I am not sure what they are on other architectures offhand` => on Linux, they are the same regardless of architecture. However, on other operating systems, it can differ: on 64-bit AIX, `pid_t` is a signed 64-bit integer, but the kernel never assigns PIDs outside of the 32-bit range, for compatibility with 32-bit processes, which use a 32-bit `pid_t`. Also, on some 32-bit platforms (e.g. Solaris), while `pid_t` is still signed 32-bit, it is `long` rather than `int`-which are physically identical, but C treats them as different types, which can cause some compilation warnings around casts/etc – Simon Kissane Feb 16 '23 at 10:38
18

The standard defines pid_t as a "signed integer type" and uid_t and gid_t merely as "integer types" (so portable code shouldn't assume any particular type for them).

Steve Emmerson
  • 7,702
  • 5
  • 33
  • 59
  • 1
    My manpage for `types.h`, which claims to be POSIX, says `uid_t` and `gid_t` are integer types (no mention of signed or unsigned), and `pid_t` is a signed integer type. – ptomato Oct 09 '13 at 17:40
  • @Chris I was wrong about "pid_t", so I corrected my posting. The standard doesn't say anything about the signedness of "uid_t" or "gid_t", however. – Steve Emmerson Oct 09 '13 at 21:41
  • Note that the standard also provides the `id_t` type, which “can be used to contain at least a `pid_t`, `uid_t`, or `gid_t`”. – rob mayoff Apr 03 '14 at 22:00
  • The pid_t data type is a signed integer type which is capable of representing a process ID. In the GNU C Library, this is an int. (https://www.gnu.org/software/libc/manual/html_node/Process-Identification.html) – debug May 30 '18 at 10:22