Reputation: 1345
I have unearthed an old C++ DLL, and I'd like to us it in one of my projects, in VS2015.
The problem is, it does not compile. I got in touch with a guy in the team that made the code in the first place, and he is positive that the exact same code compiled with VS2010.
I have an error in an otherwise very simple function:
Extract of header:
/*
Data input
*/
istream* input; //Source of data
long inputpos; // Current position in the data stream
And the code itself:
// Helper function to increment a counter while reading a character
void* Calculator::inputstream_get(char& ch)
{
++inputpos;
return input->get(ch);
}
In the end, I get an Error C2440:
'return': cannot convert from 'std::basic_istream<char,std::char_traits<char>>' to 'void *'
It is my understanding (I'm not a C++ expert I have to say...) that void pointers could represent any type of data, am I mistaken?
Is there any way to 'cast' my istream to an void pointer?
Thanks a lot for your help
Upvotes: 4
Views: 400
Reputation: 1798
This is the deal. http://en.cppreference.com/w/cpp/io/basic_ios/operator_bool
In C++03 that was operator void* and in C++11 that is operator bool.
Change that void* to bool. Note that after the change the code will be not usable in C++03 compiler. You can solve it in a portable fashion with
if (input->get(ch)) return true;
else return false;
Actually, the most proper way is to return reference to the actual istream object.
Upvotes: 0
Reputation: 171167
The reason why this compiles in VS 2010 (C++03) and not in VS 2015 (C++11) is that in C++03, standard library streams defined an implicit conversion to void*
; the purpose of that conversion was to allow testing them for truthiness (such as while (cin >> x)
) without allowing an implicit conversion to bool
(which would allows such monstrosities as 1 + (cin >> x)
to compile).
Note that the value of the returned void*
was underspecified: it was either a null pointer when the stream is in a failed state, or an unspecified non-null pointer when the stram's in good state.
C++11 introduced the notion of explicit conversion operators and contextual conversion to bool
, which means that these "hacky" conversions to void*
were replaced in the standard by a safe explicit operator bool () const
. Of course, this makes the code fail to compile as C++11.
How you can solve this is change Calculator::inputstream_get
as follows:
void* Calculator::inputstream_get(char& ch)
{
++inputpos;
return input->get(ch) ? this : nullptr;
}
This preserves the semantics of returning a null pointer on failure, and an unspecified non-null pointer on success.
Upvotes: 6
Reputation: 50
To answer your last question. You cannot cast a non pointer to a pointer. But you can cast any pointer to a void pointer with (void*)
Upvotes: 0