3.6. Objects and pointers
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete]
The literal nullptr has the internal type \mathsf{nullptr\_t}, compatible with every pointer type and with no other. Its value is \mathsf{null}.
\dfrac{}{\Gamma \vdash \mathtt{nullptr} : \mathsf{nullptr\_t}}\;\textsf{(T-Null)}
\dfrac{}{\rho, \sigma \vdash \mathtt{nullptr} \Rightarrow \mathsf{null}, \sigma}\;\textsf{(Null)}
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 Definition3.6.1●2 definitions
Associated Lean declarations
-
CoreCpp.Typing.expr[complete]
-
CoreCpp.Eval.expr[complete]
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete]
-
opaquedefined in CoreCpp/Typing.leancomplete
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.leancomplete
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, σ'
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Store.allocMany[complete] -
CoreCpp.Ty.default[complete]
The expression new C() allocates one location per field of C, each with the default value of its type, then the record itself, tagged with the class, and evaluates to a pointer to the record. Its type is C*. The empty parentheses are the whole argument list for a class without a constructor. A class with a constructor takes its arguments in those parentheses, Definition 6.2.1.
\dfrac{C \mapsto \mathtt{class}\ C\ \{\, \tau_1\, f_1; \ldots; \tau_n\, f_n; \,\}}{\Gamma \vdash \mathtt{new}\ C() : C*}\;\textsf{(T-New)}
\dfrac{\begin{array}{c} C \mapsto \mathtt{class}\ C\ \{\, \tau_1\, f_1; \ldots; \tau_n\, f_n; \,\} \\ (\ell_i, \sigma_i) = \mathrm{alloc}(\sigma_{i-1}, \mathrm{default}\,\tau_i),\ \sigma_0 = \sigma \\ (\ell, \sigma') = \mathrm{alloc}(\sigma_n, \mathsf{obj}\,C\,[f_1 \mapsto \ell_1, \ldots, f_n \mapsto \ell_n]) \end{array}}{\rho, \sigma \vdash \mathtt{new}\ C() \Rightarrow \mathsf{loc}\,\ell, \sigma'}\;\textsf{(New)}
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 Definition3.6.2●4 definitions
Associated Lean declarations
-
CoreCpp.Typing.expr[complete]
-
CoreCpp.Eval.expr[complete]
-
CoreCpp.Store.allocMany[complete]
-
CoreCpp.Ty.default[complete]
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Store.allocMany[complete] -
CoreCpp.Ty.default[complete]
-
opaquedefined in CoreCpp/Typing.leancomplete
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.leancomplete
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, σ'
-
defdefined in CoreCpp/Semantics.leancomplete
def CoreCpp.Store.allocMany (σ : CoreCpp.Store) (vs : List CoreCpp.Val) : List CoreCpp.Loc × CoreCpp.Store
def CoreCpp.Store.allocMany (σ : CoreCpp.Store) (vs : List CoreCpp.Val) : List CoreCpp.Loc × CoreCpp.Store
Allocates one fresh location per value, in order.
-
defdefined in CoreCpp/Semantics.leancomplete
def CoreCpp.Ty.default : CoreCpp.Ty → CoreCpp.Val
def CoreCpp.Ty.default : CoreCpp.Ty → CoreCpp.Val
The default value of a type, the one `new` gives to every field and element before the constructor runs. Object types have no value, their default is never asked. A field of function type starts empty, `void`, and a call through it before the constructor assigns a lambda is `error`, as the `bad_function_call` of C++.
-
CoreCpp.Typing.lval[complete] -
CoreCpp.Eval.lval[complete] -
CoreCpp.Eval.pointee[complete]
The dereference *e denotes the location the pointer holds. When the pointer is \mathsf{null} the result is error, where C++17 leaves the dereference undefined.
\dfrac{\Gamma \vdash e : \tau*}{\Gamma \vdash_{\ell} {*e} : \tau}\;\textsf{(T-LocDeref)}
\dfrac{\rho, \sigma \vdash e \Rightarrow \mathsf{loc}\,\ell, \sigma'}{\rho, \sigma \vdash {*e} \Rightarrow_{\ell} \ell, \sigma'}\;\textsf{(LocDeref)}
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 Definition3.6.3●3 definitions
Associated Lean declarations
-
CoreCpp.Typing.lval[complete]
-
CoreCpp.Eval.lval[complete]
-
CoreCpp.Eval.pointee[complete]
-
CoreCpp.Typing.lval[complete] -
CoreCpp.Eval.lval[complete] -
CoreCpp.Eval.pointee[complete]
-
opaquedefined in CoreCpp/Typing.leancomplete
opaque CoreCpp.Typing.lval (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) : CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
opaque CoreCpp.Typing.lval (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) : CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
The expressions that denote a location, with their type. A variable, a dereferenced pointer, a field of an object, a field through a pointer, and a use of the library or a member that gives a location. A variable captured by copy inside a lambda denotes no writable location. ``` Γ(x) = τ, x not captured Γ ⊢ e : τ* Γ ⊢ e : C, C has τ f ──────────────────────── (T-LocVar) ─────────── (T-LocDeref) ────────────────── (T-LocField) Γ ⊢ₗ x : τ Γ ⊢ₗ *e : τ Γ ⊢ₗ e.f : τ ``` ``` Γ ⊢ e : C*, C has τ f ────────────────────── (T-LocArrow) Γ ⊢ₗ e->f : τ Γ ⊢ e : L⟨τ̄⟩ Γ ⊢_L operator[] : τ₁ → τ, a location Γ ⊢ i ◁ τ₁ ─────────────────────────────────────────────────────────────────── (T-LocIndexLib) Γ ⊢ₗ e[i] : τ ```
-
opaquedefined in CoreCpp/Eval.leancomplete
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.
-
defdefined in CoreCpp/Eval.leancomplete
def CoreCpp.Eval.pointee (v : CoreCpp.Val) : CoreCpp.M CoreCpp.Loc
def CoreCpp.Eval.pointee (v : CoreCpp.Val) : CoreCpp.M CoreCpp.Loc
A pointer value as a live location. nullptr is error, the dereference that C++ leaves undefined.
-
CoreCpp.Typing.lval[complete] -
CoreCpp.Typing.fieldType[complete] -
CoreCpp.Eval.lval[complete] -
CoreCpp.Eval.fieldLoc[complete]
The field access e.f denotes the location of the field f in the record that e denotes, and e->f abbreviates (*e).f, so a null pointer is error. The type of the field comes from the class table.
\dfrac{\Gamma \vdash e : C \qquad C \text{ has } \tau\, f}{\Gamma \vdash_{\ell} e.f : \tau}\;\textsf{(T-LocField)}
\dfrac{\Gamma \vdash e : C* \qquad C \text{ has } \tau\, f}{\Gamma \vdash_{\ell} e\mathtt{->}f : \tau}\;\textsf{(T-LocArrow)}
\dfrac{\rho, \sigma \vdash e \Rightarrow_{\ell} \ell, \sigma' \qquad \sigma'(\ell) = \mathsf{obj}\,C\,[\ldots f \mapsto \ell_f \ldots]}{\rho, \sigma \vdash e.f \Rightarrow_{\ell} \ell_f, \sigma'}\;\textsf{(LocField)}
\dfrac{\rho, \sigma \vdash e \Rightarrow \mathsf{loc}\,\ell, \sigma' \qquad \sigma'(\ell) = \mathsf{obj}\,C\,[\ldots f \mapsto \ell_f \ldots]}{\rho, \sigma \vdash e\mathtt{->}f \Rightarrow_{\ell} \ell_f, \sigma'}\;\textsf{(LocArrow)}
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 Definition3.6.4●4 definitions
Associated Lean declarations
-
CoreCpp.Typing.lval[complete]
-
CoreCpp.Typing.fieldType[complete]
-
CoreCpp.Eval.lval[complete]
-
CoreCpp.Eval.fieldLoc[complete]
-
CoreCpp.Typing.lval[complete] -
CoreCpp.Typing.fieldType[complete] -
CoreCpp.Eval.lval[complete] -
CoreCpp.Eval.fieldLoc[complete]
-
opaquedefined in CoreCpp/Typing.leancomplete
opaque CoreCpp.Typing.lval (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) : CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
opaque CoreCpp.Typing.lval (p : CoreCpp.Program) (Γ : CoreCpp.TEnv) : CoreCpp.Expr → CoreCpp.T CoreCpp.Ty
The expressions that denote a location, with their type. A variable, a dereferenced pointer, a field of an object, a field through a pointer, and a use of the library or a member that gives a location. A variable captured by copy inside a lambda denotes no writable location. ``` Γ(x) = τ, x not captured Γ ⊢ e : τ* Γ ⊢ e : C, C has τ f ──────────────────────── (T-LocVar) ─────────── (T-LocDeref) ────────────────── (T-LocField) Γ ⊢ₗ x : τ Γ ⊢ₗ *e : τ Γ ⊢ₗ e.f : τ ``` ``` Γ ⊢ e : C*, C has τ f ────────────────────── (T-LocArrow) Γ ⊢ₗ e->f : τ Γ ⊢ e : L⟨τ̄⟩ Γ ⊢_L operator[] : τ₁ → τ, a location Γ ⊢ i ◁ τ₁ ─────────────────────────────────────────────────────────────────── (T-LocIndexLib) Γ ⊢ₗ e[i] : τ ```
-
defdefined in CoreCpp/Typing.leancomplete
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/Eval.leancomplete
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.
-
defdefined in CoreCpp/Eval.leancomplete
def CoreCpp.Eval.fieldLoc (σ : CoreCpp.Store) (l : CoreCpp.Loc) (f : String) : CoreCpp.M (CoreCpp.Loc × CoreCpp.Store)
def CoreCpp.Eval.fieldLoc (σ : CoreCpp.Store) (l : CoreCpp.Loc) (f : String) : CoreCpp.M (CoreCpp.Loc × CoreCpp.Store)
The location of field f of the object stored at ℓ.
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Eval.readLoc[complete]
Reading *e, e.f or e->f as a value is reading the content of the location it denotes, one rule for the three forms. Three typing rules give the value the type of the location. An element v[i] of a vector is a use of the library, Definition 8.1.2.
\dfrac{\Gamma \vdash e : \tau*}{\Gamma \vdash {*e} : \tau}\;\textsf{(T-Deref)}
\dfrac{\Gamma \vdash e : C \qquad C \text{ has } \tau\, f}{\Gamma \vdash e.f : \tau}\;\textsf{(T-Field)}
\dfrac{\Gamma \vdash e : C* \qquad C \text{ has } \tau\, f}{\Gamma \vdash e\mathtt{->}f : \tau}\;\textsf{(T-Arrow)}
\dfrac{\rho, \sigma \vdash e \Rightarrow_{\ell} \ell, \sigma' \qquad \ell \in \mathrm{dom}\,\sigma'}{\rho, \sigma \vdash e \Rightarrow \sigma'(\ell), \sigma'}\;\textsf{(Read)}, \quad e \in \{{*e'},\ e'.f,\ e'\mathtt{->}f\}
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 Definition3.6.5●3 definitions
Associated Lean declarations
-
CoreCpp.Typing.expr[complete]
-
CoreCpp.Eval.expr[complete]
-
CoreCpp.Eval.readLoc[complete]
-
CoreCpp.Typing.expr[complete] -
CoreCpp.Eval.expr[complete] -
CoreCpp.Eval.readLoc[complete]
-
opaquedefined in CoreCpp/Typing.leancomplete
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.leancomplete
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, σ'
-
defdefined in CoreCpp/Eval.leancomplete
def CoreCpp.Eval.readLoc (σ : CoreCpp.Store) (l : CoreCpp.Loc) : CoreCpp.M CoreCpp.Val
def CoreCpp.Eval.readLoc (σ : CoreCpp.Store) (l : CoreCpp.Loc) : CoreCpp.M CoreCpp.Val
σ(ℓ), or error when ℓ ∉ dom σ.