在c++中使用__FILE__、__LINE__和__FUNCTION__。

时间:2021-06-26 17:03:55

Presuming that your C++ compiler supports them, is there any particular reason not to use __FILE__, __LINE__ and __FUNCTION__ for logging and debugging purposes?

假设您的c++编译器支持它们,是否有什么特别的理由不使用__FILE__、__LINE__和__FUNCTION__进行日志记录和调试?

I'm primarily concerned with giving the user misleading data—for example, reporting the incorrect line number or function as a result of optimization—or taking a performance hit as a result.

我主要关心的是给用户误导的数据,例如,报告错误的行号或函数是由于优化,或者是由于性能受到影响。

Basically, can I trust __FILE__, __LINE__ and __FUNCTION__ to always do the right thing?

基本上,我可以信任__FILE__、__LINE__和__FUNCTION__来始终做正确的事情吗?

5 个解决方案

#1


145  

__FUNCTION__ is non standard, __func__ exists in C99 / C++11. The others (__LINE__ and __FILE__) are just fine.

__FUNCTION__是非标准的,__func__存在于C99 / c++ 11中。其他的(__LINE__和__FILE__)都很好。

It will always report the right file and line (and function if you choose to use __FUNCTION__/__func__). Optimization is a non-factor since it is a compile time macro expansion; it will never effect performance in any way.

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

#2


31  

In rare cases it can be useful to change the line that is given by __LINE__ to something else. I've seen GNU configure does that for some tests to report appropriate line numbers after it inserted some voodoo between lines that do not appear in original source files. For example:

在极少数情况下,更改由__LINE__提供给其他内容的行是很有用的。我已经看到GNU configure做了一些测试来报告适当的行号,因为它插入了一些在原始源文件中没有出现的行。例如:

#line 100

Will make the following lines start with __LINE__ 100. You can optionally add a new file-name

下面的几行将从__LINE__ 100开始。您可以选择添加一个新的文件名称。

#line 100 "file.c"

It's only rarely useful. But if it is needed, there are no alternatives i know of. Actually, instead of the line, a macro can be used too which must result in any of the above two forms. Using the boost preprocessor library, you can increment the current line by 50:

只有很少有用。但如果需要的话,我知道没有其他选择。实际上,可以使用宏而不是行,它必须导致以上两种形式中的任何一种。使用boost预处理器库,可以将当前行增加50:

#line BOOST_PP_ADD(__LINE__, 50)

I thought it's useful to mention it, since you asked about usage of __LINE__ and __FILE__. One never gets enough surprises out of C++ :)

我觉得有必要提一下,因为你询问了__LINE__和__FILE__的用法。一个人永远不会从c++中得到足够的惊喜。

Edit: @Jonathan Leffler provides some more good use-cases in the comments:

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

Messing with #line is very useful for pre-processors that want to keep errors reported in the user's C code in line with the user's source file. Yacc, Lex, and (more at home to me) ESQL/C preprocessors do that.

对于想要将用户的C代码中报告的错误与用户的源文件相匹配的预处理程序来说,弄乱#行是非常有用的。Yacc, Lex,和(更多的是我的家)ESQL/C预处理器可以做到这一点。

#3


22  

FYI: g++ offers the non-standard __PRETTY_FUNCTION__ macro. Until just now I did not know about C99 __func__ (thanks Evan!). I think I still prefer __PRETTY_FUNCTION__ when it's available for the extra class scoping.

FYI: g++提供了非标准__PRETTY_FUNCTION__宏。直到现在我还不知道C99的功能(谢谢Evan!)我想我还是更喜欢__PRETTY_FUNCTION__,因为它可以用于额外的类范围。

PS:

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. */
}

#4


7  

Personally, I'm reluctant to use these for anything but debugging messages. I have done it, but I try not to show that kind of information to customers or end users. My customers are not engineers and are sometimes not computer savvy. I might log this info to the console, but, as I said, reluctantly except for debug builds or for internal tools. I suppose it does depend on the customer base you have, though.

就我个人而言,除了调试消息,我不太愿意使用它们。我已经做到了,但我尽量不向客户或终端用户展示这种信息。我的客户不是工程师,有时也不是电脑高手。我可能会将此信息记录到控制台,但是,正如我说的,除了调试构建或内部工具之外,不情愿。不过,我想这取决于你的客户群。

#5


4  

I use them all the time. The only thing I worry about is giving away IP in log files. If your function names are really good you might be making a trade secret easier to uncover. It's sort of like shipping with debug symbols, only more difficult to find things. In 99.999% of the cases nothing bad will come of it.

我一直在用它们。我唯一担心的是在日志文件中泄露IP。如果你的函数名真的很好,你可能会更容易发现一个商业秘密。这有点像用调试符号运输,只是更难找到东西。在99.999%的情况下,没有什么坏事会发生。

#1


145  

__FUNCTION__ is non standard, __func__ exists in C99 / C++11. The others (__LINE__ and __FILE__) are just fine.

__FUNCTION__是非标准的,__func__存在于C99 / c++ 11中。其他的(__LINE__和__FILE__)都很好。

It will always report the right file and line (and function if you choose to use __FUNCTION__/__func__). Optimization is a non-factor since it is a compile time macro expansion; it will never effect performance in any way.

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

#2


31  

In rare cases it can be useful to change the line that is given by __LINE__ to something else. I've seen GNU configure does that for some tests to report appropriate line numbers after it inserted some voodoo between lines that do not appear in original source files. For example:

在极少数情况下,更改由__LINE__提供给其他内容的行是很有用的。我已经看到GNU configure做了一些测试来报告适当的行号,因为它插入了一些在原始源文件中没有出现的行。例如:

#line 100

Will make the following lines start with __LINE__ 100. You can optionally add a new file-name

下面的几行将从__LINE__ 100开始。您可以选择添加一个新的文件名称。

#line 100 "file.c"

It's only rarely useful. But if it is needed, there are no alternatives i know of. Actually, instead of the line, a macro can be used too which must result in any of the above two forms. Using the boost preprocessor library, you can increment the current line by 50:

只有很少有用。但如果需要的话,我知道没有其他选择。实际上,可以使用宏而不是行,它必须导致以上两种形式中的任何一种。使用boost预处理器库,可以将当前行增加50:

#line BOOST_PP_ADD(__LINE__, 50)

I thought it's useful to mention it, since you asked about usage of __LINE__ and __FILE__. One never gets enough surprises out of C++ :)

我觉得有必要提一下,因为你询问了__LINE__和__FILE__的用法。一个人永远不会从c++中得到足够的惊喜。

Edit: @Jonathan Leffler provides some more good use-cases in the comments:

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

Messing with #line is very useful for pre-processors that want to keep errors reported in the user's C code in line with the user's source file. Yacc, Lex, and (more at home to me) ESQL/C preprocessors do that.

对于想要将用户的C代码中报告的错误与用户的源文件相匹配的预处理程序来说,弄乱#行是非常有用的。Yacc, Lex,和(更多的是我的家)ESQL/C预处理器可以做到这一点。

#3


22  

FYI: g++ offers the non-standard __PRETTY_FUNCTION__ macro. Until just now I did not know about C99 __func__ (thanks Evan!). I think I still prefer __PRETTY_FUNCTION__ when it's available for the extra class scoping.

FYI: g++提供了非标准__PRETTY_FUNCTION__宏。直到现在我还不知道C99的功能(谢谢Evan!)我想我还是更喜欢__PRETTY_FUNCTION__,因为它可以用于额外的类范围。

PS:

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. */
}

#4


7  

Personally, I'm reluctant to use these for anything but debugging messages. I have done it, but I try not to show that kind of information to customers or end users. My customers are not engineers and are sometimes not computer savvy. I might log this info to the console, but, as I said, reluctantly except for debug builds or for internal tools. I suppose it does depend on the customer base you have, though.

就我个人而言,除了调试消息,我不太愿意使用它们。我已经做到了,但我尽量不向客户或终端用户展示这种信息。我的客户不是工程师,有时也不是电脑高手。我可能会将此信息记录到控制台,但是,正如我说的,除了调试构建或内部工具之外,不情愿。不过,我想这取决于你的客户群。

#5


4  

I use them all the time. The only thing I worry about is giving away IP in log files. If your function names are really good you might be making a trade secret easier to uncover. It's sort of like shipping with debug symbols, only more difficult to find things. In 99.999% of the cases nothing bad will come of it.

我一直在用它们。我唯一担心的是在日志文件中泄露IP。如果你的函数名真的很好,你可能会更容易发现一个商业秘密。这有点像用调试符号运输,只是更难找到东西。在99.999%的情况下,没有什么坏事会发生。