【问题标题】:C++ - style passing caller file and line to function (equivalent of __FILE__ and __LINE__)C++ - 将调用者文件和行传递给函数的样式(相当于 __FILE__ 和 __LINE__)
【发布时间】:2014-04-11 11:09:01
【问题描述】:

我知道,我的问题与此类似: Passing the caller __FILE__ __LINE__ to a function without using macro

但我想知道,为什么没有 C++ 等效的调用者文件和行传递给函数。

拥有类、模板、默认参数和更严格的 const 正确性使得很多宏的使用变得过时了,但是当我想将调用者文件和行传递给函数时,我会遇到麻烦,原因有两个: 1. 默认参数(很难用宏替换各种调用), 2. 宏打破类成员名称范围。 (startTimer 宏将是全局的)

考虑到函数的默认参数,为什么没有默认参数样式替换 FILELINE 宏?可以这样做:

void startTimer(int type, int id=0, string file = _CALLER_::FILE, int line = _CALLER_::LINE)

如果编译器在查找startTimer的函数调用时,可以将id参数替换为0,在没有提到的地方,应该可以将file和line替换为对应的CALLER成员,在此示例中取决于正在处理的文件以及进行调用的行 - 编译器在解析 cpp 文件时知道的内容。

知道成员函数的调用者可能对调试很有用——在哪个文件/行上调用了某些东西,这会导致以后出现问题。

【问题讨论】:

  • __FILE__ 不是宏。而且没有办法回答这个问题。 “为什么 C++ 没有 X 特性”的唯一答案是“因为你还没有向工作组提出它”。
  • @Lightness Races in Orbit:1. ISO C++ 2012 草案,16.8 预定义宏名称:“以下名称应由实现定义:[...] _ _ FILE _ _ [...]" 2. 通常有一个原因导致某些事情尚未被建议或接受,这会很有趣。
  • 您的问题可能受到 .NET 中最近的呼叫者信息功能的启发,参见。 msdn.microsoft.com/en-us/library/hh534540.aspx。它在 C# (CLR?) 中的实现基于属性。在 C/C++ 世界中类似的功能也许可以通过使用 pragma 来实现。但是,除了声明它们的效果是实现定义的声明之外,pragma 的语义不是由标准指定的。换句话说,它们的目的是专门与特定实现进行通信,而不是添加标准语言功能。
  • @PeterSchneider:哎呀,我当然想到了__function__。我的其余评论是有效的。顺便说一句,您应该引用标准,而不是草稿。

标签: c++ macros compiler-construction


【解决方案1】:

我认为拥有 可选 功能,即按照您建议的方式将其作为函数声明的一部分,并不容易或不可能。编译器必须在编译时插入所需的信息(因为文件和行信息在运行时丢失),但那时它可能根本不知道在虚拟成员函数的情况下将调用哪个函数,甚至以不可预知的方式分配的普通旧函数指针。

但也许有可能让所有函数接收两个隐藏的和未声明的参数,就像成员函数接收隐藏的this指针一样。在那种情况下,编译器不需要知道调用了哪个函数,因为 所有 函数都接收隐藏的调用者行和文件参数。

即使有可能,我也看到以下问题:

  1. 这显然是对 一个实现,可能是语言。 (我不知道 是否可以通过实现在幕后完成 它仍然声称符合今天的标准。)它将是 出于所有实际目的,在 C 语言中是不可能的,因为它会破坏 现有的 ABI(除非 Microsoft 这样做;-))。那将更少 C++ 中的问题,无论如何 ABI 兼容性要差得多。
  2. 这可能是一个性能问题,需要将两个参数传递给每个函数,尽管它们并不经常需要,甚至可能是微型(例如嵌入式)系统上的内存问题,因为堆栈会增长快点。 (当然你可以声称他们不应该从一开始就建立这么深的筹码,但仍然如此。)

如果您认为该功能现在以宏的形式可用(名称空间污染的唯一缺点是完全可以管理的),那么收益/工作量比根本不够好,这是我的猜测。

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2010-10-10
    • 2011-03-04
    • 1970-01-01
    相关资源
    最近更新 更多