Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以显式地告诉函数不接受指向非堆变量的指针吗?_C++_Compiler Construction_G++_Warnings - Fatal编程技术网

C++ 我可以显式地告诉函数不接受指向非堆变量的指针吗?

C++ 我可以显式地告诉函数不接受指向非堆变量的指针吗?,c++,compiler-construction,g++,warnings,C++,Compiler Construction,G++,Warnings,我注意到g++非常聪明,能够识别函数何时返回指向临时/局部变量的指针,例如 int *foobar() { int a; return &a; } 将导致: warning: address of local variable ‘a’ returned 有没有一种方法可以让我定义一个函数原型,只接受编译器可以判断为非临时的指针。假设我有一个函数 barfoo(int *a_int); 如果有人向g++传递指向本地/临时对象的指针,我有没有办法让g++抱怨

我注意到g++非常聪明,能够识别函数何时返回指向临时/局部变量的指针,例如

int *foobar()
{
      int a;
      return &a;
}
将导致:

 warning: address of local variable ‘a’ returned
有没有一种方法可以让我定义一个函数原型,只接受编译器可以判断为非临时的指针。假设我有一个函数

 barfoo(int *a_int);
如果有人向g++传递指向本地/临时对象的指针,我有没有办法让g++抱怨?这将禁止人们使用无效指针调用barfoo,并可能避免一些恼人的问题

例如:

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

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

cerr不,在那里做你想避免的事情是非常有用的。GCC/G++无法猜测当函数的原始调用方已经离开调用堆栈时,获取引用/指针的函数会将其存储在某个地方以供以后重用。

你可以告诉GCC使用
-Werror
选项将警告视为错误。或者他将警告指定为错误
-Werror=

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

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

您可能可以将编译器设置为将警告视为错误(无论如何,您应该这样做!),但除此之外,我认为没有其他方法可以实现您的要求。

我认为没有任何方法可以让编译器强制执行警告,但您可以通过使用malloc\u 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_尺寸是非标准尺寸

编辑:


在查看上面的一篇关于获取所有权的评论后,看起来我描述的一些假阳性的事实,实际上是你想检测的,因为你想从指针中释放内存。

永远,永远不要在C++中使用原始指针而没有一个好的理由。指针的臀部,接受一个反映该对象的对象。如果您想要独占所有权,或者“代码> > SyddYpPTR < /Cord>”,则不使用“<代码> AutoPyTP< <代码> \UnjyQPPT/<代码>。否则,如果您不拥有所有权,则接受(可能是永久的)引用。C++中的

< P>可以写一个“保证堆指针”。模板类,该类内部包含一个实指针,但具有严格限制的构造函数,因此创建一个实指针的唯一方法是通过
new
。重载足够多的运算符,可以使它的行为几乎像一个裸指针,只是它不会进行转换 从这样一个指针


(不过,我怀疑这是否值得麻烦)。

你不能获取临时变量的地址,所以这不是问题。有些情况下,将指针传递到局部变量是有效的。许多情况可以追溯到C语言,其中传递变量的一种方法是通过指针。@Dennis Zikefoose:这是什么:
void f(void){int a=0;int*pa=&a;*pa=25;return;}
。它接受一个临时变量的地址。所以你想只允许指向全局变量的指针吗?其他一切都是“临时的”,因为它可能在将来某个时候不再有效,要么因为它超出了范围,要么因为有人显式地释放了它。@Thomas,“临时的”是C++中的一个术语;它指的是由表达式生成的未知中间对象,而不是(或)被分配给命名的局部变量。它们与声明的局部变量不同。(但是,显然OP没有使用那个特殊的含义)。。问题是,如果我按照我所描述的做,编译器不会抱怨。让我用一个例子更新原始帖子。是的,可以,但我的情况不是这样。因此,我想告诉编译器,这样它就可以捕捉到人们在做。越来越近,感谢您的输入,唯一的问题是assert()我相信这是一个运行时检查。@是的,但通过这种方式,当调用函数而不是变量超出范围并且开始覆盖堆栈的一部分时,您可以检测到错误。很好!
malloc_size()
macos是唯一的吗?在linux上找不到任何关于它的信息。@我没有意识到,我以为它在所有版本的gcc中都有。这里有人说mallinfo可能是可用的。它在Windows上是msize。
malloc\u可用的\u大小()
-我认为它接近我们想要的,除了它对我来说是非堆变量上的SEGV。如果这是高可靠性和可移植性的,尽管它仍然比不确定的bug要好。感谢您的输入!有趣的评论..这些规则是出于对安全、性能、理解或什么的渴望吗?Unique\u ptr将用于实施e所有权,但无法实现我所要求的我不认为?@thehelix:安全性和IMENT的清晰性。通过要求
唯一性\u ptr
,您可以明确地告诉函数用户“我计划在此对象上调用delete”,以便他们传递其上的非堆内存。