16

According to N4606, 4.5 [conv.qual] paragraph 3 reads

A prvalue expression of type T1 can be converted to type T2 if the following conditions are satisfied, where cvij denotes the cv-qualifiers in the cv-qualification signature of Tj:

  • ...
  • If the cv1i and cv2i are different, then const is in every cv2k for 0 < k < i.

The final bullet above suggests that the following conversion fails.

T1 : pointer to / pointer to /       pointer to / T
T2 : pointer to / pointer to / const pointer to / T

In order to succeed, T2 must be pointer to / const pointer to / const pointer to / T. Isn't T2 sufficient just for being more cv-qualified than T1? Why are more cv-qualifiers in lower dimensions necessary for the conversion to succeed?

Community
  • 1
  • 1
  • 1
    My feeling is that you are seeking to discuss and understand better the question you asked. I have to admit that I wonder why the tag *language-lawyer* exists. In my opinion that is not really an SO question. Maybe try other StackExchange forums? Programming for example? .... – Ely Oct 23 '16 at 08:13
  • @Elyasin You're right. I came here to seek for a good explanation. If no answers show up, I'll consider looking for other forums. For *language-lawyer* tag, I added it because this question is related to the standard. Thank you for the comment. – eca2ed291a2f572f66f4a5fcf57511 Oct 23 '16 at 08:18
  • 2
    Note that this has been the rule since time immemorial. – Pete Becker Oct 23 '16 at 09:56
  • The question makes it (incorrectly) sound as if this was a change in the next version of the standard. I'm not sure if this was really your intention; perhaps you should reword it as a service for future readers. – Christian Hackl Oct 23 '16 at 11:08
  • @ChristianHackl I agree. My intent (for mentioning the draft) was just to clearly express the source. Also, I added *c++11* tag in order to draw more attention. I'll edit it. – eca2ed291a2f572f66f4a5fcf57511 Oct 23 '16 at 11:15
  • 2
    Isn't there an explanation and demonstration in the very same standard section? – Lightness Races in Orbit Oct 23 '16 at 14:10
  • 6
    @Elyasin: It looks like you have mistaken Stack Overflow for a code debugging/writing service. It is not. This is a great question (or, it would be had it not been answered a gazillion times before), far better than the constant stream of localised poop that forms the bulk of the site's input nowadays. Furthermore, no Stack Exchange site is a "forum". – Lightness Races in Orbit Oct 23 '16 at 14:10
  • 1
    @LightnessRacesinOrbit You're right... I have mistaken the example was for another bullet. In fact, the answer accepted below seemed to be just edited version of the example in the standard. Forgive me... – eca2ed291a2f572f66f4a5fcf57511 Oct 23 '16 at 14:30
  • @LightnessRacesinOrbit: I don't understand your accusation. Why so aggressive? Try to relax. I simply stated what I think. Maybe for you it is a great question, but that is not a requirement. "forum", "q&a site", "q&a forum", "network" or whatever, no need to ride on terminology really... – Ely Oct 23 '16 at 15:31
  • 2
    @Elyasin There is nothing aggressive about Lightness' comment-- they did no more than stating their disagreement. That is not to spite you. It is important to publicly disagree about this sort of issue, as it is not just a matter of personal opinion. For instance, every time someone shares an opinion about what they think is on-topic or off-topic in Stack Overflow, they nudge the whole community a tiny little bit in the direction of that opinion. If you care about the site and disagree, stating your disagreement publicly is an entirely natural way of countering that nudge. – duplode Oct 23 '16 at 16:19
  • That's fair enough. The first sentence in lightning's comment made me frown a bit... was not necessary I think. – Ely Oct 23 '16 at 16:27
  • There [should be a note that explains why](http://stackoverflow.com/a/29240053/1708801) ... that question is also quite similar. – Shafik Yaghmour Oct 25 '16 at 04:02

1 Answers1

23

Consider the following code:

char str[] = "p1 should always point here.";
char* const p1 = str;
char** p2 = nullptr;
char*** p3 = &p2;

char str2[] = "Can we make p1 point to here?"
// p1 = str2; // does not work: const violation

// But:
char*const** p4=p3; // if it were allowed
*p4 = &p1; // no const violation, as *p4 is of type char*const*
**p3 = str2; // oops, changed p1!

So if the conversion in question were allowed, you'd get to change a constant variable (p1) without any formal const violation.

celtschk
  • 19,311
  • 3
  • 39
  • 64
  • Can you explain when `T2` is `char*volatile**`? I don't think the same principle applies. – eca2ed291a2f572f66f4a5fcf57511 Oct 23 '16 at 12:38
  • @Il-seobBae: The same principle applies for volatile, except that the effect is different: Instead of changing something that should not be changed, you risk that a change is not properly committed to memory. – celtschk Oct 23 '16 at 13:35
  • @celtschk It all makes sense now. Thank you. – eca2ed291a2f572f66f4a5fcf57511 Oct 23 '16 at 15:11
  • @Il-seobBae General rule of thumb is that the same syntax and semantics apply to all cv-qualified versions of a type (i.e. non-qualified `T`, `const T`, `volatile T`, and `const volatile T`), with the difference being in what effect it has. Case in point, `const` correctness rules can be applied to `volatile` correctness as well, by simply changing every `const` to `volatile`. – Justin Time - Reinstate Monica Oct 23 '16 at 16:30
  • 1
    Note the [standard has a similar example](http://stackoverflow.com/a/29240053/1708801) in the same section. – Shafik Yaghmour Oct 25 '16 at 16:25