Thread: const_cast: what is it good for?

  1. #1
    Registered User
    Join Date
    Jan 2003
    Posts
    2

    const_cast: what is it good for?

    i'm using the gcc compiler for windows and when running the following program

    Code:
    #include <iostream>
    using namespace std;
    int main() {
        const int i = 100;
        int *ip = const_cast<int *>(&i);
        *ip = 110;
        cout << &i << endl;
        cout << ip << endl;
        cout << i << endl;
        cout << *ip;
    }
    it turns out that &i == ip but i = 100 and *ip = 110. Surely i have missed something about const_cast. Can somebody tell me more? Thanks anyway.

  2. #2
    Registered User
    Join Date
    Dec 2002
    Posts
    103

    Hope this helps :)

    C++ performs type_checking very strongly. If you create a constant and then try to assign it to a ordinary pointer, your compiler would generate an error. You need a pointer to a constant... in the sence

    const int i = 10;
    int *p = &i; // Error
    int const* y = &i; // perfectly valid

    But since you are trying to use a normal pointer to point to a constant object, you have to remove that const key-word's effect.

    You do that using the const_cast

    Having said that, if you dereference and change the value using the pointer, the result is undefined

    const int i = 100;
    int *ip = const_cast<int *>(&i);
    *ip = 110; // this result is undefined
    Have a wonderful day.... and keep smiling... you look terrific that way
    signing off...
    shiv... as i know him

  3. #3
    Registered User
    Join Date
    Jan 2003
    Posts
    2
    OK, so does that mean that using const_cast to cast away the "const-ness" of the variable produces unex[pected results? If that is true then const_cast is no good for anything!

  4. #4
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    It is not necessarily unpredictable, here for example, is a routine which is totally predictable...

    Code:
    void Function (const int *pInt)
    {
        int *pNew;
     
        pNew = const_cast<int *> (pInt);
    
        *pNew = 1;
    }
    ... note the parameter was typed as const but using the const_cast, one can alter the value in the calling program. Whatever the value was before the call to Function(), it is now 1.

    I, frankly, would regard this as bad practice, but the facility is there if needed.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  5. #5
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    If the variable was const at its point of definition, the results of casting it away are undefined.


    In the words of Scott Meyers
    Pretty it ain't, but sometimes a programmer's gotta do what a programmer's gotta do.
    Unless, of course, it's not guaranteed to work, and sometimes the old cast-away-constness trick isn't. In particular, if the object we point to is truly const (i.e. was declared const at its point of definition) the results of casting away its constness are undefined.

  6. #6
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> (i.e. was declared const at its point of definition)

    Which is not the case in the example I gave, in that case, in the words of adrianxw, the result is as predictable as 1 + 1.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  7. #7
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    are you sure?

    const int A = 10;
    Function(&A);

    wouldnt that cause undefined behaviour at the line...
    *pNew = 1;

    Thats my understanding of const_cast.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  8. #8
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by Stoned_Coder
    are you sure?

    const int A = 10;
    Function(&A);

    wouldnt that cause undefined behaviour at the line...
    *pNew = 1;

    Thats my understanding of const_cast.
    Yeah.....the compiler does give A a memory address.....but usually, that address is ignored as the value 10 would often appear in the assembler code produced as a literal value....so any changes to that memory location go unnoticed...and that's how its undefined (also I dont know if that memory position would be writable on all compilers......so it may even cause a crash if not)

  9. #9
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    Originally posted by Eibro
    If the variable was const at its point of definition, the results of casting it away are undefined.
    Not always -- IE, if it's a non-static const of a class that is initialized on a per-object basis!

  10. #10
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    In the example I gave, it was the parameter to the function that was const'd in the function definition, and the cast overrides the const in the function definition.

    As Fordy says, a "variable" declared as a const would have its value used at the assembler level rather thn an address. This is not the case with the example I gave, although I accept, that may not have been as obvious as I thought.

    If a writeable address has been passed to a function and the function declares that address as a const, a const_cast will reliably override the "constness" of the parameter allowing it to be written to from the function.

    I also said I would regard that as bad practice.
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  11. #11
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    Originally posted by adrianxw
    >>> (i.e. was declared const at its point of definition)

    Which is not the case in the example I gave, in that case, in the words of adrianxw, the result is as predictable as 1 + 1.
    I wasn't saying you were wrong, if that's what it looked like. I was correcting whoever posted above you saying the results are always undefined.

    (Although i'm still confused about your example )

  12. #12
    It's full of stars adrianxw's Avatar
    Join Date
    Aug 2001
    Posts
    4,829
    >>> i'm still confused about your example

    Compile this.

    Code:
    #include <iostream>
    using namespace std;
    
    void Function(const int *);
    
    int main()
    {
        int x;
    
        x = 0;
        cout << "Before call " << x << endl;
        Function(&x);
        cout << "After call " << x << endl; // Changed
    
        return 0;
    }
    
    void Function (const int *pInt) // NOTE const
    {
        int *pNew;
     
        pNew = const_cast<int *> (pInt);
        *pNew = 1;
    }
    Wave upon wave of demented avengers march cheerfully out of obscurity unto the dream.

  13. #13
    Registered User
    Join Date
    Dec 2002
    Posts
    103

    I do agree with Eibro

    ---------------------------------------------------------------------------
    const int i = 100;
    int *ip = const_cast<int *>(&i);
    *ip = 110; // this result is undefined
    ----------------------------------------------------------------------------

    When I stated that the result is undefinied, I was refering to the example that I had quoted.

    In my example the const was used for "i" at the point of creation / definition, hence if I use the pointer "ip" to change the value of "i", it would be undefined.


    int i = 10; // i is not const at its point of definition
    int const *p = i;

    int *q = const_cast<int *> p;

    *q = 20; // In this case, the result is not undefined

    i will be 20 now.

    I hope this also clarifies Eibro's doubts with respect to the example posted by adrianxw
    Have a wonderful day.... and keep smiling... you look terrific that way
    signing off...
    shiv... as i know him

  14. #14
    Registered User
    Join Date
    Dec 2002
    Posts
    103

    Do I understand you right!!!!

    Originally posted by Polymorphic OOP
    Not always -- IE, if it's a non-static const of a class that is initialized on a per-object basis!
    #include <iostream>
    class x
    {
    const int i;
    int *p;

    public:
    x(int val):i(val),p(0)
    {
    std::cout << "The value of i is " << i << std::endl;
    }

    void display()
    {
    p = const_cast<int *>(&i);
    *p = 20;
    std::cout << "The value of i is " << i << std::endl;
    }

    };

    int main()
    {
    x ob(10);

    ob.display();

    return 0;
    }

    Output
    ----------
    The value of i is 10
    The value of i is 20
    Have a wonderful day.... and keep smiling... you look terrific that way
    signing off...
    shiv... as i know him

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In a game Engine...
    By Shamino in forum Game Programming
    Replies: 28
    Last Post: 02-19-2006, 11:30 AM
  2. Good books for learning WIN32 API
    By Junior89 in forum Windows Programming
    Replies: 6
    Last Post: 01-05-2006, 05:38 PM
  3. Good resources for maths and electronics
    By nickname_changed in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 12-22-2004, 04:23 PM
  4. what is good for gaphics in dos
    By datainjector in forum Game Programming
    Replies: 2
    Last Post: 07-15-2002, 03:48 PM
  5. i need links to good windows tuts...
    By Jackmar in forum Windows Programming
    Replies: 3
    Last Post: 05-18-2002, 11:16 PM