const_cast undefined results

Discussion in 'C++' started by Simon Bailey, Oct 12, 2004.

  1. Simon Bailey

    Simon Bailey Guest

    In the following code at the end of the program z = 20 & y = 99.

    void doit(const int* x)
    {
    int* nonconst;
    nonconst = const_cast<int*>(x);
    *nonconst = 99;
    }

    int main(int argc, char* argv[])
    {
    const int y = 20;
    int z;
    doit(&y);
    z = y; // Fails
    return 0;
    }

    having looked at the generated assembler code I can see why this is
    'failing' as the assembler uses a numeric literal to assign 20 to z on the
    failing statement. This is logical & efficient in most cases as y is a
    const which can be evaluated at compile time. However, since the facility
    has been provided to un-const a const variable (bad programming practice?) I
    would have thought that this code should work. I've tried it on Microsoft &
    g++ compilers with the same result. I have seen a web site that said that
    the result of const_cast in cases like this was undefined. I find the idea
    of undefined results in programming utterly abhorrent. We might as well
    accept 'nearly working' programs with such constructs as 'do sometimes'
    loops etc. Can this 'undefined' result be correct or is it a bug in the
    language specification / compilers?

    Any comments?

    Simon
    Simon Bailey, Oct 12, 2004
    #1
    1. Advertising

  2. Simon Bailey wrote:
    > In the following code at the end of the program z = 20 & y = 99.
    >
    > void doit(const int* x)
    > {
    > int* nonconst;
    > nonconst = const_cast<int*>(x);
    > *nonconst = 99;
    > }
    >
    > int main(int argc, char* argv[])
    > {
    > const int y = 20;
    > int z;
    > doit(&y);
    > z = y; // Fails
    > return 0;
    > }
    >
    > having looked at the generated assembler code I can see why this is
    > 'failing' as the assembler uses a numeric literal to assign 20 to z on the
    > failing statement. This is logical & efficient in most cases as y is a
    > const which can be evaluated at compile time. However, since the facility
    > has been provided to un-const a const variable (bad programming practice?) I
    > would have thought that this code should work. I've tried it on Microsoft &
    > g++ compilers with the same result. I have seen a web site that said that
    > the result of const_cast in cases like this was undefined. I find the idea
    > of undefined results in programming utterly abhorrent. We might as well
    > accept 'nearly working' programs with such constructs as 'do sometimes'
    > loops etc. Can this 'undefined' result be correct or is it a bug in the
    > language specification / compilers?


    It is correct as far as the C++ standard is concerned, and it is a bug
    in your program. When you are casting away constness you are telling the
    compiler "I know better; this is really not a const object". If you are
    lying to the compiler you can be sure it will find a way to get back at
    you. When using casts it is *your* responsibility to make sure that the
    cast is correct, because you are effectively disabling the safeguards of
    the compiler. This is why casts are best avoided. Good C++ code has very
    few, if any, casts.

    --
    Peter van Merkerk
    peter.van.merkerk(at)dse.nl
    Peter van Merkerk, Oct 12, 2004
    #2
    1. Advertising

  3. Simon Bailey

    JKop Guest

    Simon Bailey posted:

    > In the following code at the end of the program z = 20 & y = 99.
    >
    > void doit(const int* x)
    > {
    > int* nonconst;
    > nonconst = const_cast<int*>(x);
    > *nonconst = 99;
    > }


    The above function's documentation would have to specify:

    This function exhibits undefined behaviour if provided with a pointer to a
    const object.

    (. . . as ludacris as it may sound)


    > int main(int argc, char* argv[])
    > {
    > const int y = 20;
    > int z;
    > doit(&y);



    AAAAAAAaaahhhhhhh!


    > z = y; // Fails
    > return 0;
    > }
    >
    > having looked at the generated assembler code I can see why this is
    > 'failing' as the assembler uses a numeric literal to assign 20 to z on
    > the failing statement.


    Beautiful!


    > This is logical & efficient in most cases as y
    > is a const which can be evaluated at compile time. However, since the
    > facility has been provided to un-const a const variable (bad
    > programming practice?) I would have thought that this code should work.


    Nope. It only works if the original object was non-const. Otherwise it's
    undefined behaviour.

    Consider if you have a "const" reference, but the reference refers to a non-
    const object. Use of "const_cast" there would be grand.

    > I've tried it on Microsoft & g++ compilers with the same result. I
    > have seen a web site that said that the result of const_cast in cases
    > like this was undefined. I find the idea of undefined results in
    > programming utterly abhorrent.


    int* const p = reinterpret_cast<int* const>(876755);

    *p = 5;

    > We might as well accept 'nearly
    > working' programs with such constructs as 'do sometimes' loops etc.


    Please speak English.

    > Can this 'undefined' result be correct or is it a bug in the language
    > specification / compilers?


    The C++ Standard explicitly defines "undefined behaviour" and specifies in
    what situations it arises. The following qualifies as undefined behaviour:

    int main()
    {
    int const blah = 5;

    const_cast<int&>(blah) = 4;
    }

    And why? Because the original object was const.


    -JKop
    JKop, Oct 12, 2004
    #3
  4. "Simon Bailey" <> wrote in message
    news:eiMad.504$...
    > In the following code at the end of the program z = 20 & y = 99.
    >
    > void doit(const int* x)
    > {
    > int* nonconst;
    > nonconst = const_cast<int*>(x);
    > *nonconst = 99;
    > }
    >
    > int main(int argc, char* argv[])
    > {
    > const int y = 20;
    > int z;
    > doit(&y);
    > z = y; // Fails
    > return 0;
    > }
    >
    > having looked at the generated assembler code I can see why this is
    > 'failing' as the assembler uses a numeric literal to assign 20 to z on the
    > failing statement. This is logical & efficient in most cases as y is a
    > const which can be evaluated at compile time. However, since the facility
    > has been provided to un-const a const variable (bad programming practice?)


    That is not correct. The facility has been provided to allow you to remove
    const in a circumstance when you know that would not result in a const being
    modified. A typical situation would be when you have to call legacy or badly
    written code that does not use const when it should. Modifying a const is
    undefined behaviour however you manage it. Having this rule allows greater
    flexibility for compiler writers, for instance in code optimization.

    > I
    > would have thought that this code should work. I've tried it on Microsoft

    &
    > g++ compilers with the same result. I have seen a web site that said that
    > the result of const_cast in cases like this was undefined.


    Correct.

    > I find the idea
    > of undefined results in programming utterly abhorrent.


    Well then you should avoid the circumstances which give rise to undefined
    behaviour like the above.

    > We might as well
    > accept 'nearly working' programs with such constructs as 'do sometimes'
    > loops etc. Can this 'undefined' result be correct or is it a bug in the
    > language specification / compilers?
    >
    > Any comments?
    >


    C and C++ have hundreds of circumstances that produce undefined behaviour.
    If you don't like it then you should pick a different programming language.

    john
    John Harrison, Oct 12, 2004
    #4
  5. Simon Bailey

    Ron Natalie Guest

    JKop wrote:
    >
    > This function exhibits undefined behaviour if provided with a pointer to a
    > const object.
    >
    > (. . . as ludacris as it may sound)
    >
    >

    It's not quite as ludicrous as it sounds. There's a difference between
    a const object and an expression of some const type that refers to a
    non-const object.
    Ron Natalie, Oct 12, 2004
    #5
  6. Simon Bailey

    rookkey Guest

    "Simon Bailey" <> wrote in
    news:eiMad.504$:

    > I have seen a web site that said that the result of const_cast in cases
    > like this was undefined. I find the idea of undefined results in
    > programming utterly abhorrent. We might as well accept 'nearly
    > working'programs with such constructs as 'do sometimes' loops etc. Can
    > this 'undefined' result be correct or is it a bug in the language
    > specification > / compilers?


    Performing a const_cast to remove the constness of a constant object and
    then modifying that object is undefined behavior. Period. The C++
    standard makes this clear.

    So, you're likely wondering: what good is const_cast then?

    Think of badly written API's.

    Suppose there is a function you would like to use that takes as an
    argument a non-const reference to an object. Unfortunately, all you have
    is a const object and you'd rather not go through the trouble of creating
    a non-const copy of it to pass as an argument. You look at the code of
    this function and you see that the reference is never modified or passed
    anywhere else! The original author of that function either neglected to
    declare the reference parameter as const or was a beginning programmer
    who did not understand the benefits of declaring parameters const
    whenever possible.

    It is a function you know will not change what's passed to it. Yet, you
    have that constant object. In this case, using const_cast is appropriate
    to have your new code work with the old.

    There are plenty of functions that take non-const references or pointers
    but which never change those parameters. const_cast is very useful in
    these cases because it promotes const correctness but allows flexibility
    when interacting with the real-world code that ignores it.
    rookkey, Oct 13, 2004
    #6
  7. Simon Bailey

    Ron Natalie Guest

    rookkey wrote:

    > Think of badly written API's.
    >


    Usually the problem. Either:

    1. Something needs a non-const value and you KNOW it won't be modified.
    2. You have a const value, but you know the object wasn't const to
    begin with (more difficult, but not impossible).
    Ron Natalie, Oct 13, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kaspar Minosiants

    [help] const_cast

    Kaspar Minosiants, Jul 21, 2003, in forum: C++
    Replies:
    2
    Views:
    417
    John Harrison
    Jul 21, 2003
  2. drowned

    const_cast question

    drowned, Aug 4, 2003, in forum: C++
    Replies:
    3
    Views:
    475
    Josephine Schafer
    Aug 4, 2003
  3. R. Anbeeswaran

    const_cast<>

    R. Anbeeswaran, Nov 13, 2003, in forum: C++
    Replies:
    7
    Views:
    592
    Ekkehard Morgenstern
    Nov 14, 2003
  4. S.Senthilvel

    const_cast

    S.Senthilvel, Jan 6, 2004, in forum: C++
    Replies:
    4
    Views:
    2,026
    Andrey Tarasevich
    Jan 8, 2004
  5. Nephi Immortal

    Const_cast as undefined behavior?

    Nephi Immortal, Jan 9, 2013, in forum: C++
    Replies:
    35
    Views:
    633
    Gerhard Fiedler
    Jan 19, 2013
Loading...

Share This Page