(char*)data is an explicit typecast. It temporarily labels data as if it was declared as char* instead of void*. Basically, the compiler won't allow you to assign a void* (pointer to unknown data type) to a char* (pointer to a known data type, a char), because from its point of view, the data at that address (that of a void*) could be anything. You need to tell it you know what you're doing, and force it to treat data as if it pointed to a char.
The fact that nothing can be inferred about what is pointed to by data is made clear by the second argument of increase(), and the way that function is used. The caller tells the function what type data actually points to (well, sort of).
I'm trying to digest it,because I also see there is void* data...hmmm
How about this:
If we write:
*p++ = *q++;
Because ++ has a higher precedence than *, both p and q are increased, but because both increase operators (++) are used as postfix and not prefix, the value assigned to *p is *q before both p and q are increased. And then both are increased. It would be roughly equivalent to:
*p = *q;
++p;
++q;
Like always, I recommend you to use parentheses () in order to avoid unexpected results and to give more legibility to the code.
I dont really get the equivalence between that two..
Could someone help me?
Personally I think this is extremely dodgy code. If someone working for me wrote it, I would tell them to try again. Rewrite. For one thing, what if psize happens to be 4 (and this is likely on some machines), and both a float and an int could be 4 bytes. So the function basically is not only incomprehensible, it is doomed to fail.
I really don't understand this style of coding - you've declared a variable, so why not save typing and screen space and initialise it at the same time?
int* pint=(int*)data;
++(*pint);
if so, it will not give equivalent result as above one.
I don't understand why you think that.
I think you may be confusing the value of a pointer and the value that it points to.
template <typename T> void increase (T & data)
{
data++;
}
void setup ()
{
float a;
int b;
char c;
long d;
unsigned long e;
long long f;
increase (a);
increase (b);
increase (c);
increase (d);
increase (e);
increase (f);
}
void loop () {}
Now that will handle any (reasonable) type.
Note that this doesn't compile in the IDE (because of the way the preprocessor works). But it will if you move the templated function into a separate .h file, and include that.
It's supposed to be demonstrating that a void * pointer can point to data of any type, but it's not a very good example.
malloc() is a better test case (not that a c++ programmer would use malloc(), of course.)
malloc(n) returns a void* pointer to a chunk of n bytes of memory, which you would then cast to whatever type was appropriate:
OK, but void pointers are rather esoteric. And thus the examples tend to be confusing. Stick to pointers to real types for now.
By and large you don't need pointers in C++ because you can use references instead. My advice is to keep it simple. Don't waste a lot of time understanding things like void pointers. Just stick to simpler things and get a good grip on them.
I dunno. Void* pointers are easy. They're just an address of some memory. You can't do much of anything with them (other than pass them around) until you've forcefully identified what's in that memory (with a cast.) That makes sense, even at machine code levels.
Now, real pointers are harder, because they're supposed to point to a particular type of thing, but that's really just a fiction that is only enforced by the compiler.
Well, look at it like this. Void pointers are like pointers to atoms. That's only useful if you know how many atoms are in something (like a cat). But a cat* pointer points at a cat. And if you add one, it points to the next cat. You don't have to care how many atoms are in the cat. Now that's useful!
I've never quite been convinced by the need for a void pointer type - a char is by definition the smallest addressable element, so is the smallest thing you can have a pointer to.
I guess void just anonymises (if such a word / verb exists) it.
void pointers aren't overly useful, they are just required. Memory allocation systems don't allocate to a type, but an address with a data range, which is a void pointer. ( explicit 'operator new' over plain old 'new' )
Also before templates were fully formed, people wrote functions like
With the only benefit for using it over typed pointers was to remove casting everything to a standard type. ( Any pointer type can be implicitly cast to void* but not the other way around ).
Also there is this example.
void Foo(void (*fp)(void *), void *q) {
fp(q);
}
This use of void*allows Foo to take a pointer to a function and handle any type of argument.