C/C++ changing the value of a const

后端 未结 18 1694
醉梦人生
醉梦人生 2020-11-28 07:28

I had an article, but I lost it. It showed and described a couple of C/C++ tricks that people should be careful. One of them interested me but now that I am trying to repli

相关标签:
18条回答
  • 2020-11-28 07:38

    Some of these answers point out that the compiler can optimize away the variable 'a' since it is declared const. If you really want to be able to change the value of a then you need to mark it as volatile

      const volatile int a = 3; // I promise i won't change a
      int *ptr = (int *)&a;
      (*ptr) = 5; // I'm a liar, a is now 5
    

    Of course, declaring something as const volatile should really illustrate just how silly this is.

    0 讨论(0)
  • 2020-11-28 07:40

    you need to cast away the constness:

    linux ~ $ cat constTest.c
    #include <stdio.h>
    
    
    void modA( int *x )
    {
            *x = 7;
    }
    
    
    int main( void )
    {
    
            const int a = 3; // I promisse i won't change a
            int *ptr;
            ptr = (int*)( &a );
    
            printf( "A=%d\n", a );
            *ptr = 5; // I'm a liar, a is now 5
            printf( "A=%d\n", a );
    
            *((int*)(&a)) = 6;
            printf( "A=%d\n", a );
    
            modA( (int*)( &a ));
            printf( "A=%d\n", a );
    
            return 0;
    }
    linux ~ $ gcc constTest.c -o constTest
    linux ~ $ ./constTest
    A=3
    A=5
    A=6
    A=7
    linux ~ $ g++ constTest.c -o constTest
    linux ~ $ ./constTest
    A=3
    A=3
    A=3
    A=3
    

    also the common answer doesn't work in g++ 4.1.2

    linux ~ $ cat constTest2.cpp
    #include <iostream>
    using namespace std;
    int main( void )
    {
            const int a = 3; // I promisse i won't change a
            int *ptr;
            ptr = const_cast<int*>( &a );
    
            cout << "A=" << a << endl;
            *ptr = 5; // I'm a liar, a is now 5
            cout << "A=" << a << endl;
    
            return 0;
    }
    linux ~ $ g++ constTest2.cpp -o constTest2
    linux ~ $ ./constTest2
    A=3
    A=3
    linux ~ $
    

    btw.. this is never recommended... I found that g++ doesn't allow this to happen.. so that may be the issue you are experiencing.

    0 讨论(0)
  • 2020-11-28 07:41

    Note any attempt to cast away constness is undefined by the standard. From 7.1.5.1 of the standard:

    Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.

    And right after this example is used:

    const int* ciq = new const int (3);     //  initialized as required
    int* iq = const_cast<int*>(ciq);        //  cast required
    *iq = 4;                                //  undefined: modifies a  const  object
    

    So in short what you want to do isn't possible using standard C++.

    Further when the compiler encounters a declaration like

    const int a = 3; // I promisse i won't change a
    

    it is free to replace any occurance of 'a' with 3 (effectively doing the same thing as #define a 3)

    0 讨论(0)
  • 2020-11-28 07:41

    The step you're missing is that you don't need the int* pointer. The line:

    const int *ptr_to_a = &a; // I still promiss i won't change a;
    

    actually says you won't change ptr_to_a, not a. So if you changed your code to read like this:

    const int a = 3; // I promise I won't change a
    const int *ptr_to_a = &a; // I promise I won't change ptr_to_a, not a.
    
    (*ptr_to_a) = 5; // a is now 5
    

    a is now 5. You can change a through ptr_to_a without any warning.

    EDIT:

    The above is incorrect. It turns out I was confusing a similar trick with a shared_ptr, in which you can get access to the raw pointer and modify the internal data value without firing off any warnings. That is:

    #include <iostream>
    #include <boost/shared_ptr.hpp>
    
    int main()
    {
        const boost::shared_ptr<int>* a = new boost::shared_ptr<int>(new int(3));
        *(a->get()) = 5;
        std::cout << "A is: " << *(a->get()) << std::endl;
    
        return 0;
    }
    

    Will produce 5.

    0 讨论(0)
  • 2020-11-28 07:42
    const int foo = 42;
    const int *pfoo = &foo;
    const void *t = pfoo;
    void *s = &t; // pointer to pointer to int
    int **z = (int **)s; // pointer to int
    **z = 0;
    
    0 讨论(0)
  • 2020-11-28 07:43
    #include<iostream>
    int main( void )
    {
       int i = 3;    
       const int *pi = &i;
       int *pj = (int*)&i;
        *pj = 4;
    
       getchar(); 
       return 0;  
    }
    
    0 讨论(0)
提交回复
热议问题