0

EDIT:

this question does NOT have an answer ^^there because it merely says

By declaring a variable as const you indicate compiler that you have no intentions of modifying that variable.

What does "modifying" mean? Changing the assigned value? What if it's a compound object - what about changing its data members (won't work), but if the data member is a reference changing it will work even if the containing object is const? Why?

I know that "Such object cannot be modified" and that "By declaring a variable as const you indicate compiler that you have no intentions of modifying that variable." I'm interested in what is meant by "modifying" when the object is not a basic type but is a compound type and besides its value data members it has references and pointers, too.

cppreference only says

Such object cannot be modified

Is "object" or "modified" a technical term associated with the memory representation or something? Experimenting shows that if the object data members are pointers or references the data represented by them can be modified.

class Vector {
public: 
    Vector () : ptr(new int[20]) {}

    void f() const {
        ptr[0] = 100;
    }
private:
    int* const ptr;
}; 

the code above compiles, doing const Vector v; does not prepend const to the int* const ptr.

Also if the data members are references, who knows how the reference is internally implemented (if it's not specified in the standard), what does then const do according to the standard?

MY ANSWER: (also thanks to info in comments)

When you declare your object const

const MyObject obj();

or

__class definition__
private:
    const MyObject obj;

you basically say the data, that are directly part of the object in memory, cannot change. Remember that sub-objects (data members), sub-sub-objects,... are directly part of the object in memory.

Thus in compound objects, it “marks” all members constant too, in a “deep const” manner, until it descends to non-compound types only.

But remember that pointers and reference don’t store the object, they store only the memory location. So for pointers you get a constant pointer and for references nothing changes (the memory location they hold, they point to, is always constant).

So a quick summary of what happens if you declare a compound object const.

for its data members:

  1. object is of a primitive data type (but non-pointer and non-reference) -> answer ^^there
  2. object is a pointer -> SomeObj* becomes SomeObj* const
  3. object is a reference -> SomeObj& stays same
  4. object is a compound data type -> “mark” all its members const with these rules

Although why it is designed that way for references might not be evident. So one should NOT think of a reference as a black box type that can be implemented in ANY way.

One HAS to think references are just pretty constant pointers, having merely their implementation in mind rather than a reference black box. Otherwise it would never make sense, references aren’t closer to value types than to pointers, they are pointers. Syntactically they might be like value types but semantically and implementation-wise they are constant pointers.

Adam
  • 1,724
  • 4
  • 21
  • 31
  • `int* const ptr;` is a constant pointer to int. So the pointer is constant but what is points to is not. If you want the `int` array to be constant as well you need: `int const * const ptr;` that is constant pointer to constant int (read right-to-left from the variable name). – Richard Critten May 07 '18 at 10:59
  • The `const` does effect `ptr` itself, but not what is pointed to. – Bo Persson May 07 '18 at 10:59
  • @RichardCritten it is. But how come doing const on the entire vector does not make all its data members including pointers and references constant? – Adam May 07 '18 at 11:01
  • that is pointers would point to constant types a references would reference constant types – Adam May 07 '18 at 11:02
  • @Adan - It does affect the vector, but the memory from `new int[20]` is on the heap, and is not part of the Vector. – Bo Persson May 07 '18 at 11:02
  • Because `const` is not transitive, it only applies to the "thing" (need a better word here) it is immediately attached to. So your vector is constant but not the members of the vector. – Richard Critten May 07 '18 at 11:03
  • so "modifying" effectively means changing the data members excluding references and excluding accesses to pointed memory? – Adam May 07 '18 at 11:05
  • `const` in C++ is *shallow*. You seem to expect a deep `const` but C++ doesn't have such a construct. – n. m. could be an AI May 07 '18 at 11:05
  • @RichardCritten no, if the member of the vector were an `int` and the vector instance were `const`, the member would have to be constant`. – Adam May 07 '18 at 11:07
  • I know that "Such object cannot be modified" and that "By declaring a variable as const you indicate compiler that you have no intentions of modifying that variable." I'm interested what is meant by "modifying" when the object is not a basic type but is a compound type and besides value data members it has references and pointers, too. – Adam May 07 '18 at 11:30
  • The thing that `ptr` points to in your question is not part of the object. Only the pointer is. The const in `Vector const v` has effect on all `v`'s members, but only it members. (Same for references. The thing the reference refers to is not part of the object (unless it is somehow self-referential of course...) - and references cannot be re-bound anyway) – Mat May 07 '18 at 11:41
  • 1
    If you want "according to the standard", you may want to tag this question `language-lawyer`. – Eljay May 07 '18 at 12:35
  • "modifiying" in this context means calling a non-const non-static member function, or modifying a non-mutable member variable – M.M May 07 '18 at 13:38
  • @n.m. declaring an object `const` means that all of its members are also `const`, recursively, so I would describe it as "deep". I guess you refer to how mean that a pointer to non-const becomes a const pointer to non-const; but in C++ pointers do not own the thing they point to so this is natural behaviour – M.M May 07 '18 at 13:40
  • @M.M having non-const subobjects in a const object would mean that "const" is simply a no-op, so this kind of depth is not a very meaningful property. – n. m. could be an AI May 07 '18 at 14:11
  • @n.m. `const` doesn't generate any assembly instructions , I'm not really sure what you mean. `const` objects can have non-const subobjects anyway, via `mutable` – M.M May 07 '18 at 23:21
  • @M.M.no-op means "does nothing", not necessarily when talking about program execution. Anyway I'm not sure what we are talking about any more. – n. m. could be an AI May 08 '18 at 03:24
  • @Adam closed questions are still searchable on Google. – TylerH Aug 24 '18 at 20:38
  • @TylerH oh sorry, maybe it's the duplicate thing. Searching for the title finds the "original", not this "dupe", question. And I'm not sure if one always checks the linked questions sidebar on the right. – Adam Aug 24 '18 at 21:09

0 Answers0