tidwall / neco

Concurrency library for C (coroutines)
MIT License
1.1k stars 79 forks source link

The description "standard C11" does not seem to be correct #17

Closed sarubo closed 2 months ago

sarubo commented 2 months ago

The README says standard C11, so I run the following:

cc -c neco.c -std=c11

I see a lot of errors.

Error ``` neco.c: In function ‘worker_entry’: neco.c:2770:9: error: implicit declaration of function ‘clock_gettime’ [-Wimplicit-function-declaration] 2770 | clock_gettime(CLOCK_REALTIME, &ts); | ^~~~~~~~~~~~~ neco.c:2770:23: error: ‘CLOCK_REALTIME’ undeclared (first use in this function) 2770 | clock_gettime(CLOCK_REALTIME, &ts); | ^~~~~~~~~~~~~~ neco.c:2770:23: note: each undeclared identifier is reported only once for each function it appears in In file included from neco.c:2868: neco.h: At top level: neco.h:175:18: warning: ‘struct addrinfo’ declared inside parameter list will not be visible outside of this definition or declaration 175 | const struct addrinfo *hints, struct addrinfo **res); | ^~~~~~~~ neco.h:177:18: warning: ‘struct addrinfo’ declared inside parameter list will not be visible outside of this definition or declaration 177 | const struct addrinfo *hints, struct addrinfo **res, int64_t deadline); | ^~~~~~~~ neco.c: In function ‘strsignal0’: neco.c:2933:16: error: implicit declaration of function ‘strsignal’; did you mean ‘strsignal0’? [-Wimplicit-function-declaration] 2933 | return strsignal(signo); | ^~~~~~~~~ | strsignal0 neco.c:2933:16: error: returning ‘int’ from a function with return type ‘const char *’ makes pointer from integer without a cast [-Wint-conversion] 2933 | return strsignal(signo); | ^~~~~~~~~~~~~~~~ neco.c: In function ‘system_out’: neco.c:2999:16: error: implicit declaration of function ‘popen’; did you mean ‘open’? [-Wimplicit-function-declaration] 2999 | FILE *ls = popen(command, "r"); | ^~~~~ | open neco.c:2999:16: error: initialization of ‘FILE *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion] neco.c:3011:13: error: implicit declaration of function ‘pclose’; did you mean ‘close’? [-Wimplicit-function-declaration] 3011 | pclose(ls); | ^~~~~~ | close neco.c: In function ‘getnow’: neco.c:3240:19: error: ‘CLOCK_MONOTONIC’ undeclared (first use in this function) 3240 | clock_gettime(CLOCK_MONOTONIC, &now); | ^~~~~~~~~~~~~~~ neco.c: At top level: neco.c:3610:22: error: array type has incomplete element type ‘struct sigaction’ 3610 | struct sigaction sigold[32]; // previous signal handlers, for restoring | ^~~~~~ neco.c: In function ‘is_main_thread’: neco.c:3692:31: error: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration] 3692 | return getpid() == (pid_t)syscall(SYS_gettid); | ^~~~~~~ neco.c: At top level: neco.c:3953:35: error: unknown type name ‘siginfo_t’ 3953 | static void sighandler(int signo, siginfo_t *info, void *ptr) { | ^~~~~~~~~ neco.c: In function ‘rt_handle_signals’: neco.c:3984:19: error: variable ‘act’ has initializer but incomplete type 3984 | static struct sigaction act = { 0 }; | ^~~~~~~~~ neco.c:3984:37: warning: excess elements in struct initializer 3984 | static struct sigaction act = { 0 }; | ^ neco.c:3984:37: note: (near initialization for ‘act’) neco.c:3984:29: error: storage size of ‘act’ isn’t known 3984 | static struct sigaction act = { 0 }; | ^~~ neco.c:3985:5: error: implicit declaration of function ‘sigemptyset’ [-Wimplicit-function-declaration] 3985 | sigemptyset(&act.sa_mask); | ^~~~~~~~~~~ neco.c:3986:25: error: ‘sighandler’ undeclared (first use in this function); did you mean ‘sigallowhandler’? 3986 | act.sa_sigaction = &sighandler; | ^~~~~~~~~~ | sigallowhandler neco.c:3987:20: error: ‘SA_SIGINFO’ undeclared (first use in this function) 3987 | act.sa_flags = SA_SIGINFO; | ^~~~~~~~~~ neco.c:3993:21: error: ‘SA_ONSTACK’ undeclared (first use in this function) 3993 | act.sa_flags |= SA_ONSTACK; | ^~~~~~~~~~ neco.c:3994:5: error: unknown type name ‘stack_t’ 3994 | stack_t ss = { | ^~~~~~~ neco.c:3995:9: error: field name not in record or union initializer 3995 | .ss_sp = rt->sigstack, | ^ neco.c:3995:9: note: (near initialization for ‘ss’) neco.c:3995:18: error: initialization of ‘int’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion] 3995 | .ss_sp = rt->sigstack, | ^~ neco.c:3995:18: note: (near initialization for ‘ss’) neco.c:3996:9: error: field name not in record or union initializer 3996 | .ss_size = NECO_SIGSTKSZ, | ^ neco.c:3996:9: note: (near initialization for ‘ss’) neco.c:54:27: warning: excess elements in scalar initializer 54 | #define DEF_SIGSTKSZ 1048576 | ^~~~~~~ neco.c:80:23: note: in expansion of macro ‘DEF_SIGSTKSZ’ 80 | #define NECO_SIGSTKSZ DEF_SIGSTKSZ | ^~~~~~~~~~~~ neco.c:3996:20: note: in expansion of macro ‘NECO_SIGSTKSZ’ 3996 | .ss_size = NECO_SIGSTKSZ, | ^~~~~~~~~~~~~ neco.c:54:27: note: (near initialization for ‘ss’) 54 | #define DEF_SIGSTKSZ 1048576 | ^~~~~~~ neco.c:80:23: note: in expansion of macro ‘DEF_SIGSTKSZ’ 80 | #define NECO_SIGSTKSZ DEF_SIGSTKSZ | ^~~~~~~~~~~~ neco.c:3996:20: note: in expansion of macro ‘NECO_SIGSTKSZ’ 3996 | .ss_size = NECO_SIGSTKSZ, | ^~~~~~~~~~~~~ neco.c:3997:9: error: field name not in record or union initializer 3997 | .ss_flags = 0, | ^ neco.c:3997:9: note: (near initialization for ‘ss’) neco.c:3997:21: warning: excess elements in scalar initializer 3997 | .ss_flags = 0, | ^ neco.c:3997:21: note: (near initialization for ‘ss’) neco.c:3999:10: error: implicit declaration of function ‘sigaltstack’; did you mean ‘SYS_sigaltstack’? [-Wimplicit-function-declaration] 3999 | must(sigaltstack(&ss, NULL) == 0); | ^~~~~~~~~~~ neco.c:2967:11: note: in definition of macro ‘must’ 2967 | if (!(cond)) { \ | ^~~~ neco.c:4003:14: error: implicit declaration of function ‘sigaction’ [-Wimplicit-function-declaration] 4003 | must(sigaction(signo, &act, &rt->sigold[signo]) == 0); | ^~~~~~~~~ neco.c:2967:11: note: in definition of macro ‘must’ 2967 | if (!(cond)) { \ | ^~~~ neco.c: In function ‘rt_sched_paused_step’: neco.c:4212:9: error: implicit declaration of function ‘nanosleep’; did you mean ‘nanosleep0’? [-Wimplicit-function-declaration] 4212 | nanosleep(&(struct timespec){ | ^~~~~~~~~ | nanosleep0 neco.c: In function ‘neco_strerror’: neco.c:5642:20: error: implicit declaration of function ‘gai_strerror’; did you mean ‘neco_strerror’? [-Wimplicit-function-declaration] 5642 | return gai_strerror(neco_gai_errno); | ^~~~~~~~~~~~ | neco_strerror neco.c:5642:20: error: returning ‘int’ from a function with return type ‘const char *’ makes pointer from integer without a cast [-Wint-conversion] 5642 | return gai_strerror(neco_gai_errno); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ neco.c: In function ‘gai_args_free’: neco.c:6486:9: error: implicit declaration of function ‘freeaddrinfo’ [-Wimplicit-function-declaration] 6486 | freeaddrinfo(args->res); | ^~~~~~~~~~~~ neco.c: In function ‘gai_args_new’: neco.c:6529:38: error: invalid application of ‘sizeof’ to incomplete type ‘struct addrinfo’ 6529 | args->hints = malloc0(sizeof(struct addrinfo)); | ^~~~~~ neco.c:6534:39: error: invalid application of ‘sizeof’ to incomplete type ‘struct addrinfo’ 6534 | memset(args->hints, 0, sizeof(struct addrinfo)); | ^~~~~~ neco.c:6535:20: error: invalid use of undefined type ‘struct addrinfo’ 6535 | args->hints->ai_flags = hints->ai_flags; | ^~ neco.c:6535:38: error: invalid use of undefined type ‘const struct addrinfo’ 6535 | args->hints->ai_flags = hints->ai_flags; | ^~ neco.c:6536:20: error: invalid use of undefined type ‘struct addrinfo’ 6536 | args->hints->ai_family = hints->ai_family; | ^~ neco.c:6536:39: error: invalid use of undefined type ‘const struct addrinfo’ 6536 | args->hints->ai_family = hints->ai_family; | ^~ neco.c:6537:20: error: invalid use of undefined type ‘struct addrinfo’ 6537 | args->hints->ai_socktype = hints->ai_socktype; | ^~ neco.c:6537:41: error: invalid use of undefined type ‘const struct addrinfo’ 6537 | args->hints->ai_socktype = hints->ai_socktype; | ^~ neco.c:6538:20: error: invalid use of undefined type ‘struct addrinfo’ 6538 | args->hints->ai_protocol = hints->ai_protocol; | ^~ neco.c:6538:41: error: invalid use of undefined type ‘const struct addrinfo’ 6538 | args->hints->ai_protocol = hints->ai_protocol; | ^~ neco.c:6539:20: error: invalid use of undefined type ‘struct addrinfo’ 6539 | args->hints->ai_next = NULL; | ^~ neco.c: In function ‘getaddrinfo_th’: neco.c:6554:14: error: implicit declaration of function ‘getaddrinfo’; did you mean ‘getaddrinfo_th’? [-Wimplicit-function-declaration] 6554 | a->ret = getaddrinfo(a->node, a->service, a->hints, &a->res); | ^~~~~~~~~~~ | getaddrinfo_th neco.c: In function ‘getaddrinfo_dl’: neco.c:6615:16: error: ‘EAI_MEMORY’ undeclared (first use in this function) 6615 | return EAI_MEMORY; | ^~~~~~~~~~ neco.c: At top level: neco.c:6684:5: error: conflicting types for ‘neco_getaddrinfo_dl’; have ‘int(const char *, const char *, const struct addrinfo *, struct addrinfo **, int64_t)’ {aka ‘int(const char *, const char *, const struct addrinfo *, struct addrinfo **, long int)’} 6684 | int neco_getaddrinfo_dl(const char *node, const char *service, | ^~~~~~~~~~~~~~~~~~~ neco.h:176:5: note: previous declaration of ‘neco_getaddrinfo_dl’ with type ‘int(const char *, const char *, const struct addrinfo *, struct addrinfo **, int64_t)’ {aka ‘int(const char *, const char *, const struct addrinfo *, struct addrinfo **, long int)’} 176 | int neco_getaddrinfo_dl(const char *node, const char *service, | ^~~~~~~~~~~~~~~~~~~ neco.c:6711:5: error: conflicting types for ‘neco_getaddrinfo’; have ‘int(const char *, const char *, const struct addrinfo *, struct addrinfo **)’ 6711 | int neco_getaddrinfo(const char *node, const char *service, | ^~~~~~~~~~~~~~~~ neco.h:174:5: note: previous declaration of ‘neco_getaddrinfo’ with type ‘int(const char *, const char *, const struct addrinfo *, struct addrinfo **)’ 174 | int neco_getaddrinfo(const char *node, const char *service, | ^~~~~~~~~~~~~~~~ neco.c: In function ‘neco_errconv_from_gai’: neco.c:6754:10: error: ‘EAI_MEMORY’ undeclared (first use in this function) 6754 | case EAI_MEMORY: | ^~~~~~~~~~ neco.c: In function ‘getaddrinfo_from_tcp_addr_dl’: neco.c:6778:12: error: variable ‘hints’ has initializer but incomplete type 6778 | struct addrinfo hints = { 0 }; | ^~~~~~~~ neco.c:6778:31: warning: excess elements in struct initializer 6778 | struct addrinfo hints = { 0 }; | ^ neco.c:6778:31: note: (near initialization for ‘hints’) neco.c:6778:21: error: storage size of ‘hints’ isn’t known 6778 | struct addrinfo hints = { 0 }; | ^~~~~ neco.c:6801:22: error: ‘EAI_FAIL’ undeclared (first use in this function) 6801 | neco_gai_errno = EAI_FAIL; | ^~~~~~~~ neco.c: In function ‘dial_tcp_dl’: neco.c:6889:32: error: invalid use of undefined type ‘struct addrinfo’ 6889 | fd = dial_connect_dl(ai->ai_family, ai->ai_socktype, ai->ai_protocol, | ^~ neco.c:6889:47: error: invalid use of undefined type ‘struct addrinfo’ 6889 | fd = dial_connect_dl(ai->ai_family, ai->ai_socktype, ai->ai_protocol, | ^~ neco.c:6889:64: error: invalid use of undefined type ‘struct addrinfo’ 6889 | fd = dial_connect_dl(ai->ai_family, ai->ai_socktype, ai->ai_protocol, | ^~ neco.c:6890:15: error: invalid use of undefined type ‘struct addrinfo’ 6890 | ai->ai_addr, ai->ai_addrlen, deadline); | ^~ neco.c:6890:28: error: invalid use of undefined type ‘struct addrinfo’ 6890 | ai->ai_addr, ai->ai_addrlen, deadline); | ^~ neco.c:6894:16: error: invalid use of undefined type ‘struct addrinfo’ 6894 | ai = ai->ai_next; | ^~ neco.c: In function ‘listen_tcp_dl’: neco.c:6977:27: error: invalid use of undefined type ‘struct addrinfo’ 6977 | int fd = socket0(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol); | ^~ neco.c:6977:45: error: invalid use of undefined type ‘struct addrinfo’ 6977 | int fd = socket0(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol); | ^~ neco.c:6977:65: error: invalid use of undefined type ‘struct addrinfo’ 6977 | int fd = socket0(ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol); | ^~ neco.c:6980:31: error: invalid use of undefined type ‘struct addrinfo’ 6980 | ok = ok && bind0(fd, ainfo->ai_addr, ainfo->ai_addrlen) != -1; | ^~ neco.c:6980:47: error: invalid use of undefined type ‘struct addrinfo’ 6980 | ok = ok && bind0(fd, ainfo->ai_addr, ainfo->ai_addrlen) != -1; | ^~ neco.c: In function ‘_pipe_’: neco.c:7794:15: error: ‘PATH_MAX’ undeclared (first use in this function) 7794 | char path[PATH_MAX]; | ^~~~~~~~ ```

I can compile it successfully by running:

cc -c neco.c

or

cc -c neco.c -std=gnu11

Environment

tidwall commented 2 months ago

cc -c neco.c -std=c11 succeeds on Mac and FreeBSD, but I can confirm it does not on Linux.

Perhaps one workaround is to add something like the following to the top of neco.c file.

#define _POSIX_C_SOURCE 200809L
#define _GNU_SOURCE

But that may cause other problems downstream.

I'll just remove the mention of it in the README.