2

From a programming language theory standpoint, in C++, qualifiers like const and volatile allow to express a form of subtyping, with for example int being a subtype of const int.

I was wondering if we could also consider that ref-qualifiers & and && allow to express a form of subtyping or not. In other words, can we consider that T, T& and T&& are related by a subtyping relationship or not, from a programming language theory standpoint? And if so, what is this relationship?

Vincent
  • 57,703
  • 61
  • 205
  • 388
  • 2
    I wouldn't think of references as types, but as aliases. In theory they don't really exist, they are just a new name for some object. – NathanOliver Dec 14 '18 at 20:28
  • 2
    Surely const objects are, if anything, a subset of non-const objects? –  Dec 14 '18 at 20:31
  • @NathanOliver Simply incorrect. References have types of *reference to objects*, which are normatively defined in ISO C++ [basic.compound]. – FrankHB Jun 10 '20 at 12:24
  • `const int` or `const int&` are both subtypes of `int` due to the single-direction adjustment rules in [expr.type]. (For semantics on the value side, see also lvalue-to-rvalue conversion.) Reference qualifiers are generally contravarint to *cv*-qualifiers except at the return type of function types, where they are covariant. – FrankHB Jun 10 '20 at 12:37
  • 1
    @FrankHB: "*References have types of reference to objects*" Irrelevant. If you have a variable, and you make a reference to that variable, you can use the reference in virtually identical circumstances with identical behavior as the original variable being referenced. The primary exceptions to this involve `return/throw `, where if the expression is the variable itself, any copy/move operation can be elided, while that doesn't work for references. There may be some `decltype` gymnastics as well. – Nicol Bolas Jun 10 '20 at 13:31
  • @NicolBolas A declared reference itself *is* a variable, distinct to the object it refers to. (And the object is not necessarily a variable because it can be introduced without a declaration.) Type of an entity is not the same of type of an expression. For a reference, it does have the type specified in its declaration, that is the reference type, not the type of the object it refers to. – FrankHB Jun 12 '20 at 06:32
  • As per [expr.type], the further adjustment works only in the context where expressions are concerned. And more specifically, it is only effective on *evaluated operands* because other cases like the operands of `decltype` obey more specialized rules and they make the adjustment conceptually redundant. – FrankHB Jun 12 '20 at 06:33
  • The key point here is that the process of the adjustment itself is a non-trivial semantic function in the meta level (the operational semantics of the typing judgement). When talking about the relationship between types of the expressions, the term before the adjustment and the term after the adjustment are not identical. OTOH, the subtyping relationship lives in both sides: whether there are the adjustment, the criteria of subtyping always remain the same. However, the adjustment actually reduces too much type information, so it is not worth the analysis for practical reasons. – FrankHB Jun 12 '20 at 06:42

2 Answers2

2

While you could consider CV-qualifiers to be "subtypes" under some definition, references are not. const T t = some_t; creates a new object of type T declared as const. You might think of it as creating a new const T, but either way, you are creating a new object whose value conceptually is a copy of an existing one.

T &t = some_t; does not create a new object. It creates a reference to an existing object. That is a fundamentally different kind of thing in C++. References are not objects; the language is very clear about that. And it serves no useful purpose to think of a reference as a "subtype".

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 2
    To lend further credence it even states that it is unspecified if a reference even occupies any space while any other "object" is required to take up at least one byte (baring EBO, but you are not treating it as a distinct object in that case) – NathanOliver Dec 14 '18 at 20:37
  • It is true that reference types are not object types. However, this fact has nothing to do with how subtype desciplines work. – FrankHB Jun 10 '20 at 12:30
0

int being a subtype of const int

Well, it's not very clear what you're asking about, but it seems to be quite the other way round, since other forms of subtyping int using const or volatile would add more constraints than the original (value) type.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 2
    An `int` can be used safely where a `const int` is expected, not the contrary. – Vincent Dec 14 '18 at 20:31
  • @Vincent perhaps you could explain in the question how "`int` is a (sub)type of `const int`"? I seem to be one of several who see only the reverse. – Drew Dormann Dec 14 '18 at 20:37
  • 3
    @Vincent Right, so an `int` is the more general case. Anyway, what you say is not really true. For example `char a[x];` - here `x` cannot be an `int`, it must be a `const int`. –  Dec 14 '18 at 20:37