C++ 中的 __FILE__、__LINE__ 和 __FUNCTION__ 用法
假设您的 C++ 编译器支持它们,是否有任何特殊原因不使用 __FILE__
、__LINE__
和 __FUNCTION__
记录和调试目的?
我主要关心的是向用户提供误导性数据,例如,由于优化而报告错误的行号或函数,或者导致性能下降。
基本上,我可以相信 __FILE__
、__LINE__
和 __FUNCTION__
能够始终做正确的事情吗?
Presuming that your C++ compiler supports them, is there any particular reason not to use __FILE__
, __LINE__
and __FUNCTION__
for logging and debugging purposes?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
__FUNCTION__
是非标准的,__func__
存在于 C99 / C++11 中。 其他的(__LINE__
和__FILE__
)都很好。它将始终报告正确的文件和行(如果您选择使用 __FUNCTION__ /
__func__
,则报告正确的文件和行)。 优化不是一个因素,因为它是编译时宏扩展; 它绝不会以任何方式影响性能。__FUNCTION__
is non standard,__func__
exists in C99 / C++11. The others (__LINE__
and__FILE__
) are just fine.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 affect performance in any way.在极少数情况下,将 __LINE__ 给出的行更改为其他内容可能会很有用。 我见过 GNU configure 在某些测试中这样做,在原始源文件中未出现的行之间插入一些巫术后报告适当的行号。 例如:
将使以下行以
__LINE__
100 开头。您可以选择添加新文件名。这很少有用。 但如果需要的话,据我所知没有其他选择。 实际上,也可以使用宏来代替行,它必须导致上述两种形式中的任何一种。 使用 boost 预处理器库,您可以将当前行增加 50:
我认为提及它很有用,因为您询问了
__LINE__
和__FILE__
的用法。 人们永远不会从 C++ 中获得足够的惊喜:)编辑: @Jonathan Leffler 在评论中提供了一些更好的用例:
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:Will make the following lines start with
__LINE__
100. You can optionally add a new file-nameIt'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:
I thought it's useful to mention it since you asked about the usage of
__LINE__
and__FILE__
. One never gets enough surprises out of C++ :)Edit: @Jonathan Leffler provides some more good use-cases in the comments:
C++20
std::source_location
C++ 终于添加了非宏选项,当 C++20 广泛普及时,它可能会在未来某个时刻占据主导地位:
文档说:
其中 NTBS 表示“空终止字节字符串”。
该功能存在于带有
-std=c++20
的 GCC 11.2 Ubuntu 21.10 上。 它不在带有g++-9 -std=c++2a
的 GCC 9.1.0 上。https://en.cppreference.com/w/cpp/utility/source_location 显示用法为:
main.cpp
编译并运行:
输出:
__PRETTY_FUNCTION__
vs__FUNCTION__
vs__func__
vsstd:: source_location::function_name
回答于:__PRETTY_FUNCTION__、__FUNCTION__、__func__ 之间有什么区别?
C++20
std::source_location
C++ has finally added a non-macro option, and it will likely dominate at some point in the future when C++20 becomes widespread:
The documentation says:
where NTBS means "Null Terminated Byte String".
The feature is present on GCC 11.2 Ubuntu 21.10 with
-std=c++20
. It was not on GCC 9.1.0 withg++-9 -std=c++2a
.https://en.cppreference.com/w/cpp/utility/source_location shows usage is:
main.cpp
Compile and run:
Output:
__PRETTY_FUNCTION__
vs__FUNCTION__
vs__func__
vsstd::source_location::function_name
Answered at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
仅供参考:g++ 提供非标准 __PRETTY_FUNCTION__ 宏。 直到现在我还不知道 C99 __func__ (谢谢 Evan!)。 我想我仍然更喜欢 __PRETTY_FUNCTION__ 当它可用于额外的类范围时。
附:
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.
PS:
就我个人而言,除了调试消息之外,我不愿意将它们用于任何其他用途。 我已经做到了,但我尽量不向客户或最终用户展示此类信息。 我的客户不是工程师,有时也不懂计算机。 我可能会将此信息记录到控制台,但是,正如我所说,除了调试版本或内部工具之外,我很不情愿地记录这些信息。 不过,我认为这确实取决于您拥有的客户群。
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.
我一直在使用它们。 我唯一担心的是在日志文件中泄露IP。 如果你的函数名称真的很好,你可能会让商业秘密更容易被发现。 这有点像附带调试符号,只是更难找到东西。 99.999% 的情况下不会有什么不好的结果。
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.