Misleading syntax/parser error: Expected > instead of * in reinterpret_cast - c++

I am getting a weird syntax error when trying to reinterpret-cast a pointer:
void my_function(std::unique_ptr<float[]> ptr) {
// Some stuff
... = reinterpret_cast<uint8_t[]*>(ptr.release());
// Some other stuff
}
I'm getting the following error message:
error: expected '>'
reinterpret_cast<uint8_t[] *>(ptr.release()));
^
I have a '<' and a matching '>', so I don't understand what's causing the error. What could be the problem here?

Assuming you're either trying to serialize data, you should be casting to a regular uint8_t pointer. For this, just do:
reinterpret_cast<uint8_t*>(ptr.release());
Note that ptr.release() releases onwership of the pointer owned by the unique_ptr, and that deleting a pointer to an array of float as a pointer to an array of uint8_t is undefined behavior. Always delete a pointer as it's original type, without casting it.
I would recommend using ptr.get() instead, as this doesn't transfer ownership:
reinterpret_cast<uint8_t*>(ptr.get());
Why you got the error: The syntax for a pointer to an array is uint8_t(*)[]. It's... weird, and until another commenter pointed it out, I didn't know that it existed (it's an artifact of backwards compatibility with C).
Because of that, the compiler doesn't expect to see a * after uint8_t[], so it says that it expected the closing bracket of the reinterpret_cast.

Do you really want a pointer to an array of uint8_t, as opposed to just a pointer to uint8_t ?
If so, it is written uint8_t(*)[].
But I think what you actually want is most likely a pointer to uint8_t, i.e. uint8_t *.

Related

How to correctly dereference a void pointer to class

I have some problems with referencing void pointer to class.
I created a node "index" with a void data pointer which point to a class "studentinfo";
however, I encountered problems when I was trying to extract data member of the class "studentinfo".
The output error message is saying:
"invalid type argument of unary '*' (have 'int')
int main()
{
...
Studentinfo *stu=new Studentinfo(id,name,score);
index=createNode(stu);
cout<<*static_cast <Studentinfo*> (index->dataPtr)->id; //Error ocurrs
...
}
-> already does a deference. So stu->id is the same as (*stu).id.
In your code you are actually trying to deference id, which is an int. This is why you get that error.
The -> operator dereferences a pointer and accesses it's member. The * also does this. Because you've included both, you're actually trying to do it twice.
Probably the correction to the code you're looking for probably just needs to remove the extra * dereference. The error you're getting is because static_cast <Studentinfo*> (index->dataPtr)->id is already fully dereferenced and returning what you want, id. id is an int, so the * dereference operator is attempting to dereference an id(an int) which gives the error invalid type argument of unary '*' (have 'int')
Now... with all that said I'm going to reiterate some of what your commentors have already said. This is extremely unsafe code. There's rarely a good reason to use void pointers or malloc in C++. Try to spend some more time learning about A: Constructors, B: How they interact with the new operator, and C: templates.
You will get code that is more readable and less error prone utilizing these techniques. Your main will be much more readable, as the statement that is currently giving you trouble can be simplified to cout<<index->dataPrt->id if your node uses templates, rather than a void pointer.

How can I cast a pointer of type size_t to a pointer of enum ?

I want to assign a size_t to this container :
std::vector <nts::Tristate *> _components;
To do so, I am trying to cast const size_t & to nts::Tristate *
this->_components[0] = static_cast<nts::Tristate *>(&value);
But I have the following error :
error: invalid static_cast from type ‘const size_t* {aka const long unsigned int*}’ to type ‘nts::Tristate*’
this->_components[0] = static_cast<nts::Tristate *>(&value);
Have any idea why ?
Without asking why you want to do something like that, the problem is that the two types (size_t* and nts::Tristate*) are completely unrelated, and you need to reinterpet one type as the other. You do thing with reinterpret_cast.
It should be noted that doing something like this will most likely lead to other problems down the road, problems that will lead to undefined behavior. One of the things you need to watch out for is if value is a local variable, because then you store a pointer to this local variable that will go out of scope and disappear. Another is that the rest of the program that uses _components[0] needs to know that it's not actually a pointer to a nts::Tristate object but a pointer to a size_t value. In short, what you're doing is very dangerous.

how can I convert a constat value into a non constant variable?

I have this code:
PARAMS Params;
Params.pwchFileName = wide.c_str() ;
But I a getting this error:
a value of type "const wchar_t *" cannot be assigned to an entity of type "wchar_t *"
How can make this assignment?
You could, with extreme caution, use a const_cast:
const_cast<wchar_t*>( wide.c_str());
But the are other issues here: if wide is a std::string then the results of c_str() are only valid for as long as wide is in scope and has not been changed in any way. Even if you conform to this, then a consumer of PARAMS could modify the string buffer which would give you undefined behaviour.
The best thing to do here is to use strcpy to take a deep copy of the string buffer, remembering to delete that buffer once you're done with it.
The only way of making a non-constant value from a constant one that would be safe in all contexts is to make a copy:
Params.pwchFileName = new char[wide.size()+1];
strcpy(Params.pwchFileName, wide.c_str());
...
// when you are done with the copy, delete it:
delete[] Params.pwchFileName;
You can convert it forcefully by casting away constness using :-
Params.pwchFileName = const_cast<wchar_t*>( wide.c_str() );
But use const_cast when you have no other choice.
Be careful, writing into that object invokes undefined behavior.

cannot convert parameter 1 from 'char *' to 'uint8_t *'

void OnReceived(std::shared_ptr<uint8_t> buffer, int len) {
.........
}
int main(){
std::vector<char> buffer(1000);
OnReceived((std::shared_ptr<uint8_t>)buffer.data(),rcvlen);
}
am trying to cast it but i cant i dont know why!!!
Error 1 error C2664: 'std::tr1::_Ptr_base<_Ty>::_Reset0' : cannot convert parameter 1 from 'char *' to 'uint8_t *' c:\program files\microsoft visual studio 10.0\vc\include\memory 1705
so how can i convert it?
You really don't want to do that. Aside from the fact that char and uint8_t may be distinct types, even if you force the code to compile, your buffer will be deallocated twice, likely crashing your program. Just change OnReceived to accept a raw pointer.
Beyond the type mismatch, you don't want to do that. It'll almost cause a crash when both the vector destructor and the shared_ptr deallocate the same memory. You should consider boost::shared_array or a shared pointer to the entire vector (shared_ptr<std::vector>) instead of what you're doing now. Or as Igor suggests, OnReceived could be changed to accept a raw pointer if it doesn't need shared ownership of the buffer.
uint8_t is an unsigned char so you'll either need to change the type of buffer or reinterpret_cast somewhere along the line.
buffer.data() will return a char *. You're trying to cast that to a std::shared_ptr - in other words, construct a shared_ptr out of it. In its implementation it tries to assign the pointer but can't since you're passing in an incompatible pointer type.
Try casting it to the appropriate type before passing it in, such as:
OnReceived((std::shared_ptr<uint8_t>)(uint8_t *)buffer.data(),rcvlen);
or, probably a better solution, convert your std::vector to a vector of uint8_t.

C++: malloc : error: invalid conversion from ‘void*’ to ‘uint8_t*’

I got this problem:
invalid conversion from ‘void*’ to ‘uint8_t*’
When doing this:
int numBytes;
uint8_t *buffer;
buffer=malloc(numBytes); //error here, why?
or must I have to put it like this?
buffer=malloc(numBytes);
Please explain this.
You cannot implicitly cast from void * in C++ (unlike C in this respect). You could do:
buffer = static_cast<uint8_t *>(malloc(numBytes));
but really, you should just be using new/delete instead of malloc/free!
In C++ it is not allowed to simply assign a pointer of one type to a pointer of another type (as always there are exception to the rule. It is for example valid to assign a any pointer to a void pointer.)
What you should do is to cast your void pointer to a uint8_t pointer:
buffer = (uint8_t *) malloc (numBytes);
Note: This is only necessary in C++, in C it was allowed to mix and match pointers. Most C compilers give a warning, but it is valid code.
Since you're using C++ you could also use new and delete like this:
buffer = new uint8_t[numBytes];
and get rid of your buffer using:
delete[] buffer;
In general you shouldn't use malloc and free unless you have to interface with c libraries.
Malloc returns a void pointer; when you use it, you have to cast the return value to a pointer to whatever datatype you're storing in it.
buffer = (uint8_t *) malloc(numBytes);