clock_t实际类型的查找流程
2016-01-21 21:57
656 查看
把握clock_t 在系统中实际是什么类型,有助于编程 人员更好的使用该类型的变量,最直接的好处就是可以防止变量溢出,在溢出时能够准确判断可能存在问题的代码。现就将clock_t 的查找过程做简单记录。
1)
首先使用clock_t 类型变量需要包含<time.h>头文件,因此到该头文件中查找,而<time.h>位于哪里,使用locate命令进行查找。为什么使用locate命令可以参考这篇blog:http://blog.csdn.net/ysdaniel/article/details/7043298
通过locate命令查找后可以发现仅<time.h>在不同文件夹下就有多个,因此哪一个<time.h>是我们要查找的,这涉及头文件的查找顺序,可参考这篇blog:http://blog.csdn.net/chosen0ne/article/details/7210946
根据以上blog中的内容,在编译时未使用-I选项,C_INCLUDE_PATH与CPLUS_INCLUDE_PATH路径为空,因此<time.h>位于/usr/include中。终于确定了time.h 的位置。
2)
在<time.h>中直接查找,clock_t,可以找到如下定义
在文件中无法找到__clock_t 的类型定义,不过发现包含<bits/types.h>。
3)
因此采用相同的方法,发现bits文件夹位于/usr/include/x86_64-linux-gnu/下,<type.h>中相关内容如下:
依然无法进一步找到__CLOCK_T_TYPE的类型,同时发现包含<bits/typesizes.h>。
4)
在<typesizes.h>中查找__CLOCK_T_TYPE的相关内容如下:
再次查找__SYSCALL_SLONG_TYPE的内容,可找到如下内容
由于我的机器是64位,因此__SYSCALL_SLONG_TYPE类型为__SQUAD_TYPE,到此查找过程实际已进入死路,因为<typesizes.h>不再包含其他头文件,不过根据注释的内容,相同的宏定义在<types.h> 中,因此回到<types.h>。
5)
在<types.h>中直接查找__SQUAD_TYPE,可得相关内容如下:
好了结果出来了,__SQUAD_TYPE类型为long int,即clock_t经过多重宏定义会被转换为long int。在编译时被包含的头文件会在包含文件中展开,__SYSCALL_SLONG_TYPE会被替换为long int,之后回溯的内容以此类推。
恩,恭喜你看到了这里。其实要知道clock_t 类型远不用这么麻烦,可以在编译时使用-E选项,-E选项的作用主要是对#include文件进行展开,并将#define的内容进行替换。
写一个简答的测试程序,#include<stdio.h>都不要了,只要#include<time.h>,测试程序如下:
#include <time.h>
int main()
{
clock_t argu;
return 0;
}
运行以下命令:
gcc -E -o test_clock_t.i test_clock_t.c
相关内容如下:
typedef long int __clock_t;
typedef __clock_t clock_t;
int main()
{
clock_t argu;
}
通过实验也可以发现,预编译过程对typedef不起作用。
1)
首先使用clock_t 类型变量需要包含<time.h>头文件,因此到该头文件中查找,而<time.h>位于哪里,使用locate命令进行查找。为什么使用locate命令可以参考这篇blog:http://blog.csdn.net/ysdaniel/article/details/7043298
通过locate命令查找后可以发现仅<time.h>在不同文件夹下就有多个,因此哪一个<time.h>是我们要查找的,这涉及头文件的查找顺序,可参考这篇blog:http://blog.csdn.net/chosen0ne/article/details/7210946
根据以上blog中的内容,在编译时未使用-I选项,C_INCLUDE_PATH与CPLUS_INCLUDE_PATH路径为空,因此<time.h>位于/usr/include中。终于确定了time.h 的位置。
2)
在<time.h>中直接查找,clock_t,可以找到如下定义
#if !defined __clock_t_defined && (defined _TIME_H || defined __need_clock_t) # define __clock_t_defined 1 # include <bits/types.h> __BEGIN_NAMESPACE_STD /* Returned by `clock'. */ typedef __clock_t clock_t; __END_NAMESPACE_STD #if defined __USE_XOPEN || defined __USE_POSIX __USING_NAMESPACE_STD(clock_t) #endif
在文件中无法找到__clock_t 的类型定义,不过发现包含<bits/types.h>。
3)
因此采用相同的方法,发现bits文件夹位于/usr/include/x86_64-linux-gnu/下,<type.h>中相关内容如下:
#include <bits/typesizes.h> # define __STD_TYPE typedef __STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */
依然无法进一步找到__CLOCK_T_TYPE的类型,同时发现包含<bits/typesizes.h>。
4)
在<typesizes.h>中查找__CLOCK_T_TYPE的相关内容如下:
/* See <bits/types.h> for the meaning of these macros. This file exists so that <bits/types.h> need not vary across different GNU platforms. */ #define __CLOCK_T_TYPE __SYSCALL_SLONG_TYPE
再次查找__SYSCALL_SLONG_TYPE的内容,可找到如下内容
#if defined __x86_64__ && defined __ILP32__ # define __SYSCALL_SLONG_TYPE __SQUAD_TYPE # define __SYSCALL_ULONG_TYPE __UQUAD_TYPE #else # define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE # define __SYSCALL_ULONG_TYPE __ULONGWORD_TYPE #endif
由于我的机器是64位,因此__SYSCALL_SLONG_TYPE类型为__SQUAD_TYPE,到此查找过程实际已进入死路,因为<typesizes.h>不再包含其他头文件,不过根据注释的内容,相同的宏定义在<types.h> 中,因此回到<types.h>。
5)
在<types.h>中直接查找__SQUAD_TYPE,可得相关内容如下:
#define __S16_TYPE short int #define __U16_TYPE unsigned short int #define __S32_TYPE int #define __U32_TYPE unsigned int #define __SLONGWORD_TYPE long int #define __ULONGWORD_TYPE unsigned long int #if __WORDSIZE == 32 # define __SQUAD_TYPE __quad_t # define __UQUAD_TYPE __u_quad_t # define __SWORD_TYPE int # define __UWORD_TYPE unsigned int # define __SLONG32_TYPE long int # define __ULONG32_TYPE unsigned long int # define __S64_TYPE __quad_t # define __U64_TYPE __u_quad_t /* We want __extension__ before typedef's that use nonstandard base types such as `long long' in C89 mode. */ # define __STD_TYPE __extension__ typedef #elif __WORDSIZE == 64 # define __SQUAD_TYPE long int # define __UQUAD_TYPE unsigned long int # define __SWORD_TYPE long int # define __UWORD_TYPE unsigned long int # define __SLONG32_TYPE int # define __ULONG32_TYPE unsigned int # define __S64_TYPE long int # define __U64_TYPE unsigned long int /* No need to mark the typedef with __extension__. */ # define __STD_TYPE typedef #else # error #endif #include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */
好了结果出来了,__SQUAD_TYPE类型为long int,即clock_t经过多重宏定义会被转换为long int。在编译时被包含的头文件会在包含文件中展开,__SYSCALL_SLONG_TYPE会被替换为long int,之后回溯的内容以此类推。
恩,恭喜你看到了这里。其实要知道clock_t 类型远不用这么麻烦,可以在编译时使用-E选项,-E选项的作用主要是对#include文件进行展开,并将#define的内容进行替换。
写一个简答的测试程序,#include<stdio.h>都不要了,只要#include<time.h>,测试程序如下:
#include <time.h>
int main()
{
clock_t argu;
return 0;
}
运行以下命令:
gcc -E -o test_clock_t.i test_clock_t.c
相关内容如下:
typedef long int __clock_t;
typedef __clock_t clock_t;
int main()
{
clock_t argu;
}
通过实验也可以发现,预编译过程对typedef不起作用。
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍