0

It's common knowledge that class methods can be qualified with const - and if they are, they're not allowed to change the instance they're called for (ignoring mutable etc). One can think of it as though the member function was freestanding, but getting a this pointer as its first parameter - which would be const MyClass* for a const method, and MyClass ptr otherwise.

I've recently become aware that there are actually additional possible qualifiers for member functions (see, e.g. this question on the site), so the qualifiers are:

  • const or non-const
  • volatile or non-volatie
  • unreferenced, regular reference (&) or rvalue-reference (&&)

About volatile, I know what that means for variables - you can't just make a copy (e.g. in a register or maybe in some non-coherent cache) and expect it to be valid, as other code might be changing the original location. This doesn't seem to apply very cleanly to the "this pointer metaphor" like the const modifier, since - it's a pointer, of course others can change the pointed-to data. I would better understand something like a __restrict__ qualifier on this. So, is volatile what I'm assuming it to be or am I misinterpreting?

Now, about the reference qualifiers for members - I'm clueless. What would that even mean? What would be a reference to what? I don't get it.

Community
  • 1
  • 1
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 2
    Have a look [here](http://stackoverflow.com/a/8610728/1460794) for reference qualifiers for member functions. – wally Jan 05 '17 at 21:32
  • This question is a bit broad. Might I suggest posting separate questions for the different qualifiers? – wally Jan 05 '17 at 21:33
  • @Muscampester: I was actually hoping there would be a single explanation which straightens it all out for us. – einpoklum Jan 05 '17 at 21:35
  • 1
    And dupe for `volatile` qualifier - https://stackoverflow.com/q/16746070/241631 – Praetorian Jan 05 '17 at 21:35
  • I'm not sure there is a grand unified theory for this. I think there is somewhere in the standard that it spells out which qualifiers are part of the function type. But again, that would be a more specific question. – wally Jan 05 '17 at 21:36
  • 1
    Dupe for the reference part: https://stackoverflow.com/questions/28066777/const-and-specifiers-for-member-functions-in-c – Baum mit Augen Jan 05 '17 at 21:37
  • 1
    @Muscampester n3337 [dcl.fct]/6: "The return type, the parameter-type-list, the *ref-qualifier*, and the *cv-qualifier-seq*, but not the default arguments (8.3.6) or the exception specification (15.4), are part of the function type." – jaggedSpire Jan 05 '17 at 21:42
  • @BaummitAugen: Can you somehow arrange it that the "this is a duplicate" box have links to both the questions? – einpoklum Jan 05 '17 at 21:45
  • @einpoklum No, that would only have happened if some non-Mjolnir user voted for that dupe before it was closed as a dupe of the other question. Maybe mods can, dunno, but we can't. – Baum mit Augen Jan 05 '17 at 21:47
  • @BaummitAugen: Bummer, see [this](http://stackoverflow.com/questions/41495011/what-do-member-function-qualifiers-other-than-const-mean). – einpoklum Jan 05 '17 at 21:48
  • 1
    @einpoklum: I don't know why you think changing the implicit argument to `volatile TheClass* this` has no effect. First, if you have a `volatile TheClass`, you can't pass that as a (non-volatile) `TheClass*`, so ordinary (non-volatile-qualified) member functions cannot be invoked on a `volatile` instance, just like unqualified member functions cannot be invoked on a `const` object instance. Second, it affects members accessed (including implicitly) through the `this` pointer, causing those accesses to have volatile semantics -- except for the defect in the Standard wording. – Ben Voigt Jan 05 '17 at 22:19
  • 1
    Of course, the defect I am referring to is the one where volatile semantics are that accesses to volatile objects are treated specially, but accesses through volatile lvalues are not. – Ben Voigt Jan 05 '17 at 22:20
  • 1
    Anyway, people often declare objects of type `volatile std::atomic`... for any member functions to be usable on those instances, those member functions must be `volatile`-qualified. – Ben Voigt Jan 05 '17 at 22:21
  • I believe you are confusing the effect of `volatile` on the optimizer with the effect of re-entrancy. Sure, every time that the member function makes a call to an opaque function, it has to assume that said function might change aliased data, so it has to flush writes before external calls and repeat reads afterward. The difference is that `volatile` assumes external changes happen at all times, not only during specified callout points. – Ben Voigt Jan 05 '17 at 22:25
  • @einpoklum That's why "one question per question" is preferred; makes it way easier to choose the right dupe. – Baum mit Augen Jan 05 '17 at 22:34
  • @BenVoigt: But isn't that assumption made about data accessed via a pointer even without `volatile`? (That is, unless you inline the function taking a pointer and know what's actually being pointed to?) – einpoklum Jan 05 '17 at 22:51
  • 1
    @einpoklum: That's what my entire last comment just explained. Normally, you only worry about changes you don't know about when you call code you don't know about. `volatile` objects can change even when you aren't calling out to any other code, as well as during the stuff in between the calls. – Ben Voigt Jan 05 '17 at 22:57
  • This is too broad, `volatile` and `&&` are completely different topics – M.M Jan 06 '17 at 01:41

1 Answers1

0

"volatile" keyword effectively tells compiler to restrain from any assumptions it can usually do in order to optimize the generated assembler instructions to deal with a particular variable.

Reference qualifiers are used to make this method be only called when the object it is called on is an lvalue reference (for &) or rvalue reference (for &&) accordingly. This helps if you want to alter the behaviour of your method based on lvalueness/rvalueness of the objects (e.g., given that rvalues are typically short-lived temporaries).

Argenet
  • 379
  • 2
  • 9