Core C++

6.1. Classes and visibility🔗

Definition6.1.1
Group: Abstract data types, objects, classes and inheritance. (11)
Group member previews
Preview
Definition 6.1.2
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 2.1.11
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
Used by 6
Reverse dependency previews
Preview
Definition 6.1.2
Loading preview
Reverse dependency preview content is loaded from the rendered-fragment cache.
✓L∃∀N

A class has an optional base, fields and methods with a visibility, at most one constructor named after the class and at most one destructor. Members before the first section label are private, as in C++.

The class is well formed when the base exists and the chain is acyclic, the fields have types with values and repeat no field of a base, the members have distinct names, a method that redefines a method of a base finds it virtual there, carries override and keeps the signature, the constructor of the base takes no parameters, and every member body is well typed under this.

\dfrac{\begin{array}{c} B \text{ exists, chain acyclic}\qquad \text{fields storable, well formed, new in the chain} \\ \text{each redefined } m \text{ is virtual in the base, marked override, same signature} \\ B \text{ has no constructor or one without parameters} \\ [\mathtt{this} \mapsto C*, p_1, \ldots, p_k] \vdash c \dashv \Gamma' \text{ for each member body} \end{array}}{\vdash \mathtt{class}\ C\ \mathtt{:}\ \mathtt{public}\ B\ \{ \ldots \}}\;\textsf{(T-Class)}

The context of a member body binds this to C* and the parameters as variables, so the current class is the class of this in \Gamma.

Lean code for Definition6.1.1●8 definitions
  • structure(6 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.ClassDecl : Type
    structure CoreCpp.ClassDecl : Type
    A class, with an optional base class, fields, methods, at most one
    constructor and at most one destructor. Names are qualified by their
    namespace, `N::C`. 
    name : String
    The name of the class, qualified by its namespace when it has one. 
    base : Option String
    The base class, when the class derives from one. 
    fields : List CoreCpp.Field
    The fields declared by the class itself. 
    methods : List CoreCpp.Method
    The methods declared by the class itself. 
    ctor : Option CoreCpp.Ctor
    The constructor, when the class declares one. 
    dtor : Option CoreCpp.Dtor
    The destructor, when the class declares one. 
  • structure(3 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.Field : Type
    structure CoreCpp.Field : Type
    A field of a class. 
    ty : CoreCpp.Ty
    The type of the field. 
    name : String
    The name of the field. 
    vis : CoreCpp.Vis
    The visibility of the field. 
  • structure(8 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.Method : Type
    structure CoreCpp.Method : Type
    A method, defined inside the class. `isVirtual` marks `virtual`, which
    makes the call dispatch by the class tag of the receiver, and `isOverride`
    marks `override`, required on a method that redefines a `virtual` one. An
    operator member is a method whose name is `operator` followed by the
    operator, `operator+` or `operator[]`, which the type checker reaches by
    rewriting the infix form. 
    name : String
    The name of the method. 
    ret : CoreCpp.Ty
    The result type. 
    params : List CoreCpp.Param
    The parameters. 
    body : List CoreCpp.Cmd
    The body, run with `this` bound to the receiver. 
    vis : CoreCpp.Vis
    The visibility of the method. 
    isVirtual : Bool
    Whether the method is declared `virtual`. 
    isOverride : Bool
    Whether the method is declared `override`. 
    retRef : Bool
    Whether the method returns a reference, `τ& m(…)`, so that a call to it
    denotes the location the body returns. 
  • structure(2 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.Ctor : Type
    structure CoreCpp.Ctor : Type
    The constructor of a class, named after the class and run by `new` after
    the fields are allocated. 
    params : List CoreCpp.Param
    The parameters of the constructor. 
    body : List CoreCpp.Cmd
    The body, run by `new C(args)` after the fields are allocated. 
  • structure(2 fields)defined in CoreCpp/Syntax.lean
    complete
    structure CoreCpp.Dtor : Type
    structure CoreCpp.Dtor : Type
    The destructor of a class, `~C()`, run by `delete` before the locations of
    the object leave the store. 
    body : List CoreCpp.Cmd
    The body, run by `delete` before the object leaves the store. 
    isVirtual : Bool
    Whether the destructor is declared `virtual`, which makes `delete`
    through a pointer to the base well defined. 
  • inductive(2 constructors)defined in CoreCpp/Syntax.lean
    complete
    inductive CoreCpp.Vis : Type
    inductive CoreCpp.Vis : Type
    Visibility of a member. Members before any section label are private, as
    in C++. 
    CoreCpp.Vis.pub : CoreCpp.Vis
    A public member, visible to every expression. 
    CoreCpp.Vis.priv : CoreCpp.Vis
    A private member, visible only inside a member body of the class that
    declares it. 
  • defdefined in CoreCpp/Typing.lean
    complete
    def CoreCpp.Typing.cls (p : CoreCpp.Program) (c : CoreCpp.ClassDecl) :
      CoreCpp.T Unit
    def CoreCpp.Typing.cls (p : CoreCpp.Program)
      (c : CoreCpp.ClassDecl) : CoreCpp.T Unit
    A class is well formed when the conditions below hold.
    
    Its base exists and the chain of bases has no cycle. Its fields have types
    that carry values, are themselves well formed, and repeat no field of a base.
    
    Its members have distinct names, and each method redefines only a method the
    base declares virtual, carrying override and the same signature. The
    constructor of the base, if the base has one, takes no parameters.
    
    Every member body is well typed under `this`.
    
    ```
    B exists, chain acyclic    fields storable, well formed, new in the chain
    for each method m of C. if some base has m then that m is virtual,
        m is override and the signatures agree
    for each override m of C. some base has a virtual m
    B has no constructor or one with no parameters
    [this ↦ C*, params] ⊢ body ⊣ Γ' for each member body
    ──────────────────────────────────────────────────────────────── (T-Class)
    ⊢ class C : public B { … }
    ```
    
  • defdefined in CoreCpp/Typing.lean
    complete
    def CoreCpp.Typing.memberEnv (c : String) (ps : List CoreCpp.Param) :
      CoreCpp.TEnv
    def CoreCpp.Typing.memberEnv (c : String)
      (ps : List CoreCpp.Param) : CoreCpp.TEnv
    The context of a member body, `this` bound to a pointer to the class and
    the parameters as variables. 
Definition6.1.2
Group: Abstract data types, objects, classes and inheritance. (11)
Group member previews
Preview
Definition 6.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 2
Statement dependency previews
Preview
Definition 2.1.9
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 1✓L∃∀N

A private member declared in class K is visible exactly when \Gamma(\mathtt{this}) = K*. Visibility is thus a typing rule, and the public section of a class is the signature of an abstract data type while the private section is its representation, reachable only from the member bodies of the class.

\dfrac{C \text{ has } \tau\ f \text{ declared in } K \qquad f \text{ public or } \Gamma(\mathtt{this}) = K*}{\Gamma \vdash e.f : \tau \text{ for } \Gamma \vdash e : C}\;\textsf{(Visible)}

The same premise applies to methods, Definition 6.2.3.

Some of the implementations are partial, so Lean records opaque constants that carry the type and not the body, and no property of them is proved here.

Lean code for Definition6.1.2●3 definitions
  • defdefined in CoreCpp/Typing.lean
    complete
    def CoreCpp.TEnv.self (Γ : CoreCpp.TEnv) : Option String
    def CoreCpp.TEnv.self (Γ : CoreCpp.TEnv) :
      Option String
    The current class, the class of `this` when Γ binds it, inside a method,
    a constructor or a destructor. 
  • defdefined in CoreCpp/Typing.lean
    complete
    def CoreCpp.Typing.fieldType (p : CoreCpp.Program) (Γ : CoreCpp.TEnv)
      (c f : String) : CoreCpp.T CoreCpp.Ty
    def CoreCpp.Typing.fieldType
      (p : CoreCpp.Program) (Γ : CoreCpp.TEnv)
      (c f : String) : CoreCpp.T CoreCpp.Ty
    The type of field f of class C as seen from Γ, or the error. A private
    field is visible only when Γ(this) is the class that declares it.
    
    ```
    C has τ f declared in K    f public or Γ(this) = K*
    ──────────────────────────────────────────────────── (Visible)
    ```
    
  • opaquedefined in CoreCpp/Typing.lean
    complete
    opaque CoreCpp.Typing.methodCall (p : CoreCpp.Program) (Γ : CoreCpp.TEnv)
      (recv : CoreCpp.Expr) (arrow : Bool) (m : String)
      (es : List CoreCpp.Expr) : CoreCpp.T CoreCpp.Ty
    opaque CoreCpp.Typing.methodCall
      (p : CoreCpp.Program) (Γ : CoreCpp.TEnv)
      (recv : CoreCpp.Expr) (arrow : Bool)
      (m : String) (es : List CoreCpp.Expr) :
      CoreCpp.T CoreCpp.Ty
    The rules T-Method and T-MethodArrow, see `expr`. 
Definition6.1.3
Group: Abstract data types, objects, classes and inheritance. (11)
Group member previews
Preview
Definition 6.1.1
Loading preview
Group member preview content is loaded from the rendered-fragment cache.
Statement uses 4
Statement dependency previews
Preview
Definition 2.1.4
Loading preview
Statement dependency preview content is loaded from the rendered-fragment cache.
used by 0✓L∃∀N

Inside a member body this is the location of the receiver. It is bound in \rho by the call as an alias, never a variable, and it evaluates to a pointer. An unqualified name that is not a variable denotes the member of this, both in the type checker and in the evaluator.

\dfrac{\Gamma(\mathtt{this}) = C*}{\Gamma \vdash \mathtt{this} : C*}\;\textsf{(T-This)}

\dfrac{x \notin \Gamma \qquad \Gamma(\mathtt{this}) = C* \qquad \Gamma \vdash \mathtt{this}\mathtt{->}x : \tau}{\Gamma \vdash x : \tau}\;\textsf{(T-VarField)}

The same holds of a call. An unqualified name that is neither a variable nor a function of the program is a member of the receiver.

\dfrac{\begin{array}{c} f \notin \Gamma\qquad f \text{ is no function of the program}\qquad \Gamma(\mathtt{this}) = C* \\ \Gamma \vdash \mathtt{this}\mathtt{->}f(e_1, \ldots, e_k) : \tau \end{array}}{\Gamma \vdash f(e_1, \ldots, e_k) : \tau}\;\textsf{(T-CallThis)}

\dfrac{\rho(\mathtt{this}) = \ell}{\rho, \sigma \vdash \mathtt{this} \Rightarrow \mathsf{loc}\,\ell, \sigma}\;\textsf{(This)}

\dfrac{x \notin \rho \qquad \rho(\mathtt{this}) = \ell \qquad \sigma(\ell) = \mathsf{obj}\,C\,[\ldots x \mapsto \ell_x \ldots]}{\rho, \sigma \vdash x \Rightarrow_{\ell} \ell_x, \sigma}\;\textsf{(LocVarField)}

The implementations are partial, so Lean records opaque constants that carry the type and not the body, and no property of them is proved here.

Lean code for Definition6.1.3●3 definitions
  • opaquedefined in CoreCpp/Typing.lean
    complete
    opaque CoreCpp.Typing.expr (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) :
      CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
    opaque CoreCpp.Typing.expr (p : CoreCpp.Program)
      (Γ : CoreCpp.TEnv) :
      CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
    Γ ⊢ e : τ 
  • opaquedefined in CoreCpp/Eval.lean
    complete
    opaque CoreCpp.Eval.expr (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env)
      (σ : CoreCpp.Store) (e : CoreCpp.Expr) :
      CoreCpp.M (CoreCpp.Val × CoreCpp.Store)
    opaque CoreCpp.Eval.expr (fs : CoreCpp.FunEnv)
      (ρ : CoreCpp.Env) (σ : CoreCpp.Store)
      (e : CoreCpp.Expr) :
      CoreCpp.M (CoreCpp.Val × CoreCpp.Store)
    ρ, σ ⊢ e ⇒ v, σ' 
  • opaquedefined in CoreCpp/Eval.lean
    complete
    opaque CoreCpp.Eval.lval (fs : CoreCpp.FunEnv) (ρ : CoreCpp.Env)
      (σ : CoreCpp.Store) (e : CoreCpp.Expr) :
      CoreCpp.M (CoreCpp.Loc × CoreCpp.Store)
    opaque CoreCpp.Eval.lval (fs : CoreCpp.FunEnv)
      (ρ : CoreCpp.Env) (σ : CoreCpp.Store)
      (e : CoreCpp.Expr) :
      CoreCpp.M (CoreCpp.Loc × CoreCpp.Store)
    ρ, σ ⊢ e ⇒ₗ ℓ, σ', the expressions that denote a location. A variable, a
    dereferenced pointer, a field of an object, a field through a pointer and an
    element of a vector.
    
    ```
    ρ(x) = ℓ                     ρ, σ ⊢ e ⇒ loc ℓ, σ'
    ──────────────────── (LocVar)  ────────────────────── (LocDeref)    nullptr is error
    ρ, σ ⊢ x ⇒ₗ ℓ, σ             ρ, σ ⊢ *e ⇒ₗ ℓ, σ'
    ```
    
    ```
    ρ, σ ⊢ e ⇒ₗ ℓ, σ'    σ'(ℓ) = obj C [… f ↦ ℓ_f …]
    ─────────────────────────────────────────────── (LocField)
    ρ, σ ⊢ e.f ⇒ₗ ℓ_f, σ'
    ```
    
    ```
    ρ, σ ⊢ e ⇒ loc ℓ, σ'    σ'(ℓ) = obj C [… f ↦ ℓ_f …]
    ────────────────────────────────────────────────── (LocArrow)    e->f is (*e).f
    ρ, σ ⊢ e->f ⇒ₗ ℓ_f, σ'
    ```
    
    An element of a vector is a use of the library, the rule LocLib.