include sys/stat.h的位置以及restrict关键字

时间:2022-11-06 16:18:14
今天看《Linux/Unix 系统编程手册》(Michael Kerrisk著)第十五章,看到,获取文件信息有以下几个系统调用可用:
#include <sys/stat.h>
int stat(const char *pathname,struct stat *statbuf)
int lstat(const char *pathname,struct stat *statbuf)
int fstat(int fd,struct stat *statbuf)

产生了以下几个疑问:

1、头文件包含为sys/stat.h。 但我在我的系统(深度,基于ubuntu)的/usr/include目录下并没有发现sys子目录。那么这个sys到底对应于系统的哪个目录?

2、stat的函数原型中,参数1使用的是

int stat(const char *pathname,struct stat *statbuf)

,而在W.Richard Stevens著的《unix环境高级编程》中stat的原型是这样的:
int stat(const char *restrict pathname,struct stat *restrict buf) 

毫无疑问,两者都是对的,但是区别在哪里?


================================================================================================

问题解决(下面是自己查找资料的过程记录,不一定对,欢迎指正)

问题1:

查找哪些地方包含stat.h文件:

/usr/include/x86_64-linux-gnu/sys$ find /usr -name stat.h
/usr/src/linux-headers-3.13.0-39/arch/mn10300/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/powerpc/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/mips/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/arm64/include/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/arm64/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/m68k/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/microblaze/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/cris/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/parisc/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/frv/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/arm/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/tile/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/score/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/x86/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/s390/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/alpha/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/ia64/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/sparc/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/xtensa/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/m32r/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/avr32/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/blackfin/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/arch/sh/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-39/include/linux/stat.h
/usr/src/linux-headers-3.13.0-39/include/uapi/linux/stat.h
/usr/src/linux-headers-3.13.0-39/include/uapi/asm-generic/stat.h
/usr/src/linux-headers-3.13.0-39-generic/include/linux/stat.h
/usr/src/linux-headers-3.13.0-39-generic/include/config/cpu/freq/stat.h
/usr/src/linux-headers-3.13.0-32-generic/include/linux/stat.h
/usr/src/linux-headers-3.13.0-32-generic/include/config/cpu/freq/stat.h
/usr/src/linux-headers-3.13.0-32/arch/mn10300/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/powerpc/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/mips/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/arm64/include/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/arm64/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/m68k/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/microblaze/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/cris/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/parisc/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/frv/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/arm/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/tile/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/score/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/x86/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/s390/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/alpha/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/ia64/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/sparc/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/xtensa/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/m32r/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/avr32/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/blackfin/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/arch/sh/include/uapi/asm/stat.h
/usr/src/linux-headers-3.13.0-32/include/linux/stat.h
/usr/src/linux-headers-3.13.0-32/include/uapi/linux/stat.h
/usr/src/linux-headers-3.13.0-32/include/uapi/asm-generic/stat.h
/usr/lib/syslinux/com32/include/sys/stat.h
/usr/include/linux/stat.h
/usr/include/x86_64-linux-gnu/sys/stat.h
/usr/include/x86_64-linux-gnu/asm/stat.h
/usr/include/x86_64-linux-gnu/bits/stat.h
/usr/include/asm-generic/stat.h

结果非常多,但根据编译器默认是从/usr/include中查找头文件的,所以#include <sys/stat.h>应该是指:/usr/include/x86_64-linux-gnu/sys/stat.h

验证方法:删除该目录下的stat.h,看编译是否能通过。

删除之后的执行结果:
@:gcc stat_test.c -o stattest
stat_test.c:1:22: fatal error: sys/stat.h: 没有那个文件或目录
#include <sys/stat.h>
^
compilation terminated.
而删除之前的执行结果:@:gcc -g stat_test.c -o stattest@: ./stattest st dev =1574892
将之前移走的stat.h文件复制到另外一个路径下,如~/sys ,然后在编译时通过-I选项手动指定头文件路径,操作过程如下:
llz@llz-pc:~/workspace4cplusplus/cLanguage/TLPI$ mkdir /home/llz/sysllz@llz-pc:~/workspace4cplusplus/cLanguage/TLPI$ mv /home/llz/stat.h /home/llz/sys/llz@llz-pc:~/workspace4cplusplus/cLanguage/TLPI$ gcc stat_test.c -o stattest -I /home/llz/llz@llz-pc:~/workspace4cplusplus/cLanguage/TLPI$ ./stattest st dev =1574892

得到了正确结果。以上验证应该足以说明:sys/stat.h 指的就是/usr/include/x86_64-linux-gnu/sys/stat.h

问题2:关键是要搞清楚restrict关键字的作用。

restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式。即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码。如

<span style="font-size:12px;">int *restrict ptr,</span>

ptr 指向的内存单元只能被 ptr 访问到,任何同样指向这个内存单元的其他指针都是未定义的,直白点就是无效指针。

restrict 的出现是因为 C 语言本身固有的缺陷,
C 程序员应当主动地规避这个缺陷,而编译器也会很配合地优化你的代码。


参考资料:


//restrict

http://www.linuxidc.com/Linux/2013-03/80940.htm

http://tieba.baidu.com/p/151610540?pid=1356089274&cid=0