Linux/UNIX下STL中宏的定义和c++config.h文件

一般会有一个Cpp配置文件c++config.h,几乎所有的定义的宏都放在其中
Linux/UNIX下STL中宏的定义和c++config.h文件_第1张图片
接着来看stl_vector.h中一些宏的定义

/** @file bits/stl_vector.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{vector}
 */
 namespace std _GLIBCXX_VISIBILITY(default)
{
     
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
	...

此处有一个_GLIBCXX_VISIBILITY(default),这是什么?

由上可知,我们可以在c++config.h中找到这个宏

#if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY
# define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))
#else
// If this is not supplied by the OS-specific or CPU-specific
// headers included below, it will be defined to an empty default.
# define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V)
#endif

GCC 有个visibility属性, 该属性是说, 启用这个属性:

  • 当-fvisibility=hidden时

动态库中的函数默认是被隐藏的即 hidden. 除非显示声明为__attribute__((visibility(“default”))).

  • 当-fvisibility=default时

动态库中的函数默认是可见的.除非显示声明为__attribute__((visibility(“hidden”))).

此用法可见说明

else之后的_GLIBCXX_PSEUDO_VISIBILITY(V)是什么?追根溯源

//如果平台既不使用可见性也不使用伪可见性,
//为命名空间注释宏指定空的默认值。
// If platform uses neither visibility nor psuedo-visibility,
// specify empty default for namespace annotation macros.
#ifndef _GLIBCXX_PSEUDO_VISIBILITY
# define _GLIBCXX_PSEUDO_VISIBILITY(V)
#endif

好了,接着来看下面两个宏

_GLIBCXX_BEGIN_NAMESPACE_VERSION

c++config.h

// 定义内联命名空间能用
// Defined if inline namespaces are used for versioning.
# define _GLIBCXX_INLINE_VERSION 0 
// 符号版本控制的内联命名空间。
// Inline namespace for symbol versioning.
#if _GLIBCXX_INLINE_VERSION
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __8 {
     

namespace std
{
     
inline _GLIBCXX_BEGIN_NAMESPACE_VERSION
// 此处应该是
/*
inline namespace __8 {
*/
	...
_GLIBCXX_END_NAMESPACE_VERSION
}

namespace __gnu_cxx
{
     
inline _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
}

#else
// 定义为空宏
# define _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_END_NAMESPACE_VERSION
#endif

	// debug,profile,parallel可见文件
// Inline namespaces for special modes: debug, parallel, profile.
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \
    || defined(_GLIBCXX_PROFILE)
namespace std
{
     
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  // Non-inline namespace for components replaced by alternates in active mode.
  namespace __cxx1998
  {
     
# if _GLIBCXX_USE_CXX11_ABI
  inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) {
      }
# endif
  }

_GLIBCXX_END_NAMESPACE_VERSION

接下来看看另一个_GLIBCXX_BEGIN_NAMESPACE_CONTAINER

// 打开、关闭条件命名空间的宏
// Macros for opening/closing conditional namespaces.
// _GLIBCXX_BEGIN_NAMESPACE_ALGO
// _GLIBCXX_END_NAMESPACE_ALGO
// _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// _GLIBCXX_END_NAMESPACE_CONTAINER
// 如果开启了debug和profile的glibcxx,定义为namespace _GLIBCXX_STD_C {,否则定义为空宏
#if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE)
# define _GLIBCXX_STD_C __cxx1998
# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \
	 namespace _GLIBCXX_STD_C {
     
# define _GLIBCXX_END_NAMESPACE_CONTAINER }
#else
# define _GLIBCXX_STD_C std
# define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
# define _GLIBCXX_END_NAMESPACE_CONTAINER
#endif

完事。

我看了SGI3.3的网上版本之后,其中的定义是这样的
__STL_HAS_NAMESPACES,应该是Windows下的吧,我也不清楚,我这里摘录的源码都是Linux/UNIX下的,毕竟glibc是Linux下的C函数库,不过网上版本的可读性也挺高的,而且没有这么复杂,可能是因为版本低的问题吧。

你可能感兴趣的:(面向对象之C++,c++,linux)