I've noticed that g++ is smart enough to identify when a function is returning a pointer to a temporary/local variable, e.g.
int *foobar()
{
int a;
return &a;
}
Will result in:
warning: address of local variable ‘a’ returned
Is there a way that I can define a function prototype to only accept pointers that the compiler开发者_Python百科 can tell are not temporary. So lets say I have a function
barfoo(int *a_int);
Is there a way I can tell g++ to complain if someone passes a pointer to a local/temporary object into it? This would prohibit people from calling barfoo with invalid pointers and potentially save debugging some annoying issues.
Example:
void barfoo(int *a)
{
cerr << a << endl;
};
void foobar()
{
int a;
barfoo(&a);
}
I would like the compiler to complain about the `barfoo(&a)'.
You could instruct the compiler to flag that warning as an error. But beware of defining your problem incorrectly. A function that accepts a pointer to a local is valid use case:
int a;
...
do_something (&a);
printf ("%d\n", a);
I don't think there is any way to get the compiler to enforce it, but you can detect some instances earlier by using malloc_size.
void someFunc(int * mustBeHeap) {
assert(0!=malloc_size(mustBeHeap));
//do stuff
}
Unfortunately you will get false positives from code like this:
void someOtherFunc() {
int * myInts=(int *)malloc(sizeof(int)*20);
someFunc(&(myInts[3]));
}
It won't work too well with anything allocated with new, boost::pool, etc. In fact, you will get false positives from just about everything.
Also, malloc_size is non-standard.
Edit:
After looking at one of your comments above about taking ownership, it looks like some of the things I described as false positives are in fact situations you also want to detect since you intended to free the memory from the pointer.
No, it can be totally useful to do what you want to avoid there. GCC/G++ cannot guess that the function taking the reference/pointer will store it somewhere to later reuse, when the original caller of the function has already left the call-stack.
You might be able to get a compiler set up to treat warnings as errors (as you should anyway!), but I don't believe there's a way to do what you're asking aside from that.
You can tell gcc to treat warnings as errors with -Werror
option. Or make the specified warning as error -Werror=
. 3.8 Options to Request or Suppress Warnings.
In c++ you could write a "guaranteed heap pointer" template class that contains a single real pointer inside but has tightly restricted constructors such that the only way to create one was by new
. Overload enough operators, and you could have it behave almost like a naked pointer, except that it will have no conversion
from such a pointer.
(I have my doubts about whether that will be worth the trouble, though).
Never, ever, use raw pointers in C++ without a good reason. In this case, since you plan on taking ownership of the pointer, accept an object that reflects that. Either auto_ptr
\ unique_ptr
, if you want sole ownership, or shared_ptr
otherwise. If you aren't taking ownership, accept a (possibly const) reference.
精彩评论