【问题标题】:Is there a template debugger?有模板调试器吗?
【发布时间】:2014-12-09 13:28:32
【问题描述】:

模板本身可以是程序。

是否有模板调试器,以便您可以单步执行模板的“执行”?

这基本上必须是在编译/链接/代码生成期间完成的事情 - 并且与调试生成的程序不同。

即使在许多不能使用调试器的“原始”环境中,通常也可以进行“printf 调试”。模板也能做到吗?

edit:另一种思考方式是类似于 C 预处理器。生成“预处理”源代码(编译器实际编译的预处理器的输出)通常非常有用,这可以让您了解宏的效果。等效的模板会很棒 - 让编译器输出与模板化输入对应的非模板源代码。我想你能得到的最接近的是 C++ 到 C 的翻译器。 (comeau 编译器不这样做吗?)

【问题讨论】:

  • 有一些工具,但我没有尝试过,所以我真的不知道他们做了什么或者他们做得如何。您可以查看TempLightmetashell
  • 我无法回答“单步执行”模板编译的问题,但就“printf 样式调试”而言,您可以使用预处理器指令将自定义 cmets 或警告打印到构建输出。 stackoverflow.com/questions/3826832/…
  • 不真正相关:类型推导出来之后,您可以使用typeid 来获取它的(损坏的)名称。
  • @black 可能并不总是像 argued here 那样是个好主意
  • black:是的,我已经做到了。不同的编译器也有不同的方式来提供 de-mangled 名称。 (关于 C++ 标准的普遍抱怨:该标准几乎没有考虑到可调试性 - 例如,应该有一个标准定义的方法来获取解构名称)。这种技术和其他技术要求您编辑源代码,猜测编译期间发生的事情,以便正确选择在何处插入错误或 typeid() 内容。

标签: c++ template-meta-programming


【解决方案1】:

您可能想查看输出模板实例化的this patch for clang

另一个简单的工具是编译器在尝试实例化未定义模板时产生的错误消息。

template< typename > struct TD;

template< typename T >
void your_template_function( T & param )
{
    // Both of these produce an error about "undefined type TD< T > with T = ..."
    TD< T > test1;
    TD< decltype( param ) > test2;
}

Scott Meyers CPPCon talk 对此进行了解释,就在环尾狐猴幻灯片之后。

【讨论】:

    【解决方案2】:

    在过去几年的 c++ 会议上,有一个关于该主题的讨论。您可以在这里找到一些信息:

    http://gsd.web.elte.hu/contents/articles/gpce06.pdf

    http://patakino.web.elte.hu/ECOOP_Templight_Poster.pdf

    我不知道这些东西现在有多实用,但这是一个非常有趣的起点。

    我个人给我写了一些帮助类,它们能够打印给定类型,例如标准代码的 printf 调试。如果编译失败,它通常会在调用 DebugPrinter 时给出一个很好的错误消息,如果程序编译但结果非常愚蠢,因为类型扩展不是我所期望的,DebugPrinter 对我有很大帮助!

        template< typename T>
    int DebugPrintArgs( T arg )
    {
        std::cout << arg  << ", ";
        return 0;
    }
    
    template <typename Head, typename ... T>
    class DebugPrinter: public DebugPrinter<T...>
    {
        public:
            DebugPrinter()
            {
                std::cout << "--------------------------" << std::endl;
                std::cout << __PRETTY_FUNCTION__ << std::endl;
                std::cout << "--------------------------" << std::endl;
            }
    
            template< typename ...Y>
                DebugPrinter( Y ... rest )
                {
                    std::cout << "Construction of: " << __PRETTY_FUNCTION__ << " Values: " ;
                    ExpandWithConstructor{DebugPrintArgs( rest)...};
                    std::cout << std::endl;
                }
    
    };
    
    
    template <typename Head>
    class DebugPrinter< Head >
    {
        public:
            DebugPrinter()
            {
                std::cout << "--------------------------" << std::endl;
                std::cout << __PRETTY_FUNCTION__ << std::endl;
                std::cout << "--------------------------" << std::endl;
            }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多