13

I am supposed to determine whether this function is syntactically correct:

int f3(int i, int j) { const int& k=i; ++i; return k; }

I have tested it out and it compiles with my main function.

I do not understand why this is so.

Surely by calling the function f3 I create copies of the variables iand j in a new memory space and setting const int& k=i I am setting the memory space of the newly created k to the exact the same space of the memory space of the copied i, therefore any change, i.e. the increment ++iwill result in ++k which is not possible given that it was set const

Any help is greatly appreciated

user9078057
  • 271
  • 1
  • 10
  • 2
    Small nitpicking: `int f3(int i, int j) { const int& k=i; ++k; return k; }` would be syntactically correct too – danielspaniol Mar 27 '19 at 06:37
  • @danielspaniol I get `error: cannot assign to variable 'k' with const-qualified type 'const int &'` – Thomas Sablik Mar 27 '19 at 10:38
  • 1
    @ThomasSablik That is a semantical error. The syntax is correct. – danielspaniol Mar 27 '19 at 10:44
  • `I am setting the memory space of the newly created k`. No. K is a reference, this means is equivalent to an alias (an alias is literally another another name for a variable). So `k` does not need its own variable it is simply another name for `i` (though it is const qualified). You can verify that it does not have its own memory because you can not take the address of `k`, if you try you will get the address of `i`. – Martin York Mar 28 '19 at 17:31
  • @MartinYork If you put `int &k` in a struct `A`, make it the first field, take address of the struct, and cast it from `A*` to `int**`: you will have the address of the `int &k`. – atomsymbol Apr 03 '19 at 22:18
  • @atomsymbol: No. What you have there is unspecified behavior. – Martin York Apr 03 '19 at 22:43
  • @MartinYork I agree with you. Please notify me if there is a C++ compiler where it would fail. – atomsymbol Apr 03 '19 at 23:12
  • @atomsymbol: "where it would fail" => All of them. Thats the point. If you are writing code with "undefined" or "unspecified" behavior. Your code is invalid. Running it makes zero sense it could break now it could work now but stop working in the future. How you can run code that could suddenly stop working with no warning! – Martin York Apr 04 '19 at 00:11
  • @MartinYork You are indirectly claiming that `int*` and `int&` might have different binary representations in a real C++ compiler. If it isn't real, it is a world of fantasy. I want to know the C++ compiler that does that because it can be interesting to see why. Managed&interpreted C++ runtimes can get away with any kind of conceivable binary representation of course because they can precisely track memory accesses. It is nice to argue with you. – atomsymbol Apr 04 '19 at 01:33
  • @atomsymbol That's a straw man argument. So you fail. Undefined/Unspecified behavior. Argument over. – Martin York Apr 04 '19 at 02:24
  • @MartinYork Taking into account you have 200K StackOverflow reputation, I expected more than just the trivial and dull undefined behavior argument. You seem to dislike multiple interpretations/viewpoints to a single problem. I already wrote that I agree with you, so no problem there. Now it is your turn to write that you accept my viewpoint as valid. Choosing denial will be simpler on the brain because there is no need to keep multiple viewpoints in mind. – atomsymbol Apr 04 '19 at 12:59

1 Answers1

27

the increment ++i will result in ++k which is not possible given that it was set const

That's a misunderstanding.

You may not change the value of the object through k but it can still be changed through other means. In other words, ++k is not allowed but ++i is still allowed, which will indirectly modify the value of k.

Here's an analogy from a non-computer world.

You may look through the window of a store and see what's inside but you won't be able to change what's inside the store. However, an employee, who is inside the store, can change the contents of the store. You will see that change from outside. You have const access or view access to the store while the employee has non-const access or change access to the store.

JFMR
  • 23,265
  • 4
  • 52
  • 76
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 9
    Not so far-fetched. That's a good analogy. – user4581301 Mar 26 '19 at 22:44
  • 1
    Note that this is so because i itself is not const. So we have a const reference a non-const object. Const objects are different. – David Schwartz Mar 26 '19 at 22:53
  • @DavidSchwartz This is true, but now that I think of it, it doesn't suit the logic for pointers, does it? since `const int *` would be a non-constant pointer to a constant int and `int * const` would be a constant pointer to a non-constant int, this should be `int & const`, shouldn't it? I feel like this is inconsistent. – Max Mar 27 '19 at 08:52