473,508 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Question about cast

Hi,

For the code below:

char *c = "0113";
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';

The output is:
*p: 12592
*c: 0113

Why?
How does LINE1 work? For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?

Thanks

Jack

Jan 25 '07 #1
8 1757
ju******@gmail.com wrote:
Hi,

For the code below:

char *c = "0113";
should be const char*.
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';

The output is:
*p: 12592
*c: 0113

Why?
What else would you expect?
How does LINE1 work? For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?
It assigns the value of c to p. Assuming sizeof unsigned short to be 2,
*p is the first two bytes of the string literal pointed to by 2.

Convert 12592 to hex and check the ASCII values for '0' and '1'

--
Ian Collins.
Jan 25 '07 #2
* ju******@gmail.com:
Hi,

For the code below:

char *c = "0113";
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';

The output is:
*p: 12592
*c: 0113

Why?
Why not? What did you expect?

How does LINE1 work?
It uses a C-style cast, which is interpreted as a reinterpret_cast.

Look up reinterpret_cast.

Then remember in the future to not use C-style casts, and remember that
while you're still a novice every occurrence of reinterpret_cast in
your code means you have a bug.

For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?
It doesn't.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jan 25 '07 #3


On 25 Jan, 08:45, junw2...@gmail.com wrote:
Hi,

For the code below:

char *c = "0113";
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';

The output is:
*p: 12592
*c: 0113

Why?
Because casts like this have undefined behaviour. There is no why,
undefined behaviour means anything is allowed to happen.
How does LINE1 work? For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?
Since LINE1 is undefined behaviour any further questions are
meaningless.

Jan 25 '07 #4


On Jan 25, 3:45 pm, junw2...@gmail.com wrote:
For the code below:

char *c = "0113";
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';

The output is:
*p: 12592
*c: 0113

Why?
It looks like the program is trying to show that the memory location
where the string is located (p) and the string. It is showing that if
you send a char * (should be const char *) to an IO stream it will
print as a character string. However, if you send a pointer to any
other type to a IO stream it will display the memory location.

The cast in //LINE1 is a nasty hack and you should never do anything
like it. I don't know if the cast itself is UB, but I'm pretty sure
that dereferencing p would be (if I had to guess I would say that the
code was written on a platform where sizeof( unsigned short ) ==
sizeof( char ) == 1). If p were a const void * then it would be
correct, but still not a good thing to do unless forced (normally to
interact with C style code).
How does LINE1 work? For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?
It doesn't. c is really a pointer to the memory location that the
string is stored at. The line is simply a way of getting that memory
location pointer into something that can be displayed by the IO stream
as a pointer rather than a string.

The first three lines are reasonable C, but unreasonable C++.
K

Jan 26 '07 #5


On Jan 25, 12:52 am, Ian Collins <ian-n...@hotmail.comwrote:
junw2...@gmail.com wrote:
Hi,
For the code below:
char *c = "0113";should be const char*.
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';
The output is:
*p: 12592
*c: 0113
Why?What else would you expect?
Maybe I should do this:
p = static_cast<unsigned short*>c;
Is it right?
I need to do checksum of a string. The function is like this: checksum(
unsigned short *p, int count).
So I have to convert char* to unsign short*. Is there any better to do
it?
>
How does LINE1 work? For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?It assigns the value of c to p. Assuming sizeof unsigned short to be 2,
*p is the first two bytes of the string literal pointed to by 2.

Convert 12592 to hex and check the ASCII values for '0' and '1'
The binary of 12592 is 11000100110000. The binary of '0' is 11000. The
binary of '1' is 110001.
After the cast, why it becomes '10' other than '01'?

Thanks.

Jack

Jan 26 '07 #6
ju******@gmail.com wrote:
>
On Jan 25, 12:52 am, Ian Collins <ian-n...@hotmail.comwrote:

Maybe I should do this:
p = static_cast<unsigned short*>c;
p = reinterpret_cast<short*>(c);
>
>>>How does LINE1 work? For the string "0113", there is a implicit '/0' at
the end. How does LINE1 handle it?It assigns the value of c to p. Assuming sizeof unsigned short to be 2,

*p is the first two bytes of the string literal pointed to by 2.

Convert 12592 to hex and check the ASCII values for '0' and '1'


The binary of 12592 is 11000100110000. The binary of '0' is 11000. The
binary of '1' is 110001.
After the cast, why it becomes '10' other than '01'?
Google for little endian.
--
Ian Collins.
Jan 26 '07 #7
ju******@gmail.com wrote:
>

On Jan 25, 12:52 am, Ian Collins <ian-n...@hotmail.comwrote:
>junw2...@gmail.com wrote:
Hi,
For the code below:
char *c = "0113";should be const char*.
unsigned short *p;
p = (unsigned short*)c; //LINE1
std::cout<<"*p: "<<*p<<'\n';
std::cout<<"*c: "<<c<<'\n';
The output is:
*p: 12592
*c: 0113
Why?What else would you expect?

Maybe I should do this:
p = static_cast<unsigned short*>c;
Is it right?
I need to do checksum of a string. The function is like this: checksum(
unsigned short *p, int count).
So I have to convert char* to unsign short*. Is there any better to do
it?
There may be no way to solve the underlying problem by casting pointer types
around. E.g., what happens if the char* points to a place not suitably
aligned for short? What happens if the string contains a number of
characters that is not a multiple of sizeof(short)? Besides, very likely
you have undefined behavior anyway, depending on what checksum() does
internally.
Best

Kai-Uwe Bux
Jan 26 '07 #8
There is a standard way to do this, though it involves a bit of
implementation-defined behavior (such as endianness). There are two
errors in your code: first, the reinterpret_cast is not valid because
unsigned short could have stricter alignment requirements than char,
and you attempt to access a string literal as an unsigned short. The
latter is wrong for two reasons, one because the alignment
requirements of short could be stricter than char, and two because the
standard disallows accessing objects as different types, so the
compiler could optimize it away.

char *c = "0113" is valid, because old C code used that idiom a lot,
so it was included for backwards compatibility. It's use is deprecated
though.

The second problem can be avoided by copying the array into an
unsigned short. The first can be avoided by first casting to void *,
then char * or unsigned char *. You could also use std::memcpy or
std::memmove, since the standard appears to make special consideration
for them (it uses them in examples). This sort of copying is only
allowed for POD types.

Technically the standard only allows for copying of this sort from one
object to another of the same type because types are allowed to have
padding bits and trap bits, but as long as (type(1) <<
type(sizeof(type)) * type(CHAR_BIT)) - 1 is equal to
std::type_traits<type>::max(), for unsigned types at least, the
copying will be valid. In practice, I doubt you'll find too many
implementations that go into these peculiarities.

Here's a valid implementation (assuming some valid min() function):

if ((unsigned short(1) << unsigned short(sizeof(unsigned short)) *
unsigned short(CHAR_BIT)) - 1 !=
std::type_traits<unsigned short>::max()) return;
unsigned short s = 0;
const char *c = "0113";
for (std::size_t i = 0; i < min(sizeof(s), 5); ++i) static_cast<const
char *>(static_cast<const void *>(&s))[i] = c[i];
std::cout<<"s: "<<s<<'\n';
std::cout<<"c: "<<c<<'\n';

The actual value of s is implementation-defined due to several factors
including the size of s, the representation of unsigned shorts and the
values '0' '1' and '3' map to. The vast majority of platforms will
represent an unsigned short as a two's complement integer of two
bytes, with the bit order the same as a char. The only thing that will
differ normally is endianness, whether the '0' or the '1' will make up
the first byte.

Jan 27 '07 #9

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

Similar topics

4
547
by: Richard Lee | last post by:
Hi, I have a question when I do a data type cast. the common way when we do a cast, is we know the type we want to cast to, i.e. we want to cast object to string, object xyz = "question";...
15
1699
by: Christopher Benson-Manica | last post by:
If you had an unsigned int that needed to be cast to a const myClass*, would you use const myClass* a=reinterpret_cast<const myClass*>(my_val); or const myClass* a=(const myClass*)myVal; ...
4
10428
by: Ray | last post by:
When a single-bit bitfield that was formed from an enum is promoted/cast into an integer, does ANSI C say anything about whether that integer should be signed or unsigned? SGI IRIX cc thinks it is...
26
2097
by: Janice | last post by:
What is the major reason for using void*? When should we use void* for both input arguments and return value? How can we cast the void* pointer to the type we need? Thanx
9
378
by: walt.stoneburner | last post by:
Why does aliasing an interface fail at runtime? SAMPLE WORKING CODE ... IHTMLDocument2 doc = (IHTMLDocument2) browser.Document; ... BROKEN CODE public interface IFooBar : IHTMLDocument2 { }...
2
1887
by: Rouben Rostamian | last post by:
The main() function in the following code defines an m by n matrix, assigns value(s) to its elements, then passes the matrix to function foo(). For whatever it's worth, I have declared foo() so...
6
365
by: spibou | last post by:
In page 81 of N1124 in footnote 87 we read: If the value of the expression is represented with greater precision or range than required by the type named by the cast (6.3.1.8), then the cast...
14
1886
by: Daniel | last post by:
Hi guys who just answered me.....it really would have helped if i had written it right. Ok i will use better names to explain my problem. I have this: InterFaceClass ^ ClassA
7
1937
by: linq936 | last post by:
Hi, I am puzzled on this C puzzle: How to interpret this C statement: sizeof (int) * p Is that the size of integer type multiplies p or the size of whatever p points to in integer type? I...
14
2414
by: subramanian100in | last post by:
Suppose fgets is used to read a line of input. char str; fgets(str, sizeof(str), stdin); After reading some characters on the same line, if end-of-file is encountered, will fgets return the 'str'...
0
7226
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
7125
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
7388
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...
1
7049
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
5631
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5055
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3186
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1561
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
422
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

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.