My question is simple: What are void pointers for in C++? (Those things you declare with void* myptr;)
What is their use? Can I make them point to a variable of any type?
Basically, a remnant from C.
What is their use?
In C, they were and are used widely, but in C++ I think they are very rarely, if ever, needed, since we have polymorphism, templates etc. which provide a much cleaner and safer way to solve the same problems where in C one would use void pointers.
Can I make them point to a variable of any type?
Yes. However, as others have pointed out, you can't use a void pointer directly - you have to cast it into a pointer to a concrete data type first.
Yes, this is a C construct (not C++-specific) that allows you to declare a pointer variable that points to any type. You can't really do much of anything with such a pointer except cast it back to the real object that it actually points to. In modern C++, void* has pretty much gone out of fashion, yielding in many cases to template-based generic code.
About one of the few uses that exist for void pointers in C++ is their use in overloading the new operators. All new operators return type void* by definition. Other than that, what others have said is true.
From cplusplus.com:
The void type of pointer is a special
type of pointer. In C++, void
represents the absence of type, so
void pointers are pointers that point
to a value that has no type (and thus
also an undetermined length and
undetermined dereference properties).
This allows void pointers to point to
any data type, from an integer value
or a float to a string of characters.
But in exchange they have a great
limitation: the data pointed by them
cannot be directly dereferenced (which
is logical, since we have no type to
dereference to), and for that reason
we will always have to cast the
address in the void pointer to some
other pointer type that points to a
concrete data type before
dereferencing it.
Type hiding. It does still have its valid uses in modern C++. Dig through the source code in boost and you'll find a few. Generally the use of a void* is buried very deep within the bowels of a more complex construct that ensures the type safety of the interface while doing black and evil magic within.
They did once in C perform the job of being the pointer-to-anything, a pointer you passed in to libraries and they gave back out to you as userdata. A void* is no use at all without the programmer knowing their context in some fashion, since you don't know what's on the other end, you can't do anything with the data. Except pass the pointer to some other code that does know.
What I don't understand is why people didn't just use undefined types, i.e. opaque pointers. Type safety, user data.
In modern C++, the pointer-to-void is nearly entirely superseded by polymorphism and template-generated generic code. However, you may still have to use them to interface with native C code. To use a void* safely, in any given context, only ever cast one type to a void*. That way, you know for sure what it points to. If you need more types, you could do a quick
struct safevoidptr {
base* ptr
}; or struct safevoidptr { void* ptr; int type; };
I believe that dynamic_cast might also be able to convert void* to polymorphic types, although I have never used dynamic_cast, so don't take my word for it.
A void pointer can point to anything, as long as its memory :-)
The C standard states that you can convert any pointer to a void-pointer, then cast it back without losing anything.
A pointer to void is the closest concept to an assembly language pointer. It is a generic pointer that reserves space for an address or location of something (function or datum). As others have stated, it must be cast before it can be dereferenced.
The void pointer is a popular tool for representing Object Orient concepts in the C language. One issue with the void pointer is that the content may not match the receiver's perception. If the caller sets the pointer to point to a square, but the receiving function is expecting a pointer to a cat, undefined and strange things will happen with the pointer is cast.
Since there are already so many good answers, I'd just provide one of the more common one I saw: template specialization. If I don't recall wrongly, Stroustrup book has an example of this: specializing vector as vector, then having vector to derive (privately) from vector. This way, vector will only contain straightforward easily inlined codes (i.e. call relevant functions from vector). This will reduce the number of duplication when vector is compiled in a program that uses it with many different types of pointers.
void ptr is basically an empty box. Fill it with whatever you want but make sure you label it(tupecasting)
I use them in my dynamic lists to hold more types of objects (all are pointers).
typedef void* Object;
Then when you declare a Object variable you can store any pointer in it.
It's more or less usefull depending on the needs.
I find it very usefull when you have to store any pointer somewhere and you can't just derive all your classes from just one. Other than that as the others said it's better to use templates, polimorphism etc.
Things you could do in C with void, but can't in C++ :
void*'s are automatically converted to other pointer types. (You know its a void* - you gain no type safety from forcing an explicit cast)
Struct* p = malloc( sizeof(Struct) );
// vs C++
Struct* p = (Struct*)malloc( sizeof(Struct) );
// Some will argue that that cast style is deprecated too, and c++ programmers
// need to actually do this:
Struct* p = reinterpret_cast<Struct*>malloc( sizeof(Struct) );
// See what C++ did there? By making you write Struct a 3rd time, you can now be sure
// you know what you are doing!
void*'s also did indirection counting in C, allowing greater safety when passing pointers to functions that take a pointer to a pointer.
void funcInitializingOutPtr( void** ppOut)
{
*ppOut = malloc( x );
}
int* out = NULL;
funcInitializingPtr(out); // C would signal this as an error
funcInitializingPtr(&out); // correct
// vs C++
funcInitializingPtr( (void**)&out ); // so much safer needing that exlicit cast.
funcInitializingPtr( (void**)out); // oops. thanks C++ for hiding the common error
I belive void* is memory location where you can typecast/Store anything. I some Language Pundit will disagree on this with me. but i have used it successfully in many of my project.
Only problem i see is of typesafety
Related
I recently read an article which said it's not necessary in C to explicitly typecast malloc and calloc but in C++ it is mandatory. Why is it so? Can anyone explain?
Because in C it is very often you need to use void * for various cases. Some of them is a cookie for a callback - when you provide pointer to user data and you do not have a way to know that data type. Or generic functions like qsort() they have to work with various data without knowing their type in advance. In C++ though you do not need to use void * as often, and in good safe code you do not need to use them at all because you have templates so you write generic code using unknown types without unsafe conversions. So creators of C++ wanted to stimulate proper usage of data types and make sure when developer doing unsafe operations he/she/it/they understands what he/she/it/they is doing.
As malloc() and calloc() return void * you have to convert them explicitly in C++. Note that you are not suppose to use them in C++, but use operator new instead - which returns proper pointer type already and you do not need cast. And even further in modern C++ it is not recommended to even call new directly.
In C, it's given T *tp; U *up; void *vp;, one can say vp = tp; up = vp; and end up with a U* which holds the address of a T, without using any casting operators. The designers of C++, however, wanted to ensure that such a thing couldn't happen without using at least one explicit casting operator somewhere along the way. In most cases, requiring the casting operator to be used between the time the pointer is represented as a void* and the time it's actually used is less of a nuisance than requiring a casting operator when a pointer is converted to void*, that's what C++ does. Neither C or C++ allows any syntactic distinction between a void* which was produced by converting the address of an object with a real type, however, versus one that is used to hold the address of a blob of storage with no type, and thus has no way of allowing the latter to be implicitly converted to any type (which would be useful) without doing likewise with the former (which the designers of C++ didn't want).
I had always thought that checking the pointer after casting a void* to a struct* was a valid way to avoid invalid casts. Something like
MyStructOne* pStructOne = (MyStructOne*)someVoidPointer;
if(!pStructOne)
return 0;
It appears that this is not the case as I can cast the same data to two different structs and get the same valid address. The program is then happy to populate my struct fields with whatever random data is in there.
What is a safe way of casting struct pointers?
I can't use dynamic_cast<> as it's not a class.
Thanks for the help!
If you have any control over the struct layout you can put your own type enumeration at the front of every struct to verify the type. This works in both C and C++.
If you can't use an enumeration because not all types are known ahead of time, you can use a GUID. Or a pointer to static variable or member that is unique per struct.
You can use dynamic_cast with structs or classes, as long as it has a virtual method. I would suggest you redesign your broader system to not have void*s anywhere. It's very bad practice/design.
There is no "safe way of casting" in general, because casting pointers is inherently an unsafe procedure. Casting says that you know better than the type system, so you can't expect the type system to be of any help after you started casting pointers.
In C++, you should never use C-style casts (like (T) x), and instead use the C++ casts. Now a few simple rules let you determine whether casting a pointer or reference is OK:
If you const_cast in the bad direction and modify the object, you must be sure that the object is actually mutable.
You can only static_cast pointers or references within a polymorphic hierarchy or from/to void pointer. You must be sure that the dynamic type of the object is a subtype of the cast target, or in the case of void pointers that pointer is the address of an object of the correct type.
reinterpret_cast should only be used to or from a char * type (possibly signed or unsigned), or to convert a pointer to and from an (u)intptr_t.
In every case, it is your responsibility to ensure that the pointers or references in question refer to an object of the type that you claim in the cast. There is no check that anyone else can do for you to verify this.
The (C-style) cast you are using is compile-time operation - that is to say that the compiler generates instructions to modify the pointer to one thing so that it points to another.
With inheritance relationships, this is simply addition or subtraction from the pointer.
In the case of your code, the compiler generates precisely no code whatsoever. The cast merely serves to tell the compiler that you know what you're doing.
The compiler does not generate any code that checks the validity of your operation. If someVoidPointer is null, so will be pStructOne after the cast. \
Using a dynamic_cast<>() doesn't validate that the thing being casted is actually an object at all - it merely tells you that an object with RTTI is (or can be converted to) the type you expect. If it's not an object to start with, you'll most likely get a crash.
There isn't one. And frankly, there can't be.
struct is simply an instruction for the compiler to treat the next sizeof() bytes in a particular semantic fashion - nothing less, nothing more.
You can cast any pointer into any pointer - all that changes is how the compiler would interpret the contents.
Using dynamic_cast<> is the only way, but it invokes RTTI (run type type information) to consider the potential legality of the assignment. Yeah, it's no longer an reinterpret_cast<>
It sounds like you want to make sure the object passed as a void* to your function is really the type you expect. The best approach would be to declare the function prototype with MyStructOne* instead of void* and let the compiler do the type checking.
If you really are trying to do something more dynamic (as in different types of objects can be passed to your function) you need to enable RTTI. This will allow you to interrogate the passed in object and ask it what type it is.
What is a safe way of casting struct pointers?
First, try to avoid needing to do this in the first place. Use forward declarations for structs if you don't want to include their headers. In general, you should only need to hide the data type from the signature if a function could take multiple types of data. The example for something like that is a message passing system, where you want to be able to pass arbitrary data. The sender and receiver know what types they expect, but the message system itself doesn't need to know.
Assuming you have no other alternatives, use a boost::any. This is essentially a type-safe void*; attempts to cast it to the wrong type will throw an exception. Note that this needs RTTI to work (which you generally should have available).
Note that boost::variant is a possibility if there is a fixed, limited set of possible types that can be used.
Since you have to use void*, your options are:
create a single base class including a virtual destructor (and/or other virtual methods) and use that exclusively across the libev interface. Wrap the libev interface to enforce this, and only use the wrappers from your C++ code. Then, inside your C++ code, you can dynamic_cast your base class.
accept that you don't have any runtime information about what type your void* really points to, and just structure your code so you always know statically. That is, make sure you cast to the correct type in the first place.
use the void* to store a simple tag/cookie/id structure, and use that to look up your real struct or whatever - this is really just a more manual version of #1 though, and incurs an extra indirection to boot.
And the direct answer to
What is a safe way of casting struct pointers?
is:
cast to the correct type, or a type you know to be layout compatible.
There just isn't any substitute for knowing statically what the correct type is. You presumably passed something in as a void*, so when you get that void* back you should be able to know what type it was.
I understand the syntax and general semantics of pointers versus references, but how should I decide when it is more-or-less appropriate to use references or pointers in an API?
Naturally some situations need one or the other (operator++ needs a reference argument), but in general I'm finding I prefer to use pointers (and const pointers) as the syntax is clear that the variables are being passed destructively.
E.g. in the following code:
void add_one(int& n) { n += 1; }
void add_one(int* const n) { *n += 1; }
int main() {
int a = 0;
add_one(a); // Not clear that a may be modified
add_one(&a); // 'a' is clearly being passed destructively
}
With the pointer, it's always (more) obvious what's going on, so for APIs and the like where clarity is a big concern are pointers not more appropriate than references? Does that mean references should only be used when necessary (e.g. operator++)? Are there any performance concerns with one or the other?
EDIT (OUTDATED):
Besides allowing NULL values and dealing with raw arrays, it seems the choice comes down to personal preference. I've accepted the answer below that references Google's C++ Style Guide, as they present the view that "References can be confusing, as they have value syntax but pointer semantics.".
Due to the additional work required to sanitise pointer arguments that should not be NULL (e.g. add_one(0) will call the pointer version and break during runtime), it makes sense from a maintainability perspective to use references where an object MUST be present, though it is a shame to lose the syntactic clarity.
Use reference wherever you can, pointers wherever you must.
Avoid pointers until you can't.
The reason is that pointers make things harder to follow/read, less safe and far more dangerous manipulations than any other constructs.
So the rule of thumb is to use pointers only if there is no other choice.
For example, returning a pointer to an object is a valid option when the function can return nullptr in some cases and it is assumed it will. That said, a better option would be to use something similar to std::optional (requires C++17; before that, there's boost::optional).
Another example is to use pointers to raw memory for specific memory manipulations. That should be hidden and localized in very narrow parts of the code, to help limit the dangerous parts of the whole code base.
In your example, there is no point in using a pointer as argument because:
if you provide nullptr as the argument, you're going in undefined-behaviour-land;
the reference attribute version doesn't allow (without easy to spot tricks) the problem with 1.
the reference attribute version is simpler to understand for the user: you have to provide a valid object, not something that could be null.
If the behaviour of the function would have to work with or without a given object, then using a pointer as attribute suggests that you can pass nullptr as the argument and it is fine for the function. That's kind of a contract between the user and the implementation.
The performances are exactly the same, as references are implemented internally as pointers. Thus you do not need to worry about that.
There is no generally accepted convention regarding when to use references and pointers. In a few cases you have to return or accept references (copy constructor, for instance), but other than that you are free to do as you wish. A rather common convention I've encountered is to use references when the parameter must refer an existing object and pointers when a NULL value is ok.
Some coding convention (like Google's) prescribe that one should always use pointers, or const references, because references have a bit of unclear-syntax: they have reference behaviour but value syntax.
From C++ FAQ Lite -
Use references when you can, and pointers when you have to.
References are usually preferred over pointers whenever you don't need
"reseating". This usually means that references are most useful in a
class's public interface. References typically appear on the skin of
an object, and pointers on the inside.
The exception to the above is where a function's parameter or return
value needs a "sentinel" reference — a reference that does not refer
to an object. This is usually best done by returning/taking a pointer,
and giving the NULL pointer this special significance (references must
always alias objects, not a dereferenced NULL pointer).
Note: Old line C programmers sometimes don't like references since
they provide reference semantics that isn't explicit in the caller's
code. After some C++ experience, however, one quickly realizes this is
a form of information hiding, which is an asset rather than a
liability. E.g., programmers should write code in the language of the
problem rather than the language of the machine.
My rule of thumb is:
Use pointers for outgoing or in/out parameters. So it can be seen that the value is going to be changed. (You must use &)
Use pointers if NULL parameter is acceptable value. (Make sure it's const if it's an incoming parameter)
Use references for incoming parameter if it cannot be NULL and is not a primitive type (const T&).
Use pointers or smart pointers when returning a newly created object.
Use pointers or smart pointers as struct or class members instead of references.
Use references for aliasing (eg. int ¤t = someArray[i])
Regardless which one you use, don't forget to document your functions and the meaning of their parameters if they are not obvious.
Disclaimer: other than the fact that references cannot be NULL nor "rebound" (meaning thay can't change the object they're the alias of), it really comes down to a matter of taste, so I'm not going to say "this is better".
That said, I disagree with your last statement in the post, in that I don't think the code loses clarity with references. In your example,
add_one(&a);
might be clearer than
add_one(a);
since you know that most likely the value of a is going to change. On the other hand though, the signature of the function
void add_one(int* const n);
is somewhat not clear either: is n going to be a single integer or an array? Sometimes you only have access to (poorly documentated) headers, and signatures like
foo(int* const a, int b);
are not easy to interpret at first sight.
Imho, references are as good as pointers when no (re)allocation nor rebinding (in the sense explained before) is needed. Moreover, if a developer only uses pointers for arrays, functions signatures are somewhat less ambiguous. Not to mention the fact that operators syntax is way more readable with references.
Like others already answered: Always use references, unless the variable being NULL/nullptr is really a valid state.
John Carmack's viewpoint on the subject is similar:
NULL pointers are the biggest problem in C/C++, at least in our code. The dual use of a single value as both a flag and an address causes an incredible number of fatal issues. C++ references should be favored over pointers whenever possible; while a reference is “really” just a pointer, it has the implicit contract of being not-NULL. Perform NULL checks when pointers are turned into references, then you can ignore the issue thereafter.
http://www.altdevblogaday.com/2011/12/24/static-code-analysis/
Edit 2012-03-13
User Bret Kuhns rightly remarks:
The C++11 standard has been finalized. I think it's time in this thread to mention that most code should do perfectly fine with a combination of references, shared_ptr, and unique_ptr.
True enough, but the question still remains, even when replacing raw pointers with smart pointers.
For example, both std::unique_ptr and std::shared_ptr can be constructed as "empty" pointers through their default constructor:
http://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr
http://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
... meaning that using them without verifying they are not empty risks a crash, which is exactly what J. Carmack's discussion is all about.
And then, we have the amusing problem of "how do we pass a smart pointer as a function parameter?"
Jon's answer for the question C++ - passing references to boost::shared_ptr, and the following comments show that even then, passing a smart pointer by copy or by reference is not as clear cut as one would like (I favor myself the "by-reference" by default, but I could be wrong).
It is not a matter of taste. Here are some definitive rules.
If you want to refer to a statically declared variable within the scope in which it was declared then use a C++ reference, and it will be perfectly safe. The same applies to a statically declared smart pointer. Passing parameters by reference is an example of this usage.
If you want to refer to anything from a scope that is wider than the scope in which it is declared then you should use a reference counted smart pointer for it to be perfectly safe.
You can refer to an element of a collection with a reference for syntactic convenience, but it is not safe; the element can be deleted at anytime.
To safely hold a reference to an element of a collection you must use a reference counted smart pointer.
There is problem with "use references wherever possible" rule and it arises if you want to keep reference for further use. To illustrate this with example, imagine you have following classes.
class SimCard
{
public:
explicit SimCard(int id):
m_id(id)
{
}
int getId() const
{
return m_id;
}
private:
int m_id;
};
class RefPhone
{
public:
explicit RefPhone(const SimCard & card):
m_card(card)
{
}
int getSimId()
{
return m_card.getId();
}
private:
const SimCard & m_card;
};
At first it may seem to be a good idea to have parameter in RefPhone(const SimCard & card) constructor passed by a reference, because it prevents passing wrong/null pointers to the constructor. It somehow encourages allocation of variables on stack and taking benefits from RAII.
PtrPhone nullPhone(0); //this will not happen that easily
SimCard * cardPtr = new SimCard(666); //evil pointer
delete cardPtr; //muahaha
PtrPhone uninitPhone(cardPtr); //this will not happen that easily
But then temporaries come to destroy your happy world.
RefPhone tempPhone(SimCard(666)); //evil temporary
//function referring to destroyed object
tempPhone.getSimId(); //this can happen
So if you blindly stick to references you trade off possibility of passing invalid pointers for the possibility of storing references to destroyed objects, which has basically same effect.
edit: Note that I sticked to the rule "Use reference wherever you can, pointers wherever you must. Avoid pointers until you can't." from the most upvoted and accepted answer (other answers also suggest so). Though it should be obvious, example is not to show that references as such are bad. They can be misused however, just like pointers and they can bring their own threats to the code.
There are following differences between pointers and references.
When it comes to passing variables, pass by reference looks like pass by value, but has pointer semantics (acts like pointer).
Reference can not be directly initialized to 0 (null).
Reference (reference, not referenced object) can not be modified (equivalent to "* const" pointer).
const reference can accept temporary parameter.
Local const references prolong the lifetime of temporary objects
Taking those into account my current rules are as follows.
Use references for parameters that will be used locally within a function scope.
Use pointers when 0 (null) is acceptable parameter value or you need to store parameter for further use. If 0 (null) is acceptable I am adding "_n" suffix to parameter, use guarded pointer (like QPointer in Qt) or just document it. You can also use smart pointers. You have to be even more careful with shared pointers than with normal pointers (otherwise you can end up with by design memory leaks and responsibility mess).
Any performance difference would be so small that it wouldn't justify using the approach that's less clear.
First, one case that wasn't mentioned where references are generally superior is const references. For non-simple types, passing a const reference avoids creating a temporary and doesn't cause the confusion you're concerned about (because the value isn't modified). Here, forcing a person to pass a pointer causes the very confusion you're worried about, as seeing the address taken and passed to a function might make you think the value changed.
In any event, I basically agree with you. I don't like functions taking references to modify their value when it's not very obvious that this is what the function is doing. I too prefer to use pointers in that case.
When you need to return a value in a complex type, I tend to prefer references. For example:
bool GetFooArray(array &foo); // my preference
bool GetFooArray(array *foo); // alternative
Here, the function name makes it clear that you're getting information back in an array. So there's no confusion.
The main advantages of references are that they always contain a valid value, are cleaner than pointers, and support polymorphism without needing any extra syntax. If none of these advantages apply, there is no reason to prefer a reference over a pointer.
Copied from wiki-
A consequence of this is that in many implementations, operating on a variable with automatic or static lifetime through a reference, although syntactically similar to accessing it directly, can involve hidden dereference operations that are costly. References are a syntactically controversial feature of C++ because they obscure an identifier's level of indirection; that is, unlike C code where pointers usually stand out syntactically, in a large block of C++ code it may not be immediately obvious if the object being accessed is defined as a local or global variable or whether it is a reference (implicit pointer) to some other location, especially if the code mixes references and pointers. This aspect can make poorly written C++ code harder to read and debug (see Aliasing).
I agree 100% with this, and this is why I believe that you should only use a reference when you a have very good reason for doing so.
Points to keep in mind:
Pointers can be NULL, references cannot be NULL.
References are easier to use, const can be used for a reference when we don't want to change value and just need a reference in a function.
Pointer used with a * while references used with a &.
Use pointers when pointer arithmetic operation are required.
You can have pointers to a void type int a=5; void *p = &a; but cannot have a reference to a void type.
Pointer Vs Reference
void fun(int *a)
{
cout<<a<<'\n'; // address of a = 0x7fff79f83eac
cout<<*a<<'\n'; // value at a = 5
cout<<a+1<<'\n'; // address of a increment by 4 bytes(int) = 0x7fff79f83eb0
cout<<*(a+1)<<'\n'; // value here is by default = 0
}
void fun(int &a)
{
cout<<a<<'\n'; // reference of original a passed a = 5
}
int a=5;
fun(&a);
fun(a);
Verdict when to use what
Pointer: For array, linklist, tree implementations and pointer arithmetic.
Reference: In function parameters and return types.
The following are some guidelines.
A function uses passed data without modifying it:
If the data object is small, such as a built-in data type or a small structure, pass it by value.
If the data object is an array, use a pointer because that’s your only choice. Make the pointer a pointer to const.
If the data object is a good-sized structure, use a const pointer or a const
reference to increase program efficiency.You save the time and space needed to
copy a structure or a class design. Make the pointer or reference const.
If the data object is a class object, use a const reference.The semantics of class design often require using a reference, which is the main reason C++ added
this feature.Thus, the standard way to pass class object arguments is by reference.
A function modifies data in the calling function:
1.If the data object is a built-in data type, use a pointer. If you spot code
like fixit(&x), where x is an int, it’s pretty clear that this function intends to modify x.
2.If the data object is an array, use your only choice: a pointer.
3.If the data object is a structure, use a reference or a pointer.
4.If the data object is a class object, use a reference.
Of course, these are just guidelines, and there might be reasons for making different
choices. For example, cin uses references for basic types so that you can use cin >> n
instead of cin >> &n.
Your properly written example should look like
void add_one(int& n) { n += 1; }
void add_one(int* const n)
{
if (n)
*n += 1;
}
That's why references are preferable if possible
...
References are cleaner and easier to use, and they do a better job of hiding information.
References cannot be reassigned, however.
If you need to point first to one object and then to another, you must use a pointer. References cannot be null, so if any chance exists that the object in question might be null, you must not use a reference. You must use a pointer.
If you want to handle object manipulation on your own i.e if you want to allocate memory space for an object on the Heap rather on the Stack you must use Pointer
int *pInt = new int; // allocates *pInt on the Heap
In my practice I personally settled down with one simple rule - Use references for primitives and values that are copyable/movable and pointers for objects with long life cycle.
For Node example I would definitely use
AddChild(Node* pNode);
Just putting my dime in. I just performed a test. A sneeky one at that. I just let g++ create the assembly files of the same mini-program using pointers compared to using references.
When looking at the output they are exactly the same. Other than the symbolnaming. So looking at performance (in a simple example) there is no issue.
Now on the topic of pointers vs references. IMHO I think clearity stands above all. As soon as I read implicit behaviour my toes start to curl. I agree that it is nice implicit behaviour that a reference cannot be NULL.
Dereferencing a NULL pointer is not the problem. it will crash your application and will be easy to debug. A bigger problem is uninitialized pointers containing invalid values. This will most likely result in memory corruption causing undefined behaviour without a clear origin.
This is where I think references are much safer than pointers. And I agree with a previous statement, that the interface (which should be clearly documented, see design by contract, Bertrand Meyer) defines the result of the parameters to a function. Now taking this all into consideration my preferences go to
using references wherever/whenever possible.
For pointers, you need them to point to something, so pointers cost memory space.
For example a function that takes an integer pointer will not take the integer variable. So you will need to create a pointer for that first to pass on to the function.
As for a reference, it will not cost memory. You have an integer variable, and you can pass it as a reference variable. That's it. You don't need to create a reference variable specially for it.
I have been using a lot of different boost smart pointers lately, as well as normal pointers. I have noticed that as you develop you tend to realise that you have to switch pointer types and memory management mechanism because you overlooks some circular dependency or some othe small annoying thing. When this happens and you change your pointer type you have to either go and change a whole bunch of you method signatures to take the new pointer type, or at each call site you have to convert between pointer types. You also have a problem if you have the same function but want it to take multiple pointer types.
I am wondering if there already exists a generic way to deal with, i.e. write methods that are agnostic of the pointer type you pass to it?
Obviously i can see a few ways to do this, one is to write overloaded methods for each pointer type, but this quickly becomes a hassle. The other is to use a template style solution with some type inference, but this will cause some significant bloat in the compiled code and is likely to start throwing strange unsolvable template errors.
My idea is to write a new class any_ptr<T> with conversion constructors from all the major pointer types, say, T*, shared_ptr<T>, auto_ptr<T>, scoped_ptr<T> perhaps even weak_ptr<T> and then have it expose the * and -> operators. In this way it could be used in any function that does not return the pointer outside of the function and could be called with any combination of common pointer types.
My question is whether this is a a really stupid thing to do? I see that it could be abused, but assuming it is never used for functions that return the any_ptr, is there a major problem I would be walking into? Your thoughts please.
EDIT 1
Having read your answers I would like to make some notes that were too long for the comments.
Firstly with regards to using raw pointers or references (#shoosh). I agree that you could make the functions use raw pointers, but then assume the case where I was using shared_ptr which means I would have had to go ptr.get() at each call site, now assume I realize I made a cyclic reference and I have to change the pointer to a weak_ptr then I have to go and change all those call sites to x.lock().get() . Now I agree this is not a catastrophe but it is irritating and I feel there is an elegant solution to this. The same could be said for passing the as T& references and going *x, similar call site changes would have to be made.
What I trying to do here is make the code more elegant to read and easier to refactor even through large changes in pointer type.
Secondly with regards to smart_ptr semantics: I agree that different smart pointers are used for different reasons , and have certain considerations that must be taken care of with regards to copying and storage (this is why boost::shared_ptr<T> is not automatically convertible to a T*).
However I envisioned any_ptr (maybe a bad name in retrospect) to only be used in cases where the pointer would not be stored (in anything other than perhaps temporary variables on the stack). It should just be implicitly constructible from the various smart pointer types, overload the * and -> operators and be convertible to a T* (through a custom conversion function T*()). In this way the semantics of any_ptr are the exact same as as T*. And as such it should only be used in places where it would be safe to use a raw ptr (This is what # Alexandre_C was saying in a comment). This also means that there would be none of the "heavy machinery" that #Matthieu_M was talking about.
Thirdly with regards to templates. While templates are great for somethings I am wary of them for the reasons I have made above.
FINALLY: So basically what I am trying to do is for functions where one would normally use raw ptr's (T*) as the parameters I would like to create a system where those parameters can automatically accept any of the various smart_ptr types without having to do the conversions at the call sites. The reason I want to do this is because I think it will make the code more readable by eliminating conversion cruft (and hence also slightly shorter, though not by much) and it would make refactoring and trying different smart pointer regimes less of a hassle.
Perhaps I should have called it unmanaged_ptr instead of any_ptr. That would more correctly describe the semantics. I apologize for the crummy name.
EDIT 2
Okay so here is the class I had in mind. I have called it dumb_ptr.
template<typename T>
class dumb_ptr {
public:
dumb_ptr(const dumb_ptr<T> & dm_ptr) : raw_ptr(dm_ptr.raw_ptr) { }
dumb_ptr(T* raw_ptr) : raw_ptr(raw_ptr) { }
dumb_ptr(const boost::shared_ptr<T> & sh_ptr) : raw_ptr(sh_ptr.get()) { }
dumb_ptr(const boost::weak_ptr<T> & wk_ptr) : raw_ptr(wk_ptr.lock().get()) { }
dumb_ptr(const boost::scoped_ptr<T> & sc_ptr) : raw_ptr(sc_ptr.get()) { }
dumb_ptr(const std::auto_ptr<T> & au_ptr) : raw_ptr(au_ptr.get()) { }
T& operator*() { return *raw_ptr; }
T * operator->() { return raw_ptr; }
operator T*() { return raw_ptr; }
private:
dumb_ptr() { }
dumb_ptr<T> operator=(const dumb_ptr<T> & x) { }
T* raw_ptr;
};
It can convert from the common smart pointers automatically and can be treated as a raw T* pointer, further it can be converted automatically to a T*. The default constructor and the assignment operator (=) have been hidden to deter people from using it for anything other than function arguments. When used as a function argument the following can be done.
void some_fn(dumb_ptr<A> ptr) {
B = ptr->b;
A a = *ptr;
A* raw = ptr;
ptr==raw;
ptr+1;
}
Which is pretty much everything you would want to do with a pointer. It has the exact same semantics as a raw pointer T*. But now it can be used with any smart pointer as the parameter without having to repeat the conversion code (.get,.lock) at each call site. Also if you change your smart pointers you don't have to go around fixing each call site.
Now I think this is reasonably useful, and I can't see problems with it?
With such a class any_ptr, you will not be able to do practically anything other than * and ->. No assignment, copy construction, duplication or destruction. if that's all you need then just write the function taking as argument the raw pointer T* and then call it use .get() or whatnot on your automatic pointer.
You can use different smart pointers because they offer different semantics and tradeoffs.
What would be the semantics of any_ptr ? If it comes from unique_ptr / scoped_ptr it should not be copied. If it comes from shared_ptr or weak_ptr it would need their heavy machinery for reference counting.
You would have a type with all the disadvantages (heavy, no copyable) for little gain...
What you have here is a problem of interface. Unless the methods manage the lifetime of the object (in which case the exact pointer type is required), then it need not be aware of how this lifetime is managed.
This means that methods that merely act on the object should take either a pointer or a reference (depending on whether it might be null), and be called accordingly:
void foo(T* ptr); which is called shared_ptr<T> p; foo(p.get());
void foo(T& ptr); which is called foo(*p);
Note: the second interface is much more pointer agnostic
This is plain encapsulation: a method need be aware only of the bare minimum it needs to operate. If it does not manage the lifetime, then exposing how this lifetime is managed to the method... causes those ripples that you've witnessed.
If your methods really have to be smart pointer-agnostic, why not pass a garden variety pointer:
virtual void MyMethod(MyClass* ptr)
{
ptr->doSomething();
}
and do
MyObj->MyMethod(mySmartPtr.get());
at the call site ?
You can even pass a reference:
virtual void MyMethod(const MyClass& ptr)
{
ptr->doSomething();
}
and do
MyObj->MyMethod(*mySmartPointer);
which has the advantage to have pretty much always the same syntax (except for std::weak_ptr).
Otherwise, smart pointer types are becoming standard: std::unique_ptr, std::shared_ptr and std::weak_ptr have their use.
Smart pointers are for storing objects according to certain resource management semantics. You can pretty much always extract a bare pointer from them.
Methods should therefore in general expect bare pointers, or specific kinds of smart pointers in case they need to. For instance, you can pass a shared_ptr by const reference in order to store a shared handle to an object.
To this goal, you can add typedefs:
struct MyClass
{
typedef std::shared_ptr<MyClass> Handle;
static Handle CreateHandle(...);
...
private:
Handle internalHandle;
void setHandle(const MyClass::Handle& h);
};
and do
void MyClass::setHandle(const MyClass::Handle& h)
{
this->internalHandle = h;
}
When this happens and you change your
pointer type you have to either go and
change a whole bunch of you method
signatures to take the new pointer
type, or at each call site you have to
convert between pointer types. You
also have a problem if you have the
same function but want it to take
multiple pointer types.
I am wondering if there already exists
a generic way to deal with, i.e. write
methods that are agnostic of the
pointer type you pass to it?
You almost answered your own question.
A smart-pointer should be present in function signatures only if ownership of an object is being transferred. If a function does not take ownership of an object, it should accept it by plain pointer or reference. Only functions that need to own an object or extend its lifetime should accept it by smart pointer.
Answering my own question so it doesn't appear in the unanswered list. Basically none of the other answers found what I considered to be a serious flaw in my idea. Props to #Alexandre C. for understanding what I was trying to do.
I need to convert an integral type which contains an address to the actual pointer type. I could use reinterpret_cast as follows:
MyClass *mc1 = reinterpret_cast<MyClass*>(the_integer);
However, this does not perform any run-time checks to see if the address in question actually holds a MyClass object. I want to know if there is any benefit in first converting to a void* (using reinterpret_cast) and then using dynamic_cast on the result. Like this:
void *p = reinterpret_cast<void*>(the_integer);
MyClass *mc1 = dynamic_cast<MyClass*>(p);
assert(mc1 != NULL);
Is there any advantage in using the second method?
Type checking on dynamic_cast is implemented in different ways by different C++ implementations; if you want an answer for your specific implementation you should mention what implementation you are using. The only way to answer the question in general is to refer to ISO standard C++.
By my reading of the standard, calling dynamic_cast on a void pointer is illegal:
dynamic_cast<T>(v)
"If T is a pointer type, v shall be an rvalue of a pointer to complete class type"
(from 5.2.7.2 of the ISO C++ standard). void is not a complete class type, so the expression is illegal.
Interestingly, the type being cast to is allowed to be a void pointer, i.e.
void * foo = dynamic_cast<void *>(some_pointer);
In this case, the dynamic_cast always succeeds, and the resultant value is a pointer to the most-derived object pointed to by v.
No, there's no specific advantage in doing so. The moment you use reinterpret_cast, all bets are off. It's up to you to be sure the cast is valid.
Actually no serious advantage. If the void* points to something that is not a pointer to a polymorphic object you run into undefined behaviour (usually an access violation) immediately.
The safe way is to keep a record of all live MyClass objects. It's best to keep this record in a std::set<void*>, which means you can easily add, remove and test elements.
The reason for storing them as void*s is that you don't risk nastyness like creating unaligned MyClass* pointers from your integers.
First of all "reinterpreting" int to void * is a bad idea. If sizeof(int) is 4 and sizeof(void *) is 8 (64x system) it is ill-formed.
Moreover dynamic_cast is valid only for the case of the polymorphic classes.
Option 1 is your only (semi) portable/valid option.
Option 2: is not valid C++ as the dynamic_cast (as void is not allowed).
At an implementation level it requires type information from the source type to get to the destination type. There is no way (or there may be no way) to get the runtime source type information from a void* so this is not valid either.
Dynamic_Cast is used to cas up and down the type hierarchy not from unknown types.
As a side note you should probably be using void* rather than an integer to store an untyped pointer. There is potential for an int not to be large enough to store a pointer.
The safest way to handle pointers in C++ is to handle them typesafe. This means:
Never store pointers in anything else than a pointer
Avoid void pointers
Never pass pointers to other processes
consider weak_ptr if you plan to use pointers over threads
The reason for this is: what you are planning to do is unsafe and can be avoided unless you're interfacing with unsafe (legacy?) code. In this case consider MSalters' answer, but be aware that it still is a hassle.
If you know for sure that the_integer points to a known base class (that has at least one virtual member), there might in fact be an advantage: knowing that the object is of a specific derived class. But you’d have to reinterpret_cast to your base class first and then do the dynamic_cast:
BaseClass* obj = reinterpret_cast<BaseClass*>(the_integer);
MyClass* myObj = dynamic_cast<BaseClass*>(obj);
Using a void* in dynamic_cast is useless and simply wrong. You cannot use dynamic_cast to check if there’s a valid object at some arbitrary location in memory.
You should also pay attention when storing addresses in non-pointer type variables. There are architectures where sizeof(void*) != sizeof(int), e.g. LP64.