用于测试__func __,__ FUNCTION __,__ PRETTY_FUNCTION__等的可用性的C ++宏

时间:2018-01-11 18:21:40

标签: c++ c++11 gcc macros

各种现代C / C ++编译器包括Install-Script / __func__中的一个或两个,用于记录当前正在执行的函数。 MSVC ++还包括__FUNCTION__和GCC __FUNCSIG__作为此功能的特定于编译器的增强版本。

GCC将这些定义为变量而不是宏,因此无法通过__PRETTY_FUNCTION__预处理器指令测试它们的存在。

我正在使用必须使用C ++ 98和C ++ 11版本的MSVC ++和GCC的代码库,并且某人错误地编写的日志记录工具会尝试#ifdef __FUNCTION__无法使用。此检查始终返回false,渲染函数日志记录支持不可操作。

问题:是否有一个好的宏可以通过嗅探编译器来确定应该存在哪些(如果有的话)这些功能版本

2 个答案:

答案 0 :(得分:1)

__func__在C99(而非C ++)中指定,gcc已提供__FUNCTION____PRETTY_FUNCTION__很长一段时间。但是,实际上没有一个是宏,所以不能这样使用。除此之外,这意味着您无法使用#ifdef来测试它们。

要测试您是否正在编译为C ++以及标准,请使用C ++标准中指定的__cplusplus,并扩展为值199711L(在C ++ 11之前),{{ 1}}(C ++ 11),201103L(C ++ 14)和201402L(C ++ 17)。这些值对应于标准化委员会批准标准的日期(年和月)(例如201703L表示C ++ 17于2017年3月获得批准)。请注意,这只是在编译C ++时定义的宏,而不是C。

除此之外,要使用特定于编译器的功能,您需要测试支持所需功能的编译器,而不是功能本身(尽管某些编译器/预处理器允许测试特定的语言功能,而且#39;在实践中不完整。)

gcc和g ++(以及声称支持gnu C方言的其他编译器)提供了许多特定的宏,因此您可以检查它们,包括

  • 201703L,为GNU C编译器定义(可以使用__GNUC__进行测试)。对于gcc版本#ifdefx.y.z扩展为值__GNUC__;
  • x,为GNU C编译器定义(可以使用__GNUC_MINOR__进行测试)。对于gcc版本#ifdefx.y.z扩展为值__GNUC_MINOR__;
  • y,为GNU C编译器定义(可以使用__GNUC_PATCH_LEVEL__进行测试)。对于gcc版本#ifdefx.y.z扩展为值__GNUC_PATCHLEVEL__;
  • z - 为g ++编译器定义。

如何使用gnu特定的宏的示例是

__GNUG__

我不知道哪些g ++版本开始支持 #ifdef __GNUG__ /* Assume all versions of gcc that you use support __FUNCTION__ */ /* can use gcc's __FUNCTION__ here */ #endif __FUNCTION__,但如果你想测试特定版本的编译器,那就很容易了。例如,要测试g ++ 3.2.0或更高版本

__PRETTY_FUNCTION__

对于MSVC ++,出于类似目的的特定于编译器的宏包括 #ifdef __GNUG__ // test for g++ 3.2.0 or better #if __GNUC__ > 3 || \ (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \ (__GNUC_MINOR__ == 2 && \ __GNUC_PATCHLEVEL__ > 0)) // use features not introduced before g++ 3.2.0 #endif #endif ,它扩展为主要版本和次要版本的编码。例如,在MSVC ++版本17.00.51106.1下,_MSC_VER扩展为1700.您可以在MSDN上找到其他人。

答案 1 :(得分:1)

T.C。首先提供了这个答案,作为我的问题的评论,我最终得到了我的解决方案:

Boost.Assert中的标题<boost/current_function.hpp>实现了一个BOOST_CURRENT_FUNCTION宏,它试图映射到一个合适的&#34;当前函数&#34;设施提供的设施。

文档在这里:

http://www.boost.org/doc/libs/1_66_0/libs/assert/doc/html/assert.html#current_function_macro_boost_current_function_hpp

以下是宏的简明复制品供参考:

#if defined( BOOST_DISABLE_CURRENT_FUNCTION )
# define BOOST_CURRENT_FUNCTION "(unknown)"
#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
# define BOOST_CURRENT_FUNCTION __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
# define BOOST_CURRENT_FUNCTION __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define BOOST_CURRENT_FUNCTION __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
# define BOOST_CURRENT_FUNCTION __func__
#else
# define BOOST_CURRENT_FUNCTION "(unknown)"
#endif

我最终修改了我正在使用的代码库,以便在可用时使用Boost宏,否则回到Boost检查的合理子集(GCC&gt; MSVC ++&gt; C ++ 11)。