Weston Markham wrote:
Mark, (and group)
I may not have explained myself clearly in my original message. Your
I think you did. I just think we disagree on this one, reasonably.
A caller of this function should not care that these things go on internally. In this sense, it is logically const. I would also add that the caller of the function does not care that the precise behavior (say, when it returns, or in other examples, the exact value that it does) of the function can depend on the actions of other threads; this is the point that I had expected resistance on.)
Similarly, the condition::wait will modify a mutex (unlocking it, and yes, through a non-const Lock object). It will do some other stuff. Bookkeeping or whatever, maybe even blocking itself. No matter what it does internally, by the time it returns control to its caller, all of this has been undone. The thread is not blocked. It is not in a waiting queue. The mutex that we pointed it at has been locked again. From the caller's perspective, the only things different after the call are:
1. Time has passed. 2. Some other threads have done some things that they might not have done otherwise. What they do is their own business. I don't see how that can affect this function's const-ness. (Am I missing something _here_?)
My conclusion is that condition::wait is logically const. I will certainly admit that const-ness may be in the eye of the beholder. I expect that the physically const vs. logically const is a problem with some people. However, there do seem to be other examples of functions that are const (in their signatures) in the same spirit that my intuition tells me condition::wait is.
[snipped to end] I say that the difference between physical const and logical const is EXACTLY what you are saying it is: A logically const method does not change the internal state of the object. A phyically const method does not modify any members of the object. A phyically const method is necessarily logically const. The converse may not be true. The distinction is that a logically, but not physically, const method requires "mutable" member variables to compile. The question is: Of what does an object's state consist? We both seem to agree that merely grabbing a mutex (or blocking on an attempt to grab a mutex) is not changing the object's state. Somehow, and this is a gut feeling, the condition.wait() seems different to me. Perhaps because it requires a change in the objects state in order to continue. Let's look at this from the other side: Would the condition.notify() method be considered logically const? I can see some circumstances in which the argument could be made. However, I would say the general case is "no, it is not". Simply because if there is no state change, what's the point of notifying anyone? Given this, a method that waits will block until the object's state is modified. When the method returns, the object's state will be different than when the method was entered (unless it restores the state, in which case I'm fine with logical const-ness). Although the method ITSELF isn't doing the changing, the state of the object changes between the call and the return. That says "non-const" to me. I'm willing to be argued out of it, but I probably won't change my code. - Mark