If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

howto restric a method to being absolutely constant

Hi,

I want to be able to declare a restriction in C++ so that a functor object can not change it's state or the state of any object it has a reference to upon calling the functor. This would have to be something like an "absolute const" object. At the same time I would like to be able to pass arguments upon calling the function object who's state it can change.

I need this because these functor objects will be scheduled between threads and I want to make sure that executing them only affects objects from the targeted thread, passed as arguments. This way I can guarantee no concurrency issues will occur.

Re: howto restric a method to being absolutely constant

I don't understand the question. Doesn't every thread have its own instance of the functor that is completely different from every other instance that was created by other threads? If all the instances do not have any way of gaining access to each other what is the problem?

if you want a functor to be "read-only" make its operator(), function arguments, and any other private members const and the compiler will ensure that you aren't modifying anything. If you build all of your functions to be const correct there shouldn't be any problems with getting the desired behavior. Do you know about the const qualifier in C++?

Re: howto restric a method to being absolutely constant

if you want a functor to be "read-only" make its operator(), function arguments, and any other private members const and the compiler will ensure that you aren't modifying anything.

I think what OP wants is something similar to

Code:

void operator()(const Target& obj) const

where the const in red won't get caught by the compiler if any modification is done on the argument.
(which I totally agree with you that it doesn't make sense)

@ssouffri
AFAIK, there's no such thing as "absolute const" for you can a) cast it away,
b) make certain members mutable.
I don't know much about pthread or boost thread functions,
but for win32 api,
even if you some how make the method "absolute const",
the chance is that you will likely pass object as the argument,
in which case data passed to the thread function

Re: howto restric a method to being absolutely constant

Originally Posted by ssouffri

Hi,

I want to be able to declare a restriction in C++ so that a functor object can not change it's state or the state of any object it has a reference to upon calling the functor. This would have to be something like an "absolute const" object.

That's pretty much just 'regular const'. Just have any references to these objects be const to achieve this part.

The problem is it's either const or not unless you cast it away or declare it mutable, but this destroys any very thin illusion that const actually restricts anything in the first place. You could protect and unprotect memory to cause it to error out but it would be a huge waste of time for no gain.

Re: howto restric a method to being absolutely constant

I know const can be overridden in more than one way but using const is at least a very strong reminder that an object should only be read. The main problem I have with a plain const method is that it can still change the state of objects its class has a pointer to. I would like an "absolute_const" keyword to declare that a method can only access pointers as if they were declared as pointers to constant objects ( const TYPE *p; ). So basically an absolute_const method could only change the state of its arguments.

First notice that

Code:

virtual void operator(Target &target) absolute_const;

in my class TargetedFunctor is a virtual function so it's behaviour is undefined for thread 2 that is going to process the functor at some time in the future.

The main problem I'm concerned about is that some class D, derived from my class TargetedFunctor, can have a pointer to some object X and can write to X in "operator()", called by thread 2, when it is concurrently being accessed by thread 1. Or that it could pass a pointer to "target" on to object X and that "target", from that point on, can also get accessed by thread 1.

If operator() was declared to be "absolutely_const" then it could not do this. It could only read from objects is has a reference to and write to argument target. Unless it was dowcasted or some things were declared as mutable .

So does absolute_const exist or can I construct something that is just as restrictive?

One alternative I thought of was to template the use of TargetedFunctor and then let my "template<F> Queue" class instantiate functors of type F. However I would need to be able to provide an argument object for the construction. And this argument object could very well contain pointers. So this doesn't work unless I can declare that this argument can't contain any pointers which, I think, is also impossible in C++.

Re: howto restric a method to being absolutely constant

I did read something somewhere about coopting the "volatile" keyword to serve more or less this purpose. I can't say I'd recommend that, though.

Perhaps you should think about whether you really need those pointers and references to be non-const *some* of the time. It might be better to have two different classes, one in which they're const and one in which they're not. It would, of course, be impossible to convert safely from the const version to the non-const version; but the other direction should be trivial.

Re: howto restric a method to being absolutely constant

Originally Posted by ssouffri

I know const can be overridden in more than one way but using const is at least a very strong reminder that an object should only be read. The main problem I have with a plain const method is that it can still change the state of objects its class has a pointer to. I would like an "absolute_const" keyword to declare that a method can only access pointers as if they were declared as pointers to constant objects ( const TYPE *p; ). So basically an absolute_const method could only change the state of its arguments.

First notice that

Code:

virtual void operator(Target &target) absolute_const;

in my class TargetedFunctor is a virtual function so it's behaviour is undefined for thread 2 that is going to process the functor at some time in the future.

The main problem I'm concerned about is that some class D, derived from my class TargetedFunctor, can have a pointer to some object X and can write to X in "operator()", called by thread 2, when it is concurrently being accessed by thread 1. Or that it could pass a pointer to "target" on to object X and that "target", from that point on, can also get accessed by thread 1.

If operator() was declared to be "absolutely_const" then it could not do this. It could only read from objects is has a reference to and write to argument target. Unless it was dowcasted or some things were declared as mutable .

So does absolute_const exist or can I construct something that is just as restrictive?

One alternative I thought of was to template the use of TargetedFunctor and then let my "template<F> Queue" class instantiate functors of type F. However I would need to be able to provide an argument object for the construction. And this argument object could very well contain pointers. So this doesn't work unless I can declare that this argument can't contain any pointers which, I think, is also impossible in C++.

First of all const and thread syncronization are two different things. If you have two threads accessing the same functor object then you have a thread synch issue which has nothing to do with const correctness.

Secondly you CAN make a function that is not able to modify what it points to I think. As I pointed out before make the function itself const. A const function can not call non-const functions or in the case of a class, a const member function cannot modify the state of the object by modifying class attributes. The compiler will flag these problems as errors.

Re: howto restric a method to being absolutely constant

Originally Posted by ssouffri

I know const can be overridden in more than one way but using const is at least a very strong reminder that an object should only be read. The main problem I have with a plain const method is that it can still change the state of objects its class has a pointer to. I would like an "absolute_const" keyword to declare that a method can only access pointers as if they were declared as pointers to constant objects ( const TYPE *p; ). So basically an absolute_const method could only change the state of its arguments.

I disagree with your assertion completely. A const member function cannot change the state of objects that it has a pointer to even if the pointer is non-const (at least not without some hacking).

In this slightly modified example you can see that the const functor cannot call non-const functions on members of the class instance. It's not necessary to limit the functor to only use const* attributes. It makes no difference whether the pointer is const or not because the caller is const. Therefore, the caller cannot use a pointer to make function calls unless the function itself is declared as const. Therefore you are still adequately protected in my opinion.

So basically an absolute_const method could only change the state of its arguments.

Well if the absolute_const function can change anything than it isn't absolute_const is it? I don't really understand what you mean by its arguments. If the arguments are passed by value or by non-const ref or pointer, it can change them because they aren't const. On the other hand a const member function can not alter the state of the object it belongs to. Is that a problem for you? What did you mean by arguments? I think that you can do exactly what you want using the const qualifier. A const function can call non-const functions on input arguments if the input arguments aren't const. If a const function receives a non-const array as an input it can modify the input array but cannot modify the state of the object that it belongs to. Understand?

The reason why your code fails is because of the following line where a class attribute is changed.

Code:

theCollector.insert(rhs[last]);

Originally Posted by kempofighter

A const function can call non-const functions on input arguments if the input arguments aren't const. If a const function receives a non-const array as an input it can modify the input array but cannot modify the state of the object that it belongs to. Understand?

Yes i do but that's not my problem. My problem is simply that

Code:

nco->nonConstMember();

does not cause any compiler errors.

My compiler is "g++ (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]". Maybe your compiler will refuse to compile the above code in which case it's an interpretation difference issue. If so, which compiler complies with which C++ standard? And which one makes more sense?

The reason why your code fails is because of the following line where a class attribute is changed.

Code:

theCollector.insert(rhs[last]);

Yes i do but that's not my problem. My problem is simply that

Code:

nco->nonConstMember();

does not cause any compiler errors.

My compiler is "g++ (SUSE Linux) 4.3.2 [gcc-4_3-branch revision 141291]". Maybe your compiler will refuse to compile the above code in which case it's an interpretation difference issue. If so, which compiler complies with which C++ standard? And which one makes more sense?

Well good point. I never realized that and now I see what you are saying. The issue has to do with pointers. It seems like a security problem to me. I wonder if there is documentation from the stds committee on this because it seems like a serious security problem with the language design, not that I really have time to go find it and read it. That's a really annoying issue. We should have been posting these types of examples in the beginning in order to clarify the problem. This has nothing to do with threading but is really more of a stds question regarding the limitation of const member functions.

Re: howto restric a method to being absolutely constant

^It's essentially the same issue which prevents you from converting a T** to a const T**.

I think the question you need to be asking is why you want a single object to have both const and non-const access to a given pointer. It would really make more sense from a safety perspective to only have one or the other from a given type.

The decorator pattern may provide a means to relate the const and non-const versions of a type effectively.

Re: howto restric a method to being absolutely constant

Anyway, I think that the problem makes perfect sense to me now. The const member function is being allowed to make non-const calls through pointers that belong to the class. I can see where this would seem confusing. The member function doesn't seem like it is truly const. Of course it can modify references/pointers that it receives as arguments (they are not part of the object's state) but why should the const member function be allowed to call non-const functions via a pointer that is a member of the class? I guess you'd have to consider that since we are dealing with a pointer that the thing pointed to is not really part of the class's state. It might be a shared pointer so perhaps that is why the language was not designed to catch this. Now if the member is an object that is owned by the class then it is part of the class's state and therefore cannot be modified by the const member function. Bonzo demonstrated this well with this example where he wrapped the pointer within a class and then instantiated an object as a class attribute.

Code:

class foo
{
// the pointer points to something that might not be owned by
// by foo instances. const member functions can make any call
// via this pointer. Is that a security issue or just a misunderstanding
// about the purpose of a const member function?
ObjectType* memberPtr;
// This object is owned by each foo instance. It cannot be modified
// by const member functions nor can any non-const function be called
// by non-const member functions
ObjectType memberPtr;
};

I think that the OP wants the complier to ensure that a const member function cannot call non-const functions on memberPtr or use memberPtr to modify any attributes of what memberPtr points to. On the other hand, input arguments received by any member function have nothing to do with the class's state (they are part of the callers state). Whether they can be modified depends only on the declaration of the argument and not the const/non-const declaration of the member function itself.

I think that Bonzo's example is an excellent work around for what could be perceived to be a security flaw by some.

* The Perfect Platform for Game Developers: Android
Developing rich, high performance Android games from the ground up is a daunting task. Intel has provided Android developers with a number of tools that can be leveraged by Android game developers.

* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.