__FILE__,__LINE__和__FUNCTION__在C ++中的用法

假定你的C ++编译器支持它们,有什么特别的理由为了logging和debugging目的而使用__FILE____FUNCTION__ __LINE____FUNCTION__

我主要关心的是如何给用户带来误导性的数据,例如,报告不正确的行号或function,作为优化的结果,或者导致性能下降。

基本上,我可以信任__FILE____FUNCTION__ __LINE____FUNCTION__ 总是做正确的事情吗?

__FUNCTION__不是标准的, __func__存在于C99 / C ++ 11中。 其他( __LINE____FILE__ )都很好。

它将始终报告正确的文件和行(如果select使用__FUNCTION__ / __func__ )。 优化是一个非因素,因为它是一个编译时的macros观扩展; 它不会以任何方式影响性能。

在极less数情况下,将由__LINE__给出的行更改为其他内容可能很有用。 我已经看到GNUconfiguration为一些testing报告适当的行号后插入一些voodoo之间的原始源文件中没有出现的行。 例如:

 #line 100 

将使下列行以__LINE__ 100开始。您可以select添加新的文件名

 #line 100 "file.c" 

这只是非常有用的。 但如果需要的话,我不知道有什么替代scheme。 实际上,也可以使用一个macros来代替这一行,这必须导致上述两种forms中的任何一种。 使用boost预处理器库,可以将当前行增加50:

 #line BOOST_PP_ADD(__LINE__, 50) 

我想这是有用的,因为你问__LINE____FILE__用法。 从来没有得到足够的惊喜C + + 🙂

编辑: @Jonathan Leffler在评论中提供了一些更好的用例:

对于希望将用户的C代码中报告的错误与用户的源文件保持一致的预处理器,对#line进行混淆非常有用。 Yacc,Lex和ESQL / C预处理程序(更多在家里)。

FYI:g ++提供了非标准的__PRETTY_FUNCTION__macros。 直到现在我还不知道C99 __func__(感谢Evan!)。 我想我还是更喜欢__PRETTY_FUNCTION__当它可用于额外的类作用域。

PS:

 static string getScopedClassMethod( string thePrettyFunction ) { size_t index = thePrettyFunction . find( "(" ); if ( index == string::npos ) return thePrettyFunction; /* Degenerate case */ thePrettyFunction . erase( index ); index = thePrettyFunction . rfind( " " ); if ( index == string::npos ) return thePrettyFunction; /* Degenerate case */ thePrettyFunction . erase( 0, index + 1 ); return thePrettyFunction; /* The scoped class name. */ } 

就个人而言,我不愿意使用这些除了debugging消息。 我已经做到了,但是我尽量不向客户或最终用户展示这种信息。 我的客户不是工程师,有时不懂电脑。 我可能会将这些信息logging到控制台,但正如我所说,除了debugging版本或内部工具之外,还不情愿。 不过,我认为这取决于您拥有的客户群。

我一直使用它们。 我唯一担心的是在日志文件中放弃IP。 如果你的function名称真的很好,你可能会更容易发现一个交易秘密。 这就像运输debugging符号,只是更难find的东西。 在99.999%的情况下,没有什么不好的。