C++の変数を理解しよう

(5/15: 明らかに意味の通っていない場所・全く記述が足りていない場所・規格書のURLの誤りを修正)
(5/17: 前半を大幅に加筆修正(と書くしかないくらい加筆修正した))

# はじめに

プログラミング初心者たちが躓きやすい点のひとつとして「変数」があります。よくある説明としては「変数とは箱のようなものである」というものがあるようです。色々な意見があると思いますが、初心者のうちは良いでしょう。しかし、本職のプログラマがこのような曖昧な理解をしていてはいけません。C++プログラマならば変数とは何であるかきちんと説明できてしかるべきです。

ではきちんとした説明とは何でしょうか。
言うまでもありません。
言語仕様書です。
言語仕様書を引くのです。
言語仕様書がプログラミング言語を定義しています。
言語仕様書こそがプログラミング言語をプログラミング言語たらしめているといっても過言ではありません。
これを引いて説明できてこそC++プログラマと言えるでしょう。

さあ、C++言語仕様書を読みましょう。「変数とは箱のようなものである」などという甘ったれた理解から抜けだしましょう。言語仕様書が唯一にして無二なる涅槃への道なのです。涅槃とは、すなわち、C++完全理解。さあ、C++完全理解への第一歩を踏み出しましょう。

まずは、変数です。

# はじめに(2)

冗談はさておきまして、本記事では言語仕様書を参照しながら「変数とは何ぞや」というあたりを追いかけてみたいと思います。言語仕様書は open-std.org さんで手に入る最新の C++17 標準の draft 版、 N4659 を使います。URLは[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf)です。本当は publish されたものを購入して読むのが本筋なのでしょうが、結構高いですし、本記事は正式な書き物でもないので、これでいいでしょう。

# 用語について

おおむね

* 言語仕様書上で意味が定義されている語は英語のまま
* 通常の英単語の意味で使っている語は和訳

という方向性です。表記揺れがでるのもなんですし、原文を参照する記事でもありますので、用語は英語のままが便利だと思います。しかしながらC++用語か自然言語の意味を用いているのか微妙なものもあり、私の感で分けてしまっているものもあります。

# 調べる対象のコード

とりあえずコードです。
変数を全て理解するのも大変なので、今回は対象をぐっと絞って次のコードだけを説明します。

```C++
#include<iostream>
int foo;
int main() {
  foo = 57;
  std::cout << foo;
  return 0;
}
```

57が表示されるだけのコードです。
`foo = 57;` で `foo` に `57` が代入され、 `std::cout << foo;` で表示されます。

本記事ではこのコード中で変数っぽい `foo` について追いかけます。`std::cout` も変数っぽいですが、本記事ではあくまで `foo` について追いかけます。

# 変数とは何か

早速ですが仕様書を引きます。
変数を英語で言うと、普通は variable ですよね。そこで "variable" で検索しつつそれっぽい文章を探すと "6. Basic Concepts" に次のような文章がみつかります。

> A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
> (拙訳)variable は非staticなデータメンバ以外の参照もしくは object の declaration で導入される。

とりあえずここを起点に言語仕様書を追いかけることにします。

謎の単語がふたつありますね。declaration と object です。これから続々とわからない言葉がでてきますのでメモしておきましょう。「調べたい言葉」リストはスタックで、わからない言葉が出てきたら詰み、右の言葉から順に調べていく、ということにします。

```text:調べたい言葉
declaration object
```
```text:調べた言葉
variable: object の declaration で導入されるもの
```

## object

object を調べます。
これは "4.5 The C++ object model" に書いてあります。やはり基本的には全文を読む必要があるのですが、簡単のため、本記事に必要そうな二文だけを抜き出します。

まず一文目は

> The constructs in a C++ program create, destroy, refer to, access, and manipulate objects.
> (拙訳) C++ program の構成物は object を create し、 destroy し、 refer し、 access し、 manipulate する。

です。

要するに「objectというのはC++プログラムの操作の対象ですよ」と言っています。

普段C++プログラマが何気なく操作しているあれやこれやには object という名前がついています。念のため書いておきますが、いわゆるオブジェクト指向のオブジェクトとは違います。C++ の仕様書の中では object というのは独自に定義された意味を持っています。(余談: 本記事ではあまり深追いはしませんが、この "object" なる用語はC/C++言語仕様書のあちこちに出てくるので、C/C++言語仕様書リーディングをしたい方は確実に抑えておきましょう。)

二文目は

> An object occupies a region of storage in its period of construction (15.7), throughout its lifetime (6.8), and in its period of destruction (15.7).
> (拙訳) object は construction の期間と、 lifetime の間と、 destruction の期間に、storage の領域を占有する。

です。要するに

* object というのは storage の一部
* object が storage を占有するのは constructor が呼ばれる直前から destructor から帰る直後まで

と言っています。

storage という新しい言葉が出てきましたね。これを調べましょう(construction/lifetime/destructionは今回は無視します)。

```text:調べたい言葉
declaration object storage
```
```text:調べた言葉
variable: object の declaration で導入されるもの
```

## storage

storage の説明は「4.4 The C++ memory model」に書いてあります。
これも二文だけ抜き出すと、

> The fundamental storage unit in the C++ memory model is the byte. A byte is at least large enough to contain any member of the basic execution character set (5.3) and the eight-bit code units of the Unicode UTF-8 encoding form and is composed of a contiguous sequence of bits, the number of which is implementation-defined.
> (拙訳)C++ memory model の基本的な storage の単位は byte である。byte は少なくとも basic execution character set と Unicode UTF-8 のエンコーディングである8bitコード単位を保持できる連続したbitの列で、その数は implementation-defined である。

要するに

* storage は byte の集合
* byte というのは 8bit の情報を保持できるもの

と言っています。
普段我々が byte という語を使うときは単に 8bit のことを指すことが多いと思いますが、C++の規格書上では「(少なくとも)8bit分の情報を『保持できる』何か」であるという点に注意しましょう。 

```text:調べたい言葉
declaration object
```
```text:調べた言葉
variable: object の declaration で導入されるもの
storage : byte の集合
byte    : (少なくとも)8bitの情報を保持できるもの
```

## object(2)

話を object に戻しましょう。

* object というのは storage の一部
* object が storage を占有するのは constructor が呼ばれる直前から destructor から帰る直後まで

でした。

storage の意味がわかったので object の意味もわかりましたね。

```text:調べたい言葉
declaration
```
```text:調べた言葉
variable: object の declaration で導入されるもの
object  : storage の一部を占有するもの
storage : byte の集合
byte    : (少なくとも)8bitの情報を保持できるもの
```

## declaration

では declaration を調べましょう。declaration の説明は "6.1 Declarations and definitions" に載っています。基本全文を読む必要があるのですが、簡単のため、一文だけを取り出します。

> A declaration (Clause 10) may introduce one or more names into a translation unit or redeclare names introduced by previous declarations.
> (拙訳) declaration は translation unit に一個以上の name を導入したり、先行する declaration により導入された name を redeclare したりする。

あたらしい概念がふたつ出てきてしまいました。translation unit と name です。これらを調べてみましょう。

```text:調べたい言葉
declaration name translation_unit
```
```text:調べた言葉
variable: object の declaration で導入されるもの
object  : storage の一部を占有するもの
storage : byte の集合
byte    : (少なくとも)8bitの情報を保持できるもの
```

## translation unit

translation unit の定義は "5.1 Separate translation" に書いてあります。

> The text of the program is kept in units called source files in this International Standard. A source file together with all the headers (20.5.1.2) and source files included (19.2) via the preprocessing directive **#include**, less any source lines skipped by any of the conditional inclusion (19.1) preprocessing directives, is called a *translation unit*.
> (拙訳)プログラムを構成する文字列は、本国際標準の中で source file と呼ばれる単位に記録される。preprocessing directive **#include** ですべての header と source file をひとつにまとめ、そこからいくらかの source line が conditional inclusion  という preprocessing directive でスキップされた source file は *translation unit* と呼ばれる。

ここはプリプロセッサが絡む話で、先に進もうとすると闇が広がっているので、詳細は省きます。要するにプリプロセッサを通した後のソースコードひとつを translation unit と呼びますよ、と言っています。

```text:調べたい言葉
declaration name
```
```text:調べた言葉
variable         : object の declaration で導入されるもの
object           : storage の一部を占有するもの
storage          : byte の集合
byte             : (少なくとも)8bitの情報を保持できるもの
translation unit : プリプロセッサを通したソースコード丸ごとひとつ
```

## name

name の定義は "6. Basic Concepts" にあります。

> A name is a use of an identifier(5.10), operator-function-id(16.5), literal-operator-id(16.5.8), conversion-function-id(15.3.2), or template-id(17.2) that denotes an entity or label (9.6.4, 9.1)
> (拙訳)name は entity もしくは label を表す identifier, operator-function-id, literal-operator-id, conversion-function-id, もしくは template-id の使用である。

今回の対象に合わせてばっさり削りますと、「name は entity を表す identifier の使用である」として良いと思います。

entity, identifier と調べなければならないものが増えました。

```text:調べたい言葉
declaration name entity identifier
```
```text:調べた言葉
variable         : object の declaration で導入されるもの
object           : storage の一部を占有するもの
storage          : byte の集合
byte             : (少なくとも)8bitの情報を保持できるもの
translation unit : プリプロセッサを通したソースコード丸ごとひとつ
```

## identifier

identifier の定義は "5.10 Identifiers" に書いてあります。

> An identifier is an arbitrarily long sequence of letters and digits.
> (拙訳)identifierは任意の長さの文字や数字の列である。

この後の細かい部分は省きますが、よくあるプログラムの範囲内であれば、正規表現的の `[a-zA-Z_][a-zA-Z_0-9]*` が accept する文字の並びを identifier と考えて良いでしょう。`x` とか `hoge` とか `abc123` とかですね。今回調べる対象にしているプログラムの中の `foo` も identifier です。

```text:調べたい言葉
declaration name entity
```
```text:調べた言葉
variable         : object の declaration で導入されるもの
object           : storage の一部を占有するもの
storage          : byte の集合
byte             : (少なくとも)8bitの情報を保持できるもの
translation unit : プリプロセッサを通したソースコード丸ごとひとつ
identifier       : [a-zA-Z_][a-zA-Z_0-9]+
```

## entity

entity の定義は "6. Basic Concepts" にあります。

> An entity is a value, object, reference, function, enumerator, type, class member, bit-field, template, template specialization, namespace, or parameter pack.
> (拙訳)entity とは value, object, reference, function, enumerator, type, class number, bit-field, template, template specialization, namespace, あるいは parameter pack である。

色々列挙されていますが、今回追いかけたい範囲内においては、「色々あるが object は entity の一種である」ぐらいの理解で良いのではないでしょうか。


```text:調べたい言葉
declaration name
```
```text:調べた言葉
variable         : object の declaration で導入されるもの
object           : storage の一部を占有するもの
storage          : byte の集合
byte             : (少なくとも)8bitの情報を保持できるもの
translation unit : プリプロセッサを通したソースコード丸ごとひとつ
identifier       : [a-zA-Z_][a-zA-Z_0-9]+
entity           : 色々あるが object は entity の一種
```

## name(2)

さて、nameの話に戻りましょう。「name は entity を表す identifier の使用である」でした。意味が通るようになりましたね。調べた言葉リストに追加しましょう。

```text:調べたい言葉
declaration
```
```text:調べた言葉
variable         : object の declaration で導入されるもの
object           : storage の一部を占有するもの
storage          : byte の集合
byte             : (少なくとも)8bitの情報を保持できるもの
translation unit : プリプロセッサを通したソースコード丸ごとひとつ
identifier       : [a-zA-Z_][a-zA-Z_0-9]+
entity           : 色々あるが object は entity の一種
name             : entity を表す identifier
```

## declaration(2)

declaration に戻ってきました。

Declaration の定義は "10 Declarations" に載っています。

> Declarations generally specify how names are to be interpreted. 
> (拙訳)declaration は通常 name がどのように解釈されるか指定する。

```text:調べたい言葉
```
```text:調べた言葉
variable         : object の declaration で導入されるもの
object           : storage の一部を占有するもの
storage          : byte の集合
byte             : (少なくとも)8bitの情報を保持できるもの
translation unit : プリプロセッサを通したソースコード丸ごとひとつ
identifier       : [a-zA-Z_][a-zA-Z_0-9]+
entity           : 色々あるが object は entity の一種
name             : entity を表す identifier
declaration      : name がどのように解釈されるか指定するもの
```

はい、調べたい言葉がとりあずなくなりました。

variable というのは object の declaration で導入されるもので、declaration は name がどのように解釈されるか指定するものです。name は entity(ここではobject)に解釈されます。

さて、これらがどのように繋がるか見ていきましょう。

"10 Declarations" に

> Declarations have the form (以下略)

に続いて構文上の規則が書かれていて、この中でそれぞれの構文がどのような意味を持つか述べられています。規則は BNF というやつで書かれていて、これについて書くと大変なことになるので、 BNF 自体の読み方は省略します。

さて、 `int foo;` を題材に追いかけていきましょう。

`int foo;` は *declaration* です。*declaration* にはいくつか種類があるのですが、`int foo;` は *block-declaration* です(天下り的な説明ですが、かなり先読みしないとわからないのでこのように読んでいくことにします)。

*block-declaration* にもいくつか種類があるのですが、`int foo;` は *simple-declaration* です。

この *simple-declaration* にもいくつか種類があるのですが、`int foo;` は *decl-specifier-seq init-declarator-list<sub>opt</sub> `;`* です。

ここで `int foo;` は3つの部分に分解されます。
`int` は *decl-specifier-seq* で、
`foo` は *init-declarator-list* で、
`;` はこの規則の末尾の `;` です。

ここで p156 の 10 を読むと次のような文章があります。

> If the *decl-specifier-seq* contains no `typedef` specifier, the declaration is called a *function declaration* if the type associated with the name is a function type (11.3.5) and an *object declaration* otherwise.
> (拙訳)もし *decl-specifier-seq* が `typedef` specifier を含まない場合、もしその name に associate された型が function type(11.3.5)であれば、その declaration は *function declaration* と呼ばれ、そうでなければ *object declaration* と呼ばれます。

`int` に `typedef` は含まれていませんので、`int foo;` は object declaration であるということになります。

さて、`int` の部分を読み進めましょう。`int` は *decl-specifier-seq* でした。この *decl-specifier-seq* の定義は "10.1 Specifiers" に *decl-specifier* の並びとして定義されています。*decl-type-specifier* にはいくつか種類があるのですが、
`int` は *defining-type-specifier* だけです。

*defining-type-specifier* の定義は "10.1.7 Type specifiers" に書かれています。ここを見ると *defining-type-specifier* にもいくつか種類があることがわかるのですが、`int` は *type-specifier* です。

この *type-specifier* の定義は "10.1.7 Type specifiers" に書かれています。ここを見ると *type-specifier* にもいくつか種類があることがわかるのですが、`int` は *simple-type-specifier* です。

この *simple-type-specifier* の定義は "10.1.7.2 Simple type specifiers" に書かれています。ここを見ると *simple-type-specifier* にもいくつか種類があることがわかります。この中に `int` が含まれています。

というわけでこれを逆順に辿ると、`int` は *decl-specifier-seq* であると言えることになります。

次は `foo` です。`foo` は *init-declarator-list* でした。*init-declarator-list* は "11 Declarators" で定義されています。*init-declarator-list* はカンマ区切りの *init-declarator* の並びなのですが、`foo` にはカンマが含まれていませんので、`foo`は *init-declarator* です。

*init-declarator* の定義は *declarator initializer<sub>opt</sub>* です。*initializer* は初期化式を書くところで、`int foo;` にはありませんので、`foo` は *declarator* であるということになります。

*declarator* にもいくつか種類がありますが、`foo` は *ptr-declarator* です。

*ptr-declarator* にもいくつか種類がありますが、`foo` は *noptr-declarator* です。

*noptr-declarator* にもいくつか種類がありますが、`foo` は *declarator-id attribute-specifier-seq<sub>opt</sub>* です。また、ここで *attribute-specifier-seq* は空ですので、`foo` は *declarator-id* である、ということになります。

*declarator-id* の定義は *`...`<sub>opt</sub> id-expressiond* ですが、`foo` の中には `...` はありませんので、`foo` は *id-expression* である、ということになります。

*id-expression* の定義は "8.1.4 Names" に書いてあります。*id-expression* にもいくつか種類がありますが、`foo` は *unqualified-id* です。

*unqualified-id* の定義は "8.1.4.1 Unqualified names" にあります。*unqualified-id* にもいくつか種類がありますが、`foo` は *identifier* です。

*identifier* の定義は "5.10 Identifiers" に書かれています。さすがにもうええやろという感じなので雑に説明しますが、いわゆる変数名になるやつが *identifier* です。(余談: C++17では *identifier* に*universal-character-name* という ASCII 以外の文字を使えるようになっています。これ、 Unicode ではなく ISO/IEC 10646 という Unicode と概ね互換ないやらしい定義になっており…。)

さて、これまでつらつらと構文規則について述べてきました。ここまでを把握していると意味規則の方についての文章を読めるようになります。さっそく "11.3 Meaning of declarators" から引いてみましょう。

> Thus, a declaration of a particular identifier has the form
> 　　**T D**
> where **T** is of the form *attribute-specifier-seq<sub>opt</sub> decl-specifier-seq* and **D** is a declarator. Following is a recursive procedure for determining the type specified for the contained
*declarator-id* by such a declaration.
> (拙訳)従って、特定の identifier の declaration は
> 　　**T D**
> の形をしていて、**T** は *attribute-specifier-seq<sub>opt</sub> decl-specifier-seq* の形をしていて、**D** は declarator である。以下はこのようなdeclaration での、 *declarator-id* にどのような type が指定されるかを決めるための再帰的な手続きである。

> First, the *decl-specifier-seq* determines a type. In a declaration **T D** the *decl-specifier-seq* **T** determines the type **T**.
> (拙訳)まず、*decl-specifier-seq* は type を決める。declaration **T D** の中で*decl-specifier-seq* **T** はその type を **T** に決める。

> In a declaration *attribute-specifier-seq<sub>opt</sub>* **T D** where **D** is an unadorned identifier the type of this identifier is "T"
> (拙訳)**D**が単なる identifier であるような declaration *attribute-specifier-seq<sub>opt</sub>* **T D** では、その identifier の type は "T" である。

`int foo` の場合 *T* が `int` で、 *D* が `foo` です。
さあ、ようやく `int foo;` の意味がわかりました。

variable の name である `foo` の type は `int` なのです！！！

## variable

では再度 "6. Basic Concepts" に戻りましょう。

variable の最初の一文はこんなでした(再掲)。

> A variable is introduced by the declaration of a reference other than a non-static data member or of an object.
> (拙訳)variable は非staticなデータメンバ以外の参照もしくは object の declaration で導入される。

こんな一文があります。

> The variable’s name, if any, denotes the reference or object.
> (拙訳)その variable の名前は、もしあれば、参照か object を表す。

`foo` は参照ではありませんので、 object を表します。
注意しなければならないのは次の二点です。

* `foo` は variable の名前である
* `foo` は object を表す

違いに注意しましょう。`foo` は object そのものではなく、object を表す「variable の name」です。

# 中間まとめ

中間まとめです。

1. `int foo;` で variable が導入される。
2. `foo` の type は `int` である。
3. `foo` は variable の name である。
4. `foo` は `identifier` である。
5. `foo` は object を表す。
6. object は storage の一部である
7. storage は byte から構成されている
8. byte は(少なくとも)8bitを保持できるものである
9. object はプログラムの読み書きの対象である 

結局 `foo` は「何らかの情報を保持できるものを表す名前」なのです。

# statement & expression

さて、「変数が何か」はとりあえずわかりました。
「変数はどう動くか」を見ましょう。
変数が何かしら動作するのは statement や expression の中です。ですので仕様書のこのへんを読みましょう。

変数の記事なので `main` の定義や `return 0;` は無視して、`foo = 57;` と `std::cout << foo;` を追いかけます。

## statement

まず軽いところから。「`foo = 57;` の次に `std::cout << foo;` が実行される」と知っている方も多いと思います。これは規格書上では "9 Statements" の冒頭に書いてあります。

> Except as indicated, statements are executed in sequence.
> (拙訳)特に言及することがない限り、statementは順に実行される。

というわけで値が代入される前に表示されてしまうことを心配する必要はありません。

`foo = 57;` と `std::cout << foo;` を個別にみていきましょう。どちらも expression statement と呼ばれる statement です。expression statement の説明は "9.2 Expression statement" にあります。expression statement の定義は「expression の後にセミコロン(;)が付いたもの」です(ちなみに expression なしで単独の ; だけでも expression statement です)。というわけで expression `foo = 57` と `std::cout << foo` を追いかければいいわけですね。

## expression

expression の定義は "8.19 Comma operator" に書かれています。*expression* は *assignment-expression* か、それをコンマ演算子で並べたものです。コンマ演算子は今回使っていないので、`foo = 57` も `std::cout << foo` も *assignment-expression* です。

*assignment-expression* の定義は"8.18 Assignment and compound assignment operators" に書かれています。*assignment-expression* は色々あるのですが、`std::cout << foo` が *conditional-expression* で、`foo = 57` が *logical-or-expression assignment-operator initializer-clause* です。`foo = 57` を分解すると、
`foo` が *logical-or-expression* で、
`=` が *assignment-operator* で、
`57` が *initializer-clause* です。

さて、 `foo = 57` の意味ですが、これは自然言語で書かれています。

> In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand.
> (拙訳) simple assingment (=) では、左側の operand で refer される object をその値で置き換える。

(すみません、ここ、the value of the expression が何を指してるか読み取れませんでした。right operand の value であることは間違いないのですが、どこに書かれているのか見つけられませんでした。どなたかご存知でしたら教えてください。)

*initializer-clause* の定義は "11.6 Initializers" に書かれています。*initializer-clause* は *assignment-expression* もしくは波括弧リストなのですが、`foo = 57` では波括弧は使っていないので、 `57` もまた *assinment-expression* です。`57` は *assignment-expression* ですので、結局これは *conditional-expression* です。

*conditional-expression* の定義は "8.16 Conditional operator" に書かれています。*conditional-expression* は *logical-or-expression* もしくはいわゆる三項演算子の expression です。

というわけで結局 `foo`, `57`, `std::cout` の3つすべてが *logical-or-expression* ということがわかりました。

ここから同じような感じで長々と続きます。長いので追いかける構文規則名だけを順にならべますと、
*logical-or-expression* → *logical-and-expression* → *inclusive-or-expression* → *exclusive-or-expression* → *and-expression* → *equality-expression* → *relational-expression* → *shift-expression* → *additive-expression* → *multiplicative-expression* → *pm-expression* → *cast-expression* → *unary-expression* → *postfix-expression* → *primary-expression*
となります。

*primary-expression* は何種類かあるのですが、
`foo` はここから *primary-expression* → *id-expression* → *unqualified-id* → *identifier* となり、
`std::cout` は *primary-expresion* → *id-expression* → *qualified-id* となり、
`57` は *literal* になります。

*literal* の定義は "5.13 Literals" に書かれています。長いので省略しますが `57` の型 `int` で、その value は文字列を10進数で解釈したものであると読み取れます。

*unqualified-id* の定義は "8.1.4.1 Unqualified names" に書かれています。*unqualified-id* にも何種類かあるのですが、`foo`の場合は*identifier*です。これに対する意味は自然言語で次のように書かれています。

> An *identifier* is an *id-expression* provided it has been suitably declared (Clause 10).(中略) The type of the expression is the type of the *identifier*. The result is the entity denoted by the identifier.
> (拙訳)*identifier*は適切に declare された *id-expression* である。(中略)この expression の type は *identifier* の type である。result はこの identifier の表す entity である。

`foo` は `int foo` のところで適切に declare されていますので、この文章を適用できます。つまり expression の中の `foo` の型は `int` で、 expression の result は `foo` の表す entity、すなわち宣言のところで導入された variable です。

## `foo = 57` の意味

`=` の左側の `foo` は「`int foo;` の宣言で導入された variable(すなわちobject)」を表しています。`=` の右側の `57` は 57 という int を表しており、その value は 57 でした。

"8.18 Assignment and compound assignment operators" の記述に戻りますと、`=` は左側の operand の表す object の value を右側の operand の表す値で置き換えるという意味でした。というわけで

`foo = 57` は「`int foo;` の declaration で導入された variable(すなわちobject)の value を 57 で置き換える」という意味になります。

## `std::cout << foo` の意味

*qualified-id* の `std::cout <<` は本記事の範囲を超えそうなので省略させてください。とりあえず `<<` の右側の値を表示するという意味です。

`<<` の右側は `foo` です。`foo`は「`int foo;` の declaration で導入された variable(すなわちobject)」を表しています。この object の value は 57 でしたので、この式を評価すると 57 が表示されます。(なぜこの object の value が 57 であると言えるかというと、"9 Statements"に書いてあった通り、 statement は順に execute されるからです。)

# まとめ

非常に雑な説明かつ省略しまくりになってしまいましたが、変数の基本的なところは抑えられたかと思います。

さあ、まとめます。

言語仕様書から
「`int foo;` で `foo` と言う名前の variable の一種である object が導入され、
`foo = 57` で `int foo;` で導入された object の値を 57 に置き換え、
`cout << foo` で `int foo;` で導入された object の値を読み取ってから使っている」
ということが読み取れました！

# さいごに

疲れた