我可以明确告诉函数不接受指向非堆变量的指针吗?

时间:2011-08-29 19:19:13

标签: c++ compiler-construction g++ warnings

我注意到g ++足够智能,可以识别函数何时返回指向临时/局部变量的指针,例如

int *foobar()
{
      int a;
      return &a;
}

将导致:

 warning: address of local variable ‘a’ returned

有没有办法可以定义一个函数原型,只接受编译器可以告诉的指针不是临时的。所以我要说我有一个功能

 barfoo(int *a_int);

如果有人将指向本地/临时对象的指针传递给它,有没有办法让g ++抱怨?这将禁止人们使用无效指针调用barfoo,并可能保存调试一些恼人的问题。

示例:

   void barfoo(int *a)
   {
        cerr << a << endl;
   };

   void foobar()
   {
        int a;
        barfoo(&a);
   }

我希望编译器抱怨`barfoo(&amp; a)'。

7 个答案:

答案 0 :(得分:1)

您可以指示编译器将该警告标记为错误。但要注意错误地定义您的问题。接受指向本地的指针的函数是有效的用例:

int a;
...
do_something (&a);
printf ("%d\n", a);

答案 1 :(得分:0)

不,做你想避免的事情是完全有用的。当函数的原始调用者已经离开调用堆栈时,GCC / G ++无法猜测带参考/指针的函数会将其存储在某个地方以便以后重用。

答案 2 :(得分:0)

您可以告诉gcc使用-Werror选项将警告视为错误。或者将指定的警告设为错误-Werror=3.8 Options to Request or Suppress Warnings

答案 3 :(得分:0)

你可能能够设置一个编译器来将警告视为错误(无论如何都应该这样!),但我不相信有办法做你要求的事情。

答案 4 :(得分:0)

我认为没有办法让编译器强制执行它,但你可以通过使用malloc_size来检测一些实例。

void someFunc(int * mustBeHeap) {
   assert(0!=malloc_size(mustBeHeap));
   //do stuff
}

不幸的是,你会从这样的代码中得到误报:

void someOtherFunc() {
    int * myInts=(int *)malloc(sizeof(int)*20);
    someFunc(&(myInts[3]));
}

对于使用new,boost :: pool等分配的任何东西都不能很好地工作。实际上,你会从几乎所有事情中得到误报。

此外,malloc_size是非标准的。

修改

在查看上述关于获取所有权的一条评论之后,看起来我所描述的一些误报实际上是您想要检测的情况,因为您打算从指针中释放内存。

答案 5 :(得分:0)

永远不要在没有充分理由的情况下在C ++中使用原始指针。在这种情况下,由于您计划取得指针的所有权,因此请接受反映该指针的对象。如果您想要独占所有权,请auto_ptr \ unique_ptr,否则为shared_ptr。如果您没有获得所有权,请接受(可能是const)参考。

答案 6 :(得分:0)

在c ++中,您可以编写一个“保证堆指针”模板类,其中包含一个真实的指针,但是具有严格限制的构造函数,因此创建一个的唯一方法是new。重载足够的运算符,你可以让它的行为几乎像一个裸指针,除了它没有转换 来自这样的指针。

(我怀疑这是否值得这么麻烦)。