From: Francis Glassborow on 23 Nov 2009 23:00 Rune Allnor wrote: > Hm. > > Wrote the code and the post in parallel, so I lost the > point first time around. > > In the code below is the test using reinterpret_cast<> > added, along with the corresponding added output. > As can be seen, each char value is preceeded by a number > of leading zeros that I am unable to get rid of. I assume > this has something to do with memory footprints and/or byte > ordering (I am using VS2008 on a PC, which, according to > > http://en.wikipedia.org/wiki/Endianness > > means that the internal byte organization is little-endian). > But reinterpret_cast<> is exactly the case where bit patterns are being considered along with memory 'footprints'. It is very low level and intentionally unlikely to be useful in a portable program. Easy detection was one reason for the long. ugly name (seriously, that was part of the design of C++ casts) -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nick Hounsome on 23 Nov 2009 23:01 On 24 Nov, 05:51, Rune Allnor <all...(a)tele.ntnu.no> wrote: > Hm. > > Wrote the code and the post in parallel, so I lost the > point first time around. > > In the code below is the test using reinterpret_cast<> > added, along with the corresponding added output. > As can be seen, each char value is preceeded by a number > of leading zeros that I am unable to get rid of. I assume > this has something to do with memory footprints and/or byte > ordering (I am using VS2008 on a PC, which, according to Output format of pointers is not portable and so should never be used except for debug. (I've seen some horrible implementations that treat pointers as signed int!!!). Incidentally you probably should have had setw(2) in your original hex output because you want 0x01 to come out as 01 not 1. Also reinterpret_cast is the one new style cast that you really really want to avoid since it is the least restrictive (The only thing that the compiler can complain about is trying to use it to remove constness or volatility) A char really IS a small integer in both C and C++ and uinsigned int is definitely at least as big as char so static_cast<unsigned int> is not in the least bit dodgy. This is why you don't even need a cast to assign to a temporary variable. A char really IS NOT a pointer which is why you have to resort to reinterpret_cast or C style cast to treat it as one. > http://en.wikipedia.org/wiki/Endianness > > means that the internal byte organization is little-endian). > Endianness is irrelevant when considering single bytes (char) and nothing in your output implies little endian anyway. The only way to see endianness is to take a multibyte integral or pointer value and treat it as a sequence of bytes: void* x = ...; // or "int x=..." char* cp = reinterpret_cast<char*>(&x); // note the & for(int i=0; i < sizeof(vp); ++i) cout << setw(2) << hex << static_cast<unsigned int>(*cp); > Rune -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: John H. on 24 Nov 2009 03:40 On Nov 23, 4:44 pm, Rune Allnor <all...(a)tele.ntnu.no> wrote: > So the question is if it is possible to achieve the desired result > by using a reinterpret_cast<> or static_cast<> directly on the uchar > values inside the buffer c? > > I can't see any obvious way to achieve this, since chars > have a different memory footprint than any of the int types > I am aware of, that otherwise would suit the purpose. static_cast can be thought of as taking a value of one type and creating a corresponding value in another type. "Corresponding" can pretty much mean any relationship, but often means the value of the created type will be as similar as possible to the value of the source type. int num1 = static_cast<long>(3.14); Here, 3.14 was typecast to a long, which is an integer, so from the 3.14 a 3 is created, which gets stored in num1. float num2 = static_cast<float>(3); Here 3 wass typecast to a float, so a 3.0f is created and stored in num2. float num3 = static_cast<float>(3.1415926535897932384626433832795); Here, pi up to many digits of accuracy was converted to a float, which will have less digits of accuracy double num4 = static_cast<float>(3.1415926535897932384626433832795); Here, pi up to many digits of accuracy was converted to a float, which will have less digits of accuracy. This then gets stored in the double num4, which could have held more digits of accuracy, but as it is, those digits were discarded by the cast to float, so when the float is stored into the double, the extra digits will just be zeros. reinterpret_cast is different. I am going to say it is usually applied to pointers and my description will reflect this, but there may be valid applications to non-pointer types. The reinterpret_cast takes the bits pointed at by a pointer of some type, and allows those bit to be accessed as if they were the bits of a variable of a different type. Here is an example that shows how the two types of casts behave differently (details may differ depending on platform): int num1 = 3; // num1 has a value of 3 and a byte pattern of 0x00000003 float num2 = static_cast<float>(num1); // num2 has a value of 3 and a byte pattern of 0x40400000 float num3 = *dynamic_cast<float*>(&num1); // num3 has a value of 4.20390e-045 and a byte pattern of 0x00000003 > std::cout << std::hex << c[n] << " "; I think the std::cout behavior for char and unsigned char is to output to the ASCII character representation, but for int, long etc. it will output the numeric representation. So to get the desired behavior, we have to get to a type that triggers the number rather than character behavior: std::cout << std::hex << static_cast<unsigned int>(c[n]) << std::endl; -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Pages: 1 2 Prev: Article: On Iteration Next: inlining of functions returning an unwindable object |