Home > Back-end >  Is there such a C feature: "const scope" in method definitions?
Is there such a C feature: "const scope" in method definitions?

Time:08-18

I was wondering if there is a safety feature to restrict a scope of a class method definition to allow disallow modifying access to *this. See this pseudo-code:

class C{
 void method();
 void const_method() const {
     // do const stuff here
 }
};

void C::method(){
    const_method();
}

Now instead of calling const_method(); I would directly have a scope which only allows const access, i.e. which only allows code that would also be valid within the const_method definition like this:

void C::method(){
    // {  "const scope"
    // instead of const_method();
    // do const stuff directly here
    // }
}

I know that I can just call a const method but when I like to modify outer local variables in the const scope I would have to make them be returned from the const function or use a reference or pointer parameter as a workaround. So I am wondering if there exists a language feature to have "const scopes"?

My goal is to have peace of mind in some sections of the code, the compiler shall verify that I do not modify the class instance in sections of code where I do not intend this.

EDIT I have seen in the comments that I can use const C* const_this{this}; But of course this does not prevent me from modifying *this when I forget to use const_this. I have the feeling that it could be done with a lambda thich captures all locals and captures *this as const somehow. How could this be done?

CodePudding user response:

You can use a immediately invoked lambda, though you still have to capture the local variables explicitly:

#include <iostream>

struct foo {
    int member = 42;
    void bar() {
        int local_var = 42;
        [const_obj=const_cast<const foo&>(*this),&local_var](){
            //member = 2;           // error: this is not captured
            //const_obj.member = 2; // error: const_obj is read-only 
            const_obj.const_method();
            std::cout << const_obj.member;
        }();
    }
    void const_method() const {};
};

However, I somewhat agree with comments. Your approach of simply calling const_method is ok, while your argument against it (Needing to pass paramteters and return values) is a matter of design that can be solved in different less arcance ways. The reluctance to pass parameters and return values around can lead to the most absurde constructs, while simply passing parameters and return values around is typically the more clear, readable and simpler code.

PS: There is a way to get somewhat the opposite of what you ask for. I am not recommending it, hence I will only outline it: In the example above you could make bar call a private bar() const. Because bar() const is only called from non-const bar() you can safely cast away constness to get a mutable reference to the current object that can be restricted to a narrow scope. Though, if you aim for "peace of mind" then this approach is not the way to go.

CodePudding user response:

Yes there is, using shadowing and static member functions. Your compiler should be configured to warn about this, so you would have to deactivate it specifically for this particular case.

class C{
 static void method(C& self) {
   // non-const stuff with self
   {
     C& ncvSelf = self;
     C const& self = ncvSelf; // intentional shadowing of self
     // const stuff with self
   }
   // non-const stuff with self
 }
};

The reason you have to use the self idiom is because you cannot declare a this variable to shadow the actual this pointer.

  •  Tags:  
  • c
  • Related