-
reinterpret_cast<> and where can it be used
Hi,
I am just reading about reinterpret_cast<> unfortunately I don't understand much other than what I have stated below:
reinterpret_cast allows any pointer to be converted into any other pointer type.
So when can this come in handy ?
I am really sorry my book doesn't speak about it, and I didn't quite understand the stuff I read on the internet.
I would appreciate any simple interpretation of reinterpret_cast and its use or any link that does that.
Thanks,
Muthu
-
Re: reinterpret_cast<> and where can it be used
Writing binary files:
Code:
ofstream file("myfile.dat", ios::binary);
int number = 20;
file.write(reinterpret_cast<const char*>(&number), sizeof(number));
Accessing the binary representation of floating point values:
Code:
int main()
{
float f = 1234.5678f;
const unsigned long* ptr = reinterpret_cast<const unsigned long*>(&f);
unsigned long bits = *ptr;
for (int i = 31; i >= 0; --i)
cout << ((bits & (1 << i)) ? 1 : 0);
return 0;
}
Are two uses that immediately come to mind.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Muthuveerappan
Hi,
I am just reading about reinterpret_cast<> unfortunately I don't understand much other than what I have stated below:
reinterpret_cast allows any pointer to be converted into any other pointer type.
So when can this come in handy ?
I am really sorry my book doesn't speak about it, and I didn't quite understand the stuff I read on the internet.
I would appreciate any simple interpretation of reinterpret_cast and its use or any link that does that.
Thanks,
Muthu
reinterpret_cast is used to when you want to handle an object as if it was of a certain type, when it isn't. Also, it guarantees it will not modify your object during the cast.
Two examples I can find are:
Many c style functions return void pointers. You can't do much with those unless you reinterpret_cast into something useful. This is usually when you do allocations. I've never done this, but I know it exists.
Another example is if you want to see the binary representation of an object, like double:
Code:
int main(int argc, char *argv[])
{
double d = 31643.496844;
std::cout << d << std::endl;
std::cout << std::dec << static_cast<unsigned long long int>(d) << std::endl;
std::cout << std::hex << static_cast<unsigned long long int>(d) << std::endl;
std::cout << std::hex << reinterpret_cast<unsigned long long int&>(d) << std::endl;
system("PAUSE");
return EXIT_SUCCESS;
}
as you can see in this example, you can "read" into your double as if it was an unsigned long long int. Notice that if you do a static_cast, however, your double will be "transformed" into the corresponding unsigned long long int value.
You shouldn't ever do this in a real program though.
But to answer your question: "When can this come in handy". The answer is that unless your are writing a low level allocation program, or hardware controller, then never. It will never come in handy.
If you feel you want to use it to have several objects share the same memory space, then I would recommend you use an "union". But, again, this is really low level stuff.
-
Re: reinterpret_cast<> and where can it be used
reinterpret_cast<>() is used for casting between unrelated types. When you use this cast you are saying to your compiler, 'I know better than you do, I want you to reinterpret the bit pattern of this object as a different type'. In cases of multiple inheritance reinterpret_cast will never perform delta arithmetic.
-
Re: reinterpret_cast<> and where can it be used
thanks a lot for all your replies.
I have a few doubts:
------------------------
1) In Speedo's 2nd program, I couldn't understand the following line:
Code:
cout << ((bits & (1 << i)) ? 1 : 0);
a) I think "1 << i" means "1 * pow(2, i)", correct me if I am wrong.
b) what is the role of "&" in that statement ?
c) I think it is like an if else statement, and "(bits & (1 << i)" is evaluated like a boolean expression.
If that evaluates to true, then 1 is returned, else 0.
------------------------
2) In Monarch_dodra's program, I couldn't understand why we have long specified twice in each casting ?
Quote:
Originally Posted by
monarch_dodra
as you can see in this example, you can "read" into your double as if it was an unsigned long long int. Notice that if you do a static_cast, however, your double will be "transformed" into the corresponding unsigned long long int value.
3) I didn't understand that quote, Did that mean that always reinterpret_cast allows only cast by reference / or by pointers while static_cast allows only casting by reference / pointers for related types and for integral types it only allows casting by value?
My understanding is given below:
Code:
casting type Integral Types Other Types
---------------- ------------------- -----------------
reinterpret_cast only cast by reference / or by pointers only cast by reference / or by pointers
static_cast only cast by value cast by reference / or by pointers / value (provided the types are related)
------------------------
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Muthuveerappan
In Monarch_dodra's program, I couldn't understand why we have long specified twice in each casting ?
"long int" is a datatype. "long long int" is another (not 100% standard) datatype.
I recommend you read this.
http://home.att.net/~jackklein/c/inttypes.html
-
Re: reinterpret_cast<> and where can it be used
Thanks monarch_dodra and others.
I think I still have some confusion and unanswered questions. It would be great if someone could answer the questions posted previously. Thanks again.
-
Re: reinterpret_cast<> and where can it be used
Quote:
In Speedo's 2nd program, I couldn't understand the following line:
Code:
cout << ((bits & (1 << i)) ? 1 : 0);
From the inside out:
1 << i
Left shift the value 1 by i bits. The result will be equivilient to 1 * 2^i
bits & (1 << i)
Do a bitwise AND of bits and result of (1 << i). The value of (1 << i) is always going to have a single bit set (in binary its values will be: 1, 10, 100, 100, 1000, and so on), and the bitwise and will tell us whether or not that particular bit is set int the value bits.
(bits & (1 << i)) ? 1 : 0
Just prints out either a 1 or 0 depending on whether or not the bit in question is set - a nonzero value returned from the bitwise AND means that the bit is set.
-
Re: reinterpret_cast<> and where can it be used
Thanks a lot Speedo, for the prompt response.
I think I understand a little better, let me do some work on this and this will come back.
Thanks all.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Many c style functions return void pointers. You can't do much with those unless you reinterpret_cast into something useful. This is usually when you do allocations. I've never done this, but I know it exists.
It's not correct you can perform cast to and from void* by using static_cast, reinterpret_cast is redundant here.
Just as complement:
Muthuveerappan, you should follow a simple rule: Don't use reinterpret_cast anywhere until you really need it. reinterpret_cast is very useful when you work with byte sequences(e.g decode protocol's messages) and it is a very harmful thing in high level programming.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
ixSci
It's not correct you can perform cast to and from void* by using static_cast, reinterpret_cast is redundant here.
Thanks for clearing that up. As I said, it is something I have never done before, so I wasn't 100% sure. That, and I've never used the reinterpret_cast either so...
-
Re: reinterpret_cast<> and where can it be used
Thanks again to everyone, I think I understand a lil better.
reinterpret_cast preserves the bit pattern after conversion while static_cast doesn't, given below is an example:
Code:
#include <iostream>
using std :: cout;
using std :: endl;
using std :: cin;
void printInBinary(const unsigned int pDecimalNumber);
int main()
{
unsigned int decimalNumber;
system("clear");
cout << "enter the decimal number : ";
cin >> decimalNumber;
cout << "decimalNumber = ";
printInBinary(decimalNumber);
bool boolean1 = static_cast<bool>(decimalNumber);
cout << "using static_cast<bool> = ";
printInBinary(boolean1);
bool boolean2 = reinterpret_cast<bool&>(decimalNumber);
cout << "using reinterpret_cast<bool&> = ";
printInBinary(boolean2);
cout << endl;
return(0);
}
void printInBinary(const unsigned int pDecimalNumber)
{
const unsigned int SIZE_OF_TYPE_IN_BITS = sizeof(pDecimalNumber) * 8;
for(int index = SIZE_OF_TYPE_IN_BITS - 1; index >= 0; index --)
{
const unsigned short int BIT = (pDecimalNumber >> index) & 1;
cout << BIT;
}
cout << endl;
}
-
Re: reinterpret_cast<> and where can it be used
Quote:
reinterpret_cast preserves the bit pattern after conversion while static_cast doesn't, given below is an example:
Consider the subject from this viewpoint.
double d (35.25);
int i;
i = d;
In this case, while the compiler will generate a warning, it will perform a conversion. A few steps are 'automatically' generated to turn a double into an integer. This is a "value = value" scenario. The same thing applies with
i = static_cast<int>( d );
..a conversion is performed, but the compiler's warning should be set aside because you've informed it of your intention to perform this cast.
i = reinterpret_cast<int>( d );
The compiler won't perform this case, because it doesn't work on values.
int * ip = &i;
double *dp = &d;
ip = dp;
This would cause a compiler error, the pointers are incompatible. "Under the hood" all pointers are the same, a simple location in RAM. The type involved, however, has several implications to C++, and in more complex types there can be pointer adjustments required.
ip = static_cast<int *>( dp );
The compiler will refuse this conversion because the types aren't related. The compiler "knows" this conversion results in nonsense (the bits comprising the double have no useful meaning when interpreted as an integer, they require conversion to make sense).
A C style cast doesn't perform this check, and permits the cast....
ip = (int *) dp;
In this case, the C style cast makes no judgment about the relationship between the two pointers. C doesn't include the intelligence instilled into static_cast (or dynamic_cast), and simply stops all complaints or checking, at gives you...nonsense from the result of this line of code.
The closest we have to this in the new casting operators is reinterpret_cast.
ip = reinterpret_cast<int *>( dp );
This essentially duplicates the non-intelligent behavior of the C style cast, but gives us the syntax benefits of a C++ style cast.
Otherwise, the unintelligent nature of the C style cast is useful when casts otherwise make no sense, but we know from other contexts beyond the "sense" of the compiler that the cast is useful.
We use this unintelligent casting from structures created with similar features from C Code (or interfaces to it) into something useful, or other situations where the type system of C++ gets in the way, because the origins of the data being acted upon were created outside the C++ type awareness.
It's fire to play with, and not generally all that useful. If there's any way around it, use that instead. If the only way to perform a cast would cause the compiler to complain, and you know it's complaint isn't valid (and you need to really understand just why), then either a C style cast or the reinterpret_cast are appropriate (though the C style cast doesn't offer a good search/replace text benefit - it lexically blends into the rest of the text of code and can't be so easily identified).
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Muthuveerappan
I would appreciate any simple interpretation of reinterpret_cast and its use or any link that does that.
According to The C++ Standard Library by Josuttis, the behavior of reinterpret_cast is implementation defined. This means you need to consult the documentation of the actual compiler you're using to figure out what it does. This also means reinterpret_cast isn't portable.
-
Re: reinterpret_cast<> and where can it be used
So what everybody's said in this thread is allright because the C++ standard allows anything; Whatever you say is fine :)
The only sensible reaction is to never use reinterpret_cast, at least not if you're aiming for portability.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
nuzzle
So what everybody's said in this thread is allright because the C++ standard allows anything; Whatever you say is fine :)
The only sensible reaction is to never use reinterpret_cast, at least not if you're aiming for portability.
That would be a bit silly, sense it would mean that it's impossible to do some very basic things in a portable manner - ie it would be impossible to read or write portable binary files, since stream read and write methods only work on char*'s.
I haven't read the book in question, but I suspect that you somewhat misread or misunderstood the statement. I imagine the author's intent was to say that the types of actions that require reinterpret_cast are inherently not portable, unless you're careful.
Edit: Well, it wouldn't be impossible (the binary file thing), but it would require a convoluted method like using a union to be able to get the data as char. I'd say that's considerably worse than reinterpret_cast.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Speedo
I suspect that you somewhat misread or misunderstood the statement.
I'll give you the exact wording (Josuttis on page 20),
-----
4. reinterpret_cast
The behavior of this operator is implementation defined. It may but is not required to reinterpret bits. Using this cast is usually not portable.
------
If you feel Josuttis is wrong please tell us how. Maybe exactly you have a better command of the C++ standard?
-
Re: reinterpret_cast<> and where can it be used
Just a couple of points (pls correct me if I am wrong):
1) I noticed a bug with my previous program:
The function printInBinary has an argument of type unsigned int
When I pass the value of the type bool, then type conversion is done implicitly. (something I didn't account for, because I do reinterpret_cast to bool& and on top of that implicit conversion is done to unsigned int). So this doesn't assure the bits are copied the way we expect it to as it involves implicit conversion.
2) I agree that reinterpret_cast is dangerous, I have stated my understanding of reinterpret_cast:
a) reinterpret_cast does a binary copy, so the bit pattern is retained.
b) reinterpret_cast allows you to convert back to the original type successfully.if you do a conversion from type A to type B, then conversion from B to A is possible and A would have the original value (provided sizeof(B) >= sizeof(A) so that you are able to accommodate all the bits)
c) Yes reinterpret_cast is not portable across systems but in the same system it can be converted back as stated above.
d) reinterpret_cast can convert totally unrelated types.
3) I have pasted below a program which tries show a) and b) and also compares with static_cast
Note - I have used a union, because that is the only way I could think of safely avoiding any implicit conversion while invoking the function printInBinary
The maximum number that a unsigned int can hold is 4294967295 (assuming it is 4 bytes).
So you can test the below program using 4294967295 (just easy to spot any bugs).
Code:
#include <iostream>
using std :: cout;
using std :: endl;
using std :: cin;
void printInBinary(const unsigned int pUnsignedNumber);
union UnionDataTypeSet
{
unsigned int unsignedNumber;
float floatNumber;
double doubleNumber;
bool boolean;
};
int main()
{
unsigned int decimalNumber0;
system("clear");
cout << "enter decimalNumber0 : ";
cin >> decimalNumber0;
cout << "decimalNumber0 in bits = ";
printInBinary(decimalNumber0);
cout << "\n=====================reinterpret_cast=====================\n";
//unsigned int to float
UnionDataTypeSet dataTypeSet1;
dataTypeSet1.floatNumber = reinterpret_cast<float&>(decimalNumber0);
cout << "floatNumber in bits = ";
printInBinary(dataTypeSet1.unsignedNumber);
//float to unsigned int
unsigned int decimalNumber1 = reinterpret_cast<unsigned int&>(dataTypeSet1.floatNumber);
cout << "decimalNumber1 in bits = ";
printInBinary(decimalNumber1);
cout << "=====================\n";
//unsigned int to double
UnionDataTypeSet dataTypeSet2;
dataTypeSet2.doubleNumber = reinterpret_cast<double&>(decimalNumber0);
cout << "doubleNumber in bits = ";
printInBinary(dataTypeSet2.unsignedNumber);
//double to unsigned int
unsigned int decimalNumber2 = reinterpret_cast<unsigned int&>(dataTypeSet2.doubleNumber);
cout << "decimalNumber2 in bits = ";
printInBinary(decimalNumber2);
cout << "=====================\n";
//unsigned int to bool (bits lost)
UnionDataTypeSet dataTypeSet3;
dataTypeSet3.boolean = reinterpret_cast<bool&>(decimalNumber0);
cout << "boolean in bits = ";
printInBinary(dataTypeSet3.unsignedNumber);
//bool to unsigned int
unsigned int decimalNumber3 = reinterpret_cast<unsigned int&>(dataTypeSet3.boolean);
cout << "decimalNumber3 in bits = ";
printInBinary(decimalNumber3);
cout << "=====================\n";
cout << "\n=====================static_cast=====================\n";
//unsigned int to float
UnionDataTypeSet dataTypeSet4;
dataTypeSet4.floatNumber = static_cast<float>(decimalNumber0);
cout << "floatNumber in bits = ";
printInBinary(dataTypeSet4.unsignedNumber);
//float to unsigned int
unsigned int decimalNumber4 = static_cast<unsigned int>(dataTypeSet4.floatNumber);
cout << "decimalNumber4 in bits = ";
printInBinary(decimalNumber4);
cout << "=====================\n";
//unsigned int to double
UnionDataTypeSet dataTypeSet5;
dataTypeSet5.doubleNumber = static_cast<double>(decimalNumber0);
cout << "doubleNumber in bits = ";
printInBinary(dataTypeSet5.unsignedNumber);
//double to unsigned int
unsigned int decimalNumber5 = static_cast<unsigned int>(dataTypeSet5.doubleNumber);
cout << "decimalNumber5 in bits = ";
printInBinary(decimalNumber5);
cout << "=====================\n";
//unsigned int to bool (bits lost)
UnionDataTypeSet dataTypeSet6;
dataTypeSet6.boolean = static_cast<bool>(decimalNumber0);
cout << "boolean in bits = ";
printInBinary(dataTypeSet6.unsignedNumber);
//bool to unsigned int
unsigned int decimalNumber6 = static_cast<unsigned int>(dataTypeSet6.boolean);
cout << "decimalNumber6 in bits = ";
printInBinary(decimalNumber6);
cout << "=====================\n";
cout << endl << endl;
return(0);
}
void printInBinary(const unsigned int pUnsignedNumber)
{
const unsigned short int SIZE_OF_TYPE_IN_BITS = sizeof(pUnsignedNumber) * 8;
for(short int index = SIZE_OF_TYPE_IN_BITS - 1; index >= 0; index --)
{
unsigned short int BIT = (pUnsignedNumber >> index) & 1;
cout << BIT;
}
cout << endl;
}
-
Re: reinterpret_cast<> and where can it be used
Quote:
The behavior of this operator is implementation defined. It may but is not required to reinterpret bits. Using this cast is usually not portable.
Do you know what he means under "not portable"? I can say that 50%(less or more) C++ features not portable between different platforms. But it's true if you use things dependent on concrete platform. For example you have an address stored inside the int type and you use reinterpret_cast , you shouldn't hope you would have the same pointer's value on different platforms but this code would portable if you don't predict pointer's value.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by nuzzle
If you feel Josuttis is wrong please tell us how. Maybe exactly you have a better command of the C++ standard?
In fact Josuttis is just paraphrasing the C++ standard:
Quote:
Originally Posted by C++03 Section 5.2.10 Paragraph 3
The mapping performed by reinterpret_cast is implementation-defined. [Note: it might, or might not, produce a representation different from the original value. ]
Quote:
Originally Posted by ixSci
For example you have an address stored inside the int type and you use reinterpret_cast , you shouldn't hope you would have the same pointer's value on different platforms but this code would portable if you don't predict pointer's value.
If you are just going to cast to and fro and that is all, that would be true. But after you cast you would likely be doing something with the result, and since that result is implementation defined, what you do with it is not guaranteed to be portable.
-
Re: reinterpret_cast<> and where can it be used
Thanks to all, has been a big learning
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
ixSci
Do you know what he means under "not portable"? I can say that 50%(less or more) C++ features not portable between different platforms.
With "not portable" he means that reinterpret_cast is defined by the C++ standard to be implementation dependent. It's left to each compiler to decide what to do with it. If you use reinterpret_cast you know that you don't know what will happen without consulting the actual compiler documentation.
The C++ language is not defined for 100% portability (like for example Java). C++ gives leeway for compiler specific variations, still the C++ standard is quite clear about the portability issues you may encounter.
To state that 50% of all C++ constructs are non-portable sounds like an exaggeration to me to say the least. Say the language itself is 5% non-portable and that non-compliancy among major compilers adds another 5%, I could agree that C++ is 10% non-portable at the most.
Note that you must separate the non-portability caused by C++ itself and its compilers, from the non-portability you induce yourself by using platform dependent constructs like specific APIs and fixed memory addresses or whatever. That's a different story. If you use Win32 and DirectX heavily throught-out your program you're likely to be 100% stuck with Microsoft Windows I should guess. :)
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
nuzzle
If you use reinterpret_cast you know that you don't know what will happen without consulting the actual compiler documentation.
I have expressed my view below (correct me if I am wrong):
reinterpret_cast will do a binary copy and you will be able to cast back to original type (as long the type is large enough to hold the bits and if it is not used across the systems).
If you are planning to use the value of the pointer after casting then it could mean trouble but reinterpret_cast only means binary copy. It means trouble because, different types use different bit patterns to represent a value.
So if you are using it in the same system, then I don't think we need to know the implementation, because we can be guaranteed that it would be a binary copy.
-
Re: reinterpret_cast<> and where can it be used
Quote:
If you feel Josuttis is wrong please tell us how. Maybe exactly you have a better command of the C++ standard?
The statement is ambiguous and misleading. It gives the impression (as evidenced by your posts) that you have literally no idea what reinterpret_cast will do on a given compiler. That is blatantly false. As usual, the standard tells us what:
- The result of reinterpret_cast is an lvalue only if the target type is a reference type.
- reinterpret_cast may not cast away constness
- A pointer can be converted to any integral type large enough to hold it
- A value of integral or enumeration type can by converted to a pointer
- A pointer converted to an integer, and back to a pointer of the same type will have its original value
- A pointer to a function can be converted to a pointer to a function of a different type, but the effect of calling the function through a pointer that doesn't match the function definition is undefined
- A pointer to an object can be converted to a pointer to an object of a different type
- A pointer to an object that's converted to a pointer to object of a different type and then back to the original type will have the original value
- The null pointer value is converted to the null pointer value of the target type
- A pointer to member can be converted to a pointer to member of a different type, but the result of the conversion is undefined except that converting the result back to the original type will yield the original value
- An lvalue of type "T1" can be cast to "reference to T2" if it is possible for reinterpret_cast to convert "pointer to T1" to "pointer to T2"; no temporary is created, no copy is made, no constructors or conversion functions are called
But it doesn't tell us anything about how:
- "The mapping performed by reinterpret_cast is implementation-defined. [Note: it might, or might not, produce a representation different from the original value. ]"
So while there is no promise of portability in the standard, I still maintain that the statement
Quote:
The only sensible reaction is to never use reinterpret_cast, at least not if you're aiming for portability.
is a bit silly, for several reasons:
A significant number of instances when reinterpret_cast needs to be used are (or should be) already in platform-specific code.
To my knowledge, the major C++ compiler vendors all implement reinterpret_cast in the same manner. Avoiding reinterpret_cast then is kind of like insisting on code which doesn't assume that a byte is 8 bits. It's technically correct, but unless you know you're going to be targetting something that breaks with the norm, really, why bother?
There are instances where reinterpret_cast is the only cast which will work. You can't simply use a C-style cast in its place if you're being paranoid about portability - the compiler is still going to do the conversion via the same underlying [non-portable] methods. This means you're going to have to resort to something like unions, which I say is uglier than reinterpret_cast.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by Muthuveerappan
reinterpret_cast will do a binary copy
It typically does, but that is not guaranteed, as I have quoted the standard.
Quote:
Originally Posted by Speedo
The statement is ambiguous and misleading. It gives the impression (as evidenced by your posts) that you have literally no idea what reinterpret_cast will do on a given compiler. That is blatantly false.
If you are talking about Josuttis' statement, then that would not be correct since Josuttis states that "the behavior of this operator is implementation defined". The term "implementation defined" makes it clear that one can find out its behaviour with respect to a given implementation, i.e., "what reinterpret_cast will do on a given compiler".
Quote:
Originally Posted by Speedo
A significant number of instances when reinterpret_cast needs to be used are (or should be) already in platform-specific code.
In this I agree: it is certainly possible to isolate nonportable code and thus get a measure of portability by being able to cater for each specific implementation to be supported.
Consequently, I would summarise Sutter and Alexandrescu's opinion on this as presented in C++ Coding Standards: "Don't try to use reinterpret_cast to force the compiler to reinterpret the bits of an object of one type as being the bits of an object of a different type", but when you have to, e.g., due to "some low-level system-specific programming", "use unsafe casting as rarely as you can and only in well-hidden functions that abstract it away, so as to make your code ready for porting with minimal changes".
-
Re: reinterpret_cast<> and where can it be used
Quote:
If you are talking about Josuttis' statement, then that would not be correct since Josuttis states that "the behavior of this operator is implementation defined". The term "implementation defined" makes it clear that one can find out its behaviour with respect to a given implementation, i.e., "what reinterpret_cast will do on a given compiler".
The behavior of reinterpret_cast -the actions that can be performed with it- is clearly defined by the standard. The results of those actions are implementation defined.
The distinction between those is subtle, and can be confusing, which is why I said that the author's statement was ambiguous.
-
Re: reinterpret_cast<> and where can it be used
I have a few doubts:
When the reinterpret_cast is implementation specific does it mean one of the the following or something else:
a) Different compilers use different bit patterns and hence binary copy would be different in different compilers, therefore reinterpret_cast would be different on different compilers (meaning reinterpret_cast does a binary copy but the bit patterns are different on different compilers / platforms) ?
b) Or does it mean reinterpret_cast in certain compilers might do something other than a binary copy ?
Which one of them is correct (or is it something else) ?
Thanks,
Muthu
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by Speedo
The behavior of reinterpret_cast -the actions that can be performed with it- is clearly defined by the standard. The results of those actions are implementation defined.
The distinction between those is subtle, and can be confusing, which is why I said that the author's statement was ambiguous.
Read the statement in context: immediately after stating that "the behavior of this operator is implementation defined", Josuttis goes on to explain that "it may reinterpret bits, but it is not required to do so". This means that Josuttis considers the specification of the result of reinterpret_cast as part of the specification of its behaviour, and I can find no fault with that.
If you still feel that the statement is too terse and thus results in ambiguity that may mislead a reader, take it up with the author, who has diligently published errata in the past.
Quote:
Originally Posted by Muthuveerappan
When the reinterpret_cast is implementation specific does it mean one of the the following or something else:
a) Different compilers use different bit patterns and hence binary copy would be different in different compilers, therefore reinterpret_cast would be different on different compilers (meaning reinterpret_cast does a binary copy but the bit patterns are different on different compilers / platforms) ?
b) Or does it mean reinterpret_cast in certain compilers might do something other than a binary copy ?
Which one of them is correct (or is it something else) ?
I consider the answer to be closer to b, but a is true as well in the sense that representation of a type may differ from implementation to implementation.
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Speedo
So while there is no promise of portability in the standard, I still maintain that the statement
"The only sensible reaction is to never use reinterpret_cast, at least not if you're aiming for portability."
is a bit silly, for several reasons:
Well, never to use reinterpret_cast should be your very strong ambition at least. Use it only under exceptional circumstances in low-level system-specific code. That's the general consensus. See for example #92. Avoid using reinterpret_cast (in C++ Coding Standards by Sutter & Alexandrescu.)
-
Re: reinterpret_cast<> and where can it be used
Quote:
Originally Posted by
Speedo
The behavior of reinterpret_cast -the actions that can be performed with it- is clearly defined by the standard. The results of those actions are implementation defined.
The distinction between those is subtle, and can be confusing, which is why I said that the author's statement was ambiguous.
The behaviour of reinterpret_cast is defined in ten paragraphs in the C++ standard, and one of them states that "the mapping performed by reinterpret_cast is implementation-defined". This paragraph renders reinterpret_cast non-portable. But there's no "subtle distinction" that sets this paragraph apart from the other nine. It's an integral part of the total definition of the behaviour of reinterpret_cast.
-
Re: reinterpret_cast<> and where can it be used
Thanks laserlight for that clarification.
just wish it was option a) :)
thanks all, i think i understand better now