![]() |
reinterpret_cast
I am trying to understand reinterpret_cast,here is what i tried,
#include<iostream> #include<cstdio> using namespace std; int main() { int x=1; int* y=&x; char* p= reinterpret_cast<char*>(y); /*I expect the following line to access different bytes of x as chars and print them.what should I expect?Am i expecting right? */ printf("\n the chars are %c %c %c %c\n",p[0],p[1],p[2],p[3]); return 0; } I want to know what is going behind. Thanks for any help. |
Re: reinterpret_cast
On Jun 10, 2:25*pm, saurabh <hah...@hehehe.com> wrote:
> I am trying to understand reinterpret_cast,here is what i tried, > > #include<iostream> > #include<cstdio> > using namespace std; > int main() > { > > * * * * int x=1; > * * * * int* y=&x; > * * * * char* p= reinterpret_cast<char*>(y); > * * * * /*I expect the following line to access different bytes of x as chars and > * * * * print them.what should I expect?Am i expecting right? */ > * * * * printf("\n the chars are %c %c %c %c\n",p[0],p[1],p[2],p[3]); > > * * * * return 0; > > } > > I want to know what is going behind. > Thanks for any help. Hi Saurabh, You are accessing uninitialized memory and the result of doing that is undefined. That is preceisely what will happen here, it will be undefined behavior. By the way, on a side note, reinterpret_cast is required in wierd cases like casting function pointers. It is not really advised to use the reinterpret_cast as its no better than our old friend the c-style cast. Regards Harsh |
Re: reinterpret_cast
saurabh wrote:
> I am trying to understand reinterpret_cast,here is what i tried, > > #include<iostream> > #include<cstdio> > using namespace std; > int main() > { > > int x=1; > int* y=&x; > char* p= reinterpret_cast<char*>(y); So far so good (btw, this is well defined because x is a POD and you may reinterpret_cast pointers to PODs to pointers to char in a well defined way using reinterpret cast). > /*I expect the following line to access different bytes of x as chars and > print them.what should I expect?Am i expecting right? */ > printf("\n the chars are %c %c %c %c\n",p[0],p[1],p[2],p[3]); Right. Tho the reason to print those bytes as characters instead of printing their numeric values avoids me. Also, notice that tho the standard says that you can treat PODs as array of chars this applies to their object representation (the bytes array that make the POD object contents as given by sizeof()) but they do not also mean the value representation (the bits from the object representation that are actually used to form the value of the POD, that is, it is to be expected that some bits are just for padding there and printing/interpreting their values in that char array of yours won't make much sense). > I want to know what is going behind. What's going behind what? -- Dizzy |
Re: reinterpret_cast
On Jun 10, 7:02 am, Harsh Puri <harsh.p...@gmail.com> wrote:
> On Jun 10, 2:25 pm, saurabh <hah...@hehehe.com> wrote: > It is not really advised to use > the reinterpret_cast as its no better than our old friend the c-style > cast. Maybe you should give reinterpret_cast another chance. It is a protective friend who will not allow you cast-away const or volatile. :) Dump the C-style cast already! It may stab you on the back one day. :) Ali |
Re: reinterpret_cast
On Jun 10, 10:02 am, Harsh Puri wrote:
> On Jun 10, 2:25 pm, saurabh wrote: > > int main() > > { > > int x=1; > > int* y=&x; > > char* p= reinterpret_cast<char*>(y); > > /*I expect the following line to access different bytes of x as chars and > > print them.what should I expect?Am i expecting right? */ > > printf("\n the chars are %c %c %c %c\n",p[0],p[1],p[2],p[3]); > > return 0; > > } > You are accessing uninitialized memory This is not true. Every variable in the above program is initialized before it is used. -- franl |
Re: reinterpret_cast
> On Tue, 10 Jun 2008 17:07:42 +0300, dizzy wrote:
>> saurabh wrote: > .....SNIP.... > So far so good (btw, this is well defined because x is a POD and you may > reinterpret_cast pointers to PODs to pointers to char in a well defined way > using reinterpret cast). >> /*I expect the following line to access different bytes of x as chars and >> print them.what should I expect?Am i expecting right? */ >> printf("\n the chars are %c %c %c %c\n",p[0],p[1],p[2],p[3]); > Right. Tho the reason to print those bytes as characters instead of printing > their numeric values avoids me. > Also, notice that tho the standard says that you can treat PODs as array of > chars this applies to their object representation (the bytes array that > make the POD object contents as given by sizeof()) but they do not also > mean the value representation (the bits from the object representation that > are actually used to form the value of the POD, that is, it is to be > expected that some bits are just for padding there and > printing/interpreting their values in that char array of yours won't make > much sense). > Thanks, I didn't know about the padding bits.I thought by guessing the binary respresentation of the integer I can guess what characters would be printed. >> I want to know what is going behind. > What's going behind what? what's going behind means whats going in the memory,How that integer is represented in the memory?Can I predict the output? |
Re: reinterpret_cast
saurabh wrote:
> Thanks, I didn't know about the padding bits.I thought by guessing the > binary respresentation of the integer I can guess what characters would be > printed. Exotic platforms have integrals with padding (I think only the unsigned ones are allowed to that, the signed ones should not). But one common case of padding is in a POD struct: struct S { char a; int b; }; std::cout << sizeof(char) << ", " << sizeof(int) << ", " << sizeof(S); Run that and try to interpret the values. Surprise? :) > >>> I want to know what is going behind. > >> What's going behind what? > > what's going behind means whats going in the memory,How that integer is > represented in the memory?Can I predict the output? Well first of all there are some guarantees from the standard. The standard says that the unsigned integral values (that is even for the signed types, if we store a value without sign) a C++ implementation will use a pure binary system. To store negative values the standard allows 3 representations 2's complement, 1's complement and sign and magnitude. All these negative value implementations (you can look them up on wikipedia or your student textbook) use a single bit for the sign. Then there are alot of platform specific details, such as the size of a byte (in bits), the size in bytes of a type, the number of bits used for the value representation. For the first you can use std::numeric_limits<unsigned char>::digits. For the second of course you can use sizeof(type) (and with these 2 you can find out the number of bits that make the object representation of a type). Using std::numeric_limits<int>::digits tells you the number of bits used for the value of an int (without the bit sign). Is that enough for your needs? -- Dizzy |
Re: reinterpret_cast
On Jun 11, 3:34 am, Fran <flitte...@gmail.com> wrote:
> On Jun 10, 10:02 am, Harsh Puri wrote: > > On Jun 10, 2:25 pm, saurabh wrote: > > > int main() > > > { > > > int x=1; > > > int* y=&x; > > > char* p= reinterpret_cast<char*>(y); > > > /*I expect the following line to access different bytes of x as chars and > > > print them.what should I expect?Am i expecting right? */ > > > printf("\n the chars are %c %c %c %c\n",p[0],p[1],p[2],p[3]); > > > return 0; > > > } > > You are accessing uninitialized memory > This is not true. Every variable in the above program is > initialized before it is used. Only if sizeof(int) >= 4. On the other hand, he's outputting what is basically binary data to a stream opened in text mode, which is undefined behavior. -- James Kanze (GABI Software) email:james.kanze@gmail.com 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 |
Re: reinterpret_cast
On Jun 11, 9:59 am, dizzy <di...@roedu.net> wrote:
> saurabh wrote: > > Thanks, I didn't know about the padding bits.I thought by > > guessing the binary respresentation of the integer I can > > guess what characters would be printed. > Exotic platforms have integrals with padding (I think only the > unsigned ones are allowed to that, the signed ones should > not). Character types are not allowed to have padding; all other types can. Signed integral types can also have two 0's (+ and -), and implementations can trap on -0. (But C++, unlike C, doesn't allow trapping representations in plain char, so if signed char has a trapping -0, then plain char must be unsigned.) BTW: your earlier comments mentionned POD's. There is no restriction to POD's here: you can access the underlying memory of any type through an lvalue of character type. (The difference is that using this to copying a non-POD elsewhere is not guaranteed to be value preserving.) > But one common case of padding is in a POD struct: > struct S { char a; int b; }; > std::cout << sizeof(char) << ", " << sizeof(int) << ", " << sizeof(S); > Run that and try to interpret the values. Surprise? :) > >>> I want to know what is going behind. > >> What's going behind what? > > what's going behind means whats going in the memory,How that > > integer is represented in the memory? Can I predict the > > output? > Well first of all there are some guarantees from the standard. > The standard says that the unsigned integral values (that is > even for the signed types, if we store a value without sign) a > C++ implementation will use a pure binary system. To store > negative values the standard allows 3 representations 2's > complement, 1's complement and sign and magnitude. All these > negative value implementations (you can look them up on > wikipedia or your student textbook) use a single bit for the > sign. The C++ standard isn't as clear as one would like in this regard, but I'm pretty sure that the intent is C compatibility. Which means that integral types (except for unsigned char, and char in C++) can have padding bits and trapping representations. One current implementation has 48 bit ints with only 39 value bits. -- James Kanze (GABI Software) email:james.kanze@gmail.com 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 |
Re: reinterpret_cast
James Kanze wrote:
> On Jun 11, 9:59 am, dizzy <di...@roedu.net> wrote: >> saurabh wrote: >> > Thanks, I didn't know about the padding bits.I thought by >> > guessing the binary respresentation of the integer I can >> > guess what characters would be printed. > >> Exotic platforms have integrals with padding (I think only the >> unsigned ones are allowed to that, the signed ones should >> not). > > Character types are not allowed to have padding; all other types > can. Good, I never was sure about how to interpret 3.9.1 1. It says "character types have no padding" but I was never sure if that means all character types or just "char". > Signed integral types can also have two 0's (+ and -), and > implementations can trap on -0. (But C++, unlike C, doesn't > allow trapping representations in plain char, so if signed char > has a trapping -0, then plain char must be unsigned.) You are right. I think I confused this with POSIX/C99 intX_t types for which it says if they exist they are a native signed integral type with no padding of those number of bits but it doesn't say the no padding thing for uintX_t. > BTW: your earlier comments mentionned POD's. There is no > restriction to POD's here: you can access the underlying memory > of any type through an lvalue of character type. (The > difference is that using this to copying a non-POD elsewhere is > not guaranteed to be value preserving.) You are right that I was thinking about the standard mentioning the copy of the value. But then I looked again and searched the standard and I can't seem to find where it says that you can convert in a well defined way a T* rvalue to a (unsigned/signed) char* rvalue. Can you point me to it? > The C++ standard isn't as clear as one would like in this > regard, but I'm pretty sure that the intent is C compatibility. > Which means that integral types (except for unsigned char, and > char in C++) can have padding bits and trapping representations. > One current implementation has 48 bit ints with only 39 value > bits. Getting OT, does this implementation offer POSIX/C99 compliant stdint.h? Because that 48 object/39 value bit integral does not seem like a good candidate for int48_t or int39_t :) -- Dizzy |
| All times are GMT. The time now is 01:22 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.