how to force blind cast from void* to struct*

A

andreyvul

g++ says a reinterpret cast from void* is disallowed; however, all I'm
trying to do is de-capsulate a void* argument that holds the pointer
to a class (and static_cast forces cast constructor)
any solutions?
also this pops up: 43: error: expected unqualified-id before 'return'
code:
includes: stdio.h, stdlib.h, time.h, pthread.h
struct:
template <typename T> struct mergesort_thread {
T* start;
T* end;
mergesort_thread(T* _start, T* _end) { start = _start; end = _end; }
static void *invoke(void *_this) {
pthread_t threads[2];
mergesort_thread<T> *child1, *child2;
T *mid, *shift, t;
T* start = (reinterpret_cast< mergesort_thread<T> >(_this))->start;
T* end = (reinterpret_cast< mergesort_thread<T> >(_this))->end;
if (start >= end) return NULL; //recursed deep enough (1 element)
//recursively sort halves of the list
mid = (T*)(start + ((end - start) >> 1));
child1 = new mergesort_thread<T>(start, mid);
pthread_create(&threads[0], NULL, mergesort_thread<T>::invoke, (void
*)child1);
child2 = new mergesort_thread<T>(mid + 1, end);
pthread_create(&threads[1], NULL, mergesort_thread<T>::invoke, (void
*)child2);
delete child1;
delete child2;
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
for (;(start <= mid) && (mid + 1 <= end); start++) {
if (*start < *(mid + 1)) //sorted (current element belongs in 1st
half)
continue;
else { /* true inplace merge requires insersion-sort-like
* methods because a value from the second half is inserted to
* the current element */
//copy the first element in the second half to t
t = *(mid + 1);
//shift first half to the right
for (shift = mid; shift >= start; shift--)
*(shift + 1) = *shift;
//copy t to start
*start = t;
mid++;
}
}
}
43: return NULL;
};
 
V

Victor Bazarov

andreyvul said:
g++ says a reinterpret cast from void* is disallowed; however, all I'm
trying to do is de-capsulate a void* argument that holds the pointer
to a class (and static_cast forces cast constructor)
any solutions?

Use 'static_cast'. That's what it's for (among some other things).
also this pops up: 43: error: expected unqualified-id before 'return'

It would seem your 'return' is outside of any function.
code:
includes: stdio.h, stdlib.h, time.h, pthread.h
struct:
template <typename T> struct mergesort_thread {
T* start;
T* end;
mergesort_thread(T* _start, T* _end) { start = _start; end = _end; }
static void *invoke(void *_this) {
pthread_t threads[2];
mergesort_thread<T> *child1, *child2;
T *mid, *shift, t;
T* start = (reinterpret_cast< mergesort_thread<T> >(_this))->start;
T* end = (reinterpret_cast< mergesort_thread<T> >(_this))->end;
if (start >= end) return NULL; //recursed deep enough (1 element)
//recursively sort halves of the list
mid = (T*)(start + ((end - start) >> 1));
child1 = new mergesort_thread<T>(start, mid);
pthread_create(&threads[0], NULL, mergesort_thread<T>::invoke, (void
*)child1);
child2 = new mergesort_thread<T>(mid + 1, end);
pthread_create(&threads[1], NULL, mergesort_thread<T>::invoke, (void
*)child2);
delete child1;
delete child2;
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
for (;(start <= mid) && (mid + 1 <= end); start++) {
if (*start < *(mid + 1)) //sorted (current element belongs in 1st
half)
continue;
else { /* true inplace merge requires insersion-sort-like
* methods because a value from the second half is inserted to
* the current element */
//copy the first element in the second half to t
t = *(mid + 1);
//shift first half to the right
for (shift = mid; shift >= start; shift--)
*(shift + 1) = *shift;
//copy t to start
*start = t;
mid++;
}
}
}
43: return NULL;
};
 
A

andreyvul

andreyvul said:
g++ says a reinterpret cast from void* is disallowed; however, all I'm
trying to do is de-capsulate a void* argument that holds the pointer
to a class (and static_cast forces cast constructor)
any solutions?

Use 'static_cast'. That's what it's for (among some other things).
also this pops up: 43: error: expected unqualified-id before 'return'

It would seem your 'return' is outside of any function.


code:
includes: stdio.h, stdlib.h, time.h, pthread.h
struct:
template <typename T> struct mergesort_thread {
T* start;
T* end;
mergesort_thread(T* _start, T* _end) { start = _start; end = _end; }
static void *invoke(void *_this) {
pthread_t threads[2];
mergesort_thread<T> *child1, *child2;
T *mid, *shift, t;
T* start = (reinterpret_cast< mergesort_thread<T> >(_this))->start;
T* end = (reinterpret_cast< mergesort_thread<T> >(_this))->end;
if (start >= end) return NULL; //recursed deep enough (1 element)
//recursively sort halves of the list
mid = (T*)(start + ((end - start) >> 1));
child1 = new mergesort_thread<T>(start, mid);
pthread_create(&threads[0], NULL, mergesort_thread<T>::invoke, (void
*)child1);
child2 = new mergesort_thread<T>(mid + 1, end);
pthread_create(&threads[1], NULL, mergesort_thread<T>::invoke, (void
*)child2);
delete child1;
delete child2;
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
for (;(start <= mid) && (mid + 1 <= end); start++) {
if (*start < *(mid + 1)) //sorted (current element belongs in 1st
half)
continue;
else { /* true inplace merge requires insersion-sort-like
* methods because a value from the second half is inserted to
* the current element */
//copy the first element in the second half to t
t = *(mid + 1);
//shift first half to the right
for (shift = mid; shift >= start; shift--)
*(shift + 1) = *shift;
//copy t to start
*start = t;
mid++;
}
}
}
43: return NULL;
};
I was using void* to encapsulate a struct, so I used reinterpret_cast
because I know the actual type of the object that the void* is
referencing.
On a related note, do you of any c++ debuggers for linux? (gdb might
not work that easily with c++)
 
V

Victor Bazarov

andreyvul said:
[..]
I was using void* to encapsulate a struct, so I used reinterpret_cast
because I know the actual type of the object that the void* is
referencing.

'reinterpret_cast' is not for that. A pointer to an object can be
converted to 'void*' implicitly. You need 'static_cast' to get the
original pointer back.
On a related note, do you of any c++ debuggers for linux? (gdb might
not work that easily with c++)

I know that gdb worked just fine for me on Linux. Ask in the Linux
newsgroup, though. They may know more.

V
 
J

James Kanze

andreyvul said:
[..]
I was using void* to encapsulate a struct, so I used
reinterpret_cast because I know the actual type of the
object that the void* is referencing.
'reinterpret_cast' is not for that. A pointer to an object can be
converted to 'void*' implicitly. You need 'static_cast' to get the
original pointer back.

I'd use static_cast in this case, too, but according to the
standard, reinterpret_cast is also legal (and should give the
same results).
 
N

Nick Keighley

g++ says a reinterpret cast from void* is disallowed; however, all I'm
trying to do is de-capsulate a void* argument that holds the pointer
to a class (and static_cast forces cast constructor)

what's a "cast constructor"?

<snip>
 
T

terminator

g++ says a reinterpret cast from void* is disallowed; however, all I'm
trying to do is de-capsulate a void* argument that holds the pointer
to a class (and static_cast forces cast constructor)
any solutions?
also this pops up: 43: error: expected unqualified-id before 'return'
code:
includes: stdio.h, stdlib.h, time.h, pthread.h
struct:
template <typename T> struct mergesort_thread {
T* start;
T* end;
mergesort_thread(T* _start, T* _end) { start = _start; end = _end; }
static void *invoke(void *_this) {
pthread_t threads[2];
mergesort_thread<T> *child1, *child2;
T *mid, *shift, t;
T* start = (reinterpret_cast< mergesort_thread<T> >(_this))->start;
T* end = (reinterpret_cast< mergesort_thread<T> >(_this))->end;
if (start >= end) return NULL; //recursed deep enough (1 element)
//recursively sort halves of the list
mid = (T*)(start + ((end - start) >> 1));
child1 = new mergesort_thread<T>(start, mid);
pthread_create(&threads[0], NULL, mergesort_thread<T>::invoke, (void
*)child1);
child2 = new mergesort_thread<T>(mid + 1, end);
pthread_create(&threads[1], NULL, mergesort_thread<T>::invoke, (void
*)child2);
delete child1;
delete child2;
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
for (;(start <= mid) && (mid + 1 <= end); start++) {
if (*start < *(mid + 1)) //sorted (current element belongs in 1st
half)
continue;
else { /* true inplace merge requires insersion-sort-like
* methods because a value from the second half is inserted to
* the current element */
//copy the first element in the second half to t
t = *(mid + 1);
//shift first half to the right
for (shift = mid; shift >= start; shift--)
*(shift + 1) = *shift;
//copy t to start
*start = t;
mid++;
}
}
}
43: return NULL;



};- Hide quoted text -

a pointer is an intrinsic type on which modern compilers are elegant
in optimizing. I mean using static_cast must not impose any overhead .

regards,
FM.
 
A

andreyvul

Nick said:
what's a "cast constructor"?

A copy constructor with an argument of an unrelated object type.
Example:
class foo1 {
...
};
class foo2 {
foo2(foo1& foo) {
...member... = foo.member...
...
}
};
 
N

Nick Keighley

The official name is converting constructor, if that matters.

aren't those invoked even if there is no cast?

class A
{
public:
A();
A(B);
};

void g(A a)
{
}

void f()
{
A a;
B b;

g(b); // CTOR A(B) invoked here?
}
 
J

James Kanze

This is the first time I've heard that expression.

If the parameter type is unrelated, it isn't a copy constructor.
aren't those invoked even if there is no cast?

It depends. They're called conversion constructors because they
can be used to convert one type to another---any constructor
which isn't a copy constructor but can be called with exactly
one argument is a conversion constructor. If the constructor
has been declared "explicit", it will only be used for explicit
conversions---some form of a conversion operator. If it hasn't
been declared "explicit", it can be used for implicit
conversions as well.
 
J

James Kanze

On Nov 1, 1:10 am, andreyvul <[email protected]> wrote:
a pointer is an intrinsic type on which modern compilers are
elegant in optimizing. I mean using static_cast must not
impose any overhead .

I'm not sure I understand. A static_cast isn't a no-op, and
compilers do generate executable code for it, when the semantics
require it. About the only cast which is really guaranteed to
be a no-op at execution time (and the standard doesn't actually
make any guarantee here either) is const_cast; on some machines,
even reinterpret_cast will sometimes require executable code.
 
T

terminator

I'm not sure I understand. A static_cast isn't a no-op, and
compilers do generate executable code for it, when the semantics
require it. About the only cast which is really guaranteed to
be a no-op at execution time (and the standard doesn't actually
make any guarantee here either) is const_cast; on some machines,
even reinterpret_cast will sometimes require executable code.
static_casting pointers generates a temporary copy of the original
pointer if pointers are of irrelevant types with similar alignment
properties ,but that can be removed by the optimizer .

regards,
FM.
 
J

James Kanze

On Nov 2, 12:20 pm, James Kanze <[email protected]>
wrote:> On Nov 1, 4:32 pm, terminator
static_casting pointers generates a temporary copy of the original
pointer if pointers are of irrelevant types with similar alignment
properties ,but that can be removed by the optimizer .

I'm having trouble understanding your sentence. The result of a
static_cast (of pointers) is an rvalue; if it is bound to a
reference, or used in any other context which requires an objet,
there will be a copy. Always.

But that doesn't have anything to do with what I was talking
about. A static_cast is not always a no-op; at times, it
requires the compiler to generate code (e.g. most often, adding
a constant to the pointer).

In the case of reinterpret_cast, on machines where all pointers
have the same representation, the reinterpret_cast will be a
no-op, almost certainly. For some pointers:
static_cast<T*>( p ) != reinterpret_cast<T*>( p )
 
T

terminator

I'm having trouble understanding your sentence. The result of a
static_cast (of pointers) is an rvalue; if it is bound to a
reference, or used in any other context which requires an objet,
there will be a copy. Always.

But that doesn't have anything to do with what I was talking
about. A static_cast is not always a no-op; at times, it
requires the compiler to generate code (e.g. most often, adding
a constant to the pointer).

In the case of reinterpret_cast, on machines where all pointers
have the same representation, the reinterpret_cast will be a
no-op, almost certainly. For some pointers:
static_cast<T*>( p ) != reinterpret_cast<T*>( p )

its a matter of context ,the OP is not referencing(nor addressing) the
casted pointer ; so there is a chance for removal of the copy as I
wrote before.
BTW while I was looking for a proof that in this context either
operator has the same effect ,I discovered that I had been mislead
here.Look out plz:

g++ says a reinterpret cast from void* is disallowed; however, all I'm
trying to do is de-capsulate a void* argument that holds the pointer
to a class (and static_cast forces cast constructor)
any solutions?
also this pops up: 43: error: expected unqualified-id before 'return'
code:
includes: stdio.h, stdlib.h, time.h, pthread.h
struct:
template <typename T> struct mergesort_thread {
T* start;
T* end;
mergesort_thread(T* _start, T* _end) { start = _start; end = _end; }
static void *invoke(void *_this) {
pthread_t threads[2];
mergesort_thread<T> *child1, *child2;
T *mid, *shift, t;
T* start =
(reinterpret_cast< mergesort_thread<T> >(_this))->start;
T* end =(reinterpret_cast< mergesort_thread<T> >(_this))->end;

the template does not inherit from its type-parameter ,hence a pointer
to template('mergesort_thread<T>') is not implicitly castable to that
of its type-param('T').So the compiler`s complaign about casting is no
surpris.whatever the casting operator,the compiler will cry that it
cannot cast.The problem is in initializing from the result of the cast
operator.

regards,
FM.
 

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