cast of ostream& to and from void*

M

Matt

I am trying to cast an ostream reference to void* and back again. The
code below shows the problem isolated from a more complex program. It
compiles quietly but seg faults upon execution.

// ===================================================================
#include <iostream>
using namespace std;

void myprint(void *s) {
(ostream&)s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)cerr);
}
// ===================================================================

Why can't I cast the ostream reference to and from void*?
 
T

TB

Matt sade:
I am trying to cast an ostream reference to void* and back again. The
code below shows the problem isolated from a more complex program. It
compiles quietly but seg faults upon execution.

// ===================================================================
#include <iostream>
using namespace std;

void myprint(void *s) {
(ostream&)s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)cerr);
}
// ===================================================================

Why can't I cast the ostream reference to and from void*?

You should stop and think if your design requires casting to void*.

#include <iostream>
using namespace std;

void myprint(void *s) {
*((ostream*)s) << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)&cerr);
}

A _much better_ solution is:

void myprint(ostream& s) {
s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint(cerr);
}
 
R

roberts.noah

Matt said:
I am trying to cast an ostream reference to void* and back again. The
code below shows the problem isolated from a more complex program. It
compiles quietly but seg faults upon execution.

// ===================================================================
#include <iostream>
using namespace std;

void myprint(void *s) {
(ostream&)s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)cerr);
}
// ===================================================================

Why can't I cast the ostream reference to and from void*?

I can't imagine that being a valid cast but I don't know for sure. One
thing that could help you a lot in figuring out what is going on is to
use C++ casts instead of C casts. C casts just do whatever but C++
casts only do the specified type of cast and some things that you
shouldn't be doing just are not possible with them where the C cast
will just silently compile and then explode on runtime.
 
J

Jim Langston

Matt said:
I am trying to cast an ostream reference to void* and back again. The code
below shows the problem isolated from a more complex program. It compiles
quietly but seg faults upon execution.

// ===================================================================
#include <iostream>
using namespace std;

void myprint(void *s) {
(ostream&)s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)cerr);
}
// ===================================================================

Why can't I cast the ostream reference to and from void*?

That's because cerr isn't a pointer in the first place. You're taking an
instance, converting it to a pointer, then trying to convert it to a
reference. As soon as you convert it to a pointer you loose everything. So
try taking the pointer to cerr instead.

This works for me (although I wouldn't do this, this just shows you how to
do what you're trying to do)

#include <iostream>
void myprint(void *s)
{
*((std::eek:stream*) s) << "hello, world" << std::endl;
}

int main(int argc, char *argv[])
{
myprint((void *)&std::cerr);
}
 
D

Daniel T.

Matt said:
I am trying to cast an ostream reference to void* and back again. The
code below shows the problem isolated from a more complex program. It
compiles quietly but seg faults upon execution.

// ===================================================================
#include <iostream>
using namespace std;

void myprint(void *s) {
(ostream&)s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)cerr);
}
// ===================================================================

Why can't I cast the ostream reference to and from void*?

The problem is that casting a basic_ios to a void* calls the operator
void* member-function who's only guaranteed to return 0 if the stream is
not good. There is no guarantee that it's return value is actually a
pointer to the cerr object.

If you want a pointer to the cerr object, then you have to do as others
have said and take the address of it.
 
M

Matt

TB said:
Matt sade:
I am trying to cast an ostream reference to void* and back again. The
code below shows the problem isolated from a more complex program. It
compiles quietly but seg faults upon execution.

// ===================================================================
#include <iostream>
using namespace std;

void myprint(void *s) {
(ostream&)s << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)cerr);
}
// ===================================================================

Why can't I cast the ostream reference to and from void*?


You should stop and think if your design requires casting to void*.

#include <iostream>
using namespace std;

void myprint(void *s) {
*((ostream*)s) << "hello, world" << endl;
}

int main(int argc, char *argv[]){
myprint((void *)&cerr);
}

Thanks for that fix, TB. That gets me going for now. Yes, I plan to
redesign so as to obviate that usage.

Thanks to all for the useful comments.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top