Maxime
Maxime

Reputation: 1345

Output of void pointer function

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

Answers (3)

dimm
dimm

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

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

AFX
AFX

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

Related Questions