Sign in to follow this  
Dragon_Strike

safe function calls

Recommended Posts

i would like a some kind of function that would take a function pointer and several arguments then check if all (or just the first?) the arguments != NULL and then call the pointed function with those parameters... it would be nice to have it as general as possible... is that possible? it would be something like this SAFE_FUNCTION(SetValue, Pointer, Value); void SetValue(int* Pointer, Value) { *Pointer = Value; }

Share this post


Link to post
Share on other sites
If you are programming in C++, the solution is simple: don't use pointers. Use references instead: references cannot be null.

If you are restricted to using C, you could use assertions or Linus' trick:
void SetValue(int *dest, int src) {
assert(dest);
*dest = src;
}

void SetValue(int *dest, int src) {
if (!dest) return;
*dest = src;
}

Share this post


Link to post
Share on other sites
Yes. Use references.

Other way is:

template < class T >
class SafePtr
{
SafePtr(T * p)
{
if (p == NULL) throw // some exception
}

T * operator->() { return ptr; }
T & operator*() { return *ptr; }

private:
T * ptr;
};


Share this post


Link to post
Share on other sites
Quote:

If this is C++, use a reference. A reference cannot be NULL.



void Foo(int& a)
{
std::cout<<"This cannot be null(or can it?):"<<a<<std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
int* a;
a=NULL;
Foo(*a);
return 0;
}



Morale: C++ is fucked up.

Share this post


Link to post
Share on other sites
Quote:
Original post by mikeman
Quote:

If this is C++, use a reference. A reference cannot be NULL.


*** Source Snippet Removed ***

Morale: C++ is fucked up.


Well, the C++ language says that code has undefined behaviour. References cannot be NULL. That code is meaningless, it is certainly not standard C++.

Share this post


Link to post
Share on other sites
Quote:
Original post by mikeman
Morale: C++ is fucked up.


I'm pretty sure that a = NULL; *a; is also incorrect in C. The fact that C++ considers lvalues to be manipulable (in the form of reference variables) doesn't change anything about lvalues not being NULL in either C or C++.

Share this post


Link to post
Share on other sites
In theory you're all right of course, but in the real world bugs like that can(and most probably will) appear, and there's little you can do to defend against them. And protection against bugs is the primary reason we're using references anyway. My point was to show that references are far from bullet-proof. You certainly can't check a reference for nullity(well you can, but you shouldn't).

Share this post


Link to post
Share on other sites
Quote:
Original post by mikeman
In theory you're all right of course, but in the real world bugs like that can(and most probably will) appear, and there's little you can do to defend against them.


Use moar references! Seriously, the less naked pointers you have in your code, the fewer places you risk dereferencing a NULL one.

Share this post


Link to post
Share on other sites
Quote:
Original post by mikeman
Quote:

If this is C++, use a reference. A reference cannot be NULL.


*** Source Snippet Removed ***

Morale: C++ is fucked up.


Yes, this is why the advice was to use references, not pointers. This applies to rest of the code as well.

Make this code crash:
int a;
Foo(a);
return 0;



A general advice is the following:
- Allocate everything on stack, if at all possible
- If allocating on heap, try to provide only references to those objects, not pointers, otherwise give smart pointers or similar
- If parameter is a primitive type, pass it by value
- If value/contents of a parameter need to be modified, pass it by reference
- Everywhere else, pass it by const reference
- A method that shouldn't modify the contents of a class should be const

The const-correctness is very useful when working with references, since it allows compiler to detect unusual situations that could lead to internal state corruption.

Unfortunately, all these takes some time to get right and get used to, but once done, memory violations should become a thing of the past.

References do exactly the same thing as pointers, except that they don't allow ownership transfer. The only problematic issue remains ability to obtain the address of a reference and turn it into a pointer, but that again is a messy thing to do.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this