You may have to forgive me as I'm new to C++ and may have made some fundamental errors with the code I have worked up so far.
static tuple<read_result, uint8_t*> m_scan_record(bool skip, uint32_t& size, FILE* file)
{
read_result result;
tuple<read_result, uint32_t*> rd_rec_size_result = m_read_generic_t<uint32_t>(file);
result = (read_result)get<0>(rd_rec_size_result);
if (result != read_success )
{
return tuple<read_result, uint8_t*>(result, nullptr);
}
size = (uint32_t) get<1>(rd_rec_size_result);
if ( skip )
{
fseek(file, size, SEEK_CUR);
}
// ...
}
template<typename T>
static tuple<read_result, T*> m_read_generic_t(FILE* file)
{
T ret = 0;
read_result result = m_read_from_file_to_buffer(&ret, sizeof(T), file);
if (result == read_success)
{
return tuple<read_result, T*>(result, &ret);
}
return tuple<read_result, T*>(result, nullptr);
}
When I compile this code I am getting this error:
cast from ‘std::__tuple_element_t<1, std::tuple<read_result, unsigned int*> >’ {aka ‘unsigned int*’} to ‘uint32_t’ {aka ‘unsigned int’} loses precision [-fpermissive]
My intentions and what I am expected to do/happen:
In the declaration of
m_scan_record, thesizeargument is declared with a&which is intended to allow me to pass the value by reference, analogous to using theREFc# keywordI make a call to generic (template) function
m_read_generic_twhich is called with the specified type<unit32_t>and therefore (according to its definition) will return a type oftuple<read_result, uint32_t*>Once I have the tuple returned by
m_read_generic_t, I want to take theunit32_tvalue pointed to by the second value of the tuple, and put that value into thesizevariable mentioned at point 1, above, which presumably will then be accessible to the calling function one step further up the stack.From the above points you can hopefully see that my intention (and I appreciate that I may be far away in reality!) is that at this line:
size = (uint32_t) get<1>(rd_rec_size_result);
all I am doing is simply grabbing a 'pointed to' value and putting it into a variable of a matching type, much like the oft-cited textbook example:
uint32_t v = 123;
uint32_t* ptr_to_v = &v;
uint32_t x = ptr_to_v; // x == 123
Clearly this is not what is really going on with my code, though, because if it were, I presume that the cast would be un-needed. But if I remove it, like this:
size = get<1>(rd_rec_size_result);
then I get a compile-time error:
a value of type "std::__tuple_element_t<1UL, std::tuple<read_result, uint32_t *>>" cannot be assigned to an entity of type "uint32_t"
I believe therefore that I am doing something badly wrong - but I can't work out what. Is this to do with the way I am taking the pointer out of the tuple; or is there something else going on when it comes to the getting a uint32_t value from a uint32_t* ?
This is all in a C++ environment on Ubuntu 20.04, FWIW
Many thanks in advance for any/all suggestions; please go easy on me!
The 2nd member of this tuple, as explicitly declared here, is a pointer to a
uint32_t. That's whatuint32_t *means, in C++.This retrieves the
uint32_t *and attempts to convert it to auint32_t. C++ does not work this way. Although this conversion can be forced your compiler has every right to believe that whatever this code is trying to do it must be wrong.Perhaps I was wondering initially, your intention was to dereference the pointer. This is the reason for your compilation error, in any case. If your intention was to, truly, dereference this pointer, then this would've been a simple matter of changing this to
However, that's not going to be the end of your troubles. Even after this compilation error is fixed, this way, the shown code will still be badly, badly broken.
This is because
m_read_generic_treturns a pointer to a local object, which will get destroyed when the function returns, and attempting to dereference this pointer, here, will make demons fly out of your nose.The real fix here is to change
m_read_generic_tto not return a pointer as the 2nd value in the tuple in the first place, thus eliminating the compilation error in the first place.