简要概述
今天突发奇想一想看一下boost/config.hpp的内部实现,以及他有哪些功能。linux
这个头文件都有一个相似的结构,先包含一个头文件,假设为头文件1,而后包含这个头文 件中定义的宏。对于头文件中1中,有大量的#if..#endif,在这些指定的宏块中定义一个头文件宏,在这些大量的#if...#end中,头文件宏 有且只会被定义一次。具体的定义详情在下面进行详解。c++
根据上面的思路分析出了,config.hpp文件中主要包含几个主要的头文件:关于 用户配置的头文件(User config)、编译器配置文件(Compiler config)、C++标准库配置文件(Standard library)、平台配置文件(Platform config)、其余零碎的配置文件。接下来描述每一个头文件里面的大概做用。eclipse
用户配置文件(可控制的)
它是可选配置,能够经过定义BOOST_NO_USER_CONFIG宏来禁止包含用户配置头文件。若是没有禁止的话,那么这个头文件就是boost/config/user.hpp。函数
若是你没有禁止的话,那么你能够在boost/config/user.hpp中定义一些关键的宏。这个文件中默认一些被注释的宏,你能够根据需求取消这些注释,而且定义本身的配置。主要有以下宏:工具
- BOOST_COMPILER_CONFIG,这个宏用来指定编译器配置的hpp文 件,他是有必定标准的,他是和编译器相关的,要定一些通用功能的宏,好比 BOOST_SYMBOL_EXPORT,BOOST_SYMBOL_IMPORT,还有一些关于编译器对于标准的支持,好比是否支持long long类型,是否支持pragma once,是否支持cxx11中的某些特性。。。,详情请参考:boost/config/compiler/gcc.hpp。通常不要定义这个宏,由于 对于主流的编译器,他都会有对应的编译器配置头文件(这个宏在下面还会介绍到)。通常是对于一种新的编译器,若是你想让他支持boost的话,那么你须要 从新定义这个宏,因此说,通常用户是不会本身定义这个宏的。
- BOOST_STDLIB_CONFIG,这个宏用来指定 标准库配置文件(hpp文件),主要描述一些标准库对于某些标准的支持(后面会有详细介绍的),由于Boost都主流的标准库都会本身定义对应这个hpp 配置文件,因此通常用户不用本身定义这个宏,只有一个新的标准库的做者,可能才要定义这个宏为本身标准库的配置文件。文件样例能够参 考:boost/config/stdlib/libstdcpp3.hpp(他是gnu自带的标准库配置文件),boost/config /stdlib/sgi.hpp(著名的sgi标准库配置文件)。
- BOOST_PLATFORM_CONFIG,平台配置文 件,普通用户不用定义,只有新的系统做者,或者某个平台做者才会定义这个文件,样例参考:boost/config/platform /win32.hpp(win32平台),boost/config/platform/linux.hpp(linux平台),boost /config/platform/bsd.hpp(bsd平台)
- BOOST_NO_COMPILER_CONFIG,定义这个宏能够取消编译器配置
- BOOST_NO_STDLIB_CONFIG,定义这个宏能够取消标准库配置
- BOOST_NO_PLATFORM_CONFIG,定义这个宏能够取消平台配置
- BOOST_NO_CONFIG,定义这个宏能够取消全部的配置
- 。。。(详情请参看boost/config/user.hpp)
编译器配置文件(和每个不一样编译器对应)
若是用户定义了:BOOST_COMPILER_CONFIG,或者定义了 BOOST_NO_COMPILER_CONFIG,或者定义了BOOST_NO_CONFIG的,这儿boost本身就不会包含编译器配置文件。若是前 面的说的条件都没有发生,才会发生下面的事情。
先包含一个头文件boost/config /select_compiler_config.hpp,他会根据每个编译器本身定义的独一无二的宏(通常vc编译器会定 义:_MSC_VER,gnu编译器会定义__GNUC__。。。)来定义BOOST_COMPILER_CONFIG(这个宏在用户配置那儿能够本身定 义,只是那儿定义后,这儿就不会再定义了),这个宏指定了编译器所对应的配置文件的路径。而后在config.hpp中包含次路径。优化
我选择gnu编译器所对应的配置文件来简要描述一下里面定义的内容。spa
- BOOST_GCC_VERSION、BOOST_GCC根据gcc的一些相关宏所必定的gcc版本号,至少是5位整数
- BOOST_HAS_PRAGMA_ONCE 定义它来代表编译器是否支持#pragma once指定,通常能够在头文件中定义以下结构:#ifdef BOOST_HAS_PRAGMA_ONCE #pragma once #endif
- BOOST_HAS_LONG_LONG 用来代表是否支持long long类型
- BOOST_HAS_NRVO 用来代表编译器是否有命名返回值优化
- BOOST_HAS_DECLSPEC 用来代表是否支持特别声明
- BOOST_SYMBOL_IMPORT 导出签名
- BOOST_SYMBOL_EXPORT 导入签名
- 固然还有一些其余的工具宏
- 还 有一些对于cxx11的某些特性的支持,若是不支持某些特性,就会定义一些特定的宏,好比:BOOST_NO_CXX11_DECLTYPE代表编译器不 支持decltype操做符,BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS代表编译器不支持函数魔板默 认参数。BOOST_NO_CXX11_RVALUE_REFERENCES代表编译器不支持右值引用。。。
- 还有一些对于cxx14标准的支持。详情请参考此hpp文件
- BOOST_ATTRIBUTE_UNUSED,指定某些签名为未使用属性
- BOOST_COMPILER 代表某种编译器类型的字符串,好比对于gnu编译器,该字符串为"GNU C++ version " __VERSION__
简单小结:BOOST_HAS_PRAGMA_ONCE能够帮助你有选择的使 用#pragma once,BOOST_SYMBOL_IMPORT,BOOST_SYMBOL_EXPORT可让你不在忙于记住不一样编译器的导入导出签名指令。 BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS。。。这些相似宏,可让你有选择地使用某些cxx11中 的特性而不会出错。线程
标准库配置文件(和每一种标准库对应)
若是用户定义了:BOOST_STDLIB_CONFIG,或者定义了BOOST_NO_STDLIB_CONFIG,或者定义了BOOST_NO_CONFIG的,这儿boost本身就不会包含编译器配置文件。若是前面的说的条件都没有发生,才会发生下面的事情。设计
先包含boost/config /select_stdlib_config.hpp,在这儿文件中和boost/config/select_compiler_config.hpp 中结构比较相似,都含有大量的if endif预处理指定,只是这儿的用来做为条件的宏是标准类型,好比若是使用__SGI_STL_PORT(即sgi标准库)他会将 BOOST_STDLIB_CONFIG设置为 "boost/config/stdlib/stlport.hpp",若是使用__GLIBCPP__(gnu自带标准库),他会将 BOOST_STDLIB_CONFIG宏定义为: "boost/config/stdlib/libstdcpp3.hpp"。而后会包含#include BOOST_STDLIB_CONFIG。orm
接下来,我会选择gnu标准库配置文件(boost/config/stdlib/libstdcpp3.hpp)来进行简要介绍配置文件里面的内容:
- BOOST_GNU_STDLIB 1 定义它来代表使用gnu标准库
- BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__)定义BOOST_STDLIB 为对应的标准库字符串形式
- BOOST_HAS_THREADS 代表支持线程
- BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx定义拓展命名空间
- BOOST_HAS_SLIST 支持单向链表(拓展的,不在std库中)
- BOOST_HAS_HASH 支持hash表(拓展的,不在std库中)
- BOOST_SLIST_HEADER单向列表头文件,能够用来被包含
- BOOST_HASH_SET_HEADER <backward/hash_set> hash表头文件
- BOOST_HASH_MAP_HEADER <backward/hash_map> hashmap头文件
- BOOST_LIBSTDCXX_VERSION cxx版本,是数字
- 下面会有一些对于cxx11标准库的支持,比 如:BOOST_NO_CXX11_HDR_FORWARD_LIST,BOOST_NO_CXX11_HDR_INITIALIZER_LIST。。。 详情参考此文件(boost/config/stdlib/libstdcpp3.hpp)。
简单小结一下:我上面标出的红色的部分,在cxx11标准没有出来以前,仍是很重要的,可是现实随着各大编译器厂商对于cxx11标准的强有力支持中,这些特性已经无关紧要了,固然对于那儿仍然在使用老的编译器进行生产的项目中仍是比较重要的。
平台配置文件(和每一种平台对应)
若是用户定义了:BOOST_PLATFORM_CONFIG,或者定义了 BOOST_NO_PLATFORM_CONFIG,或者定义了BOOST_NO_CONFIG的,这儿boost本身就不会包含编译器配置文件。若是前 面的说的条件都没有发生,才会发生下面的事情。
先包含boost/config /select_platform_config.hpp,结构和上面所描述的两个hpp文件彻底相同(boost/config /select_stdlib_config.hpp、boost/config/select_compiler_config.hpp)。逻辑就是在 这个hpp文件中,根据每一种平台所特别定义的宏来设置平台配置文件路径给BOOST_PLATFORM_CONFIG宏,而后在config.hpp文 件中包含这个宏。
接下来,我选择win32平台所对应的配置文件(boost/config/platform/win32.hpp)进行描述。
- BOOST_PLATFORM "Win32" 代表了平台的字符串名称
- 若是编译器支持__declspec(dllexport/import)的话,那么会在这儿定义BOOST_SYMBOL_EXPORT/IMPORT
- BOOST_HAS_STDINT_H、BOOST_HAS_DIRENT_H、BOOST_HAS_UNISTD_H代表有某些头文件
- BOOST_HAS_GETTIMEOFDAY、BOOST_HAS_WINTHREADS、BOOST_HAS_GETSYSTEMTIMEASFILETIME、BOOST_HAS_THREADEX。。。对于某些特性或者函数的支持
- BOOST_WINDOWS 1 也能够用来标识win32平台
- 还有一些其余的东西,详情请参阅boost/config/platform/win32.hpp。
简单总结:利用BOOST_PLATFORM 宏,来打印平台的名称,可使用BOOST_WINDOWS 来做为#if的条件,来进行选择编译。
其余一些补充配置文件(固定的:boost/config/suffix.hpp)(包含了大量经常使用跨平台(编译器)宏)
- 有一些关于编译器特性支持的宏,好比 BOOST_NO_MS_INT64_NUMERIC_LIMITS 代表不支持numeric_limit<__int64>,BOOST_MSVC6_MEMBER_TEMPLATES 用来代表不支持成员函数模板,BOOST_HAS_PARTIAL_STD_ALLOCATOR 代表有一个局部的标准分配器。。。
- 有一些工具宏:BOOST_USING_STD_MIN/MAX使用std::min/max来计算最小值和最大值,BOOST_STATIC_CONSTANT定义静态常量
- BOOST_STRINGIZE(X) 将x转换为字符串形式
- BOOST_JOIN(X, Y) 能够讲X和Y连接成一个符号好比BOOST_JOIN(My, Dog)会变成MyDog符号
- 还有一些对于编译器行为的控制:好比:BOOST_FORCEINLINE强制内联,BOOST_NOINLINE阻止函数内联。BOOST_ALIGNMENT(x)设置内存对其方式。
- 还有一些描述cxx11的是否支持某些特性的宏
- 详情请看boost/config/suffix.hpp
简单总结:这个hpp文件很是很是重要,他几乎提供了80%以上的跨平台的可使 用的宏。包含了编译器对一些基本类型的支持,对于cxx11标准的支持。而且提供了一些统一的控制编译器行为的宏,和一些比较方便的工具宏。 值得看一下这个文件里面所定义的宏,没准之后就有相似的需求,可使用里面的宏来解决问题。
整体总结一下:
1)、之前打开文本编译器看config.hpp这个头文件,进入头文件中,看到一大堆#if..#endif,头就晕,其实借助Ide的话,层次就很是清晰了,我使用eclipse,看一下他构建的Index索引数,1分钟就知道他的结构了。
2)、就包含四个文件,也上面文章的4大部分:用户配置文件(他只对 编译器开发人员,标准库设计人员,平台设计人员),编译器配置文件,平台配置文件,补充文件(工具)。
3)、 可使用config来检测编译器对于某些特性的支持,好比是否支持pragma once指定,是否支持long long类型。也能够检测标准库是否支持某些cxx11中的标准特性。还能够检测某个平台对于某些基本类型的支持,某些函数的支持。能够利用他提供的工具 宏来控制各类编译器的行为,是真正的编译器啊!!!!。
4)、列出我的认为比较有用的宏(基本上都是工具宏):
- BOOST_SYMBOL_EXPORT
- BOOST_SYMBOL_IMPORT
- BOOST_PLATFORM
- BOOST_STATIC_CONSTANT
- BOOST_STRINGIZE
- BOOST_JOIN
- BOOST_FORCEINLINE
- BOOST_NOINLINE
- BOOST_ALIGNMENT
- 。。。