Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C/++/# Can the constness be changed in the middle of the program?

Tags:
  1. Feb 29, 2016 #1

    ORF

    User Avatar

    Hello

    I'm using C++11. I had a bug (about one variable which changed at some point ), so in order to find out where it is I pass all const arguments by reference (to all functions of the program). At one point one variable must be changed, and I wonder if there is a way to convert that const variable into a non-const one.

    Thank you in advance

    Greetings
     
  2. jcsd
  3. Feb 29, 2016 #2
    Labeling a variable as CONST is a preprocessor command.
    This does a couple things.
    First off it tells the compiler that if the code tries to change the value of that variable to throw an error.
    Secondly (I think) it changes where, in the memory allocated to your program, that variable is stored.

    I'm a little surprised honestly that the compiler would let you pass a CONST variable by reference,

    if a variable has to be changed it is by definition NOT a CONST and you shouldn't label it as such. There is no safe way that I am aware of to change a value of a CONST.
     
  4. Feb 29, 2016 #3
    Do you ever take the address and use a pointer to access the variable(s)? Maybe you have an improper cast?

    const char foo[] = "hello";
    char *bar = (char*) foo;
    strcpy(bar, "world"); // Oops!
     
  5. Feb 29, 2016 #4

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    The OP was asking about const rather than CONST. The former is a keyword in C and in C++. The latter, who knows what that means? Unless the programmer has #defined CONST to mean something, even the preprocessor doesn't know what CONST means. If you worked for me and you insisted on doing this, I would think of firing you unless you had a very good reason for doing so. For example, having to deal with a compiler last updated in the previous millennium would qualify as a justifiable excuse.


    There are multiple ways of achieving this. None are all that good.

    Approach #1: Use a C-style cast to remove the const qualifier:
    Code (C):
    void some_function(const SomeType& ref) {
        ((SomeType&)ref).something_i_want_to_change = 0;
    }
    Approach #2: Use a C++ style cast to remove the const qualifier:
    Code (C):
    void some_function(const SomeType& ref) {
        const_cast<SomeType&>(ref).something_i_want_to_change = 0;
    }
    Approach #3: (Applicable to member data only): Mark a data member as mutable:
    Code (C):
    class Foo {
    public:
        some_function () const {
            something_i_want_to_change = 0;
        }
    private:
        mutable int something_i_want_to_change;
    };
     
    The first is very hard to find. Those C-style casts that cast away const-ness are just bad. The latter two are easily found via grep.

    Beautiful programming concepts aside, there are times when you either need to cast const-ness away (with a const_cast, not a C-style cast), or just magically making the const-ness disappear, which is what mutable does. Casting away const-ness is, by definition, undefined behavior. Marking a member as mutable (supposedly) is well-defined behavior. Beware, however, that a number of compilers do not treat mutable properly.
     
    Last edited: Feb 29, 2016
  6. Feb 29, 2016 #5

    Svein

    User Avatar
    Science Advisor

    In C, you are allowed to weird things. On your own head be it! But, you could use a union:
    Code (C):
    union Uconst {
      const int c_I;
      int I;
      };
    This allows you to declare a constant and modify it using another name...
     
  7. Mar 2, 2016 #6

    ORF

    User Avatar

    Thank you for all the clarification, specially to @D H ;)

    Greetings!
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted