加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

xcode – 使用c 11或旧版libstdc标准库检测clang是否正在编译

发布时间:2020-12-14 17:42:46 所属栏目:百科 来源:网络整理
导读:我有一个 Xcode项目,我正在迁移使用clang的选项-stdlib libc,以启用C 11支持.我的一些源文件需要知道正在使用哪个库,例如我这样做: #ifdef HAVE_CPP11_LIB_SUPPORT #include memory#else #include tr1/memory#endif#ifdef HAVE_CPP11_LIB_SUPPORT vector.em
我有一个 Xcode项目,我正在迁移使用clang的选项-stdlib libc,以启用C 11支持.我的一些源文件需要知道正在使用哪个库,例如我这样做:

#ifdef HAVE_CPP11_LIB_SUPPORT
  #include <memory>
#else 
  #include <tr1/memory>
#endif

#ifdef HAVE_CPP11_LIB_SUPPORT
  vector.emplace_back(newValue);
#else 
  vector.push_back(newValue);
#endif

虽然找到为此选项设置的预处理器宏(如果确实有任何),但我遇到了麻烦.我试过转储clang的输出:

clang -x c++ -std=c++11 -stdlib=libc++ -dM -E - < /dev/null

比较:

clang -x c++ -std=c++11 -stdlib=libstdc++ -dM -E - < /dev/null

但这给出了相同的结果.请注意,我不想打开是否使用c 11语言设置,而是我们是否使用c 11库.有没有可靠的方法在代码中检测到这一点?

解决方法

我不知道任何确定的方式可以保证便携,但这是我现在使用的:

// libc++ detected:     _LIBCPP_VERSION
// libstdc++ detected:  __GLIBCXX__
#if defined(__clang__)
#   if __has_include(<__config>) // defines _LIBCPP_VERSION
#       include <__config>
#   elif __has_include(<bits/c++config.h>) // defines __GLIBCXX__
#       include <bits/c++config.h>
#   else
#       include <ios>
#   endif
#elif defined(__GNUC__) // gcc does not have __has_include
#   include <ios> // ios should include the c++config.h which defines __GLIBCXX__
#endif

这不是很好,但现在对我有用.

libc定义了_LIBCPP_VERSION,stdc定义了__GLIBCXX__这很好,但不幸的是这些宏没有被编译器定义.相反,它们是在非标准头文件中定义的,除非包含该标头,否则无法测试它们的定义.

注意:显然stdc在旧版本中定义了__GLIBCPP__.既然你需要c 11,这不会有问题.

Clang有一个很好的功能__has_include,它可以用来测试这些,但是如果没有找到标题,宏就会回退到只包含一个标准的标题,希望使用内部标题.我有< ios>在这里,但要包含的标准标题的选择取决于您.您可以查找包含内部标题的标题(类似于Linux上的gcc):

grep -Rl '#include <bits/c++config.h>' /usr/include/c++

选择您可能在项目中使用的任何标题.

由于这不能保证适用于任何给定的过去或将来的编译器/标准库版本,我不会依赖这些定义,除了可选功能,如:

#ifdef __GLIBCXX__
    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
#endif

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读