473,406 Members | 2,467 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

cast required for void** to int**

Hi,

I have a template array class on T with specialization for bloat when T
is void*. Thus when T is really an int*, my base ptr is physically a
void** and needs to be converted to an int**.

This doesn't work:

void** base = ...;
int** ibase = static_cast<int**>(base); // illegal

and this is bad practice:

void** base = ...;
int** ibase = reinterpret_cast<int**>(base);

What am I supposed to do? I've been warned away from all use of
reinterpret_cast on the moderated group, and this seems to be a newbie
question.

Andy

Sep 13 '06 #1
12 2514
an*********@yahoo.com wrote:
I have a template array class on T with specialization for bloat when
T is void*. Thus when T is really an int*, my base ptr is physically
a void** and needs to be converted to an int**.
"Needs"?

Let me get this...

template<class Tclass myarray;

template<class myarray<void*{
// some implementation
void** m_storage;
public:
void* operator[](int i) { return m_storage[i]; }
};

template<class Tclass myarray<T*: public myarray<void*{
// what's here?
public:
T* operator[](int i) { return static_cast<T*>(m_storage[i]); }
};

Is that what you're doing? No problem yet, right?
>
This doesn't work:

void** base = ...;
int** ibase = static_cast<int**>(base); // illegal
Why are you trying to convert void** to int**?
and this is bad practice:

void** base = ...;
int** ibase = reinterpret_cast<int**>(base);

What am I supposed to do? I've been warned away from all use of
reinterpret_cast on the moderated group, and this seems to be a newbie
question.
Perhaps you've chosen a bad algorithm. It's a dead end, and you just
don't want to admit it to yourself?

Post more code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 13 '06 #2
<an*********@yahoo.comwrote in message
news:11*********************@i3g2000cwc.googlegrou ps.com...
: I have a template array class on T with specialization for bloat when
T
: is void*. Thus when T is really an int*, my base ptr is physically a
: void** and needs to be converted to an int**.
:
: This doesn't work:
:
: void** base = ...;
: int** ibase = static_cast<int**>(base); // illegal
:
: and this is bad practice:
:
: void** base = ...;
: int** ibase = reinterpret_cast<int**>(base);
:
: What am I supposed to do?

In theory, a void* may have a different in-memory representation
than int* -- even though conversions between the types are well
defined:
int i = 5;
void* p = &i;
*(int*)p = 6; // ok, i is now 6
**(int**)&p = 7; // undefined behavior !!

So if you want strictly portable code, you need to make sure
that the common implementation with void* arrays is always
addressed as a void* array.
: I've been warned away from all use of
: reinterpret_cast on the moderated group, and this seems to be a newbie
: question.

Specializing a template to use a common implementation is not
that much of a newbie question. It used to be more commonly
done a few years ago.
Note that some compilers/linkers today will automatically 'merge'
identical functions, and automatically take care of eliminating
the code bloat that you are trying to avoid.
hth -Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Sep 13 '06 #3

Victor Bazarov wrote:
Post more code.
template <typename T>
class PrivateArray {
T* ar;

public:
T* Ptr (int i) const
{
return ar+i;
}
};

template <typename T>
class Array : public PrivateArray<T{

public:
T& operator [] (int i) const
{
return *Ptr(i);
}
};

// specialize
template <typename T>
class Array<T*{
PrivateArray<void*ar;

public:

T& operator [] (int i) const
{
return *static_cast<T*>(ar.Ptr(i)); // illegal???
}
};

Sep 13 '06 #4

Victor Bazarov wrote:
Why are you trying to convert void** to int**?
The difference is that my operator[] function must return a reference
which is like a pointer to a pointer in this case. I want to avoid the
need to offer both set and get apis, but use ar[N] on both lhs and rhs.

The following snippet doesn't work for exactly the same reason that I'm
stuck:

void** p = ...;
int index = ...;
int*& val = static_cast<int*&>(p[index]); // illegal

Of course, reinterpret_cast and C-style casts work fine, but they're
bad practice?!

Andy

Sep 13 '06 #5
<an*********@yahoo.comwrote in message
news:11**********************@i3g2000cwc.googlegro ups.com...
: The following snippet doesn't work for exactly the same reason that
I'm
: stuck:
:
: void** p = ...;
: int index = ...;
: int*& val = static_cast<int*&>(p[index]); // illegal
:
: Of course, reinterpret_cast and C-style casts work fine,
: but they're bad practice?!

This is not a matter of good or bad practice, nor is it
about the use of reinterpret_cast itself.
It is a matter of knowing that your program is formally correct
and portable, because it obeys the rules of the C++ language.

Depending on what code you are working on, it might be
acceptable or not to break the rule. But if you intend your
code to be secure, maintainable, and portable, you probably
do not want to take this responsibility.
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Sep 13 '06 #6
an*********@yahoo.com wrote:
Victor Bazarov wrote:
>Post more code.

template <typename T>
class PrivateArray {
T* ar;

public:
T* Ptr (int i) const
{
return ar+i;
}
Supposedly, 'ar' is somehow allocated making 'i' a valid index...
};

template <typename T>
class Array : public PrivateArray<T{

public:
T& operator [] (int i) const
{
return *Ptr(i);
}
};

// specialize
template <typename T>
class Array<T*{
PrivateArray<void*ar;

public:

T& operator [] (int i) const
Wait... If this is an array of pointers to T, why are you returing
a reference to T here? Shouldn't you return a reference to a _pointer_
to T?
{
return *static_cast<T*>(ar.Ptr(i)); // illegal???
}

I think you're missing one indirection here somewhere. But, let's say
you got it right:

T*& operator[] (int i) const { ...

How are you going to use it?
};
Please post the code where this array of pointers is going to be used.
Only the use patterns will dig out correct interfaces.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 14 '06 #7
an*********@yahoo.com wrote:
>
This doesn't work:

void** base = ...;
int** ibase = static_cast<int**>(base); // illegal

and this is bad practice:

void** base = ...;
int** ibase = reinterpret_cast<int**>(base);

What am I supposed to do?
Well, I don't really understand why you are doing this, so I can't
answer that question.

But, a void ** can only point to a void *. Nothing else. It isn't
a generic pointer-to-pointer type. The only generic pointer type
is void* itself.

You could perhaps store your int* as void* in the first place and
then you can point to them with the void** ; or perhaps you
could use void * for base, rather than void ** (and remember to
keep your indirection level correct).

If your system happens to have void ** and int ** as being the
same size and representation, then you can "get away with"
a reinterpret cast. But your code would break when you port
to a platform where this guarantee doesn't hold.

Sep 14 '06 #8

Victor Bazarov wrote:
>

I think you're missing one indirection here somewhere. But, let's say
you got it right:

T*& operator[] (int i) const { ...

How are you going to use it?
};

Please post the code where this array of pointers is going to be used.
Only the use patterns will dig out correct interfaces.
Assuming that somehow we create a template Array<Twith following
unspecialized interface:

template <typename T>
class Array {
T* base; // if T==int*, then base==int**

public:
T& operator (int index) const
{
return base[index];
// ok as is, but not if we do specialization using
Array<void*>
}
};

Then I can use it with T=int* as follows once I solve the
specialization problem:

void Swap (Array<int*>& ar, int a, int b)
{
int* p = ar[a];
ar[a] = ar[b];
ar[b] = p;
}

Sep 14 '06 #9
an*********@yahoo.com wrote:
Victor Bazarov wrote:
>>

I think you're missing one indirection here somewhere. But, let's
say you got it right:

T*& operator[] (int i) const { ...

How are you going to use it?
>>};

Please post the code where this array of pointers is going to be
used. Only the use patterns will dig out correct interfaces.

Assuming that somehow we create a template Array<Twith following
unspecialized interface:

template <typename T>
class Array {
T* base; // if T==int*, then base==int**

public:
T& operator (int index) const
{
return base[index];
// ok as is, but not if we do specialization using
Array<void*>
Why would you do your specialisation using Array<void*>? I am
still in the fog about this "premise".
}
};

Then I can use it with T=int* as follows once I solve the
specialization problem:

void Swap (Array<int*>& ar, int a, int b)
{
int* p = ar[a];
ar[a] = ar[b];
ar[b] = p;
}
What a weird way to swap... Why don't you use 'std::swap' and
do

std::swap(ar[a], ar[b]);

? But in any case, why would you keep an array of 'int*'? I
can understand an array of pointers to some base class to be used
polymorphically, but int*?

Are you just being hypothetical here?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 14 '06 #10

Victor Bazarov wrote:
an*********@yahoo.com wrote:
Why would you do your specialisation using Array<void*>? I am
still in the fog about this "premise".
I was hoping to avoid bloat in the constructor and destructor which are
fairly involved. The program could have many instances of T such as
int*, char*, etc. If there was some safe way to internally hold the
representation of T* as void** then there would be no code bloat for
all T where T is a T*.
>
What a weird way to swap... Why don't you use 'std::swap' and
do
That was just an example to show that the operator[] needs to return a
reference since the array access is being used as both lhs-value and
rhs-value.
? But in any case, why would you keep an array of 'int*'? I
can understand an array of pointers to some base class to be used
polymorphically, but int*?

Are you just being hypothetical here?
Yes, just being hypothetical.

Sep 14 '06 #11
an*********@yahoo.com writes:
Victor Bazarov wrote:
// specialize
template <typename T>
class Array<T*{
PrivateArray<void*ar;

public:

T& operator [] (int i) const
{
return *static_cast<T*>(ar.Ptr(i)); // illegal???
}
};
I don't quit understand the code but maybe:

#v+
template <typename Tclass Array<T*{
PrivateArray<T*ar;
public:
T& operator [] (int i) const { return *(ar.Ptr(i)); }
};
#v-

I mean: why do you need an array of "void*" instead of array of "T*"?

--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86*tlen.pl>--<jid:mina86*jabber.org>--ooO--(_)--Ooo--
Sep 14 '06 #12

an*********@yahoo.com wrote:
I was hoping to avoid bloat in the constructor and destructor which are
fairly involved. The program could have many instances of T such as
int*, char*, etc. If there was some safe way to internally hold the
representation of T* as void** then there would be no code bloat for
all T where T is a T*.
I assume you are trying to implement a typed pointer array where
underneath you store them all as void*.

When it comes to providing iterators you now what to implement such as
a pointer so you are casting your array of void* to an array of T*.

Because the casting is all done secretly by your template you know that
what you are doing is safe.

You might, by the way, consider implementing the iterators as pointer
wrappers.

Sep 14 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

31
by: Jamie Burns | last post by:
Hello, I am writing a client / server application. There is 1 server, and many clients. The server processes requests from each client, and typically creates and manipulates C++ objects on their...
5
by: Dave Townsend | last post by:
Hi, I'm trying to port a piece of code from Windows to Linux, the following segment illustrates the coding problemI have: Under Linux, the reinterpret_cast line doesn't compile, the compiler...
7
by: James Mcguire | last post by:
Hi, I frequently do non-initialisation type structure assignment via casting: e.g. struct s{int i,j,k;} mys; .... mys=(struct s){3,4,5};
1
by: Reza Nabi | last post by:
Bakground: I have a webform (LoadCtl.aspx) which loads the user control to a placeholder dynamically based on the ctlName querystring passed in the URL. Webform (LoadCtl.aspx) also passes a...
11
by: Roman Mashak | last post by:
Hello, All! I'm implementing function parsing config file, which look like this: # this is comment port=10000 path=/var/run/dump.pid .... Declared the type
12
by: Abhishek | last post by:
now suppose I have declared an integer value inside a function as int x; now if the return type of the function is of type (void *) then can I write return((void *)x) in side the function? I...
9
by: Frederick Gotham | last post by:
Let's assume that we're working on the following system: CHAR_BIT == 8 sizeof( char* ) == 4 (i.e. 32-Bit) Furthermore, lets assume that the memory addresses are distributed as follows: ...
16
by: JoseMariaSola | last post by:
How may operators and operands does (typename) expression has? I'd say one operator, the cast operator, and two operands: typename and expression. But everywhere I read, cast is categorized as...
7
by: * Tong * | last post by:
Hi, I couldn't figure out how to properly type cast in this case: $ cat -n type_cast.c 1 #include <stdio.h> 2 3 typedef unsigned char Byte; 4 typedef signed char Small_Int; 5
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.