Turning on the -Wextra
flag to gcc
seems to have the effect of disallowing partial initialization of struct
s. E.g.:
// main.c
#include <pthread.h>
typedef struct S {
int i;
pid_t pid;
} S;
int main( int argc, char* argv[] ) {
(void)argc;
(void)argv;
S s = { 42 };
(void)s;
return 0;
}
$ gcc --version && gcc -Wall -Wextra -pedantic -Werror ./main.c
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
./main.c: In function ‘main’:
./main.c:12:3: error: missing initializer for field ‘pid’ of ‘S {aka struct S}’ [-Werror=missing-field-initializers]
S s = { 42 };
^
./main.c:6:9: note: ‘pid’ declared here
pid_t pid;
^~~
cc1: all warnings being treated as errors
Is there any reasonable initial (invalid) value for a pid_t
? I’d always felt that since pid_t
is opaque, one ought not make any assumptions about flag values.
If there is no reasonable initial/invalid value for a pid_t
is there some other good/widely-used programming practice to not hit this error?
Note: specifically interested in learning if there are options that do not involve assigning an arbitrary value that is assumed invalid until a separate validity flag variable is set true, e.g.
typedef struct S {
int i;
pid_t pid;
bool valid;
} S;
S s = { 42, 9, false };
2
Answers
pid_t
is not opaque. Zero and all negative values are explicitly exceptional (used e.g. bywaitpid
to represent particular classes of processes to wait for) and arguably 1 is exceptional too since the specialness of -1 prevents 1 from being a process group id you can use normally (traditionally, pid 1 is the init process).For your purpose, 0 seems like the most reasonable choice.
pid_t
isn’t completely opaque, it’s defined by POSIX (2.12.1) to be a signed integer type, and valid process IDs are always positive integers (3.300).I would use either
0
or-1
as a default value, since neither can be a valid process ID.fork()
, for instance, returns 0 to indicate that the current process is the parent, and-1
on error.