检测C ++模板问题的工具

时间:2012-05-15 17:57:34

标签: c++ templates g++ static-analysis

我最近花了一些时间在我的C ++模板中搜索拼写错误。 g ++没有抱怨错字,所以我想知道是否有一种工具可以在将来检查这类问题?

这是一个演示正确编译的简化示例。我希望有关struct dummy的定义没有被定义,但似乎模板类goo隐藏了这一点。

foo.h中:

struct smart {
    int x, y, z;
};

template<typename T> class goo
{
    void barf(T* ptr){}
};

template<typename T> class foo 
{
public:
    foo(){};
private:
    goo<T> x;
};

class bar: public foo<struct dummy>
{
public:
    void do_something(struct smart& thing){}
};

Foo.cpp中:

#include "foo.h"

int main()
{
    bar a;
    struct smart b;
    a.do_something(b);
    return b.x+b.y+b.z;
}

使用g ++ foo.cpp成功编译

4 个答案:

答案 0 :(得分:3)

编译器,设置为最高警告级别,是检测任何C ++问题的最佳工具。

我给你的建议有两个方面:

1)将编译器警告级别设置为最高级别。这将抓住许多错误,低级别可能会保持沉默。

2)使用编码样式,当你做错事时更容易产生编译器错误。例如:

class bar: public foo<struct dummy>
{
public:
    void do_something(struct smart& thing){}
};

老实说,我不知道这段代码是否合法。我强烈怀疑没有,但看起来您确实宣布了一种新类型struct dummy。编译器接受它,所以我不确定它是否合法。

这样做会得到很好的服务:

class bar: public foo<dummy>
{
public:
    void do_something(struct smart& thing){}
};

现在永远不能将其解析为新的类型声明,编译器将拒绝它。这会早点发现你的问题。

答案 1 :(得分:2)

如果您没有使用模板类型参数(在您的示例中就是这种情况),代码就可以了,即使该类型不存在,或者您正在调用成员函数中的类型上的函数调用。这是以C ++的名义,如果你不使用它,你就不付钱(例如没有创建新的函数)。

答案 2 :(得分:2)

这是因为你使用struct dummy,如果没有这样的struct退出,编译器被告知自动生成一个前向声明结构。如果您只使用dummy而不使用struct,则不会这样做而且会抱怨。

答案 3 :(得分:0)

Attilla已经钉了这个;不需要dummy的定义 所以它可以保持不完整的类型。这非常有用 C / C ++的特性,因为它有助于信息隐藏和使用 减少编译时间。

例如:

// Afwd.h
class A;
A * getA ();
void processA(A *);
void printA (A *);


// t.cc
#include "Afwd.h"
void bar ()
{
  A * a = getA ();
  processA (a);
  printA (a);
}

此处,A的客户端无需查看其实施细节。这也具有以下优点:客户端不需要包含A

定义所需的标头

为了在原始示例中针对dummy生成错误,必须在此翻译单元中使用该定义。

首先,ptr需要以需要完整类型的方式使用,例如通过取消引用:

template<typename T> class goo
{
public:
    void barf(T* ptr){
      *ptr;           
    }
};

这仍然不是问题,因为函数barf未被调用,因此未实例化:

template<typename T> class foo 
{
public:
    foo(){
      x.barf (0);
    };
private:
    goo<T> x;
};

此代码现在生成错误。 bar的构造函数实例化并调用foo的定义,该定义实例化并调用barf