CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 31
  1. #16
    Join Date
    Aug 2007
    Posts
    858

    Re: reinterpret_cast<> and where can it be used

    Quote Originally Posted by nuzzle View Post
    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.
    Last edited by Speedo; August 8th, 2009 at 08:01 PM.

  2. #17
    Join Date
    May 2009
    Posts
    2,413

    Re: reinterpret_cast<> and where can it be used

    Quote Originally Posted by Speedo View Post
    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?
    Last edited by nuzzle; August 8th, 2009 at 08:30 PM.

  3. #18
    Join Date
    Feb 2009
    Posts
    326

    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;
    }
    Last edited by Muthuveerappan; August 9th, 2009 at 03:26 AM. Reason: edited the program to compare with static_cast

  4. #19
    Join Date
    Apr 2009
    Location
    Russia, Nizhny Novgorod
    Posts
    99

    Re: reinterpret_cast<> and where can it be used

    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&#37;(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.

  5. #20
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  6. #21
    Join Date
    Feb 2009
    Posts
    326

    Re: reinterpret_cast<> and where can it be used

    Thanks to all, has been a big learning

  7. #22
    Join Date
    May 2009
    Posts
    2,413

    Re: reinterpret_cast<> and where can it be used

    Quote Originally Posted by ixSci View Post
    Do you know what he means under "not portable"? I can say that 50&#37;(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.
    Last edited by nuzzle; August 11th, 2009 at 06:14 AM.

  8. #23
    Join Date
    Feb 2009
    Posts
    326

    Re: reinterpret_cast<> and where can it be used

    Quote Originally Posted by nuzzle View Post
    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.

  9. #24
    Join Date
    Aug 2007
    Posts
    858

    Re: reinterpret_cast<> and where can it be used

    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

    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.

  10. #25
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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".
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  11. #26
    Join Date
    Aug 2007
    Posts
    858

    Re: reinterpret_cast<> and where can it be used

    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.

  12. #27
    Join Date
    Feb 2009
    Posts
    326

    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

  13. #28
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    Last edited by laserlight; August 11th, 2009 at 11:55 AM.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  14. #29
    Join Date
    May 2009
    Posts
    2,413

    Re: reinterpret_cast<> and where can it be used

    Quote Originally Posted by Speedo View Post
    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.)
    Last edited by nuzzle; August 11th, 2009 at 04:13 PM.

  15. #30
    Join Date
    May 2009
    Posts
    2,413

    Re: reinterpret_cast<> and where can it be used

    Quote Originally Posted by Speedo View Post
    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.
    Last edited by nuzzle; August 11th, 2009 at 04:36 PM.

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured