免责声明:这适用于编程课程,但 <=> 分配的答案或目的。
我们可以在我的大学访问多个类似* nix的服务器,并鼓励他们在每个服务器上编译我们的项目,以了解不同环境如何改变事物。我目前正在做一个涉及信号的项目,而且我遇到了一些我无法解决的问题。
在基于Solaris的服务器下,一切正常:
xxxxxxx@xxx:~/proj6$ make gcc-new
rm -f ./pr6
gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200112L -D_POSIX_PTHREAD_SEMANTICS -o pr6 pr6.2.c pr6_ctime.c pr6_signal.c
pr6_signal.c:64: warning: unused parameter 'sig'
pr6_signal.c:64: warning: unused parameter 'func'
在基于Linux的服务器下,我看到了:
xxxxxxx@xxxxx:~/proj6$ make gcc-new
rm -f ./pr6
gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200112L -D_POSIX_PTHREAD_SEMANTICS -o pr6 pr6.2.c pr6_ctime.c pr6_signal.c
pr6_signal.c: In function âinstall_signal_handlerâ:
pr6_signal.c:45: error: âSA_RESTARTâ undeclared (first use in this function)
pr6_signal.c:45: error: (Each undeclared identifier is reported only once
pr6_signal.c:45: error: for each function it appears in.)
pr6_signal.c: In function âreinstall_signal_handlerâ:
pr6_signal.c:64: warning: unused parameter âsigâ
pr6_signal.c:64: warning: unused parameter âfuncâ
make: *** [gcc-new] Error 1
我已经摆弄了c99,POSIX 2001-12和POSIX pthread的不同组合无济于事。我不明白为什么SA_RESTART
不会在Linux下定义,因为它是POSIX标准的一部分,我在GCC中包含了这个标志。如果我忘了#include某些内容,那么两个系统都应该没有,不是吗?
更新:
我使用gcc -M
来确定每台计算机上的编译中包含哪些文件,然后使用grep
来尝试查找定义。到目前为止,这些是我的结果:
(在Solaris上)
xxxxxxx@xxx:~/proj6$ grep "SA_RESTART" /usr/include/sys/signal.h
#define SA_RESTART 0x000004
xxxxxxx@xxx:~/proj6$ grep "SA_RESTART" ./linux-signal.h
xxxxxxx@xxx:~/proj6$
xxxxxxx@xxx:~/proj6$ grep "#include" ./linux-signal.h
#include <features.h>
#include <bits/sigset.h> /* __sigset_t, __sig_atomic_t. */
#include <bits/types.h>
#include <bits/signum.h>
xxxxxxx@xxx:~/proj6$ grep "#include" /usr/include/sys/signal.h
#include <sys/feature_tests.h>
#include <sys/iso/signal_iso.h>
#include <sys/siginfo.h>
#include <sys/ucontext.h>
#include <sys/t_lock.h>
(在Linux上)
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/features.h
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/bits/sigset.h
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/bits/types.h
xxxxxxx@xxxxx:~/proj6$ grep "SA_RESTART" /usr/include/bits/signum.h
xxxxxxx@xxxxx:~/proj6$
所以在Linux下包含的任何文件中没有SA_RESTART的定义(编译器告诉我这个开头)所以问题是为什么?
更新#2:Linux上/usr/include/sys/signal.h
的内容只是`#include
更新#3:grep -r SA_RESTART /usr/include
/usr/include/bits/sigaction.h:# define SA_RESTART 0x10000000 /* Restart syscall on signal return. */
/usr/include/asm-generic/signal.h: * SA_RESTART flag to get restarting signals (which were the default long ago)
/usr/include/asm-generic/signal.h:#define SA_RESTART 0x10000000
Binary file /usr/include/c++/3.4.6/x86_64-redhat-linux/bits/stdc++.h.gch/O2g matches
Binary file /usr/include/c++/3.4.6/x86_64-redhat-linux/bits/stdc++.h.gch/O0g matches
/usr/include/mysql/my_pthread.h: as Mac OS X, sigset() results in flags such as SA_RESTART being set, and
/usr/include/asm/signal.h: * SA_RESTART flag to get restarting signals (which were the default long ago)
/usr/include/asm/signal.h:#define SA_RESTART 0x10000000u
grep: warning: /usr/include/gphoto2/gphoto2: recursive directory loop
/usr/include/valgrind/vki/vki-ppc64-linux.h:#define VKI_SA_RESTART 0x10000000u
/usr/include/valgrind/vki/vki-darwin.h:#define VKI_SA_RESTART SA_RESTART
/usr/include/valgrind/vki/vki-ppc32-linux.h:#define VKI_SA_RESTART 0x10000000
/usr/include/valgrind/vki/vki-x86-linux.h:#define VKI_SA_RESTART 0x10000000u
/usr/include/valgrind/vki/vki-s390x-linux.h: * SA_RESTART flag to get restarting signals (which were the default long ago)
/usr/include/valgrind/vki/vki-s390x-linux.h:#define VKI_SA_RESTART 0x10000000
/usr/include/valgrind/vki/vki-amd64-linux.h:#define VKI_SA_RESTART 0x10000000
/usr/include/valgrind/vki/vki-arm-linux.h:#define VKI_SA_RESTART 0x10000000u
所以它驻留在一个名为sigaction.h的文件中(这很有意义)并且该文件被包含在内(用gcc -M
验证),为什么编译器会抱怨?
答案 0 :(得分:7)
这是由于你的-D标志:
#include <signal.h>
#include <stdio.h>
int main(void) {
#ifdef SA_RESTART
puts("have SA_RESTART");
#else
puts("no SA_RESTART");
#endif
return 0;
}
$ cc foo.c && ./a.out
have SA_RESTART
$ gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200112L -D_POSIX_PTHREAD_SEMANTICS foo.c && ./a.out
no SA_RESTART
$ gcc -std=c99 -Wall -Wextra -D_POSIX_C_SOURCE=200809L -D_POSIX_PTHREAD_SEMANTICS foo.c && ./a.out
have SA_RESTART
特别是,“200112L”的意思是“不要给我SA_RESTART”。请参阅/usr/include/features.h
。