473,666 Members | 2,357 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 1769
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_cas t.

Look up reinterpret_cas t.

Then remember in the future to not use C-style casts, and remember that
while you're still a novice every occurrence of reinterpret_cas t 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.co mwrote:
junw2...@gmail. com wrote:
Hi,
For the code below:
char *c = "0113";shou ld 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<uns igned 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.co mwrote:

Maybe I should do this:
p = static_cast<uns igned short*>c;
p = reinterpret_cas t<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.co mwrote:
>junw2...@gmail .com wrote:
Hi,
For the code below:
char *c = "0113";shou ld 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<uns igned 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_cas t 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(typ e)) * type(CHAR_BIT)) - 1 is equal to
std::type_trait s<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(un signed short)) *
unsigned short(CHAR_BIT) ) - 1 !=
std::type_trait s<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<con st
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"; (string)xyz; now we only have a type object of System.String type
15
1723
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
10460
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 an unsigned integer, so I see a +1 if the bit is set. Microsoft VC++ thinks it's signed, so I see -1 if the bit is set. Ex. typedef enum {
26
2117
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
1923
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 as to make it treat its first argument as a "read-only" object, that is, foo() can read but not alter the matrix. I have a problem, however, with /calling/ foo. If I call foo as foo(a,m,n), my compiler (gcc) complains about:
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 specifies a conversion even if the type of the expression is the same as the named type. Can someone give me an example of what this means ?
14
1901
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
1944
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 think it should be the latter because there are 4 parser tokens here, sizeof, int, * and p, the first and the second are of same precedence which are higher than the third and all three operators are
14
2431
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' parameter and set EOF indicator for the stream ? Or will it return the string argument and set EOF indicator only on subsequent call ? Kindly clarify
0
8440
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8352
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8863
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8780
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8549
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7378
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5661
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4192
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2765
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 we have to send another system

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.