how to force blind cast from void* to struct*

Discussion in 'C++' started by andreyvul, Oct 31, 2007.

  1. andreyvul

    andreyvul Guest

    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;
    };
     
    andreyvul, Oct 31, 2007
    #1
    1. Advertising

  2. andreyvul wrote:
    > 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;
    > };


    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 31, 2007
    #2
    1. Advertising

  3. andreyvul

    andreyvul Guest

    On Oct 31, 6:16 pm, "Victor Bazarov" <> wrote:
    > andreyvul wrote:
    > > 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;
    > > };

    >
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask

    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++)
     
    andreyvul, Oct 31, 2007
    #3
  4. andreyvul wrote:
    > [..]
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Nov 1, 2007
    #4
  5. andreyvul

    James Kanze Guest

    On Nov 1, 4:37 am, "Victor Bazarov" <> wrote:
    > andreyvul wrote:
    > > [..]
    > > 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).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 1, 2007
    #5
  6. On 31 Oct, 22:10, andreyvul <> wrote:

    > 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>


    --
    Nick Keighley
     
    Nick Keighley, Nov 1, 2007
    #6
  7. andreyvul

    terminator Guest

    On Nov 1, 1:10 am, andreyvul <> wrote:
    > 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.
     
    terminator, Nov 1, 2007
    #7
  8. andreyvul

    andreyvul Guest

    Nick Keighley wrote:
    > On 31 Oct, 22:10, andreyvul <> wrote:
    >
    > > 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"?


    A copy constructor with an argument of an unrelated object type.
    Example:
    class foo1 {
    ...
    };
    class foo2 {
    foo2(foo1& foo) {
    ...member... = foo.member...
    ...
    }
    };
     
    andreyvul, Nov 1, 2007
    #8
  9. On 2007-11-01 18:06, andreyvul wrote:
    > Nick Keighley wrote:
    >> On 31 Oct, 22:10, andreyvul <> wrote:
    >>
    >> > 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"?

    >
    > A copy constructor with an argument of an unrelated object type.


    The official name is converting constructor, if that matters.

    --
    Erik Wikström
     
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=, Nov 1, 2007
    #9
  10. On 1 Nov, 17:23, Erik Wikström <> wrote:
    > On 2007-11-01 18:06, andreyvul wrote:
    >
    > >Nick Keighleywrote:
    > >> On 31 Oct, 22:10, andreyvul <> wrote:

    >
    > >> > 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"?

    >
    > > A copy constructor with an argument of an unrelated object type.

    >
    > 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?
    }


    --
    Nick Keighley
     
    Nick Keighley, Nov 2, 2007
    #10
  11. andreyvul

    James Kanze Guest

    On Nov 2, 9:34 am, Nick Keighley <>
    wrote:
    > On 1 Nov, 17:23, Erik Wikström <> wrote:
    > > On 2007-11-01 18:06, andreyvul wrote:
    > > >Nick Keighleywrote:
    > > >> On 31 Oct, 22:10, andreyvul <> wrote:


    > > >> > 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"?


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

    > > > A copy constructor with an argument of an unrelated object
    > > > type.


    If the parameter type is unrelated, it isn't a copy constructor.

    > > The official name is converting constructor, if that matters.


    > 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 2, 2007
    #11
  12. andreyvul

    James Kanze Guest

    On Nov 1, 4:32 pm, terminator <> wrote:
    > On Nov 1, 1:10 am, andreyvul <> 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.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 2, 2007
    #12
  13. andreyvul

    terminator Guest

    On Nov 2, 12:20 pm, James Kanze <> wrote:
    > On Nov 1, 4:32 pm, terminator <> wrote:
    >
    > > On Nov 1, 1:10 am, andreyvul <> 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.
    >

    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.
     
    terminator, Nov 5, 2007
    #13
  14. andreyvul

    James Kanze Guest

    On Nov 5, 3:49 pm, terminator <> wrote:
    > On Nov 2, 12:20 pm, James Kanze <>
    > wrote:> On Nov 1, 4:32 pm, terminator
    > <> wrote:


    > > > On Nov 1, 1:10 am, andreyvul <> 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.


    > 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 )

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Nov 5, 2007
    #14
  15. andreyvul

    terminator Guest

    On Nov 5, 8:42 pm, James Kanze <> wrote:
    > On Nov 5, 3:49 pm, terminator <> wrote:
    >
    >
    >
    >
    >
    > > On Nov 2, 12:20 pm, James Kanze <>
    > > wrote:> On Nov 1, 4:32 pm, terminator
    > > <> wrote:
    > > > > On Nov 1, 1:10 am, andreyvul <> 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.

    > > 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 )
    >


    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:

    On Nov 1, 1:10 am, andreyvul <> wrote:
    > 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.
     
    terminator, Nov 6, 2007
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hats
    Replies:
    0
    Views:
    520
  2. Ollej Reemt
    Replies:
    7
    Views:
    551
    Jack Klein
    Apr 22, 2005
  3. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    795
    The Real OS/2 Guy
    Oct 28, 2003
  4. Replies:
    5
    Views:
    842
    S.Tobias
    Jul 22, 2005
  5. Replies:
    1
    Views:
    413
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page