各种现代C / C ++编译器包括Install-Script
/ __func__
中的一个或两个,用于记录当前正在执行的函数。 MSVC ++还包括__FUNCTION__
和GCC __FUNCSIG__
作为此功能的特定于编译器的增强版本。
GCC将这些定义为变量而不是宏,因此无法通过__PRETTY_FUNCTION__
预处理器指令测试它们的存在。
我正在使用必须使用C ++ 98和C ++ 11版本的MSVC ++和GCC的代码库,并且某人错误地编写的日志记录工具会尝试#ifdef
__FUNCTION__
无法使用。此检查始终返回false,渲染函数日志记录支持不可操作。
问题:是否有一个好的宏可以通过嗅探编译器来确定应该存在哪些(如果有的话)这些功能版本
答案 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版本#ifdef
,x.y.z
扩展为值__GNUC__
; x
,为GNU C编译器定义(可以使用__GNUC_MINOR__
进行测试)。对于gcc版本#ifdef
,x.y.z
扩展为值__GNUC_MINOR__
; y
,为GNU C编译器定义(可以使用__GNUC_PATCH_LEVEL__
进行测试)。对于gcc版本#ifdef
,x.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;设施提供的设施。
文档在这里:
以下是宏的简明复制品供参考:
#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)。