1
struct S { string s; }

void method() 
{
    const S s = { "s" };
    s.s = "l"; // Error
}

I can't understand why a compile-error is being generated here. From my understanding, making a struct-referencing variable const should make the variable itself immutable (only s = { "m" } after s initialization should generate error), not the structure itself (so s.s = "l" should pass OK). Why const makes both the variable and the struct immutable?

bitmask
  • 32,434
  • 14
  • 99
  • 159
nyarian
  • 4,085
  • 1
  • 19
  • 51
  • 1
    Would an object really be `const` if you could change some parts of it? – cigien May 19 '20 at 23:49
  • No, and that's actually the question - struct's fields are not `const`, only a variable referencing a struct instance is `const`, so why the object itself becomes immutable, not only the variable? – nyarian May 19 '20 at 23:51
  • I'm not sure I follow. It's *only* through the `const` variable that you can't change the fields. You can still create another non-const variable and change the fields of that. A variable *is* an object. – cigien May 19 '20 at 23:55
  • @Andrey Ilyunin The qualifier const makes the object denoted by a variable immutable. – Vlad from Moscow May 19 '20 at 23:59
  • @cigien I could have `struct S { const string s; }` if I wanted the struct to be immutable. What I wanted here is a mutable struct with an immutable variable pointing to struct. But as @hobbs said there is no indirection like in Java, where you have a variable and an object inside the heap to which the variable actually points to. So if a variable is `final` in Java, and the object the variable is referencing is mutable (it's fields are not `final`, where `final` is equal to C++ `const` in many cases), then you can change the object's fields freely, but not the variable's reference value. – nyarian May 20 '20 at 00:01

1 Answers1

3

It's not "a variable referencing a struct instance". There's no indirection. The value of s is a struct S, which includes all of its fields.

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • Ah, I see. I just come from Java background, and a syntactic analogy for this in Java is to declare a class with mutable fields, but making a variable referencing the instance of the class `final` won't make the object itself immutable. Semantics seem to be different though. Thanks! – nyarian May 19 '20 at 23:57
  • Java isn't C++ and vice versa. You don't pay for what you don't use in C++. I recommend reading up on the distinction between the C++ concepts of **automatic storage** versus **dynamic storage**. – bitmask May 20 '20 at 00:01
  • @bitmask I started learning C++ with Eckel's `Thinking in C++` a week ago, and if I knew this concepts before posting a question, then, actually, the question would not exist at all. So everything has it's time basically. But thanks, I'll follow the advice when it's time to learn this stuff too. – nyarian May 20 '20 at 00:04
  • I didn't mean to fault you for not knowing this. I thought that researching storage in C++ will give you the understanding that you require to rectify the underlying misapprehensions expressed in your comment and question. To make the transition from Java to C++ I think the biggest hurdle is RAII and storage (and maybe templates). – bitmask May 20 '20 at 00:11
  • @AndreyIlyunin C++ does have a [`mutable specifier`](https://en.cppreference.com/w/cpp/language/cv) that allows a member to be modified even if the containing object is `const`. – Blastfurnace May 20 '20 at 00:15
  • @Blastfurnace, thanks, that's useful! Basically a solution to the aforementioned "task" :) – nyarian May 20 '20 at 00:17
  • Something to note - Thinking in C++ was written before 2011, which means that most of modern features of C++ are not mentioned there (as they just didn't exist back then). Try to use or (supplement your learning) with a more recent book. – Myrddin Krustowski May 20 '20 at 00:49
  • @RazielMagius which one for instance? Nothing as nicely rated shows up among recent books, plus I'm not planning to make C++ my main language of development - it's mostly for general education and understanding what's going on under JNI layer. Won't it be more effective to understand the fundamentals and then learn new standards-specific stuff? – nyarian May 20 '20 at 06:46
  • There is [The Definitive C++ Book Guide and List](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). If you like algorithms, Data Structures & Algorithm Analysis in C++ by Weiss covers some of the fundamental modern c++ features in first 3 chapters. Some things in old c++ is sort of obsolete - for example move semantics which appeared in C++11 are important from the beginning - as move constructor and move assignment operator should be defined on any class that allocates resources. And there are many others... – Myrddin Krustowski May 20 '20 at 08:55