473,387 Members | 1,882 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,387 software developers and data experts.

uchar -> void* -> uchar

Hi All,

Is it safe to store a uchar in a void* and then extract the uchar value
out of it again ?

My understanding is that the size of a void* should always be equal to
or greater than the size of a uchar. So, theoretically, this should be
safe. Please correct me if I am wrong.

I've got the following code that compiles (with warnings), and it also
works as desired.

3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 b = (void*) a;
14 printf("\nb is %x\n", b);
15
16 c = (unsigned char) b;
17 printf("\nc is %c\n", c);
18 }

I get the following warnings, for obvious reasons:

~/strings #5 > gcc void.c
void.c: In function `main':
void.c:13: warning: cast to pointer from integer of different size
void.c:16: warning: cast from pointer to integer of different size

Is there anyway to get rid of these warnings (without using memcpy) ?

I rewrote the code as follows:

3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 memcpy(&b, &a, sizeof(unsigned char));
14 printf("\nb is %x\n", b);
15
16 memcpy(&c, &b, sizeof(unsigned char));
17 printf("\nc is %c\n", c);
18 }

No warnings, and it works as before.

Are there any gotchas as to the safety or portability of this code ?

TIA,
rouble

Nov 14 '05 #1
6 3452
rouble wrote:
Hi All,

Is it safe to store a uchar in a void* and then extract the uchar value
out of it again ?
Pointers store addresses in them. The following piece of code should
make things a bit more clearer:

int main()
{
unsigned char a='A', c;
void *b=NULL;

printf("sizeof(void *)=%d\n",sizeof(void *)); // 4
printf("sizeof(unsigned char)=%d\n",sizeof(unsigned char)); // 1

printf("a is %c(0x%x)\n",a,a); // A(0x41)
printf("b points to %p\n",b); // nil
memcpy(&b, &a, sizeof(unsigned char));
printf("now b points to %p\n",b); // (0x41) <- this is what you are
doing
memcpy(&c, &b, sizeof(unsigned char));
printf("c is %c(0x%x)\n",c,c); // A(0x41)
}
My understanding is that the size of a void* should always be equal to
or greater than the size of a uchar. So, theoretically, this should be
safe. Please correct me if I am wrong.

Although you are right about the size part, you cant make use of the
pointer in a manner that makes sense to use a pointer, i.e. address
0x41(or some other value that you assign) could be anything! Trying to
modify it (or even access it) might raise errors. It would be safer to
allocate space for an unsigned char using malloc, then put the value of
'a' in _that_ space, and then copy it from there to 'c'.

cheers,
forayer

Nov 14 '05 #2
On Sun, 19 Jun 2005 22:39:46 -0700, forayer wrote:
rouble wrote:
Is it safe to store a uchar in a void* and then extract the uchar value
out of it again ?

Pointers store addresses in them. The following piece of code should
make things a bit more clearer:


<snip explanation>
My understanding is that the size of a void* should always be equal to
or greater than the size of a uchar. So, theoretically, this should be
safe. Please correct me if I am wrong.

Although you are right about the size part, you cant make use of the
pointer in a manner that makes sense to use a pointer,


From the tone of his post I gather that rouble understands this.

I'm no standards guru like many on this group are but it looks kosher to
me. I don't know if it's guaranteed that void* is always larger than uchar
but I'd be very surprised if it wasn't.
It would be safer to
allocate space for an unsigned char using malloc, then put the value of
'a' in _that_ space, and then copy it from there to 'c'.


Sure. But he's not asking for a safer or different way to do it, he seems
to understand that it's a quirky thing to do and simply wants to know
whether this quirky thing is standards-compliant.

Or perhaps I've wildly misread his post - you do realise that this is an
odd and unnecessary thing to be doing, right?

Nov 14 '05 #3


rouble wrote:
Hi All,

Is it safe to store a uchar in a void* and then extract the uchar value
out of it again ?
Converting an integer to a pointer type is implementation defined.
And it is better to avoid this.
My understanding is that the size of a void* should always be equal to
or greater than the size of a uchar. So, theoretically, this should be
safe. Please correct me if I am wrong.

Since, pointers and integers may have different representation on
a particular implementation, size doesn't matter.
You are not guaranteed to get the same integer value back.

<snip>

Nov 14 '05 #4
rouble wrote:
Hi All,

Is it safe to store a uchar in a void* and then extract the uchar
value out of it again ?
You haven't said _why_ you feel this is important?
My understanding is that the size of a void* should always be equal
to or greater than the size of a uchar.
It must be at least 1 byte.
So, theoretically, this should be safe. Please correct me if I am
wrong.
Gladly...
I've got the following code that compiles (with warnings), and it
also works as desired.
On your implementation perhaps.
3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 b = (void*) a;
This involves an implementation defined conversion.
14 printf("\nb is %x\n", b);
15
16 c = (unsigned char) b;
This also involves an implementation defined conversion and need
not yield the original value.
17 printf("\nc is %c\n", c);
18 }

I get the following warnings, for obvious reasons:

~/strings #5 > gcc void.c
void.c: In function `main':
void.c:13: warning: cast to pointer from integer of different size
void.c:16: warning: cast from pointer to integer of different size

Is there anyway to get rid of these warnings (without using
memcpy) ?
It would be better if you understood why the warnings were there
in the first place, rather than seek a method of removing them.

C programmers should not play Russian Roulette.
I rewrote the code as follows:

3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 memcpy(&b, &a, sizeof(unsigned char));
Another way is...

* (unsigned char *) &b = a;
14 printf("\nb is %x\n", b);
15
16 memcpy(&c, &b, sizeof(unsigned char));
c = * (unsigned char *) &b;
17 printf("\nc is %c\n", c);
18 }

No warnings, and it works as before.


You can safely imprint any byte within an object, however the original
object becomes unspecified. [In other words, b becomes useless as a
void *.]

It all sounds like classic trap for young players...

I have a problem A. I think the solution is X but I can't make it
work. I'll ask how to do X.

You should be asking how to solve problem A.

--
Peter

Nov 14 '05 #5
rouble wrote:
Hi All,

Is it safe to store a uchar in a void* and then extract the uchar value
out of it again ?

My understanding is that the size of a void* should always be equal to
or greater than the size of a uchar. So, theoretically, this should be
safe. Please correct me if I am wrong.

I've got the following code that compiles (with warnings), and it also
works as desired.

3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 b = (void*) a;
14 printf("\nb is %x\n", b);
15
16 c = (unsigned char) b;
17 printf("\nc is %c\n", c);
18 }
See the explanations in other replies.

I get the following warnings, for obvious reasons:

~/strings #5 > gcc void.c
void.c: In function `main':
void.c:13: warning: cast to pointer from integer of different size
void.c:16: warning: cast from pointer to integer of different size

Is there anyway to get rid of these warnings (without using memcpy) ?
Yes, access b using an unsigned char*.
I.e.
unsigned char *p = (unsigned char *)&b;
*p = a;

Note: Even if a is not of type unsigned char, p has to be of type
unsigned char*; one then has to access a in the same way.
p[i] = ((unsigned char *)&a)[i];
I rewrote the code as follows:

3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 memcpy(&b, &a, sizeof(unsigned char));
14 printf("\nb is %x\n", b); ITYM: %p - everything else is not safe. 15
16 memcpy(&c, &b, sizeof(unsigned char));
17 printf("\nc is %c\n", c);
18 }

No warnings, and it works as before.

Are there any gotchas as to the safety or portability of this code ?


Yep. Copying a to the first byte of b might bring b into a trap
representation, so that b cannot be safely accessed.

There is no way around this. As long as you only access
*(unsigned char *)&b, you should be on the safe side, though.
I strongly discourage that.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 14 '05 #6
On Sun, 19 Jun 2005 17:27:55 -0700, rouble wrote:
Hi All,

Is it safe to store a uchar in a void* and then extract the uchar value
out of it again ?

My understanding is that the size of a void* should always be equal to
or greater than the size of a uchar. So, theoretically, this should be
safe. Please correct me if I am wrong.

I've got the following code that compiles (with warnings), and it also
works as desired.
What was it you wanted it to do, what are you trying to achieve? Why is it
necessary to use a void * variable here?
3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 b = (void*) a;
14 printf("\nb is %x\n", b);
15
16 c = (unsigned char) b;
17 printf("\nc is %c\n", c);
18 }

I get the following warnings, for obvious reasons:

~/strings #5 > gcc void.c
void.c: In function `main':
void.c:13: warning: cast to pointer from integer of different size
void.c:16: warning: cast from pointer to integer of different size

Is there anyway to get rid of these warnings (without using memcpy) ?
Yes, you fix the code by not trying to cast an integer to a pointer and
back again. This isn't a meaningful operation in standard C.
I rewrote the code as follows:

3 int
4 main ()
5 {
6
7 unsigned char a = 'A';
8 void *b = NULL;
9 unsigned char c;
10
11 printf("\na is %c\n", a);
12
13 memcpy(&b, &a, sizeof(unsigned char)); 14 printf("\nb is
%x\n", b);
15
16 memcpy(&c, &b, sizeof(unsigned char)); 17 printf("\nc is
%c\n", c);
18 }

No warnings, and it works as before.
This works because the value is not converted to void * and back. It is
legitimate to treat any addressible object as an array of unsigned char
which is in effect what memcpy() does. It is not doing the same thing as
the casting version.
Are there any gotchas as to the safety or portability of this code ?


Yes, integer/pointer casting is inherently non-portable.

Lawrence
Nov 14 '05 #7

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

Similar topics

8
by: maths_fan | last post by:
Can't understand how to overload these operations and for what reason?
6
by: Anuradha | last post by:
Below is the code which was written VC++ 6.0 under windows environment. Executing the same throws: ------------------ Debug Error! Program: ccheck.exe DAMAGE: after normal block (#41) at...
0
by: Plumer | last post by:
Good morning everyone, Using C# I create a bog-standard System.Data.DataTable which I then Add to a System.Data.Dataset. I need to import that structure into an Access .adp file so I have...
3
by: Ben | last post by:
I'm having problems with cookies from asp.net to asp back to asp.net. It seems like I can set a cookie in asp.net fine, and alter it at will, as soon as asp touches it, asp.net won't have...
4
by: Alex Vinokur | last post by:
Should 'delete below (after casting to void*)' work fine? ------------------------------------------ char* p1 = new (nothrow) char; if (p1 == 0) return; void* p2 = reinterpret_cast<void*> (p1);...
3
by: Alex Maghen | last post by:
Hi. I'm a little confused about the code that resides in the code-behind of a MasterPage and the code that resides in the code-behind of the actual pages that USE that MasterPage. I'm noticing,...
11
by: Ole Nielsby | last post by:
First, sorry if this is off-topic, not strictly being a C++ issue. I could not find a ng on numerics or serialization and I figure this ng is the closest I can get. Now the question: I want...
3
by: yancheng.cheok | last post by:
Hello all, I try to figure out what is the sequence when we create and delete an object. After experiment on my VC++ 2003, I found that here is the sequence new-constructor-destructor-delete ...
3
by: Peterwkc | last post by:
Hello all expert C++ programmer, i fairly new to C++ programming. I have a class cellphone which contain dynamic pointer. I have create (example)ten cellphone. I want to ask user for the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

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.