>サイトトップへ >このカテゴリの一覧へ

X 3016

:2010 (ISO/IEC 23271:2006) 

(1) 

目  次

ページ

序文 

1

第 章  概念及びアーキテクチャ

1

1

  適用範囲

1

2

  適合性

2

3

  引用規格

2

4

  形式

4

4.1

  構成

4

4.2

  参考情報 

4

5

  用語及び定義 

4

6

  共通言語基盤の概要

9

6.1

  型安全との関係

10

6.2

  管理下メタデータ駆動実行との関係 

10

7

  共通言語仕様 

12

7.1

  導入

12

7.2

  CLI 合致についての見方 

12

7.3

  CLS 合致

14

8

  共通型システム 

16

8.1

  オブジェクト指向プログラムとの関係 

17

8.2

  値及び型 

18

8.3

  格納域

22

8.4

  型メンバ 

23

8.5

  名前付け 

24

8.6

  契約

30

8.7

  代入互換性 

34

8.8

  型安全及び正当性検証 

35

8.9

  型定義側 

36

8.10

  メンバの継承 

46

8.11

  メンバ定義 

49

9

  メタデータ 

52

9.1

  構成部品及びアセンブリ 

52

9.2

  メタデータへのアクセス 

53

9.3

  管理外コード 

53

9.4

  メソッド実装メタデータ 

54

9.5

  クラスの配置 

54

9.6

  アセンブリ,すなわち,型のための名前の有効範囲 

55


X 3016

:2010 (ISO/IEC 23271:2006)  目次

(2) 

ページ

9.7

  メタデータの拡張性

56

9.8

  大域的,移入及び移出 

57

9.9

  有効範囲付けされた静的な関数又はデータメンバ 

58

10

  共通言語仕様のための名前及び型の規則 

58

10.1

  識別子

58

10.2

  多重定義 

58

10.3

  演算子多重定義

59

10.4

  命名パターン 

62

10.5

  例外

63

10.6

  カスタム属性 

63

10.7

  総称型及び総称メソッド 

64

11

  共通言語仕様規則の集約 

69

12

  仮想実行システム

73

12.1

  提供されるデータ型 

73

12.2

  モジュール情報

83

12.3

  計算機状態 

83

12.4

  制御フロー 

88

12.5

  代理及び遠隔処理

105

12.6

  メモリモデル及び最適化 

105

第 章  メタデータ定義及び意味

109

1

  序論

109

2

  概要

109

3

  妥当性検証及び正当性検証 

109

4

  例 

110

4.1

  例 Hello World 

110

4.2

  例 

111

5

  一般的な構文 

111

5.1

  一般的な構文記法

111

5.2

  基本構文要素 

112

5.3

  識別子

113

5.4

  ラベル及びラベルの並び 

114

5.5

  16 進バイトの並び

114

5.6

  浮動小数点数 

115

5.7

  ソース行情報 

115

5.8

  ファイル名 

115

5.9

  属性及びメタデータ

115

5.10

  ilasm ソースファイル 

116

6

  アセンブリ,目録及びモジュール

116

6.1

  モジュール,アセンブリ及びファイルの概要

117


X 3016

:2010 (ISO/IEC 23271:2006)  目次

(3) 

ページ

6.2

  アセンブリの定義

117

6.3

  アセンブリの参照

121

6.4

  モジュールの宣言

123

6.5

  モジュールの参照

123

6.6

  モジュール又はアセンブリの内部の宣言 

123

6.7

  移出された型定義

124

7

  型及び識別情報 

124

7.1

  型 

124

7.2

  組込み型 

126

7.3

  利用者定義型(《型参照》)への参照 

126

7.4

  プラットフォーム固有なデータ型 

127

8

  可視性,アクセス可能性及び隠ぺい 

129

8.1

  最上位の型の可視性及び入れ子型のアクセス可能性 

129

8.2

  アクセス可能性

129

8.3

  隠ぺい

129

9

  総称性

130

9.1

  総称型定義 

131

9.2

  総称性及び再帰的継承グラフ

132

9.3

  総称メソッド定義

133

9.4

  総称型のインスタンス化 

133

9.5

  総称における変性

134

9.6

  インスタンス化された型の代入互換性 

136

9.7

  メンバ識別情報の妥当性 

136

9.8

  識別情報及び結合

138

9.9

  継承及び上書き

138

9.10

  明示的なメソッドの上書き

140

9.11

  総称仮引数に対する制約 

141

9.12

  総称型のメンバへの参照 

142

10

  型の定義 

142

10.1

  型ヘッダ(《クラスヘッダ》)

142

10.2

  型定義の本体 

150

10.3

  仮想メソッドの導入及び上書き

151

10.4

  メソッド実装要件

153

10.5

  特殊なメンバ 

153

10.6

  入れ子型 

157

10.7

  インスタンスの配置制御 

157

10.8

  大域フィールド及び大域メソッド 

159

11

  クラスの意味 

159

12

  インタフェースの意味 

160


X 3016

:2010 (ISO/IEC 23271:2006)  目次

(4) 

ページ

12.1

  インタフェースの実装 

160

12.2

  インタフェース上の仮想メソッドの実装

161

13

  値型の意味 

162

13.1

  値型の引用 

163

13.2

  値型の初期化 

163

13.3

  値型のメソッド

165

14

  特殊な型の意味

166

14.1

  ベクトル 

166

14.2

  配列

167

14.3

  enum 

169

14.4

  ポインタ型 

171

14.5

  メソッドポインタ

173

14.6

  委譲

174

15

  メソッドの定義,参照,及び呼出し 

179

15.1

  メソッド記述子

179

15.2

  静的メソッド,インスタンスメソッド及び仮想メソッド

180

15.3

  呼出し規約 

181

15.4

  メソッドの定義

182

15.5

  管理外メソッド

190

16

  フィールドの定義及び参照 

193

16.1

  フィールドの属性

193

16.2

  フィールド初期化メタデータ

195

16.3

  PE ファイル中の埋込みデータ

196

16.4

  非リテラル静的データの初期化

197

16.5

  ロード時に判明するデータ

198

17

  特性の定義 

199

18

  イベントの定義

200

19

  例外処理 

203

19.1

  限定公開ブロック

204

19.2

  ハンドラブロック

204

19.3

  catch ブロック

204

19.4

  フィルタブロック

205

19.5

  finally ブロック

205

19.6

  fault ハンドラ

206

20

  セキュリティ宣言

206

21

  カスタム属性 

207

21.1

  CLS 記法  カスタム属性使用例

208

21.2

  CLI で使われる属性 

208

22

  メタデータ論理形式  表 

211


X 3016

:2010 (ISO/IEC 23271:2006)  目次

(5) 

ページ

23

  メタデータ論理形式における他の構造体 

252

23.1

  ビットマスク及びフラグ 

252

23.2

  BLOB 及び識別情報 

258

23.3

  カスタム属性 

268

23.4

  組換え記述子 

270

24

  メタデータの物理的な配置 

272

24.1

  固定フィールド

272

24.2

  ファイルヘッダ

272

25

  PE へのファイル形式拡張 

277

25.1

  実行時ファイル形式の構造体

277

25.2

  PE ヘッダ 

278

25.3

  セクションヘッダ

280

25.4

  共通中間言語の物理的配置

284

第 章  CIL 命令集合

287

1

  有効範囲

287

1.1

  データ型 

287

1.2

  命令変異形の表

292

1.3

  スタック推移図

297

1.4

  日本語による命令の定義 

297

1.5

  演算対象の型の表

297

1.6

  暗黙の実引数強制型変換 

300

1.7

  CIL コード列の制限 

301

1.8

  正当性検証可能性及び適正性

303

1.9

  メタデータトークン

310

1.10

  送出される例外

310

2

  命令の接頭辞 

310

3

  基本命令

316

4

  オブジェクトモデル命令 

356

第 章  プロファイル及びライブラリ

378

1

  概要

378

2

  ライブラリ及びプロファイル

379

2.1

  ライブラリ 

379

2.2

  プロファイル 

380

2.3

  ライブラリとプロファイルとの関係 

380

3

  標準プロファイル

381

3.1

  カーネルプロファイル 

382

3.2

  小型プロファイル

382

4

  カーネルプロファイル機能要件

382

4.1

  カーネルプロファイルから除外される機能

382


X 3016

:2010 (ISO/IEC 23271:2006)  目次

(6) 

ページ

5

  標準ライブラリ 

384

5.1

  一般的なコメント

384

5.2

  実行時基盤ライブラリ 

384

5.3

  基底クラスライブラリ(BCL) 

384

5.4

  ネットワークライブラリ 

384

5.5

  自己反映ライブラリ

384

5.6

  XML ライブラリ 

385

5.7

  拡張数値ライブラリ

385

5.8

  拡張配列ライブラリ

385

5.9

  Vararg ライブラリ

385

5.10

  並列ライブラリ

385

6

  システムライブラリに対する実装固有の変更

386

7

  XML 仕様 

387

7.1

  意味規則 

387

7.2

  XML における識別情報の記法の問題点

396

第 章  デバッグ情報交換形式 

398

1

  可搬性 CILDB ファイル

398

1.1

  整数の符号化 

398

1.2

  CILDB ヘッダ 

398

1.3

  表及びヒープ 

399

1.4

  識別情報 

401

第 章  附属書 

402

附属書 A(参考)有効範囲

402

附属書 B(参考)見本プログラム 

403

附属書 C(参考)CIL アセンブラの実装 

417

附属書 D(参考)クラスライブラリの設計ガイドライン 

476

附属書 E(参考)可搬性に関する考察

477

附属書 F(参考)厳密でない違反 

479

附属書 G(参考)並列ライブラリ

484

索引 

487


X 3016

:2010 (ISO/IEC 23271:2006)

(7) 

まえがき

この規格は,工業標準化法第 14 条によって準用する第 12 条第 1 項の規定に基づき,一般社団法人情報

処理学会(IPSJ)及び財団法人日本規格協会(JSA)から,工業標準原案を具して日本工業規格を改正す

べきとの申出があり,日本工業標準調査会の審議を経て,経済産業大臣が改正した日本工業規格である。

これによって,JIS X 3016:2006 は改正され,この規格に置き換えられた。

この規格は,著作権法で保護対象となっている著作物である。

この規格の一部が,特許権,出願公開後の特許出願,実用新案権又は出願公開後の実用新案登録出願に

抵触する可能性があることに注意を喚起する。経済産業大臣及び日本工業標準調査会は,このような特許

権,出願公開後の特許出願,実用新案権及び出願公開後の実用新案登録出願にかかわる確認について,責

任はもたない。

X 3016

:2010 (ISO/IEC 23271:2006)


1

X 3016

:2010 (ISO/IEC 23271:2006)

   

日本工業規格

JIS

 X

3016

:2010

(ISO/IEC 23271

:2006

)

共通言語基盤(CLI)

CLI: Common Language Infrastructure

序文 

この規格は,2006 年に第 2 版として発行された ISO/IEC 23271 を基に,技術的内容及び構成を変更する

ことなく作成した日本工業規格である。

なお,この規格で点線の下線を施してある参考事項は,対応国際規格にはない事項である。

第 章  概念及びアーキテクチャ 

適用範囲 

この規格は,

異なるシステム環境で,

それらの環境の独特な性質を考慮に入れた書換えを行うことなく,

複数の高水準言語で書かれたアプリケーションを動作させることを可能とする共通言語基盤(CLI)を定

義する。

この規格は次の部分からなる。

第 章  概念及びアーキテクチャ  ―  ここでは,CLI のアーキテクチャの総覧をし,共通型システ

ム(CTS)

,仮想実行システム(VES)及び共通言語仕様(CLS)について規定する。さらに,メタデ

ータについての参考情報を示す。

第 章  メタデータ定義及び意味  ―  ここでは,メタデータについて規定する。その(ファイル形

式としての)物理的な配置,その論理的な内容(複数の表の集合及び表間の関係)並びにその(仮想

アセンブラとしての ilasm から見た)意味を規定する。

第 章  CIL 命令集合  ―  ここでは,共通中間言語(Common Intermediate Language,CIL)命令集

合について規定する。

第 章  プロファイル及びライブラリ  ―  ここでは,CLI ライブラリの概要を示し,これをプロフ

ァイル及びライブラリへ分割する仕様を規定する。ECMA 335 及び ISO 23271:2006 から入手可能な,

XML 書式で配布される CLILibrary.xml は CLI ライブラリの各クラス,値型及びインタフェースの詳細

を規定する。

第 章  デバッグ情報交換形式 

第 章  附属書  次を含む。

−  アセンブリ言語(ILAsm)で書かれた幾つかのサンプルプログラム。

−  アセンブラの特定の実装に関する情報。

− CIL 命令集合の機械可読記述。このアセンブラによって使用される文法の一部を派生するために使

用する。また,CIL を操作する他のツールも使用する。

第 章のライブラリの設計の中で使用されたガイドライン。

−  移植における考慮事項


2

X 3016

:2010 (ISO/IEC 23271:2006)

   

注記  この規格の対応国際規格及びその対応の程度を表す記号を,次に示す。

ISO/IEC 23271:2006

,Information technology−Common Language Infrastructure (CLI) Partitions I to

VI(IDT)

なお,対応の程度を表す記号“IDT”は,ISO/IEC Guide 21-1 に基づき,

“一致している”こ

とを示す。

適合性 

この規格への適合性を表明するシステムは,この規格の必す(須)要件をすべて実装しなければならな

いし,それが実装するプロファイル(

第 章参照)を指定しなければならない。最小実装はカーネルプロ

ファイルとする。さらに,規格適合処理系は,プロファイルだけに依存する書かれた現行のコードを妨げ

ないのであれば,補足機能を取り込むことができる。例えば,規格適合処理系は追加のクラス,既存のク

ラス上の新しいメソッド又は標準化されたクラス上の新しいインタフェースを提供できる。しかし,処理

系はこの規格の中で指定されたインタフェースへメソッド又は特性を加えてはならない。

共通中間言語(

第 章参照)を生成しこの規格への適合性を表明するコンパイラは,この規格の中で指

定された形式での出力ファイルを作成しなければならない。また,それが生成する CIL はこの規格の中で

指定されるような正しい CIL でなければならない。そのようなコンパイラは,更にそれが正当性検証可能

なコードを生成すると表明することができる。その場合には,コンパイラが生成する CIL は,この規格の

中で規定されるように正当性検証可能でなければならない。

引用規格 

次に掲げる規格は,この規格に引用されることによって,この規格の規定の一部を構成する。これらの

引用規格のうちで,西暦年を付記してあるものは,記載の年の版を適用し,その後の改正版(追補を含む。

は適用しない。西暦年の付記がない引用規格は,その最新版(追補を含む。

)を適用する。

注記  これらの参照の多くは,クラスライブラリの XML 記述の中で引用される。

JIS X 0304:1999

  国名コード

注記  対応国際規格:ISO 3166-1:1997,Codes for the representation of names of countries and their

subdivisions−Part 1: Country codes (IDT)

JIS X 0412-1:2004

  言語名コード−第 1 部:2 文字コード

注記  対応国際規格:ISO 639-1:2002,Codes for the representation of names of languages−Part 1:

Alpha-2 code (MOD)

JIS X 0412-2:2004

  言語名コード−第 2 部:3 文字コード

注記  対応国際規格:ISO 639-2:1998,Codes for the representation of names of languages−Part 2:

Alpha-3 code (MOD)

JIS X 3014:2003

  プログラム言語 C++

注記  対応国際規格:ISO/IEC 14882:2003,Programming languages−C++ (IDT)

JIS X 4159

  拡張可能なマーク付け言語(XML)1.0

注記  Extensible Markup Language (XML) 1.0 (Third Edition), 2004 February 4,

http://www.w3.org/TR/2004/REC-xml-20040204/が,この引用規格と対応している。

IEC 60559:1989

,Binary floating-point arithmetic for microprocessor systems(従前の番号は,IEC 559:1989。

この規格は,米国規格 ANSI/IEEE Standard 754-1985,IEEE Standard for Binary Floating-Point


3

X 3016

:2010 (ISO/IEC 23271:2006)

Arithmetic としてよく知られている。)

Federal Information Processing Standard (FIPS 180-1), Secure Hash Standard (SHA-1), 1995, April.

次の規格は,参考とする。

JIS X 0201

  7 ビット及び 8 ビットの情報交換用符号化文字集合

注記  対応国際規格:ISO/IEC 646:1991,Information technology−ISO 7-bit coded character set for

information interchange (MOD)

JIS X 0221

  国際符号化文字集合(UCS)

注記  対 応 国 際 規 格 : ISO/IEC 10646   Information technology − Universal Multiple-Octet Coded

Character Set(UCS)(IDT)

JIS X 3010:2003

  プログラム言語 C

注記  対応国際規格:ISO/IEC 9899:1999,Programming languages−C (IDT)

JIS X 3015:2008

  プログラム言語 C#

注記  対応国際規格:ISO/IEC 23270:2006,Information technology−Programming languages−C# (IDT)

JIS X 5718

  開放型システム間相互接続−遠隔手続呼出し

注記  対応国際規格:ISO/IEC 11578:1996,Information technology−Open Systems Interconnection−

Remote Procedure Call (RPC), Annex A: Universal Unique Identifier (IDT)

RFC-768, User Datagram Protocol. J. Postel. 1980, August.

RFC-791, Internet Protocol, Darpa Internet Program Protocol Specification. 1981, September.

RFC-792, Internet Control Message Protocol, Darpa Internet Program Protocol Specification. Network Working

Group. J. Postel. 1981, September.

RFC-793, Transmission Control Protocol, Darpa Internet Program Protocol Specification. J. Postel. 1981,

September.

RFC-919, Broadcasting Internet Datagrams. Network Working Group. J. Mogul. 1984, October.

RFC-922, Broadcasting Internet Datagrams in the presence of Subnets. Network Working Group. J. Mogul.

1984, October.

RFC-1035, Domain Names - Implementation and Specification. Network Working Group. P. Mockapetris. 1987,

November.

RFC-1036, Standard for Interchange of USENET Messages, Network Working Group. M. Horton and R.

Adams. 1987, December.

RFC-1112, Host Extensions for IP Multicasting. Network Working Group. S. Deering 1989, August.

RFC-1222, Advancing the NSFNET Routing Architecture. Network Working Group. H-W Braun, and Y.

Rekhter. 1991, May. ftp://ftp.isi.edu/in-notes/rfc1222.txt

RFC-1510, The Kerberos Network Authentication Service (V5). Network Working Group. J. Kohl and C.

Neuman. 1993, September.

RFC-1741, MIME Content Type for BinHex Encoded Files. Network Working Group. P. Faltstrom, D. Crocker,

and E. Fair. 1994, December.

RFC-1764, The PPP XNS IDP Control Protocol (XNSCP). Network Working Group. S. Senum. 1995, March.

RFC-1766, Tags for the Identification of Languages. Network Working Group. H. Alvestrand. 1995, March.

RFC-1792, TCP/IPX Connection Mib Specification. Network Working Group. T. Sung. 1995, April.

RFC-2236, Internet Group Management Protocol, Version 2. Network Working Group. W. Fenner. 1997,


4

X 3016

:2010 (ISO/IEC 23271:2006)

   

November.

RFC-2045, Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies.

Network Working Group. N. Freed. 1996, November.

RFC-2616, Hypertext Transfer Protocol−HTTP/1.1. Network Working Group. R. Fielding, J. Gettys, J. Mogul,

H. Frystyk, L. Masinter, P. Leach, and T. Berners-Lee. 1999 June. ftp://ftp.isi.edu/in-notes/rfc2616.txt

RFC-2617, HTTP Authentication: Basic and Digest Access Authentication. Network Working Group. J. Franks,

P. Hallam-Baker, J. Hostetler, S. Lawrence, P. Leach, A. Luotonen, and L. Stewart. 1999 June,

ftp://ftp.isi.edu/in-notes/rfc2617.txt

The Unicode Consortium. The Unicode Standard, Version 4.0, The Unicode Standard, Version 4.0 (Boston, MA,

Addison-Wesley, 2003. ISBN 0-321-18578-1)

形式 

4.1 

構成 

この規格の章立ては階層構造を用いて構成される。最上位には,章がある。次に,箇条及び細分箇条が

続く。

4.2 

参考情報 

この規格は,実装側,研究者及びアプリケーションプログラマによって使用されるように意図されてい

る。そのため,厳密にいえば,正式な規定としては不必要な説明も含む。

例は,記述された構築の具体的な形式を例示するために提供される。参照は関連する箇条を参照するた

めに使用される。注記は実装側又はプログラマに助言又は手引を与えるために提供される。附属書は追加

情報を提供する。

用語及び定義 

5.1 

ANSI

文字(ANSI character)

実装定義による 8 ビットの文字集合の文字であり,その最初の 128 個の符号位置は,JIS X 0221 に正確

に対応する文字。

5.2 

ANSI 

文字列(ANSI string)

ANSI 文字からなる文字列であり,最後の文字は,すべてのビットが 0 である値をもつ文字列。

5.3 

アセンブリ(assembly)

1 単位機能を実装するロード可能なコードモジュール及び他の資源によって構成された集合。

5.4 

属性(attributes)

記述的情報を含む型及び/又は型のメンバの特徴。

注記  最も典型的な属性は,あらかじめ定義されていて,それに関連付けられたメタデータの中に,

特定の符号化されたものとして含まれるが,利用者定義の属性をメタデータへ追加することも

できる。


5

X 3016

:2010 (ISO/IEC 23271:2006)

5.5 

実装固有の動作(behavior, implementation-specific)

それぞれの実装が行った選択を文書として明記する必要がある未規定の動作。

5.6 

未規定の動作(behavior, unspecified)

適格なプログラム構築要素及び正しいデータに対する動作であって,振る舞いが実装に依存する動作。

注記  その実装は,どんな動作が起こるかを文書として明記する必要はない。

5.7 

未定義の動作(behavior, undefined)

不正なプログラム構築要素又は不正なデータを使用したために起こり得る動作であり,この規格では要

件を定めない動作。

注記  未定義の動作は,この規格が明確な動作の定義を省略した場合にも起こり得る。

5.8 

ボックス化(boxing)

値型の値を,参照型である System.Object の新しく割り付けられたインスタンスへ変換すること。

5.9 

共通中間言語[Common Intermediate Language(CIL)]

VES によって理解される命令セット。

5.10 

共通言語基盤[Common Language Infrastructure(CLI)]

実行可能コードの形式及びそのコードを実行できる実行時環境のための規定。

5.11 

共通言語仕様[Common Language Specification(CLS)]

言語設計者とフレームワーク(クラスライブラリ)設計者との間の合意事項。

注記  CTS の部分集合及び使用規約を規定する。

5.12 

共通型システム[Common Type System(CTS)]

コンパイラ,ツール及び CLI 自体によって共有される単一の型システム。

注記  型を宣言し,使用し,管理する場合に,CLI が従う規則を定義するモデルとする。CTS は,プ

ログラム言語をまたぐ統合,型安全及び高い性能のコード実行を可能にするフレームワークを

確立する。

5.13 

委譲(delegate)

参照型であり,そのインスタンスは呼出し並びの中に一つ以上のメソッドをカプセル化することができ

るもの。

注記  委譲インスタンスと適切な引数の集合とが与えられた場合,その引数の集合を用いて,委譲の

呼出し並びの中のすべてのメソッドを呼び出すことができる。

5.14 

イベント(event)

オブジェクト又はクラスによる通知の提供を可能にするメンバ。


6

X 3016

:2010 (ISO/IEC 23271:2006)

   

5.15 

実行エンジン(Execution Engine)

仮想実行システムを参照。

5.16 

フィールド(field)

プログラムのデータを格納する,型付けされたメモリの位置を指し示すメンバ。

5.17 

ガーベジコレクション(garbage collection)

管理下データのためのメモリが,割り付けられ解放される処理。

5.18 

総称実引数(generic argument)

特定の総称型又は総称メソッドをインスタンス化するために使用される実際の型。

注記  例えば,List<string>  の場合の string は,総称型の定義 List<T>  の総称仮引数 T に対

応する総称実引数である。

5.19 

総称仮引数(generice parameter)

総称型又は総称メソッドの定義において,総称実引数のための場所取りとして動作する仮引数。

注記  例えば,総称型の定義 List<T> における T は,総称仮引数である。

5.20 

総称性(generics)

一つ以上の総称仮引数による引数化された型及びメソッドの定義を可能にする機能。

5.21 

ライブラリ(library)

型の集合を一つ以上のアセンブリに区分けして貯蔵したもの。

注記  ライブラリは,他のライブラリで定義した型に関する更新を含むこともできる。例えば,ライ

ブラリは,他のライブラリに定義された型に関する,追加のメソッドやインタフェース,例外

を含むことができる。

5.22 

管理下コード(managed code)

CLI  が主要なサービスの集合を提供することを可能にする十分な情報を含むコード。

注記  例えば,コードの中のメソッドを指し示すアドレスが与えられると,メソッドを説明するメタ

データを CLI は特定できなければならない。また,CLI は,スタックをたどり,例外に対処し,

セキュリティ情報を取り出すことができなければならない。

5.23 

管理下データ(managed data)

管理下データは,ガーベジコレクションと呼ばれる処理を通じて,CLI によって自動で割り付けられ解

放されるデータ。

5.24 

目録(manifest)

あるアセンブリの一部であって,そのアセンブリに関する次の情報を指定するもの。


7

X 3016

:2010 (ISO/IEC 23271:2006)

−  その版,名前,文化圏,及びセキュリティの要件

−  もしあれば,そのアセンブリに属する別のファイル,及びそれぞれのファイルの暗号化ハッシュ

−  アセンブリの中の他のファイルに定義された型で,そのアセンブリから移出されるもの

−  省略可能なものとして,

目録自身のデジタル署名,

及びそれを計算するために使用される公開かぎ

(鍵)

5.25 

メンバ(member)

型のフィールド,配列要素,メソッド,特性,及びイベントのいずれか。

5.26 

メタデータ(metadata)

CTS(共通型システム)によって定義された型について記述参照するデータ。

注記  メタデータは,特定のプログラム言語に依存しない方法で格納され,“永続化”される。したが

って,メタデータは,ツールと仮想実行システムとの間だけでなくプログラムを操作するツー

ル(コンパイラ,デバッガなど)の間においても,共通の交換機構を提供する。

5.27 

メソッド(method)

正確な型の値に基づいて行うことができる操作を記述するメンバ。

5.28 

総称メソッド(method, generic)

型の中で定義され,型自身には現れない一つ以上の型仮引数をその識別情報にもつメソッド(静的メソ

ッド,インスタンスメソッド,又は仮想メソッドであってもかまわない。

注記  取り囲む型は,総称又は総称でない場合がある。例えば,総称型 List<T>の中で,総称メソッ

ド ConbertTo<S>()は総称である。

5.29 

総称でないメソッド(method, non-generice)

総称メソッドではないメソッド。

5.30 

モジュール(module)

VES によって実行される単一ファイル。

5.31 

オブジェクト(object)

参照型のインスタンス。

注記  オブジェクトは,値よりも多くをもつ。オブジェクトは,それ自体,型付けされている。すな

わち,その型は,明示的にその表現の中に含まれている。オブジェクトは,それを他のすべて

のオブジェクトと識別する同一性(識別性)をもち,

(オブジェクト又は値のいずれかであって

よい)他の実体を格納するスロットをもつ。そのスロットの内容は変化してもよいが,オブジ

ェクトの同一性は決して変化しない。

5.32 

プロファイル(profile)

一定の水準の機能を提供する統一体となるようにひとまとめにされた,ライブラリの集合。


8

X 3016

:2010 (ISO/IEC 23271:2006)

   

5.33 

特性(property)

名前付きの値と,その値にアクセスする複数のメソッドとを定義したメンバ。

注記  特性は,その値にアクセスする契約を定義する。よって,特性の定義は,存在するアクセスメ

ソッド及びそれぞれのメソッドの契約を指定する。

5.34 

識別情報(signature)

検査可能であって自動的に強制実行可能な契約の一部。

注記  識別情報は,型及び他の識別情報に制約を加えて作られる。この制約は,値又は格納域の,使

用方法に関する制限又は許される操作に関する制限とする。

5.35 

総称型(type, generic)

一つ以上の他の型によって,その定義が引数化された型。例えば,T が総称仮引数である List<T>。

注記  CLI は,総称型のインスタンスの生成と使用を提供する。例えば,List<int32>又は List<string>。

5.36 

参照型(type, reference)

そのインスタンスがデータの参照を含む型。

5.37 

値型(type, value)

そのインスタンスがそのデータ全体を直接的に含む型。

5.38 

ボックス化解除(unboxing)

実行時型が値型である System.Object 型の値を値型インスタンスに変換する操作。

5.39 

管理外コード(unmanaged code)

管理下にないコード。

5.40 

管理外データ(unmanaged data)

管理下にないデータ。

5.41 

値(value)

整数又は浮動小数点数のような簡単なビットパターン。

注記  各値は,それが占める領域を記述するための型及びそのビット表現での意味をもち,また,そ

の表現において行うことができる操作ももつ。値は,各プログラム言語での単純な値及びオブ

ジェクトでないデータを表すことを意図している。

5.42 

正当性検証(verification)

CIL コード列がプログラムの論理アドレス空間の外側のメモリへのアクセスを与えないことを保証する

ための,CIL 及びその関連メタデータの両方に対する検査。

注記  妥当性検証とともに,正当性検証は,プログラムがアクセスを許可されていないメモリ及びそ


9

X 3016

:2010 (ISO/IEC 23271:2006)

の他のリソースにアクセスできないことを保証する。

5.43 

仮想実行システム[Virtual Execution System(VES)]

CTS のモデルを実装し,実行するシステム。

注記 VES は,CLI 向けに書かれたプログラムを読み込み,実行する責任をもつ。VES は,個別に作

成されたモジュールを実行時に一つにつなぐためのメタデータを用いて,管理下コード及び管

理下データを実行する上で必要なサービスを提供する。VES  は,実行エンジンとしても知られ

ている。

共通言語基盤の概要 

共通言語基盤(CLI)は,実行可能なコード,及びそれが動作する実行環境(仮想実行システム)につ

いて規定する。実行可能なコードはモジュールとして VES に入力される。モジュールは,単一のファイル

で,実行可能な内容物を第 2 章で規定される形式で含む。

注記  この箇条(6.2.3 まで)は参考情報であり規定ではない。

共通言語基盤(CLI)の中心に,共通型システム(CTS)という名の統合型システムがあり,それはコン

パイラ,ツール及び CLI 自体が共有する。それは,型を宣言し,使用し,管理する場合,CLI が従う規則

を定義するモデルとする。CTS は,言語間統合,型安全及び高性能コード実行を可能にするフレームワー

クを確立する。この箇条は,CTS についての記述によって CLI のアーキテクチャについて記述する。

この箇条では,次の四つの領域について説明する。

共通型システム(CTS)  共通型システム(CTS)は,多くのプログラム言語に存在する型及び操作を

実現する豊富な型システムを提供する。共通型システムは,広範囲のプログラム言語の完全な実装を

実現するように意図されている。箇条 参照。

メタデータ  CLI は,共通型システムによって定義された型について記述し引用する目的でメタデー

タを使用する。メタデータは,任意の特定のプログラム言語に依存しない方法で格納される(

“永続化

される”

。したがって,メタデータは,これらのツールと仮想実行システムとの間の共通の交換機構

であるのと同様に,プログラムを操作するツール(コンパイラ,デバッガなど)間の使用に共通の交

換機構を供給する。箇条 を参照する。

共通言語仕様(CLS)  共通言語仕様は言語設計者及びフレームワーク(クラスライブラリ)設計者の

間の協定である。それは,CTS 型システムの部分集合及び利用規約を規定する。CLS の一部分である

CTS の部分さえ実装すれば,言語は,利用者に対してフレームワークへのアクセスに関する最大の能

力を提供する。同様に,フレームワークは,その公開される側面(クラス,インタフェース,メソッ

ド,フィールドなど)が CLS の一部である型だけを使用し,かつ,CLS 規定を遵守している場合に,

最も使われやすくなる。箇条 10 を参照する。

仮想実行システム(VES)  仮想実行システム(VES)は CTS モデルを実装し強制する。VES は,CLI

のために書かれたプログラムのロード及び実行を行う。それは,管理下コード及び管理下データを実

行するために必要とされるサービスを提供する。別々に生成されたモジュールを,実行時にともに結

合させる(遅延結合)ためにメタデータを使用する。箇条 12 を参照する。

CLI のこれらの側面は,分散コンポーネント及びアプリケーションを設計し,開発し,配置し,実行す

るための統一フレームワークを形作る。共通型システムの適切な部分集合は CLI を対象とする各プログラ

ム言語から使用可能である。アプリケーションを構築するために使用される型を定義し参照するメタデー


10

X 3016

:2010 (ISO/IEC 23271:2006)

   

タを使用することによって,言語を基礎としたツールは互いに連携し,また,仮想実行システムと連携す

る。仮想実行システムは,必要に応じて型のインスタンスを生成し,かつ,基盤(遠隔処理サービス,ア

センブリのダウンロード,セキュリティなど)の他の一部にデータ型情報を供給するためにメタデータを

使用する。

6.1 

型安全との関係 

型安全は,通常,何を行うかという観点又は何を行わせないかという観点から論じられる。前者の例と

しては,異なるオブジェクト間のカプセル化の保証がある。後者の例としては,書かれるべきでないとこ

ろに書かれたことによるメモリの破壊の防止がある。しかし,共通型システムの観点から,型安全は次を

保証する。

−  参照は,宣言とおりのものとする。すべての参照は型づけされ,参照されたオブジェクト又は値も型

をもつ。そして,それらは代入互換とする(8.7 参照)

−  識別性はごまかせない。オブジェクトを改ざん(竄)したりだましたりする方法はなく,したがって,

利用者又はセキュリティ領域を改ざん(竄)したりだましたりする方法はない。オブジェクトへのア

クセスは,アクセス可能な関数及びフィールドを通じて行われる。オブジェクトは,セキュリティが

危険にさらされるような方法で設計され得る。しかし,クラスのすべての利用の大域分析を行わなく

ても,クラス,そのメソッド及びそのクラスが使用するものの局所分析を行うだけで,ぜい弱性を十

分に調査評価できる。

−  適切な操作だけを呼び出すことが可能とする。参照型はアクセス可能な関数及びフィールドを定義す

る。これは参照がどこにあるかに基づいた可視性を限定することを含んでいる。例えば下位クラスに

おいてだけ可視の限定公開のフィールドが挙げられる。

共通型システムは型安全を促進する。例えば,あらゆるものが型づけされている。型安全は強制しても

よい。実装が型安全宣言に適合するかどうかを決めるのは難しい問題である。宣言は,プログラムのコン

パイルされた形式を備えたメタデータとして利用されるから,共通中間言語(CIL)からプラットフォー

ムコード(8.8 参照)に変換するコンパイラは,実装を型検査することが可能である。

6.2 

管理下メタデータ駆動実行との関係 

メタデータは,コードが定義する型と,コードが外部的に参照する型とを記述することによってコード

を記述する。コードが作成される場合,コンパイラはメタデータを生成する。次のために,十分な情報が

メタデータに格納される。

コード実行の管理  単にロード,実行するだけでなく,メモリ管理及び実行状態検査を行う。

コードの管理  インストール,解決及び他のサービスを管理する。

コード内の型の参照  他の言語及びツールへのインポート,並びに,スクリプティング及び自動化の

実現。

共通型システムは,実行環境がメタデータで駆動されることを前提としている。メタデータの使用は,

CLI が次を実現することを可能にする。

多重実行モデル  メタデータによって更に実行環境は,逐次解釈コード,JIT(Just In Time)実行コー

ド,

プラットフォーム固有コード及びレガシーコードの混合を取り扱うことが可能になり,デバッガ,

プロファイラなどのツールに対して,一様なサービス,すなわち,一貫性例外処理,スタック巻戻し

(unwinding)

,信頼性のあるコードアクセスセキュリティ,及び効率的なメモリ管理,を提供するこ

とが可能になる。

サービスの自動実現  メタデータが実行時に使用可能であるから,実行環境及び基底ライブラリは,


11

X 3016

:2010 (ISO/IEC 23271:2006)

プログラマ側の努力をほとんど必要とせずに,自動的に,自己反映,自動化,シリアル化,遠隔オブ

ジェクト,及び既存の管理外プラットフォーム固有コードとの相互運用性の実現を可能とする。

より良い最適化  物理的なオフセット,配置及び大きさの代わりにメタデータ参照を使用することに

よって,CLI がメンバ及び割当表の物理的な配置を最適化することを可能にする。さらに,これは,

特定の CPU 又は環境に合わせた生成コードの最適化が行われることを可能にする。

結合のぜい弱性の軽減  メタデータ参照を使用することによって,コンパイル時オブジェクト配置を

実行時オブジェクト配置に置き換え,また,ロード時の名前による結合に置き換えることによって,

版から版に移る場合のぜい弱性を軽減する。

柔軟性のある配備解決  型の参照及び型の定義の両方用のメタデータをもつことができるから,より

信頼性が高く,かつ,より柔軟性のある,配備機構及び解決機構が可能となる。解決とは,適正な場

所の集合を調べることによって,使えるための要件を,ある文脈中で最適に満たす実装を見つけるこ

とができることをいう。この解決の意味の中に含まれる五つの要素は,次のようにして得られる。ま

ず,メタデータによって二つの要素,すなわち,要件及び文脈,が使用可能になる。アプリケーショ

ンのパッケージ及び配備から,その他の三つの要素,すなわち,調査すべき適正な場所,実装を見つ

ける方法及び実装の最適性を決定する方法,が定まる。

6.2.1 

管理下コード 

管理下コードは,CLI が取り込んで,次を含むコアサービスの一集合を提供することを可能にするため

に十分な情報を提供するコードとする。

−  メソッドのためのコードの内部のアドレスを与えられて,メソッドについて記述するメタデータを見

つける。

−  スタックをたどる。

−  例外を扱う。

−  セキュリティ情報を格納し取り出す。

この規格は,管理下コードの特定の命令集合,共通の中間言語(

第 章 CIL 参照)及び管理下コードの

格納及び送信のためのファイル形式(

第 章参照)を規定する。

6.2.2 

管理下データ 

管理下データはガーベジコレクションと呼ばれる処理を通じて,CLI によって自動で割り付けられ解放

されるデータとする。

6.2.3 

概要 

共通型システムは言語間の統合に関係している。すなわち,別の言語のオブジェクトをあたかも自らの

言語のもののように使用できるようにしている。

CLI の目的は,任意の言語を使って,ソフトウェア部品及びアプリケーションを作成することをより容

易にすることである。CLI は,型の標準集合を定義し,すべてのソフトウェア部品をすべて自己記述とし,

高性能の共通の実行環境を提供することによって,その目的を達成する。これは,すべての CLI 合致のシ

ステムサービス及びソフトウェア部品が,すべての CLI 実現言語及びツールからアクセス可能になること

を保証する。さらに,これは,それらを使用するソフトウェア部品及びアプリケーションの配備を単純化

し,並びにコンパイラと他のツールとによって高機能実行環境に強化する方法を単純化する。共通型シス

テムは,すべての可能性を生み出す概念及び相互作用を高水準に包含する。

その記述は,四つの領域に及ぶ。

型システム  型の状態及びそれらを定義する方法。


12

X 3016

:2010 (ISO/IEC 23271:2006)

   

メタデータ  型はどのように記述されるか,また,それらの記述がどのように格納されるか。

共通言語仕様  言語相互運用性に必要な制限。

仮想実行システム  コードはどのように実行され,型はどのようにインスタンス化し,相互作用し,

消去されるか。

共通言語仕様 

7.1 

導入 

共通言語仕様(CLS)は,言語相互運用性を推進することを意図した規則の一集合とする。CLS に適合

するためにはこれらの規則に従わなければならない。それらは,後続の箇条によって詳細に記述され,箇

条 11 で要約される。CLS 合致性は,CLI の実装上で実行するために生成される型の特徴とする。そのよう

な型は CLS 規則に加えて CLI 規格に適合しなければならない。これらの追加の規則は,型が定義されてい

るアセンブリの外部に対して可視性がある型にだけ適用する,また,アセンブリの外部からアクセス可能

なメンバ,すなわち,可視性が“公開”のメンバ,

“ファミリ”の(しかし封印型でない)メンバ又は“フ

ァミリ又はアセンブリ”の(しかし封印型でない)メンバに適用する。

注記 CLS 合致のコードからなるライブラリはここに“フレームワーク”と呼ばれる。CLI のための

コードを生成するコンパイラには,そのようなライブラリを利用できるが,作成又は拡張でき

ないように設計できる。そのようなコンパイラは“使用側”と呼ばれる。フレームワークを作

成し,かつ,拡張することを目指しているコンパイラは“拡張側”と呼ばれる。各 CLS 規則の

記述では,付加的な参考情報は,規則のこれらの各々の状況に対する含意を読者が理解するの

を支援するために提供される。

7.2 CLI

合致についての見方 

注記  7.27.2.1 及び 7.2.2 は参考情報であり規定ではない。

CLS は生成されたアセンブリに適用される規則の一集合とする。CLS はライブラリとそれらを記述する

高水準プログラム言語との相互運用性を実現するために設計されているから,アセンブリの生成の過程内

で使用される,高水準のソースコード及びツールの観点から CLS 規則について考えることは多くの場合有

用である。この理由から,ツール及び利用者の幾つかの異なるクラスについてのルールの暗黙的な側面を

読者が理解するのを支援するため,参考となる注記を CLS 規則の記述に加える。記述の中で使用される異

なる観点は,フレームワーク,使用側及び拡張側と呼ばれ,ここで説明される。

7.2.1 CLS

フレームワーク 

CLS 合致のコードからなるライブラリはこの規格では“フレームワーク”と呼ばれる。フレームワーク

(ライブラリ)は,CLS 使用側言語及び拡張側言語の両方を取り込む広範囲のプログラム言語及びツール

によって使用される目的で設計される。CLS の規則を厳守することによって,ライブラリ作成者は,ライ

ブラリが,それらが CLS 規則を厳守しないことに決めた場合より,大きなツールクラスによって使用可能

になることを保証する。次は CLS 合致のフレームワークが従うのが望ましい幾つかの追加の手引とする。

−  プログラム言語の中でキーワードとして一般に使用される名前の使用を回避するのが望ましい。

−  フレームワークの利用者が入れ子にした型を表現することが可能であるとは仮定しないほうが望まし

い。

−  異なるインタフェース上の同じ名前及び識別情報のメソッドの実装が独立していると仮定するのが望

ましい。

−  初期化子値に基づいて自動的に実行される値型の初期化に依存しないほうが望ましい。


13

X 3016

:2010 (ISO/IEC 23271:2006)

−  利用者は総称型をインスタンス化し,使用できると想定してもよいが,新しい総称型や総称メソッド

を定義することを要求しないのが望ましく,また,部分的な構築総称型を扱うことを要求しないほう

が望ましい。

フレームワークは,次のことをするのが望ましくない。

−  すなわち,新しい総称型及び総称メソッド,既存の総称メソッドの上書き,又は,いかなる方法での

部分的な構築総称性を利用者に要求しないほうが望ましい。

この話題に関する CLS の規則は,7.2 の CLS 規則 48 を参照する。

7.2.2 CLS

使用側 

CLS 使用側とは,CLS 合致のフレームワーク(ライブラリ)によって供給された機能のすべてへのアク

セスを許可するが,

必ずしも,

それらを作成できる必要性はないように設計された言語又はツールとする。

次は CLS 使用側ツールが行うことが可能であると予想されるものの一部である。

−  任意の CLS 合致のメソッド又は委譲を呼び出すことを実現する。

−  プログラム言語でキーワードとして扱われる名前のメソッドを呼び出す機構をもっている。

−  一つの型の中で,同じ名前及び識別情報をもつが,複数の異なるインタフェースに実装されたメソッ

ドを,区別して呼び出すことを実現する。

−  任意の CLS 合致の型のインスタンスを生成する。

−  任意の CLS 合致のフィールドを読み込み及び変更する。

−  入れ子にした型にアクセスする

−  任意の CLS 合致の特性をアクセスする。これは,特性の取得子(getter)メソッドと設定子(setter)

メソッドとを呼び出す能力以外に,特殊な実現を要求しない。

−  任意の CLS 合致のイベントをアクセスする。これは,イベントのために定義されたメソッドを呼び出

す能力以外に,特殊な実現を要求しない。

−  総称型及び総称メソッドを移入,インスタンス化,及び使用する。

注記  次は,CLS 使用側が提供することを考慮することが望ましい。

言語で定義された規則に基づいて,総称メソッドを一致させるための型推論

あいまい(曖昧)なキャストを共通の上位型へキャストする構文

次は,CLS 使用側ツールの機能として不必要とする。

−  新しい型又はインタフェースの生成。

−  静的リテラルフィールド以外のフィールド及び仮引数での初期化メタデータ

第 章参照)。使用側は,

初期化メタデータを使用することを選択できるが,しかし静的リテラルフィールド以外の何かについ

てのメタデータを無視しても問題ない。

7.2.3 CLS

拡張側 

注記  ここから“参考情報終わり”という文を含む注記までは,参考情報であり規定ではない。

CLS 拡張側はフレームワークを使用及び拡張することをプログラマができるように設計された言語又は

ツールとする。CLS 拡張側は,CLS 使用側が提供する振る舞いの上位集合を提供する。すなわち,CLS 使

用側に適用するものはすべて,CLS 拡張側にも適用される。使用側の要件に加えて,拡張側は次のものが

可能であることが期待される。

−  すべての(封印されなかった)CLS 合致の基底クラスを拡張する CLS 合致の新しい型を定義する。

−  言語でキーワードである名前をもった型を定義する目的のある機構をもっている。

−  型に保持されたすべてのインタフェースのすべてのメソッドに独立した実装を供給する。すなわち,


14

X 3016

:2010 (ISO/IEC 23271:2006)

   

拡張側が同じ名前及び識別情報のすべてのインタフェースメソッドを単一のコード本体に実装するこ

とだけでは十分ではない。

−  任意の CLS 合致のインタフェースを実装する。

−  メタデータのすべての適切な要素に任意の CLS 合致のカスタム属性を設定する。

−  いずれかの(封印されなかった)CLS 合致の基底型を拡張して,新しい(総称でないもの)CLS 合致

の型を定義する。有効な基底型には,通常の(総称でない)型及び完全構築総称型も含まれる。

注記  次は,CLS 拡張側が提供することを考慮することが望ましい。

言語で定義された規則に基づいて,総称メソッドを一致させるための型推論

曖昧なキャストを共通の上位型へキャストする構文

拡張側は次を提供する必要はない。

− CLS 合致のインタフェースを新しく定義する。

−  入れ子にした型を定義する。

−  総称型及び総称メソッドを定義する。

−  既存の仮想総称メソッドを上書きする。

共通言語仕様は,適正に,表現力が豊かであるほどに十分に大きく,すべての言語が合理的にそれを提

供することが可能であるように十分に小さく設計される。

注記  参考情報終わり

CLS

規則 48  一つの型の中で宣言された二つ以上の CLS 合致のメソッドが同じ名前をもち,かつ,あ

る特定の型のインスタンス化集合に対して,同じ仮引数及び返却値型をもつ場合,これらすべてのメソッ

ドは,それらの型のインスタンス化において意味的に同じでなければならない。

注記   

CLS

(使用側)  メソッドのいずれかを選ぶことができる。

CLS

(拡張側)  使用者側と同じ。

CLS

(フレームワーク)  この規則に違反するメソッドを公開してはならない。

注記  混乱を避けるため,この標準の版における規則の削除や追加にかかわらず,CLS 規則は前の版

からの時系列的な番号に従う。そして,この章に示す最初の規則は,48 である。

7.3 CLS

合致 

CLS 合致に関する規則の詳細な説明は,共通の形式でなされる。例えば,次の最初の規則を参照された

い。最初の段落は規則それ自体を規定する。その後,上に記述されるような三つの異なる観点からの規則

の含意についての規定ではない記述が続く。

CLS は言語相互運用性規則を定義する。それは“外部的に可視の”項目にだけ適用する。その言語相互

運用性の CLS 単位はアセンブリである,すなわち,単一のアセンブリ内では,使用されるプログラム技法

に関して制限はない。すなわち,CLS 規則が適用される項目は,その項目を定義するアセンブリの外部か

らの可視性(8.5.3 参照)をもつ項目であり,

“公開”

“ファミリ”又は“ファミリ又はアセンブリ”のア

クセス可能性(8.5.3.2 参照)をもつ項目に限られる。

CLS

規則 1  CLS 規則は,定義の行われるアセンブリの外部からアクセス可能又は可視である型の部分

に適用される。


15

X 3016

:2010 (ISO/IEC 23271:2006)

注記   

CLS

(使用側)  影響はない。

CLS

(拡張側)  コンパイル時に CLS 合致を確認する場合,必ずアセンブリの外部に移出さ

れる情報にだけ規則を適用する。

CLS

(フレームワーク) CLS 規則はアセンブリ内の内部実装に適用されない。型が CLS  合

致であるのは,すべての公開アクセス可能部分(別のアセンブリで実行するコードで使用可能

であるクラス,インタフェース,メソッド,フィールド,特性及びイベント)が次の条件の少

なくとも一つを満たす場合だけになる。

各部分は,CLS 合致の型からだけで構成される識別情報をもっている。

各部分は,CLS 合致でないものとして特に印付けされている。 

素早くコードを検証することが不可能なすべての構築要素は CLS から除外される。これによって,CLS

合致のすべての言語翻訳プログラムに対して,正当性検証可能なコードの作成を可能にする。

7.3.1 CLS

合致のものとして印付ける項目 

CLS は,アセンブリの外部的に可視の一部に対して,それらが CLS 要件に応じるかどうかを印付けする

方法を指定する(実装者が,CLS 合致としてこの規格の印付けを拡張することは,奨められない。

。これ

はカスタム属性機構

9.7 及び

第 章参照)を用いて行われる。クラス System.CLSCompliantattribute

第 章参照)は,どの型及びどの型のメンバが CLS  合致であるかを示す。さらに,それはアセンブリ

が含んでいるすべての最上位の型に対する省略時の合致水準を指定するためにアセンブリに付けることが

可能である。

System.CLSCompliantattribute

に対する構築子は,関係している項目が CLS  合致かどうか示す

真理値の実引数をとる。これは,任意の項目(アセンブリ,型又は型メンバ)が CLS  合致のものとして

明示的に印付けされることを可能にする。

CLS 合致を決定するための規則は次のとおりとする。

−  ア セ ン ブ リ が 明 示 的 な System.CLSCompliantattribute を も た な い 場 合 , そ れ は

System.CLSCompliantattribute(false)

をもつと仮定されなければならない。

−  既定では,型は,それを囲む型(入れ子にした型のための)の CLS 合致の属性を継承するか,又はそ

のアセンブリ(最上位の型のための)に付けられた値を得る。System.CLSCompliantattribute

属性の添付によって CLS 合致のもの,又は,CLS 合致でないもののいずれかとして,それが印付けで

きる。

−  既定では,他のメンバ(メソッド,フィールド,特性及びイベント)は,CLS 合致のそれらの型を継

承する。属性 System.CLSCompliantattribute(false)の添付によって CLS 合致でないものと

して,それらが印付けされることができる。

CLS

規則 2  CLS 合致でない型のメンバは CLS 合致に印付けされてはならない。

注記   

CLS

(使用側)  上の規則を用いて CLS 合致でないあらゆるメンバを無視してもよい。

CLS

(拡張側)  新たに作成されたアセンブリ,並びに公開された型及び公開されたメンバの

正確な印付けを促進するのが望ましい。CLS 規則のコンパイル時適用は強く推奨される。

CLS

(フレームワーク)  正確にそれらの CLS 合致に関して,公開であるメンバにすべて印


16

X 3016

:2010 (ISO/IEC 23271:2006)

   

付けなければならない。ここで指定された規則は要求される標示子の個数をできるだけ少なく

する目的で使用することができる(例えば,型及びメンバがすべて合致である場合に又は印付

けされる必要のあるほんの少数の例外がある場合に,全アセンブリを印付けることができる。

共通型システム 

型は,値を記述し,その型のすべての値が提供しなければならない契約(8.6参照)を規定する。共通型

システム(Common Type System,以下 CTS ともいう。

)は,関数型プログラム言語及び手続型プログラム

言語だけでなくオブジェクト指向プログラム(OOP)にも提供されるから,2 種類の実体,オブジェクト

(Object)及び値(Value)を扱う。値は,整数,浮動小数点数などのための単純なビットパターンとする。

それぞれの値は型をもつ。

型は,

その値が占有する記憶域及びその表現におけるビットの意味を記述する。

値は,その表現において実行可能な演算ももつ。値は,C のようなプログラム言語での対応する単純な型

を表現することを意図しているが,C++及び Java

1)

といったプログラム言語の非オブジェクトを表現する

ことも意図している。

1)

 Java は,Sun Microsystems の商標及び登録商標である。この情報は,この規格の利用者の便宜

を図って記載するもので,この製品を推奨するものではない。

オブジェクトは,値がもつ以上のことをもつ。各オブジェクトは,それ自体,型付けされている。すな

わち,その型は,明示的にその表現の中に含まれている。オブジェクトは,それを他のすべてのオブジェ

クトと区別する同一性(識別性)をもち,

(オブジェクト又は値のいずれかが可能な)他の実体を格納する

スロットをもつ。そのスロットの内容は変化可能だが,オブジェクトの同一性は決して変化しない。

(参考である)

図 に示すとおり,オブジェクト及び値には,幾つかの種類がある。

総称性という機能によって,型及びメソッドの一族全体をパターンを用いて定義できる。このパターン

には,総称仮引数という場所取りの仮引数が含まれる。これらの総称仮引数は,実際に要求されるその一

族のメンバをインスタンス化するために,必要に応じて,指定された型によって置き換えられる。総称性

の設計は,次の目的を満たす。

−  直交性。可能な場合,既存の CLI の型が出現可能なあらゆる文脈で,総称型は出現できる。

−  言語の独立性。元となる言語についていかなる仮定も行わない。しかし,CLI 総称性は,可能な限り

多くの言語の既存の総称性らしい機能を提供しようとする。さらに,CLI 総称性の設計は,現在総称

性をもたない言語の新たな拡張を許す。

−  実装の独立性。CLI の実装は,その場その場に応じて表現及びコードを特殊化するか,又はすべての

表現及びコードを共有できる。これを達成するために,おそらく,値のボックス化及びボックス化解

除を行うことがある。

−  実装の効率性。総称性の実行効率は,総称性を模擬する Object を使うよりも悪いことはない。よい

実装は,参照型のインスタンス化についてキャストを避け,値型のインスタンス化について特殊化し

たコードを生成するから,ずっと効率的にできる。

−  定義における静的検査可能性。総称型定義は,そのインスタンス化とは独立に,妥当性検証及び正当

性検証を行うことができる。そこで,総称型は,静的に正当性検証可能であって,そのメソッドは,

すべての妥当なインスタンス化に対して JIT コンパイルを保証できる。

−  総称仮引数に関する一様な振る舞い。一般に,仮引数化された型及び総称メソッドの振る舞いは,す

べての型のインスタンス化において“同じ”となる。

加えて,CLI は,次の特徴をもつ,共変及び反変な総称仮引数を提供する。


17

X 3016

:2010 (ISO/IEC 23271:2006)

−  (純粋に静的な検査に基づいた)型安全。

−  単純性。特に,

(共変及び反変の)可変性は,

(クラス又は値型でない)総称インタフェース及び総称

委譲にだけ許可される。

−  可変性を提供したくない言語は,その機能を無視し,すべての総称型を可変ではないとして取り扱う

ことができる。

− Eiffel などの言語で使用されるより複雑な共変性方式の実装を可能にする。

図 に型システムを示す。

注記  図 は,参考とする。

注記  管理下ポインタは,ヒープ領域を指し示すかもしれない。

図 1−型システム 

8.1 

オブジェクト指向プログラムとの関係 

注記  この細分箇条は参考情報であり規定ではない。

型は,値指向プログラムの世界で,データ表現を意味するためによく使用される。オブジェクト指向の

世界では,表現よりむしろ振る舞いを参照するために使用する。CTS では,型は,これら両方を意味する

ために使用する。二つの実体は,それらが互換性のある表現及び互換性のある振る舞いをもつ場合かつそ

の場合に限り,互換性のある型をもつ。このように,CTS では,一つの型が基底型から派生する場合,そ

の派生型のインスタンスは,その表現及び振る舞いの両方とも(基底型のインスタンスと)互換性がある

から,基底型のインスタンスに対して置き換えることができる。

幾つかのオブジェクト指向プログラム言語(以下,OOP 言語ともいう。

)とは異なり,CTS では,基本

的に異なる表現をもつ二つのオブジェクトは,異なる型をもつ。OOP 言語の中には,異なる型の概念を使

用するものがある。それらは,二つのオブジェクトがメッセージの同じ集合に対して同じ方法で応答する


18

X 3016

:2010 (ISO/IEC 23271:2006)

   

場合に同じ型をもつと考える。CTS では,この概念は,オブジェクトが同じインタフェースをもつとして

取り込まれている。

同様に,

(例えば Smalltalk といった)幾つかの OOP 言語は,メッセージの受渡しを計算の基本モデルと

考える。CTS では,これは,仮想メソッド呼出し(8.4.4 参照)に対応する。この場合,仮想メソッドの識

別情報がメッセージの役割をする。

CTS それ自体は,“型のないプログラム”の概念を直接には取り込んでいない。すなわち,オブジェク

トの型を知ることなしに非静的メソッドを呼び出す方法はない。それにもかかわらず,自己反映パッケー

ジ(

第 章参照)が実装されている場合には,それが提供する能力に基づいて,型のないプログラムを実

装できる。

8.2 

値及び型 

型は,値を記述する。型によって記述されるあらゆる値を,その型のインスタンスと呼ぶ。値のあらゆ

る使用,すなわち,それを格納し,受け渡し,操作するには,型が要求される。これは,特に,すべての

変数,実引数,評価スタックの格納域及びメソッド結果に適用される。型は,可能な値及びその型の値が

提供する可能な演算を定義する。すべての演算子及び関数は,アクセスされる値又は使用される値のそれ

ぞれについて期待される型をもつ。

すべての値は,その型の特性を十分に記述する厳密な型をもつ。

すべての値は,その厳密な型のインスタンスとするが,同様に他の型のインスタンスになることもでき

る。特に,値が別の型から継承された型のインスタンスである場合,その値は,その別の型のインスタン

スにもなる。

8.2.1 

値型及び参照型 

型には,値型(value type)及び参照型(reference type)の 2 種類がある。

−  値型  値型によって記述される値は,自己充足している。すなわち,それぞれは,他の値を参照する

ことなく理解できる。

−  参照型  参照型によって記述される値は,他の値の格納域を表示する。参照型には,次の 4 種類があ

る。

−  オブジェクト型は,自己記述的な値の参照型とする(8.2.3 参照)

。幾つかのオブジェクト型(例え

ば,抽象クラスなど)は,値の部分的な記述だけになっている。

−  インタフェース型は,常に,値の部分的な記述であって,多くのオブジェクト型によって使用され

る可能性がある。

−  ポインタ型は,その表現が格納域の計算機アドレスになっている値のコンパイル時の記述とする。

−  組込み参照型。

8.2.2 

組込みの値型及び参照型 

表 のデータ型は,CTS の重要な部分であって,仮想実行システム(Virtual Execution System,VES)が

直接に提供する。それらは,永続的メタデータの中で特殊な符号化をもつ。


19

X 3016

:2010 (ISO/IEC 23271:2006)

表 1−特殊な符号化 

CIL

アセンブラにおける名前

(第 章参照) 

CLS

型かどうか

クラスライブラリにおける名前

(第 章参照) 

説明 

bool

Yes

System.Boolean true

又は false の値

char

Yes

System.Char

Unicode の 16 ビットの文字

object

Yes

System.Object

オブジェクト又はボックス化
された値型

string

Yes

System.String

Unicode 文字列

float32

Yes

System.Single

IEC 60559:1989

の 32 ビット浮

動小数点数

float64

Yes

System.Double

IEC 60559:1989

の 64 ビット浮

動小数点数

int8

No

System.SByte

符号付き 8 ビット整数

int16

Yes

System.Int16

符号付き 16 ビット整数

int32

Yes

System.Int32

符号付き 32 ビット整数

int64

Yes

System.Int64

符号付き 64 ビット整数

native int

Yes

System.IntPtr

符号付き整数,プラットフォー

ム固有のサイズ

native unsigned int

No

System.UIntPtr

符号なし整数,プラットフォー

ム固有のサイズ

typedref

No

System.TypedReference

厳密な型の付いたポインタ

unsigned int8

Yes

System.Byte

符号なし 8 ビット整数

unsigned int16

No

System.UInt16

符号なし 16 ビット整数

unsigned int32

No

System.UInt32

符号なし 32 ビット整数

unsigned int64

No

System.UInt64

符号なし 64 ビット整数

注記  bool 及び char は,図 の分類では整数型になっている。

8.2.3 

クラス,インタフェース及びオブジェクト 

型は,その値の表現及びその値で定義された演算をあいまい(曖昧)性なく定義する場合に,値を十分

に記述するという。

値型について,その表現を定義するとは,その値の表現を構成するビットの列を記述することをいう。

参照型について,その表現を定義するとは,その値の表現を構成するビットの列及びその格納域を記述す

ることをいう。

メソッドは,厳密な型の値で実行できる演算を記述する。厳密な型の値で許される演算の集合を定義す

るとは,それぞれの演算のための名前付きメソッドを規定することをいう。

型の中には,例えば,インタフェース型のように,部分的な記述だけのものもある。インタフェース型

は,演算の部分集合を記述するが表現は記述せず,いかなる値の厳密な型にもなれない。その結果,値は

ただ一つの厳密な型をもつが,同様に多くの他の型の値となることもできる。さらに,厳密な型は,その

値を十分に記述するから,その厳密な型の値がもつことができる他の型のすべても十分に規定する。

すべての値が一つの厳密な型をもつことは正しいが,その値の表現を調べることによってその厳密な型

を常に決定できるというわけではない。特に,値型の値の厳密な型を決定することは不可能である。例え

ば,二つの組込みの値型である,32 ビットの符号付き整数及び符号なし整数を考える。それぞれの型は,

それぞれの値の十分な規定になっているが,すなわち,厳密な型であるが,一つの値の特定の 32 ビット列

からその厳密な型がいずれであるのかを導出する方法はない。


20

X 3016

:2010 (ISO/IEC 23271:2006)

   

オブジェクトという値については,

その値から厳密な型を常に決定できる。オブジェクトの厳密な型は,

オブジェクト型という。オブジェクトは,参照型の値だが,すべての参照型がオブジェクトを記述するわ

けではない。32 ビット整数へのポインタである値を考える。この型は,参照型である。ポインタのビット

の並びを調べることによってその値の厳密な型を発見する方法はない。したがって,これはオブジェクト

ではない。組込みの CTS 参照型  System.String(

第 章参照)を考える。この型の値の厳密な型は,

その値を調べることによって常に決定できる。したがって,型 System.String の値はオブジェクトであ

って,System.String はオブジェクト型になる。

8.2.4 

値のボックス化及びボックス化解除 

すべての値型について,CTS は,ボックス化型という対応する参照型を定義する。この逆は正しくない。

すなわち,参照型は,一般には,対応する値型をもたない。ボックス化型の値(ボックス化値)の表現は,

その値型の値が格納できる格納域とする。ボックス化型はオブジェクト型であって,ボックス化値はオブ

ジェクトになる。

ボックス型は,名前によって直接には参照できない。その結果,いかなるフィールドにも局所変数にも

ボ ック ス化型 を与 える こ と は で きな い 。 ボ ッ ク ス 化 列挙 値型 に 最 も 近い名 前 付 き 基 礎ク ラス は ,

System.Enum

と す る 。 そ れ 以 外 の す べ て の 値 型 に 対 し て は , System.ValueType と す る 。

System.ValueType

の型をもつフィールドは,null 値又はボックス化値型のインスタンスだけを含むこ

とができる。System.Enum の型をもつ局所変数は,null 値又はボックス化列挙型のインスタンスだけを

含むことができる。

すべての値型は,ボックス化という演算をもつ。値型の値をボックス化すると,そのボックス化値が生

成される。すなわち,その値は,元の値のビット単位のコピーを含む対応するボックス化型の値になる。

値型が,値型 System.Nullable<T>のインスタンス化として定義されるヌル許容型である場合,(ボッ

クス化の)結果は,その HasValue 特性に依存して,すなわち,その値の偽又は真に依存して,それぞれ,

ヌル参照又は型 T の Value 特性のビット単位のコピーになる。すべてのボックス化型は,ボックス化解

除という演算をもつ。ボックス化解除を行うと,その元の値のビット表現への,管理されたポインタを生

じる。

ボックス化命令は,単に値型以上のものに適用できる。そのような型を,ボックス化可能型という。型

は,次の一つの場合にボックス化可能とする。

− CIL 評価スタックを指し示すことができるフィールドを含まない(総称値型のインスタンス化を含む)

値型。

注記  この根拠は次のとおりである。そのようなフィールドを含む値型はボックス化できない。こ

れは,そうでないと,これらの埋め込まれたポインタ,例えば,

System.RuntimeArgumentHandle

,System.TypedReference などが指し示す CIL 評

価スタックの中の項目よりも長続きすることが可能になってしまう。それらのポインタを含

む値型を,非形式的には,

“byref 風”値型という。

−  (クラス,配列,委譲及び総称クラスのインスタンス化を含む)参照型。

−  管理外ポインタ型。

−  (総称型定義又は総称メソッド定義に対する)総称仮引数。

注記  総 称 実 引 数 の ボ ッ ク ス 化 及 び ボ ッ ク ス 化 解 除 は , CLI 実 装 に 性 能 の 負 荷 を 課 す 。

Constrained

接頭辞は,値型のボックス化を避けることによって,値型が定義するメソッ

ドへの仮想ディスパッチの最中の性能を改善できる。


21

X 3016

:2010 (ISO/IEC 23271:2006)

型 System.Void は,ボックス化不可とする。

インタフェース及び継承は,参照型だけに定義される。値型の定義(8.9.7 参照)は,その値型が実装し

な け れ ば な ら な い イ ン タ フ ェ ー ス 及 び そ の 値 型 を 継 承 す る ク ラ ス ( System.ValueType 又 は

System.Enum

)の両方を規定できるが,これらのインタフェース及びクラスは,ボックス化値に対して

だけ適用される。

CLS

規則 3  ボックス化値は,CLS 合致ではない。

注記  ボ ックス化 型の代わ りに, 必要に応 じて, System.Object, System.ValueType 又 は

System.Enum

を使用する。

CLS

(使用側)  ボックス化値の型を移入する必要はない。

CLS

(拡張側)  ボックス化値の型を定義又は使用するための構文を提供する必要はない。

CLS

(フレームワーク)  公開する部分でボックス化値の型を用いてはならない。 

8.2.5 

値の同一性及び等価性 

値のすべての対で定義される二つの 2 項演算子,同一性演算子及び等価(性)演算子が存在する。これ

らは真理値の結果を返す。これらの演算は,数学的には,両方とも同値演算子になる。すなわち,次が成

立する。

−  反射律  a op a  が成り立つ。

−  対称律  a op b  が成り立つのは,b op a  が成り立つ場合かつその場合に限る。

−  推移律  a op b  が成立し,b op c  が成立する場合,a op c  が成立する。

さらに,同一性は常に等価性を意味するが,逆はいえない。

これらの演算の間の違いを理解するのに,型が System.String である三つの変数 A,B 及び C を考え

る(次の図参照)

。ここで,矢印は“…への参照である”ことを意図している。

変数の値は,文字の列の格納域が同じ場合,同一になる。すなわち,実際,記憶域上にはただ一つの文

字列だけが存在する。変数の中に格納された値は,文字の列が同じ場合,等価になる。そこで,変数 A 及

び B の値は同一になり,変数 A 及び C の値,並びに,変数 B 及び C の値は,同一ではないが,A,B 及

び C の三つすべての値は等価になる。

8.2.5.1 

同一性 

同一性演算子は,CTS によって次のとおりに定義される。

−  値が,異なる厳密な型をもつ場合,それらは同一ではない。

−  値が,同じ厳密な型をもつ場合であって,それらの厳密な型が値型である場合,値のビット列が同じ

場合かつその場合に限り,それらの値は,同一とする。

−  値が,同じ厳密な型をもつ場合であって,それらの厳密な型が参照型である場合,値の格納域が同じ

場合かつその場合に限り,それらの値は,同一とする。

同一性は,System.Object 上に ReferenceEquals メソッドを通じて実装される。


22

X 3016

:2010 (ISO/IEC 23271:2006)

   

8.2.5.2 

等価性 

値型に対して,等価演算子は,その厳密な型の定義の一部になる。等価性の定義は,次の規則に従うの

が望ましい。

−  等価演算子は,先に定義した同値演算子であることが望ましい。

−  同一性は,先に示したとおり,等価性を示唆することが望ましい。

−  いずれか(又は両方)の演算対象がボックス化値である場合,等価性は,次によって計算されること

が望ましい。

−  最初に,ボックス化された演算対象のボックス化を解除する。

−  次に,結果として生じた値に等価性の通常の規則を適用する。

等価性は,System.Object 上に Equals メソッドを通じて実装される。

注記  二つの浮動小数点数 NaN は,IEC 60559:1989 によって,常に等価ではないとして比較されると

定義されているが,System.Object.Equals についての契約は,その上書きメソッドが同値

演算子に対する要件を満足しなければならないことを要求する。その結果,

System.Double.Equals

及び System.Single.Equals は,二つの NaN を比較したとき,

True を返す。その一方で,等価演算子は,IEC 60559:1989 が要求するとおり,NaN の比較で

False を返す。

8.3 

格納域 

値は,ある格納域に格納される。一つの格納域は,一度にただ一つの値を保持できる。すべての格納域

は型付けされている。格納域の型は,その格納域に格納される値が満たさなければならない要件を具現化

している。格納域の例としては,局所変数及び仮引数がある。

更に重要なことだが,格納域の型は,その格納域からロードされるあらゆる値の使用法についての制限

を規定する。例えば,一つの格納域は,潜在的に多くの厳密な型の値を,それらの値すべてが格納域の型

と互換性があるように代入される限りは,保持できる。一つの格納域からロードされるすべての値は,そ

れらがその格納域の型をもつものとして,取り扱われる。たとえ,格納域に格納された値の厳密な型が付

加的な演算を可能にしていたとしても,

その格納域の型に対して有効な演算だけを呼び出すことができる。

8.3.1 

代入互換な格納域 

値は,その値の型の一つが格納域の型と代入互換な場合に限り,その格納域に格納できる。型は,常に

それ自体と代入互換とする。代入互換性はコンパイル時に決定されることが多く,その場合には,実行時

の試験は不要になる。代入互換性は,8.7 で詳細に示す。

8.3.2 

強制型変換 

場合によっては,格納域と代入互換ではない型の値をとり,そして,その値を代入互換のある型に変換

することが望ましいことがある。強制型変換は,特定の型の値及び望まれる型をとり,元の値と同等な意

味をもつ望まれる型の値を生成しようとする。強制型変換は,型の変更だけでなく表現の変更を生じる可

能性がある。だから,強制型変換は,必ずしもオブジェクトの同一性を保存しない。

強制型変換には 2 種類ある。それらは,決して情報を失わない拡大及び情報を失うかもしれない縮小と

する。32 ビット符号付き整数の値を 64 ビット符号付き整数の値に強制型変換するのは,拡大強制型変換

の例である。この逆,すなわち,64 ビット符号付き整数の値を 32 ビット符号付き整数の値に強制型変換

するのは,縮小強制型変換の例である。プログラム言語は,拡張強制型変換を暗黙的変換として実装する

ことが多い。一方,縮小強制型変換は,通常,明示的変換として実装される。

拡張強制型変換の中には,直接に,組込み型上の VES 演算で構築されるものがある(12.1 参照)

。他の


23

X 3016

:2010 (ISO/IEC 23271:2006)

すべての強制型変換は,明示的に要求されなければならない。組込み型について,CTS は,実行時検査な

しの拡大強制型変換及び実行時検査付きの縮小強制型変換を実行するための演算を提供する。

8.3.3 

キャスト 

値は二つ以上の型をもちうるから,値を使用するときには,その値のどの型を用いているかを明確に識

別する必要がある。値は型付けされた格納域から読み込まれるから,使用される値の型は,その値が読み

込まれた格納域の型とする。異なる型を使用するのが望ましい場合,その値は,他の型の一つにキャスト

される。キャストは,通常はコンパイル時の演算だが,コンパイラが値のターゲット型を静的に知らない

場合,実行時のキャスト検査が行われる。強制型変換とは異なり,キャストは,オブジェクトの実際の型

を変更しないしその表現も変更しない。キャストは,オブジェクトの同一性を保存する。

例えば,特定のインタフェースの値を保持しながら,型付けされた格納域から読み出された値をキャス

トするとき,実行時検査を必要とするかもしれない。インタフェースは値の不完全な記述なので,その値

を異なるインタフェース型にキャストすると,通常は,実行時キャスト検査が生じる。

8.4 

型メンバ 

先に示したとおり,型は,許可される値及びその型の値が提供する許可される演算を定義する。型の許

可される値が部分構造をもつ場合,その部分構造は,その型のフィールド又は配列要素を通じて記述され

る。型の一部である演算が存在する場合,それらの演算は,その型のメソッドを通じて記述される。フィ

ールド,配列要素及びメソッドは,型のメンバという。特性及びイベントも型のメンバとする。

8.4.1 

フィールド,配列要素及び値 

値の表現は,

(組込み型である場合を除いて)部分値に分割できる。この部分値は,名前をもつか,又は

添字指定式によってアクセスされる。名前をもつ場合は,フィールドという。添字指定式を使う場合は,

配列要素という。配列要素から構成される値を記述する型は,配列型とする。フィールドから構成される

値を記述する型は,複合型とする。一つの値は,フィールド及び配列要素の両方を含むことはできない。

ただし,複合型のフィールドが配列型であったり,配列要素が複合型であったりすることができる。

配列要素及びフィールドは型付けされており,

それらの型は決して変化しない。

一つの配列中の要素は,

すべて同じ型をもたなければならない。

複合型のそれぞれのフィールドは,

異なる型をもつことができる。

8.4.2 

メソッド 

型は,演算を,その型又はその型の各インスタンスと関連付けることができる。それらの演算をメソッ

ドという。メソッドは,名前をもち,その実引数のすべて及び存在する場合にはその返却値に対して許さ

れる型を規定する識別情報(8.6.1 参照)をもつ。

型の特定のインスタンスにではなく,型それ自体だけと関連付けられたメソッドを静的メソッド(8.4.3

参照)という。

型のインスタンスに関連付けられたメソッドは,インスタンスメソッド又は仮想メソッド(8.4.4 参照)

のいずれかとする。インスタンスメソッド及び仮想メソッドが呼び出されるとき,それらは,この呼出し

が演算を行う(this  又は this pointer として知られる)インスタンスに渡される。

インスタンスメソッドと仮想メソッドとの基本的な違いは,その実装の格納域の与えられる方法にある。

インスタンスメソッドは,クラス及びそのクラス内のそのインスタンスメソッドを指定することによって

呼び出される。this として渡されるオブジェクトは,null(インスタンスが指定されていないことを示す特

殊な値。ヌル,ナルなどともいう。

)又はそのメソッドを定義するクラスから継承(8.9.8 参照)される型

のインスタンスとすることができる。仮想メソッドも,これと同じ方法で呼び出すことができる。例えば,

仮想メソッドの実装が基底クラスが提供する実装を呼び出したい場合に,これが発生する。CTS は,仮想


24

X 3016

:2010 (ISO/IEC 23271:2006)

   

クラスの本体の内部で this を null とすることを許している。

注記  この根拠は次のとおりである。仮想メソッドを非仮想呼出しで呼び出せるようにしたから,

“call super”命令が不要になり,仮想メソッドと非仮想メソッドとの間で版の変更が可能にな

る。これは,CIL 生成器が null の this ポインタを呼び出されたメソッドに伝ぱ(播)したくな

い場合には,CIL 生成器に,ヌルポインタのための明示的な試験を要求する。

仮想メソッド又はインスタンスメソッドは,仮想呼出しという異なる機構によって呼び出すこともでき

る。仮想メソッドを定義する型から継承されるあらゆる型は,そのメソッドのその型それ自体の実装を提

供できる。これは,上書きとして知られている(8.10.4 参照)

。どの実装が呼び出されるかを決定するのに

使用されるのは,

(実行時に決定される)オブジェクトの厳密な型とする。

8.4.3 

静的フィールド及び静的メソッド 

型は,その型の特定の値ではなくてその型に関連した格納域を宣言できる。このような格納域を,その

型の静的フィールドという。すなわち,静的フィールドは,その型のすべての値が共有する格納域を宣言

する。非静的(インスタンス)フィールドと同様に,静的フィールドは型付けされており,その型は決し

て変化しない。静的フィールドは,常に一つのアプリケーションドメイン(12.5 参照)に制限されている

が,スレッドごとに割り当てることもできる。

同様に,型は,その型の値ではなくその型に関連するメソッドも宣言できる。このようなメソッドをそ

の型の静的メソッドという。静的メソッドの呼出しは,その静的メソッドが演算を行う関連する値をもた

ないから,静的メソッド内に利用可能な this ポインタは存在しない。

8.4.4 

仮想メソッド 

オブジェクト型は,そのメソッドを仮想として宣言できる。他のメソッドとは異なり,その型を実装す

る厳密な型が,仮想メソッドのその型自体の実装を提供できる。仮想メソッドは,実装を選択するための,

静的な型,

メソッド名及び仮引数の型を用いる通常のメソッド呼出し機構を通じて呼び出すことができる。

この場合,this ポインタは null にできる。しかし,更に,仮想メソッドは,ある特殊な機構,仮想呼出し

によって呼び出すことができる。この場合,メソッドの実装は,コンパイル時に静的に知られる型ではな

く,その仮想呼出しを行うのに使用されたインスタンスの動的に検知された型に基づいて選択される。仮

想メソッドは,final(8.10.2 参照)と印付けできる。

8.5 

名前付け 

名前は,型システムの実体に与えられ,その結果として,実体は,その型システムの他の部分によって

又はその型の実装によって参照できるようになる。型,フィールド,メソッド,特性及びイベントは,名

前をもつ。型システムでは,値,局所変数及び仮引数は名前をもたない。型システムの実体は,一つの名

前を与えられる。例えば,一つの型にはただ一つの名前だけが存在する。

8.5.1 

妥当な名前 

すべての名前の比較は,バイトごとに(すなわち,大文字と小文字とを区別し,ロケールに依存せず,

符号位置の比較としても知られている方法で)行われる。名前が,組込みの VES 提供機能(例えば,クラ

ス初期化メソッドなど)にアクセスするために使用される場合,

(その名前が)予約された名前のあらゆる

集合の中で構築されないように,常に,

(その名前の)定義に関して付随する指示が存在する。

CLS

規則 4  アセンブリは,識別子の開始文字及び継続文字の集合を規定する Unicode Standard 3.0 の技

術文書 15 の附属書 7 に従わなければならない。この文書は,

http://www.unicode.org/unicode/reports/tr15/tr15-18.html で入手できる。識別子は,Unicode 正規化形式 C


25

X 3016

:2010 (ISO/IEC 23271:2006)

(Unicode Normalization Form C)が定義する正規形式でなければならない。CLS の目的に対しては,二つ

の識別子は,

(Unicode のロケールを意識しない 1 対 1 小文字対応付けが規定するとおりに)それら識別子

を小文字に対応付けたものが同じ場合に同じとする。すなわち,二つの識別子が CLS において異なってい

ると考えられる場合,それらは,単に大文字と小文字とが異なっている以上に異なっている。しかし,継

承された定義を上書きするときに,CLI は,元の宣言の正確な符号化が使用されることを要求する。

注記   

CLS

(使用側) CLS 規則 4 に違反する型を使う必要はない。しかし,使用側それ自体のキー

ワードの一つを名前として使用する名前付けられた項目にアクセス可能な機構をもたなければ

ならない。

CLS

(拡張側) CLS 規則 4 に違反する型を生成する必要はない。しかし,これらの規則に従

い,拡張側の言語におけるキーワードと同じ新しい名前を定義する機構を提供しなければなら

ない。

CLS

(フレームワーク) CLS 規則 4 に違反する型を移出してはならない。各種のプログラム

言語で共通的にキーワードとして使用される名前の使用は避けることが望ましい(

第 章,附

属書 参照)。

8.5.2 

アセンブリ及び有効範囲付け 

一般に,名前は一意ではない。名前は,有効範囲というグループ化されたものに集められる。一つの有

効範囲内では,一つの名前は,それが参照する実体が異なる種類(メソッド,フィールド,入れ子になっ

た型,特性及びイベント)であるか,又は異なる識別情報をもつ限り,複数の実体を参照できる。

CLS

規則 5  CLS 合致の有効範囲で導入されるすべての名前は,それら名前が同一であって多重定義に

よって解決される場合を除いて,種類とは独立に異なっていなければならない。すなわち,CTS は,一つ

の型がメソッド及びフィールドに対して同じ名前を使用することを許すが,CLS は許さない。

CLS

規則 6  CTS では異なる識別情報は区別可能だが,CLS では,フィールド及び入れ子になった型は,

識別子の比較だけによって異なっていなければならない。

(識別子の比較によって)

同じ名前をもつメソッ

ド,特性及びイベントは,単に返却値の型だけ以外によって異なっていなければならない。ただし,CLS

規則 39 で規定した場合を除く。

注記   

CLS

(使用側) CLS 合致ではないと印付けられたあらゆるメンバを無視した後で,これらの

規則に違反する型を使用する必要はない。

CLS

(拡張側)  これら規則に違反する型を定義するための構文を提供する必要はない。

CLS

(フレームワーク)  型内の規則を破る項目を,残りのメンバが互いに矛盾しないように

CLS 合致でないと印付けしていない場合,型がこれらの規則に違反するならば,それらの型を

CLS 合致と印付けしてはならない。 

名前付けされた実体は,ただ一つの有効範囲の中でその名前をもつ。そこで,名前付けされた実体を識

別するためには,有効範囲及び名前の両方が提供される必要がある。有効範囲は,名前を限定する。型は,

その型の中の名前に対して一つの有効範囲を提供する。その結果,型は,その型の中の名前を限定する。

例えば,x と名前を付けられたフィールドをもつ複合型 Point を考える。名前“フィールド x”は,それ

自体では,名前付けられたフィールドを一意には識別しない。しかし,限定名“型 Point の中のフィール


26

X 3016

:2010 (ISO/IEC 23271:2006)

   

ド x”は一意に識別する。

型は名前をもつから,型の名前も有効範囲にグループ化される。型を十分に識別するためには,その型

名は,それを含む有効範囲によって限定されていなければならない。型名は,その型の実装を含むアセン

ブリによって有効範囲付けされる。アセンブリは,ロード可能なコードモジュールと,機能の単位を一緒

に実装している他の資源とから構成された集合とする。型名は,その型を実装するアセンブリのアセンブ

リ有効範囲の中にあるという。アセンブリそれ自体は,CTS 名前階層の基礎となる名前をもつ。

型定義は,次を行う。

−  定義している型に対する名前,すなわち,型名を定義し,その名前が見いだされる有効範囲を規定す

る。

−  メンバの異なる種類(フィールド,メソッド,イベント及び特性)の名前を束縛するメンバ有効範囲

を定義する。メンバ名,メンバ種類,メンバ識別情報の組は,型のメンバ有効範囲内で一意とする。

−  暗黙的に,型を,その型定義を含むアセンブリのアセンブリ有効範囲に割り当てる。

CTS は,既存の型に対して代替の名前を与える(列挙型としても知られる)enum を提供する。識別情

報を対応付けるために,enum は,それの基礎となる型と同じであってはならない。しかし,enum のイン

スタンスは,基礎となる型と互換性のある代入が可能でなければならず,逆もいえなければならない。す

なわち,キャスト(8.3.3 参照)も強制型変換(8.3.2 参照)も enum からその基礎となる型への変換で要求

されず,基礎となる型から enum への変換でも要求されない。enum は,次のとおりに,本当の型よりも

注意深く制限されている。

−  enum は,ただ一つのインスタンスフィールドをもち,そのフィールドの型は,その列挙の基礎とな

る型を定義する。

−  enum は,それ自体のメソッドをもってはならない。

−  enum は,System.Enum(

第 章参照)から派生しなければならない。

−  enum は,それ自体のインスタンスを実装してはならない。

−  enum は,それ自体の特性又はイベントをもってはならない。

−  enum は,そのフィールドがリテラルでない限り,静的なフィールドをもってはならない(8.6.1.2 

照)

基礎となる型は,組込みの整数型でなければならない。enum は,System.Enum から派生していなけれ

ばならない。その結果,値型になる。すべての値型と同様に,それは封印されなければならない(8.9.9 

照)

CLS

規則 7  enum の基礎となる型は,組込みの CLS 整数型でなければならない。フィールドの名前は,

“value__”でなければならず,そのフィールドは,RTSpecialName と印付けされなければならない。

CLS

規則 8  System.FlagsAttribute(第 章参照)カスタム属性が存在する又は存在しないによ

って示される二つの異なる種類の enum が存在する。一つは,名前付き整数値を表現し,もう一つは,名

前付きでない値を生成するために結合可能な名前付きビットフラグを表現する。enum の値は,指定され

た値に制限されない。

CLS

規則 9  enum のリテラル静的フィールド(8.6.1 参照)は,enum それ自体の型をもたなければなら

ない。

注記   

CLS

(使用側)  これらの規則に従う enum の定義を受け入れなければならない。しかし,フ


27

X 3016

:2010 (ISO/IEC 23271:2006)

ラグを名前付き値と区別する必要はない。

CLS

(拡張側)  使用側と同じ。拡張側の言語は,enum の編集を可能にすることが望まれる

が,必す(須)ではない。

CLS

(フレームワーク)  これらの規則に違反する enum を開示してはならないし,(enum

が名前付き値であっても)enum が指定された値だけをもつと仮定してはならない。 

8.5.3 

可視性,アクセス可能性及びセキュリティ 

有効範囲の中の名前付き実体を参照するためには,有効範囲及びその有効範囲の中の名前の両方が,可

視でなければならない(8.5.3.1 参照)

。可視性は,参照を含む実体(参照元)と参照される名前を含む実

体との間の関係によって決定される。次の擬似コードを考える。

class A

{ int32 IntInsideA;

}

class B inherits from A

{ method X(int32, int32)

  { IntInsideA := 15;

  }

}

クラス A の中の IntInsideA フィールドへの参照を考える。

−  クラス B はそのフィールドを参照するメソッドをもつから,クラス B を参照元と呼ぶ。

−  クラス A の中の IntInsideA を,参照される実体と呼ぶ。

参照元が,参照される実体にアクセス可能かどうか,を決定するために答える必要がある二つの基本的

な問題が存在する。一つは,参照される実体の名前が参照元に対して可視かどうかである。可視である場

合,参照される実体がアクセス可能(8.5.3.2 参照)かどうか,すなわち,参照元がアクセス可能権限をも

っているかどうか,という異なる問題がある。

型のメンバへのアクセスは,次の三つの条件すべてが満たされる場合だけに許可される。

−  型が可視であって入れ子になった型である場合は,アクセス可能になっている。

−  メンバがアクセス可能になっている。

−  すべての意味のあるセキュリティ要求(8.5.3.3 参照)が満たされている。

インスタンス化された総称型は,その総称型それ自体と,その構成部分(総称型定義及び総称実引数)

のそれぞれとが可視である場合かつその場合に限り,あるアセンブリから可視とする。例えば,List がア

センブリ A から移出されており(すなわち,

“public”と宣言されており)

,MyClass がアセンブリ B で

定義されているが移出されていない場合,List<MyClass>は,アセンブリ B 内からだけ可視となる。

インスタンス化された総称型のメンバのアクセス可能性は,インスタンス化には依存しない。

その結果,メンバ C<T1, 

 Tn>.m

へのアクセスは,次の条件を満足する場合に許される。

− C<T1, ... Tn>が可視になっている。

−  総称型 内のメンバ m(すなわち,C.m)が,アクセス可能になっている。

−  セキュリティ許可が,認められている。

8.5.3.1 

型の可視性 

メンバの名前ではなく型の名前だけが,制御された可視性をもつ。型名は,次の三つの分類の一つに所


28

X 3016

:2010 (ISO/IEC 23271:2006)

   

属する。

−  型名が定義されているアセンブリから移出されている。型がアセンブリから移出可能と印付けできて

も,その型名が使用可能かどうかを決定するのはアセンブリの構成とする。

−  型名が定義されているアセンブリの外部には移出されていない。

−  他の型の内部に入れ子になっている。この場合,入れ子になっている型それ自体は,それを内部に入

れ子にしている型(その囲み込む型)の可視性をもつ(8.5.3.4 参照)

最上位の名前付きの型は,それが公開の可視性をもつ場合かつその場合に限り,移出されている。型定

義子が生成する型は,それが移出されている型から作られる場合かつその場合に限り,移出されている。

型定義子が生成する型は,それが生成されたすべての型が可視である場合に,可視となる。

8.5.3.2 

メンバ及び入れ子型のアクセス可能性 

型は,そのメンバすべてを有効範囲付けし,更に,そのメンバにアクセス可能性規則を指定する。特に

注意を促さない場合には,アクセス可能性は,参照されているメンバの型の静的な可視性,並びに参照を

行っている型及びアセンブリだけに基づいて決定される。CTS は,アクセス可能性のために七つの異なる

規則を提供する。

−  コンパイラ制御(compiler-controlled)  参照ではなく定義の使用を通じてだけ,アクセス可能(権限が

ある)とする。その結果,一つのコンパイル単位内からコンパイラの制御下だけでアクセス可能にな

る。

−  私的(private)  メンバを定義しているその型(厳密な型)の実装の中にある参照元に対してだけ,ア

クセス可能(権限がある)とする。すなわち,それらの参照元だけがアクセスできる。

−  ファミリ(family)  同じ型,すなわち,厳密な型及びそれから継承される型のすべてを提供する参照

元に対して,アクセス可能(権限がある)とする。正当性検証可能コード(8.8 参照)に対しては,実

行時検査を要求できるという付加的な要件がある。その実行時検査は,参照は,厳密な型が参照元の

厳密な型である項目を通じて行われなければならないという検査とする。すなわち,メンバがアクセ

スされている項目は,そのアクセスを実行している型から継承されなければならない。

−  アセンブリ(assembly)  型の実装を含む同じアセンブリの中にある参照元に対してだけ,アクセス可

能(権限がある)とする。

−  ファミリ及びアセンブリ(family-and-assembly)  ファミリアクセス及びアセンブリアクセスの両方に

限定される参照元に対してだけ,アクセス可能(権限がある)とする。

−  ファミリ又はアセンブリ(family-or-assembly)  ファミリアクセス又はアセンブリアクセスのいずれか

に限定される参照元に対してだけ,アクセス可能(権限がある)とする。

−  公開(public)  すべての参照元に対して,アクセス可能(権限がある)とする。

メンバ又は入れ子になった型は,それが,公開,ファミリ又はアセンブリ,ファミリといったアクセス

可能性をもち,

(メンバである場合は)その定義する型又は(入れ子になった型である場合は)その囲む型

が移出されている場合及びその場合に限り,移出されている。

型定義子のアクセス可能性は,それが生成された型のアクセス可能性と同じとする。

一般に,型のメンバは,それに割り当てられるこれらのアクセス可能性規則のいずれか一つをもつこと

ができる。しかし,次の三つの例外がある。

1)

インタフェースによって定義される(入れ子になった型ではなく)メンバは,公開でなければなら

ない。

2)

型が,継承された定義を上書きする仮想メソッドを定義している場合,そのアクセス可能性は,二


29

X 3016

:2010 (ISO/IEC 23271:2006)

つの定義において同一になっていなければならないか,上書きする定義が元の定義よりも広いアク

セスを許可していなければならない。例えば,アセンブリ仮想(assembly virtual)メソッドを公開

仮想(public virtual)な新しい実装で上書きすることは可能だが,ファミリ仮想(family virtual)な

実装で上書きはできない。他のアセンブリから派生した定義を上書きする場合,基底定義がファミ

リ又はアセンブリ(family-or-assembly)アクセスをもち,上書きがファミリ(family)アクセスだけ

をもつならば,アクセスを制限しているとは考えない。

3)

入れ子になった型によって定義されるメンバ,又は入れ子になった型によって囲まれる入れ子にな

った型は,

(メンバである場合には)それを定義する入れ子になった型より,又は(入れ子になった

型である場合には)それを囲む入れ子になった型よりも,広いアクセス可能性をもつ。

注記  この根拠は次のとおりである。C++を含む言語は,アクセスのこの“拡大”を許している。ア

クセスを制限するとセキュリティが向上すると思うのは,間違った考えである。これは,単に

オブジェクトを(暗黙的にメソッド呼出しが発生する。

)基底クラスにキャストしても,アクセ

ス可能性は制限されるがメソッドは呼出し可能であることによる。仮想メソッドの上書きを禁

止するためには,宣言されたアクセス可能性に頼るのではなく final を使用する。

CLS

規則 10  アクセス可能性は,継承されたメソッドを上書きしても変更してはならない。ただし,フ

ァミリ又はアセンブリのアクセス可能性をもつ異なるアセンブリから継承されたメソッドを上書きする場

合は除く。この場合は,ファミリアクセス可能性になる。

注記   

CLS

(使用側) 継承された仮想メソッドへのアクセスを拡大する型を受け入れる必要はない。

CLS

(拡張側) 継承された仮想メソッドへのアクセスを拡大する構文を提供する必要はない。

CLS

(フレームワーク)  フレームワークの開示された部分又はフレームワークの利用者によ

る,仮想メソッドへのアクセスを拡大する能力に依存してはならない。 

8.5.3.3 

セキュリティ許可 

メンバへのアクセスは,アセンブリ,型,メソッド,特性又はイベントに添付できるセキュリティ要求

によっても制御される。セキュリティ要求は,型契約(8.6 参照)の一部ではなく,継承されない。次の 2

種類の要求がある。

−  継承要求。この要求が型に添付される場合,この型からの継承を望むあらゆる型が指定されたセキュ

リティ許可をもたなければならないことを要求する。この要求が最終(final)でない仮想メソッドに

添付される場合,このメソッドの上書きを望むあらゆる型が指定されたセキュリティ許可をもたなけ

ればならないことを要求する。それ以外のメンバに添付してはならない。

−  参照要求。この印を付けられた項目への参照を解決しようとする場合,指定されたセキュリティ許可

をもっていなければならない。

それぞれの種類のただ一つの要求だけを,項目に添付できる。アセンブリに一つのセキュリティ要求を

添付すると,アセンブリの中のすべての型に対して,その型に同じ種類の他の(レベルの)要求が添付さ

れている場合を除き,そのセキュリティ要求が添付される。同様に型にセキュリティ要求を添付すると,

その型のすべてのメンバに対して,そのメンバに同じ種類の他の要求が添付されている場合を除き,その

同 じ セ キ ュ リ テ ィ 要 求 が 添 付 さ れ る 。 詳 細 は ,

第 章 の 宣 言 的 セ キ ュ リ テ ィ 及 び 第 章 の

System.Security

名前空間の中のクラスを参照。

8.5.3.4 

入れ子になった型 


30

X 3016

:2010 (ISO/IEC 23271:2006)

   

型は,囲む側の型のメンバとなることができる。この場合,それを入れ子になった型という。入れ子に

なった型は,囲む側の型と同じ可視性をもち,囲む側の型の他のメンバと同じアクセス可能性をもつ。こ

のアクセス可能性は,他のどの型が入れ子になった型を参照できるかを決定する。すなわち,あるクラス

が,入れ子になった型のフィールド又は配列要素を定義している,仮引数又は返却値の型が入れ子になっ

た型をとるメソッドをもっているなどの場合,その入れ子になった型は,参照している型に対して可視で

あってしかもアクセス可能になっていなければならない。入れ子になった型は囲む側の型の一部なので,

そのメソッドは,継承されている(親の)型のメンバへのファミリアクセスと同様に,囲む側の型のすべ

てのメンバへのアクセスをもつ(8.9.8 参照)

。入れ子になった型の名前は,アセンブリではなく囲む側の

型によって有効範囲付けされる(最上位の型だけが,アセンブリによって有効範囲付けされる。

。入れ子

になった型の名前がアセンブリ内で一意になるという要件は存在しない。

8.6 

契約 

契約には名前が与えられる。契約は,その契約のすべての実装者とすべての利用者との間の識別情報

8.6.1 参照)の集合における共有された想定とする。識別情報は,検査でき強制できる契約の一部とする。

契約は型ではない。むしろ,型の実装についての要件を指定する。型は,それがどの契約に従っている

か,すなわち,型のすべての実装がどの契約を提供しているかを示す。型の実装は,契約の強制可能な部

分,すなわち,名前の付いた識別情報が実装されたかを検査するために正当性検証できる。契約には次の

種類がある。

−  クラス契約  クラス契約は,クラス定義を用いて指定される。その結果,クラス定義は,クラス契約

及びクラス型の両方を定義する。

クラス契約の名前及びクラス型の名前は同じとする。クラス契約は,

クラス型の値の表現を指定する。さらに,クラス契約は,クラス型が提供する他の契約,例えば,ど

のインタフェース,どのメソッド,どの特性及びどのイベントを実装しなければならないかを指定す

る。クラス契約,すなわち,クラス型は,他のクラス型によって提供されることもできる。他のクラ

ス型のクラス契約を提供するクラス型は,そのクラス型から継承されるという。

−  インタフェース契約  インタフェース契約は,インタフェース定義を用いて指定される。そして,イ

ンタフェース定義は,インタフェース契約及びインタフェース型の両方を定義する。インタフェース

契約の名前及びインタフェース型の名前は同じとする。多くの型が,同じインタフェース契約を提供

できる。クラス契約と同様に,インタフェース契約は,そのインタフェースが他のどの契約を提供す

るか,例えば,どのインタフェース,どのメソッド,どの特性及びどのイベントを実装しなければな

らないかを指定する。

注記  インタフェース型は,値の表現を十分には記述できない。だから,インタフェース型は,ク

ラス契約を提供できず,クラス型又は厳密な型となることはできない。

−  メソッド契約  メソッド契約は,メソッド定義を用いて指定される。メソッド契約は,メソッドの実

装とメソッドの呼出し側との間の契約を指定する名前付き演算とする。メソッド契約は,常に,型契

約(クラス,値型又はインタフェースの契約)の一部であって,特定の名前付き演算を実装する方法

を示す。メソッド契約は,メソッドへの各仮引数が提供しなければならない契約及び返却値がある場

合には返却値が提供しなければならない契約を指定する。

−  特性契約  特性契約は,特性定義を用いて指定する。名前付き値を扱う演算の拡張可能な集合が存在

する。これは,値を読み,値を変更する標準的な対の操作を含む。特性契約は,特性契約を提供する

型が実装しなければならない演算の部分集合のためのメソッド契約を指定する。一つの型は,多くの

特性契約を提供できるが,与えられた特性契約は,ちょうど一つの型によって提供可能になる。その


31

X 3016

:2010 (ISO/IEC 23271:2006)

結果,特性定義は,その特性を提供する型の型定義の一部になる。

−  イベント契約  イベント契約は,イベント定義を用いて指定する。名前付きイベントを扱う演算の拡

張可能な集合が存在する。これは,あるイベントに関心があることを登録し,その登録を取り消し,

イベントを発火させるという,三つの標準的なメソッドを含む。イベント契約は,イベント契約を提

供する型が実装しなければならないすべての演算のためのメソッド契約を指定する。一つの型は,多

くのイベント契約を提供できるが,与えられたイベント契約は,ちょうど一つの型によって提供可能

になる。そして,イベント定義は,そのイベントを提供する型の型定義の一部になる。

8.6.1 

識別情報 

識別情報は,検査可能であって自動的に強制実行可能な契約の一部とする。識別情報は,型及び他の識

別情報に制約を追加することによって形成される。制約は,値又は格納域における演算の使用又は可能な

演算の制限とする。例えば,格納域が異なる値で上書きできるかどうか,値を変更できるかどうかなどは,

制約の例になる。

すべての格納域は,すべての値と同様に,識別情報をもつ。代入互換性は,制約も含む値の識別情報が

制約も含む格納域の識別情報と互換になることを要求する。4 種類の基本的な識別情報,すなわち,型識

別情報(8.6.1.1 参照)

,格納域識別情報(8.6.1.2 参照)

,仮引数識別情報(8.6.1.4 参照)及びメソッド識別

情報(8.6.1.5 参照)が存在する。5 番目の局所識別情報(8.6.1.3 参照)は,格納域識別情報の一種とする。

注記 CLI での用語“識別情報”は,C#におけるメソッドに対する用語“呼出し情報”に対応するが,

これを,メソッドだけでなく,型,格納域及び仮引数にも拡張したものになっている。これを

明確化するために,新たに“識別情報”を使用する。

CLS

規則 11  識別情報に出現するすべての型は,CLS 合致でなければならない。インスタンス化された

総称型を構成するすべての型は,CLS 合致でなければならない。

CLS

規則 12  型及びメンバの可視性及びアクセス可能性は,そのメンバそれ自体が可視であってアクセ

ス可能なときにはいつでも,メンバの識別情報内の型が可視であってアクセス可能でなければならないと

いうようになっていなければならない。例えば,アセンブリの外部で可視である公開メソッドは,そのア

センブリ内でだけ可視な型の実引数をもっていてはならない。あらゆるメンバの識別情報の中で使用され

るインスタンス化された総称型を構成する型の可視性及びアクセス可能性は,そのメンバそれ自体が可視

及びアクセス可能なときはいつでも,可視及びアクセス可能でなければならない。例えば,アセンブリの

外で可視なメンバの識別情報の中に存在するインスタンス化された総称型は,型がそのアセンブリ内部だ

けで可視な総称実引数をもってはならない。

注記   

CLS

(使用側)  これらの規則に違反するメンバをもつ型を受け入れる必要はない。

CLS

(拡張側)  これらの規則に違反する構文を提供する必要はない。

CLS

(フレームワーク)  移出されている型及びそのメンバで,これらの規則に違反してはな

らない。 

8.6.1.1

8.6.1.5 において,様々な種類の識別情報を示す。これらは,簡単なものから複雑なものへと並

んでいる。すなわち,最も簡単な識別情報は型識別情報であって,格納域識別情報は,型識別情報に省略

可能な幾つかの追加属性を加えたもの,などとなっている。

8.6.1.1 

型識別情報 

型識別情報は,値及びその使用法に関する契約を定義する。型は,それ自体で,有効な型識別情報にな


32

X 3016

:2010 (ISO/IEC 23271:2006)

   

っている。値の型識別情報は,値を調べることによって決定できないし,値のクラス型を知ることによっ

てさえも決定できない。値の型識別情報は,その値がロードされる格納域の格納域識別情報(8.6.1.2 参照)

から,又はそれを計算する演算から,導出される。通常,値の型識別情報は,その値がロードされる格納

域の格納域識別情報の型になる。

注記  この根拠は次のとおりである。“定数”のようなある制約は値の制約であって格納域の制約では

ないから,型識別情報と格納域識別情報との違いが設けられている。この規格の将来の版又は

規格外の拡張で,型制約を導入可能だが,この場合には,この違いが意味をもつ。

8.6.1.2 

格納域識別情報 

すべての格納域は型をもっている。これは,すべての格納域は格納域識別情報をもつことを意味する。

格納域識別情報は,格納域,その使用法及びその格納域に格納された値の使用法についての制約を定義す

る。有効な型識別情報は,有効な格納域識別情報になる。したがって,格納域識別情報は,型を含み,追

加的に定数制約を含むことができる。格納域識別情報は,格納域の使用に更なる制限を与える格納域制約

を含むことができる。格納域制約は,次による。

−  初期化値不変制約は,格納域が一度初期化されたらその内容は決して変化しないことを約束(すなわ

ち,要求)する。すなわち,内容はあらゆるアクセスの前に初期化され,初期化の後ではいかなる値

もその格納域には格納できない。内容は,常に初期化値(8.2.3 参照)に同一とする。この制約は,論

理的にはあらゆる格納域に適用可能だが,複合型の(静的又はインスタンス)フィールドだけに課さ

れなければならない。

−  リテラル制約は,格納域の値が実際には組込み型の固定された値になっていることを取り決める。そ

の値は,制約の一部として指定される。コンパイラには,その格納域へのすべての参照をその値に置

き換えることが要求され,その結果,VES は,その格納域のために空き領域を割り当てる必要はない。

この制約は,論理的にはあらゆる格納域に適用可能だが,複合型の静的フィールドだけに課されなけ

ればならない。そのように印付けられたフィールドは,CIL から参照されてはならない(すなわち,

そのフィールドは,コンパイル時にその定数値にインライン展開されなければならない。

)が,自己反

映及びメタデータを直接に扱うツールを用いて利用されてもよい。

CLS

規則 13  リテラルであって静的な値は,フィールド初期化メタデータ(第 章参照)を用いて指定

される。CLS 合致のリテラルは,そのリテラルと厳密に同じ型(又はそのリテラルが enum である場合は

基礎となる型)のフィールド初期化メタデータで指定される値をもたなければならない。

注記   

CLS

(使用側)  静的なリテラルフィールドのためのフィールド初期化メタデータを読み,参

照されたときには指定された値をインライン展開できなければならない。使用側は,フィール

ド初期化メタデータの型がリテラルフィールドの型と厳密に同じと想定できる。すなわち,使

用側のツールは,値の変換を実装する必要はない。

CLS

(拡張側)  フィールド初期化メタデータの型がそのフィールドの型と厳密に一致しない

場合の静的なリテラルフィールドのフィールド初期化メタデータを生成することは避けなけれ

ばならない。

CLS

(フレームワーク)  値の変換を要求するリテラルの値を指定する構文の使用は避けるこ

とが望ましい。コンパイラは,フィールド初期化メタデータに固執せずに,CLS 合致のフレー

ムワークを生じるようにそれ自体で変換を実行できることに注意する。ただし,フレームワー


33

X 3016

:2010 (ISO/IEC 23271:2006)

クは,そのような暗黙的な変換に依存しないことが望ましい。 

注記  格納域に格納された値がアクセスの間にキャッシュされないことを要求するために,格納域に

揮発性制約を与えるのは,もっともらしく思えるかもしれない。それをする代わりに,CIL は,

値がキャッシュされないし,既存のキャッシュを用いて計算もされないことを指定するために,

ある命令に volatile.  接頭辞を含めている。このような制約は,カスタム属性(9.7 参照)を用い

て符号化してもよいが,この規格は,そのような属性を規定しない。

8.6.1.3 

局所識別情報 

局所識別情報は,メソッドの実行中に割り付けられた局所変数に関する契約を指定する。局所識別情報

は,格納域識別情報を完全に含み,それに加えて,次の一つの追加の制約を指定できる。

byref 制約は,対応する格納域の内容が管理下ポインタであることを示す。管理下ポインタは,局所変数,

仮引数,複合型のフィールド又は配列の要素を指せる。しかし,呼出しが遠隔境界(12.5 参照)にまたが

っている場合,規格適合処理系は,管理下ポインタの代わりにコピー取込み及びコピー取出しの機構(ポ

インタの先の値を実際にコピーして受け渡す機構)をも使用できる。したがって,プログラムは,真のポ

インタの別名的な振る舞い,その名前から類推される振る舞い,に依存してはならない。

さらに,一つの特殊な局所識別情報が存在する。型付けされた参照の局所変数識別情報は,その局所変

数が,格納域への管理下ポインタ及びその格納域に格納されてもよい型の実行時表現を含むことを示す。

型付けされた参照識別情報は,byref 制約と類似しているが,byref が型を byref 制約の一部として(すなわ

ち,静的に型記述の一部として)指定するのに対し,型付けされた参照は,動的に型情報を提供する。型

付けされた参照は,それ自体で完全な識別情報であって,他の制約と結合することはできない。特に,そ

れは,型が型付けされた参照になっている byref を指定できない。

型付けされた参照識別情報は,実際には,整数型及び浮動小数点数型と同様に,組込みの値型として表

現される。その型は,基本クラスライブラリ(

第 章参照)では,System.TypedReference として知

られ,

第 章のアセンブリ言語では,キーワード typedref によって示される。この型は,仮引数及び局所

変数についてだけ使用しなければならない。ボックス化したり,フィールド,配列の要素又は返却値の型

として用いてはならない。

CLS

規則 14  型付けされた参照は,CLS 合致ではない。

注記   

CLS

(使用側)  この型を受諾する必要はない。

CLS

(拡張側)  この型を定義する構文を提供したり,この型を使用するインタフェース又は

クラスを拡張したりする必要はない。

CLS

(フレームワーク)  この型は,移出しているメンバの中に出現してはならない。 

8.6.1.4 

仮引数識別情報 

仮引数識別情報は,個々の値がメソッド呼出しの一部としてどのように渡されるかの制約を定義する。

仮引数識別情報は,メソッド定義によって宣言される。有効な局所識別情報は,有効な仮引数識別情報と

する。

8.6.1.5 

メソッド識別情報 

メソッド識別情報は,次からなる。

−  呼出し規約。


34

X 3016

:2010 (ISO/IEC 23271:2006)

   

−  メソッドが総称的な場合,総称仮引数の個数。

−  メソッドの各仮引数に対して一つずつの,0 個以上の仮引数識別情報の並び。

−  返却値が生成される場合には,返却値のための型識別情報。

メソッド識別情報は,メソッド定義によって宣言される。次のただ一つの制約だけが,仮引数識別情報

の制約に加えてメソッド識別情報に追加できる。

− vararg 制約を,対応する位置より後にあるすべての実引数が省略可能であることを示すために,含め

ることができる。これが出現する場合,呼出し規約は,可変長の実引数並びを提供するものでなけれ

ばならない。

メソッド識別情報は,二つの異なる方法で,すなわち,メソッド定義の一部として,及び関数ポインタ

を通じて呼び出される場合の呼出し側の記述として,使用する。後者の場合,メソッド識別情報は次を示

す。

−  呼出し規約。これは,プラットフォーム固有の呼出し規約を含むことができる。

−  渡されるすべての実引数値の型。

−  必要な場合,固定数の仮引数並びの終了,及び可変数の仮引数並びの開始の格納域を示す vararg 標示

子。

vararg 制約は,それがメソッド定義の一部として使用される場合,呼出し規約の選択によって表現され

る。

CLS

規則 15  vararg 制約は CLS の一部ではなく,CLS が提供する呼出し規約だけを標準の管理下呼出

し規約とする。

注記   

CLS

(使用側)  可変数の実引数並び又は管理外呼出し規約をもつメソッドを受け入れる必要

はない。

CLS

(拡張側) vararg(をもつ)メソッド又は管理外呼出し規約を宣言する構文を提供する

必要はない。

CLS

(フレームワーク) vararg(をもつ)メソッドも,管理外呼出し規約をもつメソッドも,

明示的に移出してはならない。 

8.7 

代入互換性 

代入互換性は,

(型識別情報によって静的に示される)値 V を(格納域識別情報によって示される)格

納域 L に格納する能力を表し,L := V と簡略表記する。

V についての型識別情報は静的に記述されるから,

実際には,V は,その識別情報が記述する型の値ではないかもしれず,むしろ,その型と互換なものかも

しれない。格納域又は値は,型 System.Void をもっていてはならない。

代入互換性の正式な規定は,

第 章に示す。そこでは,型互換性の正当性検証として参照されている。

本質的には,値 V は,それが次の条件の一つを満たす場合に,格納域 L と代入互換とする。

−  V の型識別情報によって参照される厳密な静的な型が,その格納域識別情報の厳密な型と一致する。

−  V が総称型識別情報 G<U1,...,Un>によって記述され,L が総称型識別情報 H<T1,…,Tn>によって記述さ

れる場合,G=H であって,かつ,G の各総称仮引数 Ui の共変反変の注記を var_i としたときに,次

のことがいえる場合及びその場合に限り,V は L と代入互換とする。

−  var_i = none,すなわち,Ti が値型のとき又は Ti が総称仮引数のとき,Ui は,Ti と同じ厳密な型で

ある。


35

X 3016

:2010 (ISO/IEC 23271:2006)

−  var_i = +  のとき,Ti := Ui である(すなわち,共変のとき,Ui のインスタンスは,型 Ti の格納域に

格納できる。

− var_i

=

- のとき,Ui := Ti である(すなわち,反変のとき,Ti のインスタンスは,型 Ui の格納域に

格納できる。

−  V が型識別情報 U[]によって記述され,L が格納域識別情報 T[]によって記述されるとした場合,T 及

び U が参照型又はインタフェースのいずれかであり,T := U であって,その配列型が両方ともベクト

ル(添字が 0 から始まり次元数が 1)か又は両方ともベクトルでなく同じ階数をもつ場合及びその場

合に限り,V は L と代入互換とする。

注記  これは,配列型が共変であることを意味する。

−  型識別情報 U[]によって記述される V は,System.Collections.Generic.IList<U>と代入互換

であって,B が U によって提供される型の集合である場合には,

System.Collections.Generic.IList<B>

とも代入互換とする。

−  V の型識別情報が,列挙型であって,L の型識別情報が,その列挙型の基礎となる型とする。

−  V の型識別情報が,符号付き整数への byref(8.6.1.3 参照)であって,L の格納域識別情報が,同じ大

きさの符号なし整数への byref である場合,又はその逆の場合。例えば,int32& := uint32&。

−  V の型識別情報が int32 であって,L の格納域識別情報が bool である場合。

注記 CLI スタックは,たとえ,short の整数がプッシュされても,int32 だけを追跡する。第 3

章を参照する。

−  V の厳密な型が提供する型の一つが,L の型と代入互換である場合。これによって,例えば,基底ク

ラスから継承された(すなわち,基底クラスの型制約を提供する)クラスのインスタンスを,型が基

底クラスの型である格納域に格納できる。

注記  格納域制約は,ちょうど,型制約及び二つの追加的な可能な制約(リテラル及び定数)にな

っていることを思い出してほしい。つまり,格納域制約は自然な方法で型制約に変換できる。

この規則の集合のもとで,代入互換性の推移性は維持される。つまり,L:=V であり,M:=L であれば,

M:=V とする。

−  符合付き及び符号なしの整数の基礎的な型は,互いに代入できる。例えば,int8 := uint8 は正当

とする。このためには,bool は uint8 と代入互換でなければならず,その逆もそうであるとする。

つまり,bool := uint8 及びその逆の代入は正当になる。これは,同じ大きさの符号付き及び符号

なしの整数の基礎的な型の配列に対しても正しい。例えば,int32[] := uint32[]は正当とする。

8.8 

型安全及び正当性検証 

型は契約を指定するから,与えられた実装がこれらの契約に従っているかどうかを知ることが重要にな

る。契約の強制可能部分(名前を付けられた識別情報)に従う実装は,型安全という。契約の重要な部分

は,名前をメモリの中の実装及び格納域へ対応付けることだけでなく,名前をもつ項目の可視性及びアク

セス可能性に関する制限を扱う。

型安全な実装は,格納域の格納域識別情報と代入互換(8.7 参照)である格納域の型識別情報が示す値だ

けを格納する(8.6.1 参照)

。型安全な実装は,決して,値の厳密な型が定義しない値に演算を適用しない。

型安全な実装は,その実装に対して可視であってアクセス可能でもある格納域だけにアクセスする。型安

全な実装では,値の厳密な型は変化しない。

正当性検証は,実装を調べ,それが型安全であると表明する機械的な処理とする。正当性検証は,その

処理が,実装が型安全であることを証明する場合,成功したという。正当性検証は,その処理が,実装の


36

X 3016

:2010 (ISO/IEC 23271:2006)

   

型安全性を証明しない場合,失敗したという。正当性検証は,必然的に保守的になる。型安全な実装に対

して失敗を報告できる。しかし,型安全でない実装に対して成功を報告してはならない。例えば,ほとん

どの正当性検証処理は,ポインタに基づく算術計算(ポインタ自体の算術計算)を行う実装を,たとえ,

その実装が実際には型安全であっても,正当性検証失敗として報告する。

正当性検証の基礎とすることが可能な多くの異なる処理がある。最も簡単な処理は,すべての実装は型

安全でないとするものである。これは(論理的には)正しいし効率的だが,明らかに実用的には役に立た

ない。処理は,より多くの資源(時間及びメモリ)を費やすことによって,より多くの型安全な実装を正

しく識別できる。しかし,有限時間で誤りなく,すべての実装を型安全かそうでないか正しく識別する機

械的な処理は,存在不可能なことが証明されている。したがって,特定の正当性検証処理の選択は,決定

のために利用可能な資源と,異なるプログラム構成要素の型安全を検出することの重要性とに基づいた,

技術的な問題になる。

8.9 

型定義側 

型定義側は,既存の型から新しい型を構成する。暗黙的な型(例えば,組込み型,配列,関数ポインタ

を含むポインタなど)は,使用されるときに定義される。識別情報での暗黙的な型の記述は,それ自体で,

その型の完全な定義になる。暗黙的な型は,VES が,メンバ,インタフェースなどの標準的な集合をもつ

インスタンスを作り出すことを可能にする。暗黙的な型は,利用者が提供する名前を必要としない。

その他のすべての型は,明示的な型の定義を用いて明示的に定義されなければならない。明示的な型定

義側は,次による。

−  インタフェース定義  インタフェース型を定義するために使用する。

−  クラス定義  次のいずれかでありうるクラス型を定義するために使用する。

−  (委譲を含む)オブジェクト型

−  値型及びそれの関連するボックス化型

注記  クラス定義は常にクラス型を定義するが,すべてのクラス型がクラス定義を要求するわけでは

ない。暗黙的に定義される配列型及びポインタ型も,クラス型である(8.2.3 参照)

同様に,クラス定義が定義するすべての型が,オブジェクト型になるわけではない。配列型,

明示的に定義されたオブジェクト型及びボックス化型は,オブジェクト型である。ポインタ型,

関数ポインタ型及び値型は,オブジェクト型ではない(8.2.3 参照)

クラス定義,インタフェース定義及び値型定義は,総称型定義として知られる機能であって,

(型の)仮

引数をもつことができる。すなわち,クラス型,インタフェース型又は値型の定義は,総称仮引数を含む

ことができる。使用されるときには,総称クラス型,総称インタフェース型又は総称値型に特定のインス

タンス化が行われる。このとき,総称仮引数は,特定の総称実引数に束縛される。総称仮引数に制約を与

えることができる。その結果,これら制約に一致する総称実引数だけが,インスタンス化で使用できる。

8.9.1 

配列型 

配列型は,配列の要素型,配列の次元数,並びに配列の各次元の上限及び下限(限界)を指定すること

によって定義しなければならない。その結果,配列型のこれとは異なる定義は必要ない。

(配列への添字子

と同様に)限界は,符号付き整数でなければならない。各次元の実際の限界は実行時にだけ分かるが,識

別情報が,

[例えば,限界なし,下限(値)

,上限及び下限の両方(の値)といった]コンパイル時に分か

る情報を指定できる。

配列要素は,列を主とする(優先する)順番で,配列オブジェクト内に配置されなければならない。す

なわち,最右配列次元と関連付けられた要素が,最小の添字から最大の添字へと連続的に配置されなけれ


37

X 3016

:2010 (ISO/IEC 23271:2006)

ばならない。

各配列要素に割り付けられる実際の格納域は,

プラットフォーム固有の詰物を含んでもよい。

この格納域のバイト単位での大きさが,sizeof 命令によって,それがその配列要素の型に適用されたと

きに,返される。

配列型の値は,オブジェクトとする。そこで,配列型は,オブジェクト型の一種になる(8.2.3 参照)

配列オブジェクトは,CTS によって,配列の要素型の値を格納した格納域の繰返しと定義される。繰り返

される値の個数は,配列の次元数及び限界によって決定される。

格納域識別情報ではなく型識別情報だけが,配列の要素型として許される。

厳密な配列型は,それが要求されたときに,VES によって自動的に生成される。そして,配列型の演算

は,CTS によって定義される。これらは,一般的には,大きさ及び下限の情報に基づいて配列を割り付け

ること,値の読み書きのために配列に添字指定すること,配列の要素のアドレス(管理下ポインタ)を計

算すること,並びに配列に格納された値の次元数,限界及び総数を問い合わせることである。

さらに,要素型 T をもつ生成されたベクトルは,インタフェース

System.Collections.Generic.IList<U>

8.7 参照)を実装する。ただし,U := T とする。

CLS

規則 16  配列は,CLS 合致の型をもつ要素をもち,配列のすべての次元は,0 の下限をもたなけれ

ばならない。項目が配列であるという事実及び配列の要素型だけが,多重定義を区別する目的で必要とな

る。多重定義が二つ以上の配列型に基づいている場合,要素型は名前付きの型でなければならない。

注記  いわゆる“非く(矩)形配列”は,CLS 合致とする。しかし,複数の配列型を多重定義する場

合,それらは,型 Sytem.Array の 1 次元で添字が 0 から始まる配列とする。

CLS

(使用側)  System.Array のインスタンスを扱う場合であっても,非 CLS の型の配列

を扱える必要はない。多重定義の解決には,配列型の完全な複雑さを意識する必要はない。プ

ログラマは,配列型の全範囲についての言語構文が存在しない場合には,System.Array のイ

ンスタンス上の Get メソッド,Set メソッド及び Address メソッドへのアクセスをもつこと

が望ましい。

CLS

(拡張側)  配列の非 CLS の型を定義するための構文,又は非 CLS の配列型を使うイン

タフェース若しくはクラスを拡張するための構文を提供する必要はない。型 System.Array

へのアクセスを提供しなければならないが,すべてのインスタンスが CLS 合致の型をもつと想

定してよい。配列の仮引数をもつ継承されたメソッドを上書きするためには完全な識別情報を

使用しなければならないが,配列型の完全な複雑さをプログラマに見せる必要はない。プログ

ラマは,配列型の全範囲についての言語構文が存在しない場合には,System.Array のインス

タンス上の Get メソッド,Set メソッド及び Address メソッドへのアクセスをもつことが望

ましい。

CLS

(フレームワーク)  非 CLS の配列型が,移出されているメンバの中に現れてはならな

い。可能な場合には,1 次で,添字が 0 から始まる単純な名前付きの型の配列だけを使用しな

ければならない。これは,これらの配列が広範囲のプログラム言語で提供されていることによ

る。配列型の多重定義は,避けることが望ましく,使用する場合には,ここで示した制限に従

わなければならない。プログラマは,配列型の全範囲についての言語構文が存在しない場合に

は,System.Array のインスタンス上の Get メソッド,Set メソッド及び Address メソッド

へのアクセスをもつことが望ましい。 

配列型は,すべての配列型が型 System.Array から継承されているという階層をなす。これは,その


38

X 3016

:2010 (ISO/IEC 23271:2006)

   

要素の型,次元数,又は上限及び下限にかかわらず,すべての配列を表現する抽象クラス(8.9.6.2 参照)

といえる。VES は,それぞれの区別可能な配列型に対して一つの配列型を生成する。一般に,配列型は,

その要素の型及び次元数によってだけ区別できる。しかし,VES は,1 次元で,添字が 0 から始まる配列

(ベクトルとしても知られているもの)を特殊なものとして取り扱う。ベクトルもその要素の型によって

区別されるが,ベクトルは,0 でない下限をもつ同じ要素型の 1 次元配列とは区別される。0 次元の配列は

提供されない。

第 章で示されるとおりの CIL 構文を用いて,表 に例を示す。

表 2−配列の例 

型の静的な規定 

構成される実際の型 CLS で許されるかどうか 

int32[]

int32 のベクトル

許される

int32[0..5]

int32 のベクトル

許される

int32[1..5]

int32 の次元数 1 の配列

許されない

int32[

,]

int32 の次元数 2 の配列

許される

int32[0..3, 0..5]

int32 の次元数 2 の配列

許される

int32[0.., 0..]

int32 の次元数 2 の配列

許される

int32[1.., 0..]

int32 の次元数 2 の配列

許されない

8.9.2 

管理外ポインタ型 

管理外ポインタ型(単に“ポインタ型”としても知られる。

)は,そのポインタが参照する格納域のため

の格納域識別情報を指定することによって定義される。ポインタ型のあらゆる識別情報は,この格納域識

別情報を含む。だから,ポインタ型の個別の定義は必要ない。

ポインタ型は参照型だが,ポインタ型の値はオブジェクトではない(8.2.3 参照)

。だから,ポインタ型

の値を与えて,その厳密な型を決定することはできない。CTS は,ポインタ型に関して二つの型安全な演

算を提供する。一つは,ポインタが参照する格納域から値をロードする演算であって,もう一つは,その

格納域に代入互換な値を格納する演算とする。CTS は,ポインタ型に関して三つの演算,バイトに基づく

アドレスの算術計算を行う三つの演算も提供する。すなわち,ポインタに整数を加算すること,ポインタ

から整数を減算すること及び一つのポインタからもう一つのポインタを減算することである。最初の二つ

の演算の結果は,元のポインタと同じ型識別情報へのポインタとなる(

第 章参照)。

CLS

規則 17  管理外ポインタ型は,CLS 合致ではない。

注記   

CLS

(使用側)  管理外ポインタ型を使えるようにする必要はない。

CLS

(拡張側)  管理外ポインタ型を定義したりアクセスしたりする構文を提供する必要はな

い。

CLS

(フレームワーク)  管理外ポインタ型を外部に移出してはならない。 

8.9.3 

委譲 

委譲は,オブジェクト指向において,関数ポインタに相当するものである。関数ポインタとは違い,委

譲は,オブジェクト指向であって,型安全で,安全(secure)である。委譲は,基底型 System.Delegate

から派生するクラスを定義することによって生成される(

第 章参照)。それぞれの委譲型は,適切な仮

引数をもつ Invoke という名前のメソッドを提供しなければならず,

委譲の各インスタンスは,

その Invoke


39

X 3016

:2010 (ISO/IEC 23271:2006)

メソッドへの呼出しを特定のオブジェクト上の一つ以上の互換な静的メソッド又はインスタンスメソッド

に転送する。委譲インスタンスが委譲するオブジェクト及びメソッドは,委譲インスタンスが生成された

ときに選ばれる。

インスタンス構築子及び Invoke メソッドに加えて,委譲は,任意選択で,二つの付加的なメソッド

BeginInvoke

及び EndInvoke をもつことができる。これらは,非同期呼出しのために使用する。

大部分の場合,委譲は,単にある種の利用者定義クラスとして出現するが,しっかりと制御されている。

メソッドの実装は,利用者コードではなく VES によって提供される。委譲型で定義できる追加的なメンバ

は,静的メソッド又はインスタンスメソッドだけとする。

8.9.4 

インタフェース型定義 

インタフェース定義は,インタフェース型を定義する。インタフェース型は,同じ名前のインタフェー

ス契約をもつオブジェクト型によって実装されなければならないメソッド,格納域及び他の契約の名前付

きグループとする。インタフェース型は,常に,値の不完全な記述であって,クラス型又は厳密な型を定

義できないし,オブジェクト型にもなれない。

0 個以上のオブジェクト型が一つのインタフェース型をもつことができ,オブジェクト型だけがインタ

フェース型をもつことができる。インタフェース型は,それをもつオブジェクト型が他の(指定された)

インタフェース型ももたなければならないと要求できる。名前付きインタフェース契約をもつオブジェク

ト型は,そのインタフェース型によって指定された(しかし実装はされていない)メソッド,格納域及び

他の契約の完全な実装を与えなければならない。その結果,オブジェクト型の値は,そのオブジェクト型

がもつすべてのインタフェース型の値にもなっている。インタフェース契約の提供は,宣言されるが推論

はされない。すなわち,インタフェース型が要求するメソッド,格納域及び他の契約の実装の存在は,イ

ンタフェース契約の提供を意味しない。

CLS

規則 18  CLS 合致のインタフェースは,それを実装するために CLS 合致でないメソッドの定義を

要求してはならない。

注記   

CLS

(使用側)  そのようなインタフェースを扱う必要はない。

CLS

(拡張側)  そのようなインタフェースを扱うための機構を提供する必要はない。

CLS

(フレームワーク)  外部使用のために定義されたインタフェース上の CLS 合致でない

メソッドを開示してはならない。 

インタフェース型は,インタフェース型の値の表現について何も示していないから,必ず,不完全にな

っている。この理由によって,インタフェース型は,静的フィールドを宣言できるが,そのインタフェー

ス型の値のためのフィールド定義(すなわち,インスタンスフィールド)を提供してはならない(8.4.3 

照)

同様に,インタフェース型定義は,その型の値に関するメソッドのための実装を提供してはならない。

しかし,インタフェース型定義は,提供している型によって実装されなければならないメソッド契約(メ

ソッド名及びメソッド識別情報)を定義できるし,通常は定義する。静的メソッド(8.4.3 参照)はインタ

フェース型の値にではなくてその型それ自体と関連しているから,インタフェース型定義は,静的メソッ

ドを定義し実装できる。

インタフェースは,静的メソッド又は仮想メソッドをもつことができるが,インスタンスメソッドをも

ってはならない。


40

X 3016

:2010 (ISO/IEC 23271:2006)

   

CLS

規則 19  CLS 合致のインタフェースは,静的メソッドを定義してはならないし,フィールドを定

義してもならない。

注記 CLS 合致インタフェースは,特性,イベント及び仮想メソッドを定義できる。

CLS

(使用側)  これらの規則に違反するインタフェースを受け入れる必要はない。

CLS

(拡張側)  これらの規則に違反するインタフェースを編集する構文を提供する必要は

ない。

CLS

(フレームワーク)  これらの規則に違反するインタフェースを外部に開示してはならな

い。静的メソッド,インスタンスメソッド又はフィールドが要求される場合,それらを提供す

る別々のクラスを定義できる。

インタフェース型は,そのインタフェースを提供するオブジェクト型によって実装されなければならな

いイベント契約及び特性契約も定義できる。イベント契約及び特性契約はメソッド契約の集合に還元され

る(8.6 参照)から,メソッド定義のための規則が適用される。更なる情報については,8.11.3 及び 8.11.4

を参照。

インタフェース型定義は,そのインタフェース型の実装が提供することを要求される他のインタフェー

ス契約を指定できる。固有の問題については,8.9.11 を参照。

インタフェース型は,8.5.3 で示したとおり,そのインタフェース型が参照可能な場所を制御する可視性

属性を与えられている。インタフェース型定義は,そのインタフェース型を提供するオブジェクト型定義

とは分離されている。その結果,インタフェース型及びそれを実装するオブジェクト型に対して異なる可

視性をもつことが可能になっており,それが望ましいことが多い。しかし,アクセス可能性属性はインタ

フェースそれ自体よりも実装の型に関係しているから,インタフェースのすべてのメンバは,公開のアク

セス可能性をもたなければならず,セキュリティ許可をそのメンバ又はインタフェースそれ自体に添付す

ることはできない。

8.9.5 

クラス型定義 

インタフェース以外のすべての型であって,CTS が自動的に定義を供給する型は,クラス定義によって

定義される。クラス型は,そのクラス型の値の表現及びそのクラス型が提供する契約(クラス,インタフ

ェース,メソッド,特性及びイベント)の完全な規定とする。その結果,クラス型は厳密な型になる。ク

ラス定義における,そのクラスが抽象クラス型であると指定している場合を除いて,そのクラス型を定義

するだけでなく,そのクラス型が提供する契約すべてのための実装も提供する。

クラス定義及びそのクラス型の実装は,常に,あるアセンブリの中に存在する。アセンブリは,ロード

可能なコードモジュールと,一緒に機能単位を実装する他の資源とから構成された集合とする。

注記  クラス定義は常にクラス型を定義するが,すべてのクラス型がクラス定義を要求するわけでは

ない。配列型及びポインタ型は,暗黙的に定義されるが,それらもクラス型になる(8.2.3 参照)

明示的クラス定義は,次を定義するために使用する。

−  オブジェクト型(8.2.3 参照)

−  値型及びその関連ボックス化型(8.2.4 参照)

明示的クラス定義は,次を行う。

−  クラス型に名前を付ける。

−  暗黙的にそのクラス型名に一つの有効範囲,すなわち,そのクラス定義を含むアセンブリを割り当て

る(8.5.2 参照)


41

X 3016

:2010 (ISO/IEC 23271:2006)

−  同じ名前のクラス契約を定義する(8.6 参照)

−  フィールド,メソッド,特性及びイベントのためのメンバ定義を用いて,そのクラス型のすべての値

の表現及び妥当な演算を定義する(8.11 参照)

−  クラス型の静的メンバを定義する(8.11 参照)

−  そのクラスが提供する他のインタフェース契約及びクラス契約を指定する。

−  そのクラス型が提供するメンバ契約及びインタフェース契約のための実装を供給する。

−  型の可視性を明示的に公開又はアセンブリのいずれかと宣言する(8.5.3 参照)

−  任意選択で,型を初期化するために呼び出される(.cctor と呼ばれる)メソッドを指定できる。

このような型初期化の実行がいつ引き起こされるのか及び何が引き起こすかの意味は,次による。

1)

型は,型初期化子メソッドをもつことができるし,もたなくてもよい。

2)

型は,その型初期化子メソッドのために緩和された意味をもつと指定できる(次では,便宜のため

に,この緩和された意味を BeforeFieldInit と呼ぶ。

3) BeforeFieldInit

と印付けされている場合,型の初期化子メソッドは,その型のために定義された静的

フィールドへの最初のアクセスの時点又はその前のある時点で実行される。

4) BeforeFieldInit

と印付けされていない場合,型の初期化子メソッドは,次の時点で実行される(すな

わち,次の時点までに引き起こされる。

−  その型の静的フィールドへの最初のアクセス。

−  その型の静的メソッドの最初の呼出し。

−  その型のあらゆる構築子の最初の呼出し。

5)

型の初期化子メソッドの実行は,その基底型が定義する初期化子メソッドの自動的な実行を引き起

こさないし,その型が実装するインタフェースの自動的な実行をも引き起こさない。

参照型については,構築子が,null でないインスタンスを生成するために呼び出されなければならない。

そこで,参照型では,null でないインスタンス上でインスタンスフィールドがアクセスでき,メソッドが

呼び出せる前に,.cctor が,呼び出される。値型については,構築子なしに“すべて 0”のインスタンスが

生成できる(ただし,この値だけが構築子なしで生成できる。

。そこで,値型では,

“すべて 0”ではない

値型のインスタンスに対してだけ,.cctor が呼び出されることを保証する。

注記 1  このことは,“this”実引数が null である場合,インスタンスメソッドが呼び出される前

に.cctor が呼び出されないかもしれないという点で,この規格の第 1 版から,参照クラスであ

る場合の意味を少し変更する。クラス構築子を回避するという付加的な性能向上が,この変

更を裏付ける。

注記 2 BeforeFieldInit の振る舞いは,興味深い副作用を伴わない初期化コードのために意図されてい

る。この場合,

(実行の)厳密なタイミングは問題ではない。BeforeFieldInit の意味のもとで

は,型初期化子は,その型の静的フィールドへの最初のアクセス時又はその前に実行されて

よい。実行の時点は,CLI の裁量による。

(プログラム)言語がより厳密な振る舞いを提供することを望む場合,例えば,型の初期

化が自動的に基底クラスの初期化子の実行を,最上位から最下部へという順番で,引き起こ

すなどを望む場合,言語は,次のいずれかによってそれを行うことができる。

−  それぞれのクラスの基底クラス及び/又はそのクラスが実装するインタフェースの隠ぺい

された静的フィールドにアクセスする,隠ぺいされた静的フィールド及びコードを,その

クラスの構築子の中に定義すること。


42

X 3016

:2010 (ISO/IEC 23271:2006)

   

− System.Runtime.CompilerServices.Runtime-Helpers.RunClassConstructor

に対して明示的な呼出しを行うこと(

第 章参照)。

8.9.6 

オブジェクト型定義 

すべてのオブジェクトは,オブジェクト型のインスタンスとする。オブジェクトのオブジェクト型は,

オブジェクトが生成されたときに設定され,不変とする。オブジェクト型は,インスタンスの物理的構造

及びその上で許される演算を記述する。同じオブジェクト型のすべてのインスタンスは,同じ構造及び同

じ使用可能な演算をもつ。オブジェクト型は,配列型を除いて,クラス型定義によって明示的に宣言され

る。配列型は,本来的に VES によって提供される。

8.9.6.1 

有効範囲及び可視性 

オブジェクト型定義は,クラス型定義なので,オブジェクト型の名前の有効範囲を暗黙的にそのオブジ

ェクト型定義を含むアセンブリと指定する(8.5.2 参照)

。同様に,オブジェクト型定義は,オブジェクト

型の可視性の属性(公開又はアセンブリのいずれか)も明示的に示さなければならない(8.5.3 参照)

8.9.6.2 

具象性 

オブジェクト型は,オブジェクト型定義によって abstract と印付けできる。abstract と印付けられていな

い(抽象ではない)オブジェクト型は,定義によって具象的(concrete)となる。オブジェクト型だけが抽

象と宣言できる。抽象オブジェクト型だけが,型又は VES が実装を提供しないメソッド契約を定義するこ

とを許される。このようなメソッド契約を抽象メソッドという(8.11 参照)

。抽象クラスのすべてのメソッ

ドが抽象である必要はない。

型が抽象メソッドをもつかどうかに関係なく,抽象オブジェクト型のインスタンスを生成しようとする

ことはエラーとする。抽象オブジェクト型から派生するオブジェクト型は,それが,基底オブジェクト型

の中のすべての抽象メソッドのための実装を提供し,それ自体は abstract と印付けられていない場合,

具象とできる。インスタンスは,このような具象派生クラスから構成できる。格納域は抽象型をもつこと

ができ,その抽象型から派生した具象型のインスタンスをその格納域に格納できる。

8.9.6.3 

型メンバ 

オブジェクト型定義は,その型のメンバすべてのためのメンバ定義を含む。簡単にいうと,型のメンバ

は,値が格納されるフィールド,呼び出してよいメソッド,利用可能な特性及び発生可能なイベントを含

む。型の各メンバは,8.4 で示したとおりの属性をもってよい。

−  オブジェクト型のフィールドは,そのオブジェクト型を構成する構成要素の断片を指定することによ

って,オブジェクト型の値の表現を指定する(8.4.1 参照)

。静的フィールドは,オブジェクト型それ

自体と関連するフィールドを指定する(8.4.3 参照)

。オブジェクト型のフィールドは,名前が付けら

れており,格納域識別情報を通じて型付けされている。型のメンバの名前は,その型を有効範囲とし

て与えられる(8.5.2 参照)

。フィールドは,フィールド定義を用いて宣言される(8.11.2 参照)

−  オブジェクト型のメソッドは,その型の値における演算を指定する(8.4.2 参照)

。静的メソッドは,

型それ自体についての演算を指定する(8.4.3 参照)

。メソッドは,名前が付けられており,メソッド

識別情報をもつ。メソッドの名前は,その型を有効範囲として与えられる(8.5.2 参照)

。メソッドは,

メソッド定義を用いて宣言される(8.11.1 参照)

−  オブジェクト型の特性は,値を読むメソッド及び書くメソッドを通じてアクセス可能な名前の付いた

値を指定する。特性の名前は,メソッドをグループ化したものである。メソッドそれ自体も,メソッ

ド識別情報を通じて名前付けされ型付けされている。特性の名前は,その型を有効範囲として与えら

れる(8.5.2 参照)

。特性は,特性定義を用いて宣言される(8.11.3 参照)


43

X 3016

:2010 (ISO/IEC 23271:2006)

−  オブジェクト型のイベントは,アクセス操作子を通じて登録者の関心があることを登録及び/又は登

録解除してよい名前付きの状態遷移を指定する。状態が変化するとき,登録者は状態遷移を通知され

る。イベントの名前は,アクセス操作子メソッドをグループ化したものである。メソッドそれ自体も,

メソッド識別情報を通じて名前付けされ型付けされている。イベントの名前は,その型を有効範囲と

して与えられる(8.5.2 参照)

。イベントは,イベント定義を用いて宣言される(8.11.4 参照)

8.9.6.4 

インタフェース契約の提供 

オブジェクト型定義は,0 個以上のインタフェース契約を提供すると宣言できる。インタフェース契約

についての提供を宣言すると,そのインタフェース契約を完全に実装するオブジェクト型の実装に要件が

課せられる。インタフェース契約を実装することは,常に,メソッドの要求された集合,すなわち,その

インタフェース型が要求するメソッド群を実装することに還元される。

オブジェクト型が実装する異なる型,すなわち,オブジェクト型及び実装されたインタフェース型は,

それぞれ,

名前の付いたメンバの分離した論理グループに分けられる。クラス Foo がインタフェース IFoo

を実装し,Ifoo がメンバメソッド int a()を宣言し,Foo もメンバメソッド int a()を宣言している

場合,二つのメンバ,IFoo インタフェース型の中のメンバ及び Foo クラス型の中のメンバが存在する。

Foo

の実装は,両方の実装を提供し,潜在的に共有する。

同様に,クラスが一つのメソッド int a()を定義する二つのインタフェース IFoo  及び IBar を実装す

る場合,

そのクラスは,

各インタフェースについて一つずつの二つのメソッド実装を提供することになる。

ただし,それらは,実際の実装のコードを共有できる。

CLS

規則 20  CLS 合致のクラス,値型及びインタフェースは,CLS 合致でないメンバの実装を要求し

てはならない。

注記   

CLS

(使用側)  この規則に違反するクラス,値型又はインタフェースを受け入れる必要はな

い。

CLS

(拡張側)  この規則に違反するクラス,値型又はインタフェースを作成する構文を提供

する必要はない。

CLS

(フレームワーク)  この規則に違反するクラス,値型又はインタフェースを外部に開示

してはならない。CLS 合致のフレームワークが CLS 合致ではないインタフェースを実装するク

ラスを開示している場合,そのフレームワークは,すべての CLS 合致ではないメンバの(具象

的な)実装を提供しなければならない。このことは,CLS 拡張側が CLS 合致ではないメンバを

実装するための構文を必要としないことを保証する。

8.9.6.5 

クラス契約の提供 

オブジェクト型定義は,一つの他のクラス契約の提供を宣言できる。他のクラス契約の提供を宣言する

ことは,オブジェクト型の継承と同義とする(8.9.9 参照)

8.9.6.6 

構築子 

オブジェクト型の新しい値は,構築子を通じて生成される。構築子は,メソッド契約の特殊な形式を通

じて定義されるインスタンスメソッドでなければならない。ここで,この特殊な形式は,メソッド契約を

特定のオブジェクト型のための構築子として定義する。オブジェクト型のための構築子は,オブジェクト

型定義の一部とする。CTS 及び VES は,確実に,適正に定義された構築子だけをオブジェクト型の新しい

値を作成するために使用するようにするが,新しく構築されたオブジェクトが完全に正しいかどうかは,


44

X 3016

:2010 (ISO/IEC 23271:2006)

   

構築子自体の実装に依存する。

オブジェクト型は,少なくとも一つの構築子メソッドを定義しなければならないが,そのメソッドは,

公開である必要がない。構築子を呼び出すことによってオブジェクト型の新しい値を生成するには,次の

過程を順番に行う。

1)

新しい値のための空領域を管理下メモリの中に割り付ける。

2)

新しい値の VES データ構造を初期化し,利用者に見えるメモリをゼロクリアする。

3)

オブジェクト型のための指定された構築子を呼び出す。

構築子の内部で,オブジェクト型は,それが選択するいかなる初期化をも行える(何もしないという選

択もできる)

CLS

規則 21  オブジェクト構築子は,継承されたインスタンスデータへのアクセスが発生する前に,そ

の基底クラスのクラス構築子を呼び出さなければならない。これは,値型には適用されない。値型は,構

築子をもつ必要はない。

CLS

規則 22  オブジェクト構築子は,オブジェクトの生成の一部として以外では呼び出されてはならな

いし,一つのオブジェクトは,2 回初期化されてはならない。

注記   

CLS

(使用側)  オブジェクトが生成されるときに呼び出される構築子を選択するための構文

を提供しなければならない。

CLS

(拡張側)  異なる識別情報をもつ構築子メソッドを定義するための構文を提供しなけれ

ばならない。構築子がこれらの規則に従わない場合は,コンパイルエラーを発生してもよい。

CLS

(フレークワーク)  オブジェクト生成は(幾つかの)構築子の一つへの呼出しを含み,

オブジェクトは 2 回は初期化されないと想定できる。System.Object.MemberwiseClone

第 章参照)及び(オブジェクトの遠隔実行を含む)直列化解除は,構築子を実行してはな

らない。 

8.9.6.7 

終了化子 

オブジェクト型を生成するクラス定義は,そのクラスのインスタンスがもはや到達可能ではない場合に

呼び出される(終了化子という)インスタンスメソッドを供給できる。クラス System.GC(

第 章参照)

は,メソッド SuppressFinalize  及びメソッド ReRegisterForFinalize を通じて,終了化子の振る

舞いに制限された制御を提供する。CLI 規格合致実装は,終了化子の振る舞いに影響する追加的な機構を

指定し提供できる。

CLI 規格合致実装は,次の場合を除き,同じオブジェクトに対して終了化子を 2 回自動的に呼び出して

はならない。例外の場合は,次による。

−  (SuppressFinalize への呼出しが後続しない)ReRegisterForFinalize への呼出しが挟み込

まれた場合。

−  プログラムが,この振る舞いの代替となるものを生成するように明示的に指定された実装固有の機構

を呼び出した場合。

注記  この根拠は次のとおりである。プログラマは,終了化子を複数回実行することを引き起こす明

示的な動作をさせない限り,与えられたオブジェクトに関して,終了化子は正確に 1 回実行さ

れることを期待している。

値型に対して終了化子を定義することは正当とする。しかし,その終了化子は,値型のボックス化され


45

X 3016

:2010 (ISO/IEC 23271:2006)

たインスタンスに対してだけ実行される。

注記  プログラマは終了化子が呼び出されることに依存するかもしれないから,CLI は,終了する前

に,SuppressFinalize への呼出しによる終了化をまぬがれていたすべてのオブジェクトに

対して,確実に終了化子が呼び出されるようにあらゆる努力を行うことが望ましい。実装は,

この振る舞いを保証できないあらゆる条件を指定することが望ましい。

注記  終了化子が迅速に呼び出されない場合には資源が枯渇するかもしれないから,CLI は,インス

タンスがアクセス可能でなくなった後すぐに終了化子を確実に呼び出すことが望ましい。終了

化子の呼出しのきっかけをメモリの不足に依存することは受け入れられる方策だが,実装者は,

(きっかけを計る)追加的な測度の使用を考慮したほうがよい。

8.9.7 

値型定義 

クラス定義が定義するすべての型がオブジェクト型というわけではない(8.2.3 参照)

。特に,値型はオ

ブジェクト型ではないが,クラス定義を用いて定義される。値型のためのクラス定義は,

(ボックス化され

ていない)値型及び関連するボックス化型の両方を定義する(8.2.4 参照)

。クラス定義のメンバは,それ

ら両方の表現を定義する。

1)

非静的メソッド(すなわち,インスタンスメソッド又は仮想メソッド)が値型で呼び出される場合,

その this ポインタは,インスタンスへの管理下参照になる。一方,そのメソッドが関連するボック

ス化型で呼び出される場合,this ポインタは,オブジェクト参照になる。

値型のインスタンスメソッドは,ボックス化されていない型への管理下ポインタである this ポイ

ンタを受け取り(その値型が実装するインタフェース上のものも含む)

,仮想メソッドは,ボックス

化された型のインスタンスを受け取る。

2)

値型はインタフェース契約を提供しないが,その関連するボックス化型は提供する。

3)

値型は継承されない。むしろ,クラス定義の中で指定された基底型は,ボックス化型の基底型を定

義する。

4)

ボックス化型の基底型は,フィールドをもってはならない。

5)

オブジェクト型とは違い,値型のインスタンスは,インスタンスが生成されるときに呼び出される

構築子を要求しない。代わりに,正当性検証規則が,正当性検証可能コードがインスタンスを 0 に

(オブジェクトについては null に)初期化することを要求する。

8.9.8 

型の継承 

型の継承は,

派生した型が基底型の型契約のすべての提供を保証することを示すもう一つの方法とする。

さらに,派生した型は,通常,追加的な機能又は特殊化された振る舞いを提供する。型は,基底型の型契

約を実装することによって,基底型から継承される。一つのインタフェース型は,0 個以上の他のインタ

フェースを実装する。値型は継承されない。ただし,関連するボックス化型はオブジェクト型であって,

他の型から継承される。

派生したクラス型は,その基底型の提供するインタフェース契約,クラス契約,イベント契約,メソッ

ド契約及び特性契約のすべてを提供しなければならない。さらに,基底型が定義する格納域のすべては,

派生型でも定義される。継承の規則は,基底型の値を用いて動作するようにコンパイルされたコードが,

派生型の値を渡されたときでも動作することを保証する。このために,派生型は,基底型の実装をも継承

する。派生型は,この実装を拡張,上書き及び/又は隠ぺいできる。

8.9.9 

オブジェクト型の継承 

System.Object

が他のオブジェクト型から継承されないという唯一の例外を除いて,すべてのオブジ


46

X 3016

:2010 (ISO/IEC 23271:2006)

   

ェクト型は,明示的又は暗黙的のいずれかで,ただ一つの他のオブジェクト型を提供する(すなわち,そ

のオブジェクト型から継承される。)と宣言しなければならない。継承関係のグラフは,その基底を

System.Object

とする一つの根をもつ木を形成しなければならない。すなわち,すべてのオブジェクト

型は,結局のところ,型 System.Object から継承される。

総称型の導入によって,正確な定義を与えることがより難しくなる。

第 章を参照。

オブジェクト型は,それを封印された型,すなわち,封印型と宣言することによって,それを基底型と

して用いてはならない(それを継承してはならない)と宣言する。

CLS

規則 23  System.Object は,CLS 合致とする。あらゆる他の CLS 合致クラスは,一つの CLS 合

致クラスから継承されなければならない。 

配列はオブジェクト型であって,それ自体,他のオブジェクト型から継承される。配列オブジェクト型

は VES によって操作されるから,配列の継承は固定される(8.9.1 参照)

8.9.10 

値型の継承 

値型は,そのボックス化されていない形式では,いかなる型からも継承されない。ボックス化された値

型は,それが列挙型でない限り,System.ValueType から直接に継承されなければならない。列挙型で

ある場合には,System.Enum から継承されなければならない。ボックス化された値型は,封印されなけ

ればならない。

論理的に,値型に対応するボックス化型は,次のとおりになる。

−  オブジェクト型である。

−  どのオブジェクト型がその基底型になるかを,

すなわち,

それが継承するオブジェクト型を指定する。

−  フィールドが定義されていない基底型をもつ。

−  値断片化の複雑さの処理を避けるために封印される。

ここでより多くの規則を規定することによって,面倒な妥協的機能を用いることなく,より効率的な実

装が可能になる。

8.9.11 

インタフェース型の継承 

インタフェース型は,一つ以上の他のインタフェース型の実装を要求できる。インタフェース型の提供

を実装する型は,そのインタフェースによって指定されるあらゆる要求されるインタフェースの提供をも

実装しなければならない。これは,オブジェクト型の継承と次の二つの点で異なっている。

−  オブジェクト型は,一つの根をもつ木を構成するが,インタフェース型はそうではない。

−  オブジェクト型の継承は,どのようにして実装が継承されるのかを指定するが,要求されるインタフ

ェース型はそうではない。これは,インタフェースは実装を定義しないことによる。要求されるイン

タフェースは,実装するオブジェクト型が提供しなければならない追加的契約を指定する。

後者の違いを明確にするために,一つのメソッドをもつインタフェース IFoo を考える。それから派生

するインタフェース IBar は,IBar が提供するオブジェクト型が IFoo も提供することを要求している。

IBar

それ自体がどのメソッドをもつかについては何もいっていない。

8.10 

メンバの継承 

オブジェクト型だけが実装を継承できる。したがって,オブジェクト型だけがメンバを継承できる(8.9.8

参照)

。インタフェース型は,他のインタフェース型から派生できるが,メソッド契約を実装するための要

件だけを“継承”し,フィールドもメソッドの実装も継承しない。

8.10.1 

フィールドの継承 


47

X 3016

:2010 (ISO/IEC 23271:2006)

派生オブジェクト型は,

その基底オブジェクト型の静的でないフィールドのすべてを継承する。

これは,

基底型のインスタンスが期待されるいずれの箇所でも,派生型のインスタンスを使用できるようにする。

これらのインスタンスの形状,すなわち,配置が,同じになる。静的フィールドは継承されない。フィー

ルドが存在するという理由だけでは,それを読んだり書いたりできることを意味しない。型の可視性,フ

ィールドのアクセス可能性及びフィールド定義のセキュリティ属性(8.5.3 参照)が,フィールドが派生オ

ブジェクト型に対してアクセス可能かどうかを決定する。

8.10.2 

メソッドの継承 

派生オブジェクト型は,その基底オブジェクト型のインスタンスメソッド及び仮想メソッドのすべてを

継承する。構築子及び静的メソッドは継承しない。メソッドが存在するという理由だけでは,それを呼び

出せることを意味しない。参照しているコードで使われている型付けされた参照を通してアクセス可能と

なる。型の可視性,メソッドのアクセス可能性及びメソッド定義のセキュリティ属性(8.5.3 参照)が,メ

ソッドが派生オブジェクト型に対してアクセス可能かどうかを決定する。

派生オブジェクト型は,同じ名前,又は同じ名前及び同じ識別情報をもつ新しいメソッド定義を提供す

ることによって,その基底型の仮想でないメソッド(すなわち,静的メソッド又はインスタンスメソッド)

を隠ぺいできる。そうであっても,メソッドのアクセス可能性規則に従って,いずれかのメソッドを呼び

出すことができる。これは,メソッドを含む型がメソッド参照を限定することによる。

仮想メソッドは,final(最終)と印付けできる。この場合,それらは,派生オブジェクト型の中で上

書きされてはならない。これによって,メソッドの実装が,最終の実装を供給する基底クラスの契約を提

供するあらゆるオブジェクトで,仮想呼出しによって,確実に利用可能になる。仮想メソッドが最終(final)

でない場合,仮想メソッドを上書きするためにセキュリティ許可を要求することが可能であって,その結

果として,実装を提供する能力を特定の許可をもつクラスに制限できる。派生クラスが仮想メソッドを上

書きする場合,そのクラスは,その仮想メソッドのために新しいアクセス可能性を指定できる。しかし,

派生クラスにおけるアクセス可能性は,少なくとも,そのクラスが上書きしているメソッドに与えられる

アクセスと同じ程度のアクセスを許可しなければならない。8.5.3 を参照。

8.10.3 

特性及びイベントの継承 

基本的に,特性及びイベントは,CLI を目標とするが VES それ自体によって直接には支援されないツー

ルが使用することを意図しているメタデータの構成要素とする。そこで,名前の隠ぺい,継承などのため

の規則を決定するのは,ソース言語コンパイラ及び自己反映ライブラリ(

第 章参照)の仕事とする。ソ

ースコンパイラは,イベント及び特性によって名前を付けられるメソッドに直接にアクセスする CIL を生

成しなければならないが,イベント又は特性を生成してはならない。

8.10.4 

隠ぺい,上書き及び配置 

継承に関連して二つの異なる問題がある。一つめは,型が実装しなければならないのはどの契約か,す

なわち,型が提供しなければならないのはどのメンバ名及び識別情報かという問題である。二つめは,派

生型のインスタンスでその基底型のインスタンスを置換することができるための,インスタンスの配置で

ある。派生型の一部である静的でないフィールド及び仮想メソッドだけが,オブジェクトの配置に影響す

る。

CTS は,基底型から可視な名前と,派生クラスにおける配置スロットの共有との両方に関する独立な制

御を提供する。それら制御のうち,前者が隠ぺい,後者が上書きになる。名前による隠ぺい(hide by name)

又は名前及び識別情報による隠ぺい(hide by name-and-signature)のいずれかと印付けることによって制御

する。隠ぺいは,常に,メンバの種類に基づいて実行される。すなわち,派生フィールド名は,基底フィ


48

X 3016

:2010 (ISO/IEC 23271:2006)

   

ールド名を隠ぺいできるが,メソッド名,特性名及びイベント名を隠ぺいしない。派生メンバが名前によ

る隠ぺいと印付けられる場合,基底クラスの中の同じ名前をもつ同じ種類のメンバは,派生クラスの中で

は可視でない。メンバが名前及び識別情報による隠ぺいと印付けられる場合,フィールドに対しては,同

じ名前であって同じ型をもつ同じ種類のメンバだけが,メソッドに対しては,同じ名前であって同じ識別

情報をもつ同じ種類のメンバだけが,派生クラスから隠ぺいされる。隠ぺいのこれら二つの形式の間の違

いの実装は,完全に,ソース言語コンパイラ及び自己反映ライブラリによって提供される。VES それ自体

には,何ら直接の影響はない。

次に例を示す。

class Base

{  field  int32         A;

  field  System.String  A;

  method  int32         A();

  method  int32         A(int32);

}

class Derived inherits from Base

{  field  int32  A;

  hidebysig method int32 A();

}

型 Derived の中で使用可能なメンバ名を

表 に示す。

表 3−メンバ名 

メンバの種類 

メンバの型又は識別情報 

メンバの名前 

Field int32

A

Method

() -> int32

A

Method

(int32) -> int32

A

隠ぺいは型のすべてのメンバに適用されるが,上書きは,オブジェクトの配置を扱い,インスタンスフ

ィールド及び仮想メソッドだけに適用可能とする。CTS は,メンバ上書きの二つの形式,新規スロット(new

slot)及び既存スロット期待(expect existing slot)を提供する。新規スロットと印付けられた派生型のメン

バは,常に,オブジェクトの配置の中で新規スロットを得て,そのオブジェクトの中で基底型のフィール

ド又はメソッドは,基底型の名前をメンバ及びその型又は識別情報の名前と結合する限定された参照を使

用することによって使用可能になることを保証する。

既存スロット期待と印付けられた派生型のメンバは,

同じ種類(フィールド又はメソッド)

,同じ名前及び同じ型のメンバに対応するスロットを,それが基底型

で既に存在している場合には,再利用(すなわち,共有又は上書き)する。そのようなスロットが存在し

ない場合には,新しいスロットが割り付けられ使用される。

型における名前及び型のオブジェクトの配置を決定するために使用する一般的なアルゴリズムは,おお

よそ,次による。

−  アクセス可能性規則は無視し,

(名前による隠ぺい又は名前及び識別情報による隠ぺいの規則を使っ

て)継承された名前を平たん化する。

−  “既存スロット期待”と印付けられた新しいメンバそれぞれに対して,種類(すなわち,フィールド


49

X 3016

:2010 (ISO/IEC 23271:2006)

又はメソッド)

,名前及び識別情報に関する厳密な一致が存在するかどうかを(すなわち,既存のスロ

ットの存在を)調べ,見つかった場合にはそのスロットを使用し,そうでない場合には新しいスロッ

トを割り付ける。

−  すべての新しいメンバに対してこれを行った後で,これらの新しいメンバ,その種類,名前及び識別

情報をこの型のメンバの一覧に追加する。

−  最後に,名前による隠ぺい又は名前及び識別情報による隠ぺいの規則に基づいて新しいメンバに一致

する継承された名前を取り除く。

8.11 

メンバ定義 

オブジェクト型定義,インタフェース型定義及び値型定義は,メンバ定義を含むことができる。フィー

ルド定義は,値の下位構造を指定することによって型の値の表現を定義する。メソッド定義は,型の値に

関する演算及び型それ自体に関する演算(静的メソッド)を定義する。特性定義及びイベント定義は,オ

ブジェクト型についてだけ定義されなければならない。特性及びイベントは,名前の付いたイベント又は

特性の振る舞いを実装するアクセス操作子メソッド定義の名前の付いたグループを定義する。入れ子にな

った型宣言は,囲む側の型が有効範囲を与える名前をもち,囲む側の型のすべてのメンバへの完全なアク

セスをもつインスタンスを生成する型を定義する。

型定義の種類に依存して,許されるメンバ定義には制限が存在する。

8.11.1 

メソッド定義 

メソッド定義は,名前,メソッド識別情報及び任意選択でメソッドの実装から構成される。メソッド識

別情報は,呼出し規約,メソッドへの仮引数の型及びメソッドの返却値型を定義する(8.6.1 参照)

。実装

は,メソッドが呼び出されたときに実行されるコードとする。値型又はオブジェクト型は,与えられた名

前及び識別情報のただ一つのメソッドを定義しなければならない。しかし,派生オブジェクト型は,その

基底オブジェクト型の同じ名前及び識別情報をもつメソッドをもつことができる

8.10.2 及び 8.10.4 参照)

メソッドの名前の有効範囲は,その型になる(8.5.2 参照)

。メソッドには,アクセス可能性属性を与え

ることができる(8.5.3 参照)

。メソッドは,メソッド識別情報の仮引数型と代入互換な実引数をもつ場合

にだけ呼び出さなければならない。メソッドの返却値も,それが格納される格納域と代入互換でなければ

ならない。

メソッドは,static(静的)と印付けできる。これは,メソッドが型の値の演算ではなくむしろ全体

として型と関連する演算であることを示す。static と印の付いていないメソッドは,型の値の妥当な演

算を定義する。静的ではないメソッドを呼び出す場合,this 又は this ポインタとして参照される型の

特定の値が暗黙の仮引数として渡される。

メソッド実装を含まないメソッド定義は,abstract(抽象)と印付けられなければならない。インタ

フェース定義の静的ではないメソッドは,抽象的とする。抽象メソッド定義は,abstract と印を付けられた

オブジェクト型の中だけで許される。

オブジェクト型における静的ではないメソッドは,virtual(仮想)として印付けできる。これは,派

生型の中で代替の実装が提供できることを示す。インタフェース定義の中のすべての静的ではないメソッ

ド定義は,仮想メソッドでなければならない。仮想メソッドは,final(最終)と印付けできる。これは,

派生オブジェクト型がメソッド実装を上書きすることを許されていないことを示す。

メソッド定義は,総称メソッド定義として知られる機能として,総称仮引数をもつことができる。使用

するときには,総称メソッドの特定のインスタンス化が行われ,その時点で,総称仮引数は特定の総称実

引数に束縛される。総称メソッドは,非総称型のメンバとして定義できるし,総称型のメンバとしても定


50

X 3016

:2010 (ISO/IEC 23271:2006)

   

義できる。しかし,それ自体の型とは異なる総称仮引数(又は仮引数)によって仮引数化されることがあ

る。例えば,Stack<T>クラスは,総称メソッド  S ConvertTo<S> ()  を含むかもしれない。ここで,

総称仮引数 S は,Stack<T>の総称仮引数 T と異なっている。

8.11.2 

フィールド定義 

フィールド定義は,名前及び格納域識別情報から構成される。格納域識別情報は,そのフィールドの型

及びアクセス制約を定義する(8.6.1 参照)

。値型又はオブジェクト型は,与えられた名前及び型のただ一

つのフィールドを定義しなければならない。しかし,派生オブジェクト型は,その基底オブジェクト型と

同じ名前及び型のフィールドをもつことができる(8.10.1 及び 8.10.4 参照)

フィールドの名前の有効範囲は,その型になる(8.5.2 参照)

。フィールドは,アクセス可能性属性を与

えることができる(8.5.3 参照)

。フィールドは,そのフィールドの型と代入互換な値だけを格納しなけれ

ばならない(8.3.1 参照)

フィールドは,static(静的)と印付けできる。これは,フィールドが型の値の一部ではなくむしろ全体

として型と関連する格納域であることを示す。静的フィールドのための格納域は,型がロードされたとき

に生成され,型が初期化されたときに初期化される。

static と印付けられていないフィールドは,値の下位構造を定義することによって型の値の表現を定義す

る(8.4.1 参照)

。そのようなフィールドのための格納域は,新しい値が構築されるときにいつでも,型の

すべての値(インスタンス)の内部に生成される。その格納域は,新しい値の構築中に初期化される。与

えられた名前の静的ではないフィールドは,常に,型のすべての値(インスタンス)の内部の同じ格納域

に位置付けられる。

serializable(直列化可能)と印付けられたフィールドは,型の値の永続的状態の一部として直列化され

ることが望ましい。この規格は,規格適合処理系が直列化(又はその反対の直列化解除)を提供すること

を要求しないし,これらの操作を達成するかもしれない機構を規定しない。

8.11.3 

特性定義 

特性定義は,名前の付いた値及びその値にアクセスするメソッドを定義する。特性定義は,その値に関

するアクセス契約を定義する。したがって,特性定義は,どのアクセスメソッドが存在するか及びそのそ

れぞれのメソッド契約を指定する。特性契約の提供を宣言する型の実装は,その特性契約が要求するアク

セスメソッドを実装しなければならない。アクセスメソッドの実装は,値が取得され格納される方法を定

義する。

特性定義は,常に,インタフェース定義又はクラス定義のいずれかの一部になる。特性定義の名前及び

値の有効範囲は,その特性定義を含む型になる。CTS は,特性を含むメソッド契約が,他のいかなるメソ

ッド契約をもつ場合と同様に,メソッド実装と一致することを要求する。特性と関連する CIL 命令は存在

せず,単にメタデータとする。

規約として,特性は,

(特性の現在の値にアクセスするための)getter メソッド及び任意選択で(特性

の現在の値を修正するための)setter メソッドを定義する。CTS は,特性と関連するメソッドの集合,

それらメソッドの名前,又はその利用法についていかなる制限も課さない。

CLS

規則 24  特性の getter  メソッド及び setter  メソッドを実装するメソッドは,メタデータの中

に SpecialName と印付けられなければならない。

CLS

規則 25  この規則は,もはや使用しない。

注記  この規格の以前の版では,この規則は,“特性及びそのアクセス操作子のアクセス可能性は,同


51

X 3016

:2010 (ISO/IEC 23271:2006)

じでなければならない。”と規定されていた。この規則を取り除くことによって,例えば,

setter

へのアクセスを制限しながら getter へのアクセスを公開できる。

CLS

規則 26  特性のアクセス操作子は,すべて静的,すべて仮想又はすべてインスタンスでなければな

らない。

CLS

規則 27  特性の型は,getter の返却値型でなければならず,setter の最後の実引数の型でなけ

ればならない。特性の仮引数の型は,getter の仮引数の型でなければならず,setter の最後の仮引数

以外のすべての仮引数の型でなければならない。これらの型のすべては,CTS 合致でなければならず,管

理下ポインタであってはならない。すなわち,参照によって渡されてはならない。

CLS

規則 28  特性は,固有の名前付けパターンを守らなければならない(10.4 参照)。CLS 規則 24 で

参照された SpecialName 属性は,適切な名前比較においては無視されなければならず,識別子規則を守

らなければならない。特性は,getter メソッド,setter メソッド又は両方をもたなければならない。

注記   

CLS

(使用側)  適切な名前比較においては SpecialName ビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,特性を定義するメソッドへの通常のアクセ

ス以外の直接の提供は必要ない。

CLS

(拡張側)  適切な名前比較においては SpecialName ビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,特性を定義するメソッドへの通常のアクセ

ス以外の直接の提供は必要ない。特に,拡張側は,特性を定義できる必要はない。

CLS

(フレームワーク)  すべての CLS 言語が特殊な構文を用いて特性にアクセスするわけ

ではないことを理解して設計を行わなければならない。 

8.11.4 

イベント定義 

CTS は,それが特性を提供するのと正確に同じ方法でイベントを提供する(8.11.3 参照)。しかし,規約

として決められているメソッドは異なっており,イベントの発火だけでなく,イベントへの登録及び登録

解除の手段を含む。

CLS

規則 29  イベントを実装するメソッドは,メタデータの中に SpecialName と印付けられなけれ

ばならない。

CLS

規則 30  イベント及びそのアクセス操作子のアクセス可能性は,同一でなければならない。

CLS

規則 31  イベントのための add メソッド及び remove メソッドは,両方とも存在するか,両方と

も存在しないかのいずれかでなければならない。

CLS

規則 32  イベントのための add メソッド及び remove メソッドは,それぞれ,その型がイベント

の型を定義する一つの仮引数をもたなければならず,System.Delegate から派生していなければならな

い。

CLS

規則 33  イベントは,固有の名前付けパターンを守らなければならない(10.4 参照)。CLS 規則 29

で参照された SpecialName 属性は,適切な名前比較においては無視されなければならず,識別子規則を

守らなければならない。

注記   

CLS

(使用側)  適切な名前比較においては SpecialName ビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,イベントを定義するメソッドへの通常のア


52

X 3016

:2010 (ISO/IEC 23271:2006)

   

クセス以外の直接の提供は必要ない。

CLS

(拡張側)  適切な名前比較においては SpecialName ビットを無視しなければならず,

識別子規則を守らなければならない。それ以外は,イベントを定義するメソッドへの通常のア

クセス以外の直接の提供は必要ない。特に,拡張側は,イベントを定義できる必要はない。

CLS

(フレームワーク)  すべての CLS 言語が特殊な構文を用いてイベントにアクセスする

わけではないことを理解しそれに基づいて設計を行わなければならない。 

8.11.5 

入れ子になった型定義 

入れ子になった型定義は,一つの違いを除いて,最上位の型定義と同一とする。その違いとは,最上位

の型定義は可視性属性をもつが,入れ子になった型の可視性は,それを囲む側の型の可視性と同じとする

8.5.3 参照)

メタデータ 

注記  箇条 は,ここで導入され箇条 11 で繰り返される CLS 規則を除いて,参考情報だけを含む。

メタデータの書式は,

第 章で規定する。

値型及び参照型である新しい型は,メタデータで表現される型宣言を通じて,CTS に導入される。さら

に,メタデータは,CLI が,クラスを位置決めしてロードし,メモリにインスタンスを配置し,メソッド

呼出しを解決し,CIL をプラットフォーム固有のコードに翻訳し,セキュリティを強制的に実行し,実行

時文脈境界を設定するために使用するすべての情報を表現するための構造化された方法とする。すべての

CLI PE/COFF モジュール(第 章参照)は,CLI を実現可能にする開発ツール又はコンパイラがモジュー

ルの中に生成するコンパクトなメタデータバイナリをもつ。

CLI に対応するそれぞれの言語は,型及びメンバを宣言し,それらがインフラストラクチャのどのサー

ビスを要求するかを表現する属性を用いてそれらの型及びメンバを注記するために,それらの言語に適切

な構文を開示する。型の移入も言語に適切な方法で扱われ,開発者が目にする型の開示のためにメタデー

タを使用するのは,開発ツール又はコンパイラとする。

典型的な構成部品又はアプリケーションの開発者は,CLI メタデータを生成し使用するための規則を意

識する必要はない。箇条 で概要を示す規則は,開発者がメタデータの構造を理解するのを助けることが

できるが,基本的には,ツール構築者及びコンパイラ作成者の関心事である。

9.1 

構成部品及びアセンブリ 

それぞれの CLI 構成部品は,その構成部品に固有な宣言,実装及び参照のためのメタデータをもつ。そ

の結果,構成部品固有なメタデータは,構成部品メタデータとして参照され,その結果生じる構成部品を

自己記述的という。COM 又は CORBA といったオブジェクトモデルでは,この情報は,型ライブラリ,IDL

ファイル,DLLRegisterServer 及び別々の書式の無数のカスタムファイルの結合によって表現され,実際の

実行ファイルとは分離されている。これと対照的に,メタデータは,CLI 構成部品の基礎的な部分とする。

CLI 構成部品及びその他のファイルの集まりは,一緒にしてアセンブリに配備するようにパッケージ化

される。アセンブリは,後の箇条でより詳細に示す。アセンブリは,CLI での再利用の基本的な単位とし

て役に立つ機能の論理的単位とする。アセンブリは,型のために名前の有効範囲を確立する。

個々の構成部品の中で宣言され実装された型は,構成部品が参加するアセンブリを通じて他の実装が使

用するために移出されている。型へのすべての参照は,その型が使用されている文脈のアセンブリの同一

性によって有効範囲付けされる。CLI は,参照されたアセンブリを位置決めし,型参照の解決を要求する


53

X 3016

:2010 (ISO/IEC 23271:2006)

ためのサービスを提供する。アプリケーションごとに分離した有効範囲を提供するのはこの機構とする。

アセンブリだけがその構成を制御する。

9.2 

メタデータへのアクセス 

メタデータは,

第 章で示されるとおりにファイル書式に直接にアクセスするか,又は自己反映ライブ

ラリを通じて,CLI モジュールに生成されそれから読まれる。

第 章及び第 章で与えられる規定に基づ

き,開発中に,メタデータを含む CLI モジュールを正当性検証するツールを生成するのは可能である。

クラスが実行時にロードされるとき,CLI ローダは,メタデータをそれ自体のメモリ上のデータ構造に

送る。この構造は,CLI 自己反映サービスを通じて閲覧できる。自己反映サービスは,コンパイラと同様

と考えることが望ましい。それは,継承されたメソッド及びフィールドについての情報を得るために継承

階層を自動的に巡回し,名前又は名前及び識別情報によって隠ぺいする規則をもち,メソッド及び特性の

継承についての規則をもつなどを行う。

9.2.1 

メタデータトークン 

メタデータトークンは,実装依存の符号化機構とする。

第 章では,どのメタデータトークンが CLI

PE/COFF モジュールの様々な節に埋め込まれるかという方法を示す。メタデータトークンは,呼出し元で

メソッド呼出し及びフィールドアクセスを符号化するために CIL 及びプラットフォーム固有のコードに埋

め込まれる。トークンは,参照及びその参照を解決するためにそれが有効範囲付けされていた型について

のメタデータからの情報を取得するために,様々なインフラストラクチャサービスによって使用される。

メタデータトークンは,

(型宣言,メンバ宣言といった)メタデータオブジェクトの型付けされた識別子

とする。トークンを与えると,その型を決定でき,そのメタデータオブジェクトについて固有なメタデー

タ属性を取得できる。しかし,メタデータトークンは,永続的な識別子ではない。むしろ,それは特定の

メタデータバイナリに有効範囲を提供する。メタデータトークンは,メタデータのデータ構造内の添字と

して表現される。それゆえ,高速かつ直接的なアクセスができる。

9.2.2 

メタデータの中のメンバ識別情報 

フィールド,仮引数,メソッド返却値及び特性を含むすべての格納域は,型をもち,その型の規定は,

メタデータ内にもつ。

値型は,ビットの並びとして表現される値を記述する。参照型は,ビットの並びの格納域として表現さ

れる値を記述する。CLI は,組込み型の明示的な集合を提供し,組込み型のそれぞれは,値型又は参照型

のいずれかとして既定の実行時形式をもつ。メタデータの API は,追加的な型を宣言するために用いるこ

とができ,変数の型規定の一部は,その型が実行時にどの形式(値又は参照)をとるのがよいかだけでな

く型の同一性も符号化する。

符号化された型を表現するメタデータトークンは,型を受諾する CIL 命令(newobj,newarray,

ldtoken

など)に渡される。

第 章の CIL 命令集合規定を参照。

これらの符号化された型メタデータトークンは,メンバ識別情報の中にも埋め込まれる。フィールドア

クセス及びメソッド呼出しの実行時結合を最適化するために,フィールド及びメソッドに関連する型識別

情報及び格納域識別情報は,メタデータの中のメンバ識別情報に符号化される。メンバ識別情報は,メン

バへの参照が成功するか又は失敗するかどうかを決定するために使用する契約情報のすべてを具現化する。

9.3 

管理外コード 

CLI 管理下コードから管理外コードへデータを渡すのは,可能とする。これは,管理下コードから管理

外コードへの遷移を常に含む。その中には,何らかの実行時コストが発生するが,データは,コピーなし

に転送できる場合が多い。データが再書式化されなければならない場合,VES は,既定の振る舞いの合理


54

X 3016

:2010 (ISO/IEC 23271:2006)

   

的な規定を提供するが,組換え(すなわち,再書式化されたコピー動作)の他の形式を明示的に要求する

ためにメタデータを使用できる。メタデータは,実装固有の既存機構を通じての管理外コードへのアクセ

スも許可する。

9.4 

メソッド実装メタデータ 

実装が現在の CLI モジュールで供給されているメソッドそれぞれのために,ツール又はコンパイラは,

CIL からプラットフォーム固有のコードへのコンパイラ,CLI ローダ及び他の情報サービスが使用する情

報を生成する。この情報は,次を含む。

−  コードが,管理下又は管理外かどうか。

−  実装が,その CPU に固有なコード又は CIL かどうか。すべての CIL コードは管理下であることに注

意する。

−  現在のモジュールの中での,メソッド本体が置かれているモジュールファイルの先頭からの相対的な

アドレスとしての位置。これを,相対仮想アドレス又は RVA という。他の方法として,RVA は 0 に

符号化し,メソッド実装が見いだされる格納域をインフラストラクチャに示すために他のメタデータ

を使用することもある。これは,次を含む。

−  メソッド実装は,この規格以外で記述される実装固有の手段によって位置決めされる。

−  移入されている大域静的メソッドを通じて呼出しを転送する。

9.5 

クラスの配置 

一般に,CLI ローダは,CTS の規則と矛盾しないように,それが選択する方法でクラスのインスタンス

を自由に配置する。しかし,ツール又はコンパイラが,より多くの制御を配置に必要とする場合がある。

メタデータでは,クラスは,その配置規則が次のいずれであるかを示す属性を用いて印付けられる。

−  自動配置(autolayout)  autolayout と印付けられたクラスは,ローダが整合すると判断する方法で

クラスを自由に配置することを示す。指定されるかもしれない配置情報は,無視される。この自動配

置を,省略時の値とする。

−  順次配置(sequentiallayout)  sequentiallayout と印付けられたクラスは,生成されたフィールド

の順番を保存するようにローダを導くが,それ以外の特定のオフセットは,フィールドの CLI 型に基

づいて計算される。これらは,明示的なオフセット,詰物及び/又は境界調整の情報によってずらす

ことができる。

−  明示配置(explicitlayout)  explicitlayout と印付けられたクラスは,ローダに,フィールドの列

を無視し,フィールドオフセット及び/又は全体的なクラスの大きさ若しくは境界調整の形式で提供

される明示的な配置規則を使用するようにする。

第 章に示すように,正当な配置には制限が存在す

る。

クラスの全体の大きさを指定することも可能とする。これによって,ツール又はコンパイラが,型の大

きさだけが供給されている値型指定を生成できる。これは,

(32 ビット整数といった)CLI 組込み型の宣

言に役立つ。

構造化された値型のメンバのデータ型が CLI メタデータの中に表現をもたない場合

(例えば,

C++ビットフィールドなど)にも役に立つ。後者の場合,ツール又はコンパイラが配置を制御し,CLI が

詳細を知る又は配置にかかわる必要がない限り,これで十分になる。これは,VES はビットを移動するこ

とはできるが,機械にまたがって組換えはできないことを意味することに注意する。生成を行うツール又

はコンパイラが,組換えを処理する必要がある。

任意選択で,開発者は,クラスの詰める大きさを指定できる。これは,それほど多く使用される配置情

報ではないが,開発者がフィールドの境界調整を制御するのを可能にする。それは,本質的に境界調整指


55

X 3016

:2010 (ISO/IEC 23271:2006)

定ではなく,むしろ,すべての境界調整に上限を設ける修飾子としてのサービスになる。典型的な値は,1,

2,4,8  又は 16 である。総称型は,explicitlayout と印付けしてはならない。

クラス配置属性の完全な規定については,

第 章の System.Runtime.InteropServices におけるク

ラス群を参照。

9.6 

アセンブリ,すなわち,型のための名前の有効範囲 

アセンブリは,機能のまとまりのある集合を配布する目的で一緒に作動するために組み立てられた資源

の集まりとする。アセンブリは,そのまとまりを確実にするのに必要な規則のすべてをもつ。それは,CLI

において資源にアクセスする単位とする。

外部的には,アセンブリは,型を含む移出されている資源の集まりになる。資源は,名前によって移出

されている。内部的には,アセンブリは,公開(移出されている)資源及び私的(アセンブリ内部の)資

源の集まりになる。どの資源をアセンブリの外部に移出しているか,どの資源を現在のアセンブリの有効

範囲の内部だけでアクセス可能とするかを決定するのは,アセンブリとする。資源への参照,公開又は私

的が資源を実装するビットに対応付けられる方法を制御するのは,アセンブリとする。特に型に対して,

アセンブリは,実行時構成情報を供給できる。CLI モジュールは,型の宣言及び実装のパッケージ化した

ものと考えることができる。ここで,パッケージ化の決定は,アセンブリのクライアントに影響を与える

ことなく,そのパッケージ化する対象範囲の中で変更できる。

型の同一性は,そのアセンブリの有効範囲及びその宣言された名前による。二つの異なるアセンブリの

中で同一的に定義された型は,二つの異なる型と考えられる。

アセンブリ依存性  アセンブリは,他のアセンブリに依存できる。これは,一つのアセンブリの有効範

囲の中の実装が,他のアセンブリの中に有効範囲をもつ場合,又はそれが所有する資源を参照する場合に

発生する。

−  他のアセンブリへのすべての参照は,現在のアセンブリの有効範囲の制御の下に解決される。これに

よって,アセンブリは,他のアセンブリへの参照がその参照されるアセンブリの特定の版(又は他の

特徴)へと対応付けられる方法を制御する可能性をもつ。ただし,参照される資源が実装に対して解

決される方法に関しては,その対象となるアセンブリが独立の制御をもっている。

−  特定の実装がその中で実行されるアセンブリ有効範囲を決定するのは,常に可能とする。そのアセン

ブリ有効範囲から発生するすべての要求は,その有効範囲に対して相対的に解決される。

配備の観点からは,アセンブリは,それが参照する他のアセンブリがその配備環境の中で使用可能と仮

定して,それ自体,配備できる。その依存するアセンブリと一緒に配備できる。

内容目録  すべてのアセンブリは,アセンブリを構成するファイル,移出されている型及びアセンブリ

の内部で型参照を解決するために要求される他のアセンブリ,を宣言する内容目録をもつ。CLI 構成部品

がその CLI 構成部品の中のメタデータを通じて自己記述的であるように,アセンブリは,内容目録を通じ

て自己記述的とする。一つのファイルがアセンブリを形成する場合,そのファイルは,アセンブリの中で

定義される型を記述するメタデータ及びアセンブリそれ自体を記述するメタデータの両方を含む。アセン

ブリが,メタデータをもつ二つ以上のファイルを含む場合,それぞれのファイルは,存在する場合にはそ

のファイルの中で定義される型を記述し,さらに,これらのファイルの一つが,そのアセンブリを記述す

るメタデータ(他のファイルの名前,その暗号レベルの精度のハッシュ及びアセンブリの外部に移出して

いる型を含む。

)も含む。

アプリケーション  アセンブリは,アプリケーションごとに分離した意味を導入する。アプリケーショ

ンは,単に,新しいアプリケーション領域の生成を引き起こす(又はブラウザのようなホスト環境に生成


56

X 3016

:2010 (ISO/IEC 23271:2006)

   

を引き起こさせる)外部入口点をもつアセンブリとする。この入口点は,実効的に,要求の呼出し及び解

決木の根となる。アプリケーションの中には,一つの自己完結したアセンブリもあるが,それが必要とす

る資源を提供する他のアセンブリが利用可能であることを要求するものもある。いずれの場合も,ロード

されるモジュールに対して要求が解決されるとき,そのモジュールは,その要求が発生した同じアプリケ

ーション領域へとロードされる。アプリケーション領域を通じて,アプリケーションを監視又は停止する

ことができる。

注記  型への参照は,常に,その参照が解決されるのが望ましいアセンブリ有効範囲を用いて,型名

を限定する。すなわち,アセンブリは,利用可能な資源の名前の有効範囲を確立する。しかし,

個々のモジュールと参照されるアセンブリとの間の関係を確立するのではなく,すべての参照

は,現在のアセンブリを通じて解決される。これによって,それぞれのアセンブリが,参照を

解決する方法の絶対的な制御をもつことが可能になる(

第 章参照)。

9.7 

メタデータの拡張性 

CLI メタデータは,拡張可能とする。これを重要とするのには,次の三つの理由がある。

−  共通言語規定(Common Language Specification,CLS)は,言語及びツールが,よりよい言語統合のた

めに一様な方法で提供するのを合意した規約のための規定とする。CLS は,CTS モデルの一部を制約

し,CLS は,CTS の上位の層を成すより高位の抽象を導入する。ツールが使用するこれら種類の開発

時における抽象化をメタデータによって捕そく(捉)できることが重要である。ただし,これらの抽

象化は,CLI によって明示的には認識されていないし提供されていないことに注意する。

− CLI でも CLS の言語抽象でもない言語固有の抽象をメタデータで表現できることが望ましい。

例えば,

C++のような言語が,コンパイルされたモジュールによって移出されている型,メソッド及びデータ

メンバを使用するために,別々のヘッダ又は IDL ファイルを,長い年月にわたって,必要としないよ

うにできることが望ましい。

−  メンバ識別情報において,言語固有の多重定義で使用される型及び型修飾子を符号化できることが望

ましい。例えば,基礎となる型 int32 に int 及び long の両方を対応付ける 32 ビット機械上でさえ

も,C++が,int を long から区別できるようにする。

この拡張可能性は,次の形式になる。

−  すべてのメタデータオブジェクトは,カスタム属性をもつことができ,メタデータ API は,カスタム

属性を宣言し,数え上げ,取得する方法を提供する。カスタム属性は,単純名によって識別できるが,

この場合,値符号化は不透明であって,それを定義した特定のツール,言語又はサービスにだけ知ら

れているとする。カスタム属性は,型参照によっても識別できる。この場合には,その属性の構造は,

(その型で宣言されたデータメンバを通じて)自己記述的であって,CLI 自己反映サービスを含むあ

らゆるツールがその値符号化を閲覧できる。

CLS

規則 34  CLS は,カスタム属性の符号化の部分集合だけを許す。これらの符号化で出現しなけれ

ばならないものは,

System.Type

System.String

,System.Char,

System.Boolean

System.Byte

System.Int16

,System.Int32,System.Int64,System.Single,System.Double 及び CLS 合

致の基底整数型に基づく列挙型だけとする(

第 章参照)。

注記   

CLS

(使用側)  制限された方式を使って符号化された属性を読むことができる。

CLS

(拡張側) CLS 使用側のためのすべての要件を満たし,新しいクラス及び新しい属性を


57

X 3016

:2010 (ISO/IEC 23271:2006)

編集できなければならない。既存の属性クラスに基づく属性を生成されたあらゆるメタデータ

に添付できる。

System.AttributeUsageAttribute

のための規則を実装する

第 章参照)。

CLS

(フレームワーク) CLS 規則の範囲内であって,System.AttributeUsageAttribute

のために規定された規約に従って符号化された属性だけを外部に開示する。

− CTS 型拡張可能性に加えて,カスタム修飾子をメンバ識別情報の中に生成できる(型,

第 章参照)。

CLI は,メソッドの結合のためだけでなく,多重定義及び隠ぺいの目的でこれらの修飾子を大切にし,

言語固有の意味を強制はしない。これらの修飾子は,メソッドの返却値型若しくは仮引数又はフィー

ルドの型を参照できる。それらは 2 種類になる。一つは,正しく使用するためにそのメンバを使うす

べてが理解しなければならない必す(須)修飾子であって,もう一つは,修飾子が理解されない場合

には無視できる任意選択修飾子とする。

CLS

規則 35  CLS は,公開の可視である必す(須)修飾子(modreq,第 章参照)を許さないが,CLS

が理解しない任意選択修飾子(modopt,

第 章参照)は許す。

注記   

CLS

(使用側)  任意選択修飾子を含むメタデータを読み,それらを含む識別情報を正しくコ

ピーできなければならない。型一致及び多重定義解決ではこれらの修飾子を無視できる。任意

選択修飾子を無視した場合にあいまい(曖昧)になる型,又は必す(須)修飾子を使用する型

を無視できる。

CLS

(拡張側)  任意選択修飾子を含む識別情報をもつ継承されたメソッドのための上書きを

編集できなければならない。その結果として,拡張側は,それが移入するメタデータからそれ

ら修飾子をコピーできなければならない。必す(須)修飾子を提供するという要件も,その識

別情報の中にあらゆる種類の修飾子をもつ新しいメソッドを編集するという要件も存在しな

い。

CLS

(フレームワーク)  必す(須)修飾子が CLS 合致ではないと印付けられていない場合,

外部に可視な識別情報の中で必す(須)修飾子を用いてはならない。一つのクラスの二つのメ

ンバが,それらの識別情報の中での任意選択修飾子の使用だけで異なっており,それらの一つ

だけが CLS 合致と印付けられているわけではない場合,それらの二つのメンバを開示してはな

らない。 

9.8 

大域的,移入及び移出 

CTS は,大域的に静的という概念をもたない。すべての静的なものは,特定のクラスと関連している。

それにもかかわらず,メタデータは,PE/COFF ファイルの中に直接に格納され,その相対仮想アドレスに

よってアクセスされる静的データに依存する言語を,支援するように設計されている。さらに,管理下デ

ータ及び管理下関数へのアクセスは,完全にメタデータそれ自体を通じて仲介される一方で,メタデータ

は,管理外データ及び管理外コードにアクセスする機構を提供する。

CLS

規則 36  大域的に静的なフィールド及びメソッドは,CLS 合致ではない。

注記   

CLS

(使用側)  大域的に静的なフィールド又はメソッドを支援する必要はない。

CLS

(拡張側)  大域的に静的なフィールド又はメソッドを編集する必要はない。

CLS

(フレームワーク)  大域的に静的なフィールド又はメソッドを定義してはならない。 


58

X 3016

:2010 (ISO/IEC 23271:2006)

   

9.9 

有効範囲付けされた静的な関数又はデータメンバ 

CTS は,ファイル又は関数に有効範囲付けされた静的な関数又はデータメンバを含まない。しかし,コ

ンパイラは,有効範囲付けされた関数又はデータメンバのために CIL の中にメタデータトークンを生成す

ることが必要となる場合がある。メンバが宣言されており,コンパイラがすべてのアクセス規則の強制実

行を保証する PE/COFF ファイルの外部で,メタデータは,そのメンバが決して可視でなくアクセス可能で

ないとするように,メンバが印付けされることを許す。

10 

共通言語仕様のための名前及び型の規則 

10.1 

識別子 

大文字と小文字とを区別する言語又は大文字と小文字とを区別しない言語のいずれも,CLS を提供でき

る。この規則は他の言語に開示される項目にだけ適用されるから,アセンブリから移出されない非公開メ

ンバ又は非公開型には,それぞれの言語が選択した任意の名前を利用できる。しかし,相互運用に関する

制限が幾つか存在する。

ツールに対して大文字と小文字とを区別する言語に十分に対応できるようにさせるには,識別子の大文

字と小文字とを正確に維持することが重要である。同時に,Unicode で符号化された非英語を処理する場

合,結合文字を含んだ正確に同じ識別子を表現する方法が複数あり得る。CLS は,その識別子が適切な

Unicode 標準の制限に従い,正規形式 C で永続化することを要求する。この正規形式 C は大文字と小文字

との違いを保持するが,結合文字を標準的な表現に強制する(8.5.1 CLS 規則 4 参照)

同時に,外部可視名が大文字と小文字とを区別しない言語で利用された場合,他の外部可視名と衝突し

ないことは重要である。結果として,すべての識別子比較は正規形式 KC を使った CLS 合致ツール内でな

されなければならない。この正規形式 KC は,最初に文字をその大文字と小文字との正規形式に変換する

8.5.1 CLS 規則 4 参照)

CLS 合致の言語のコンパイラが,CLS 合致でない言語との相互運用性を提供する場合,CLS 合致の言語

のコンパイラは,CTS 及び VES が符号位置(バイト単位)の比較を使ってすべての比較を行うことを承知

していなければならない。すなわち,CLS が永続化された識別子に対して正規形式 C であることを要求し

ているにもかかわらず,CLS 合致でない識別子の参照は,その CLS 合致でない言語が利用すると選択した

どんな符号化でも,それらを用いて永続化されなければならない。これは,言語設計上の課題であり,こ

れを正確にどのように扱わなければならないかは CTS 又は CLS の範ちゅう(疇)にない。

10.2 

多重定義 

注記 CTS は継承,オブジェクト配置,名前の隠ぺい及び仮想メソッドの上書きについて記述する一

方,多重定義について何も記述していない。これは驚くべきことであるが,多重定義は CTS を

対象とするコンパイラですべて扱うものであり,型システム自身が扱うものではないという事

実からそうなっている。メタデータでは,型及び型メンバのすべての参照は完全に解決され,

意図された正確な識別情報を含む。どのプログラム言語も型付けに対する規則を独自にもち,

VES はそれらの規則を表現するための手段を提供していないから,この選択がなされた。

CTS の規則によれば,種類(フィールド,メソッドなど),又は,識別情報が異なれば,同じ名前を同

じ有効範囲に複数定義することができる。CLS はメソッドの多重定義に対してより強力な制約を課してい

る。単一の有効範囲内で,与えられた名前は,次のいずれかが異なるように提供された複数のメソッドを

参照できる。

−  仮引数の個数


59

X 3016

:2010 (ISO/IEC 23271:2006)

−  任意の仮引数の型

識別情報には多くの情報を含んでいるが,CLS 合致の言語は,付加情報だけが異なるクラスを生成又は

消費する必要はないことに注意する(識別情報に載る情報の完全なリストは

第 章を参照)。

−  呼出し規約

−  カスタム修飾子

−  返却型

−  仮引数が値渡し又は参照渡しの区別

この規則には一つの例外がある。

10.3.3

に記述されている特殊な名前 op_Implicit 及び op_Explicit

は,それらの返却値だけが異なるメソッドを提供できる。これらは特別に印付けられ,演算子多重定義を

扱わないコンパイラは,これらを無視できる。

特性は,型(すなわち,それらの getter メソッドの返却型)によって多重定義されてはならないが,

添字の個数又は型(すなわち,それらの取得メソッドの仮引数の個数又は型)が異なる特性は多重定義で

きる。特性に対する多重定義の規則は,メソッドの多重定義規則と同一とする。

CLS

規則 37  特性及びメソッドだけを多重定義できる。

CLS

規則 38  特性及びメソッドは,それらの仮引数の個数及び型にだけ基づいて多重定義できる。ただ

し,op_Implicit 及び op_Explicit という名前の変換演算子は,それらの返却型に基づいても多重定

義できる。

注記   

CLS

(使用側)  特性及びメソッドだけが多重定義されるという仮定ができると,演算子多重

定義に対する特殊な構文が提供されていなければ,返却型に基づく多重定義を扱う必要がない。

返却値による多重定義を扱わないならば,その機能は CLS 合致のフレームワークによる他の方

法で提供されなければならないから,op_Implicit 及び op_Explicit を無視できる。使用

側は,どんなあいまい(曖昧)さも避けるために,名前による隠ぺい(蔽)規則並びに,識別

情報及び名前による隠ぺい(蔽)規則(8.10.4 参照)を最初に適用しなければならない。

CLS

(拡張側)  ここで規定された以上に多重定義の作成を許可してはならない。演算子多重

定義を扱う必要性は全くないから,返却値による多重定義を完全に扱わないようにすることも

できる。

CLS

(フレームワーク)  ここで規定した以外に多重定義を公に開示してはならない。フレー

ムワーク作成者は,オブジェクト指向言語を含む多くのプログラム言語では多重定義を扱わず,

名前変換された名前を通して多重定義されたメソッド又は特性を開示することに気に留めてお

かなければならない。ほとんどの言語は,演算子多重定義も返却型による多重定義も扱わない。

そのため,op_Implicit 及び op_Explicit は,常に,同じ機能を提供する何らかの代替方

法で補強しなければならない。 

注記  任意のクラス C において可視な名前は,そのクラス及びその基底クラスで可視である。結果と

して,MethodImpls(2

章参照)を介して実装されただけのクラス C で実装されたインタフェー

スのメソッド名は,クラス C で可視ではない。インタフェース I で可視な名前は,このインタ

フェースで直接定義された名前だけから構成される。その結果,インタフェース I が実装を要

求している他のインタフェースからのメソッド名は,インタフェース I から可視ではない。

10.3 

演算子多重定義 


60

X 3016

:2010 (ISO/IEC 23271:2006)

   

CLS 合致の使用側ツール及び拡張側ツールには,演算子多重定義を可能としなくてもよい。CLS 合致の

使用側ツール及び拡張側ツールは,これらのメソッドを呼び出す特殊な機構を提供する必要もない。

注記  この話題は,次の事項が可能なように,CLS によって取り組まれている。

−  演算子多重定義を提供する言語は,他の言語が理解できる方法で,その規則を記載する。

−  演算子多重定義を提供しない言語は,特殊な構文を追加せずに,依然として基本となる機能

にアクセスする。

演算子多重定義は,それらは利用者の名前空間と衝突することがないように,次に規定された名前の使

用及びメタデータ(SpecialName)内の特殊なビットの設定によって記述される。CLS 合致の生産側ツ

ールは,このビットを設定するための何らかの手段を提供しなければならない。これらの名前が使われて

いるならば,それらはここで記載した意味規則を正確にもたなければならない。

10.3.1 

単項演算子 

単項演算子は一つの実引数を取り,それに対する何らかの演算を実行し,その結果を返却する。単項演

算子は,その一つの演算項の型を定義したクラスの静的メソッドとして表現される。

表 4  単項演算子名

に,定義済みの名前を示す。

表 4−単項演算子名 

名前 

JIS X 3014 C++

演算子記号(この欄は参考とする。) 

op_Decrement

--  と類似

1)

op_Increment

++  と類似

1)

op_UnaryNegation

-(単項)

op_UnaryPlus

+(単項)

op_LogicalNot

!

op_True

2)

未定義

op_False

2)

未定義

op_AddressOf

&(単項)

op_OnesComplement

~

op_PointerDereference

*(単項)

1)

  純粋な C++の観点から見ると,CLI では,これらの関数を書かなければならない方法は,次の非常に重要な

点に関して異なる。C++では,これらのメソッドは,それらの演算対象を直接増加又は減少させなければな

らない。一方,CLI ではそうしてはならない。代わりに,それらの演算対象を変更せずに,単に演算対象に
対して適切に 1 を加えた値又は 1 を減じた値を返す。演算対象は,++演算子又は—演算子に対するコードを
生成するコンパイラによって増加又は減少されなければならず,これらのメソッドの呼出しとは区別されな

ければならない。

2)

  op_True 演算子及び op_False 演算子は,C++には存在しない。それらは,データベース言語で使われてい

るような三つの状態をもつ Boolean 型に対応するために提供される。

10.3.2 2

項演算子 

2 項演算子は二つの実引数を取り,何らかの演算を実行し,一つの値を返却する。2 項演算子は,二つの

演算対象の一つの型を定義したクラスの静的メソッドとして表現される。

表 1-5  項演算子名に定義済み

の名前を示す。


61

X 3016

:2010 (ISO/IEC 23271:2006)

表 5項演算子名 

名前 

JIS X 3014 C++

演算子記号(この欄は参考とする。) 

op_Addition

+(2 項)

op_Subtraction

-(2 項)

op_Multiply

*(2 項)

op_Division

/

op_Modulus

%

op_ExclusiveOr

^

op_BitwiseAnd

&(2 項)

op_BitwiseOr

|

op_LogicalAnd

&&

op_LogicalOr

||

op_Assign

未定義(=と同じではない)

op_LeftShift

<<

op_RightShift

>>

op_SignedRightShift

未定義

op_UnsignedRightShift

未定義

op_Equality

==

op_GreaterThan

>

op_LessThan

<

op_Inequality

!=

op_GreaterThanOrEqual

>=

op_LessThanOrEqual

<=

op_UnsignedRightShiftAssignment

未定義

op_MemberSelection

->

op_RightShiftAssignment

>>=

op_MultiplicationAssignment

*=

op_PointerToMemberSelection

->*

op_SubtractionAssignment

-=

op_ExclusiveOrAssignment

^=

op_LeftShiftAssignment

<<=

op_ModulusAssignment

%=

op_AdditionAssignment

+=

op_BitwiseAndAssignment

&=

op_BitwiseOrAssignment

|=

op_Comma

op_DivisionAssignment

/=

10.3.3 

変換演算子 

変換演算子は,ある型から別の型への変換を許可する単項演算とする。この演算子メソッドは,演算対

象の型又は返却型のいずれかの静的メソッドとして定義しなければならない。次に示す 2 種類の変換があ

る。

−  暗黙の(

拡大)強制型変換は,数の大きさ又は精度を失ってはならない。暗黙の強制型変換は,

op_Implicit

という名前のメソッドを使って提供されることを推奨する。

−  明示的な(

縮小)強制型変換は,数の大きさ又は精度を失うことができる。明示的な強制型変換は,

op_Explicit

という名前のメソッドを使って提供されることを推奨する。


62

X 3016

:2010 (ISO/IEC 23271:2006)

   

注記  変換は,他の方法では生成できない機能を提供する。多くの言語は,特殊な構文による変換演

算子の使用を提供しない。したがって,CLS の規則は,同じ機能を代替機構で利用可能にする

ことを要求する。より一般的な ToXxx(Xxx を変換後の型の名前とする。

)及び FromYyy(Yyy

を変換前の型の名前とする。

)という命名パターンの使用を推奨する。

これらの演算は,その演算対象の型(いわゆる“From”変換。

)のクラスに存在できる。したがって,

返却型だけが異なることになるから,CLS は特に,これら二つの演算子は,その返却型に基づいて多重定

義されることを許可する。しかし,すべての CLS 言語が特殊な構文で演算子を実装しているとは限らない

から,この形態の多重定義が使われるならば,CLS は,その言語が同じ機能を提供する代替手段を提供し

なければならないことも要求する。

CLS

規則 39  op_Implicit 又は op_Explicit のいずれかが提供されている場合,その強制型変換に

対する代替手法を提供しなければならない。

注記   

CLS

(使用側)  言語設計において必要に応じて,メソッド多重定義の選択及び自動強制型変

換の生成において,op_Implicit 及び/又は op_Explicit の存在を使う。

CLS

(拡張側)  言語設計において必要に応じて,対応する op_Implicit,op_Explicit,

ToXxx

及び/又は FromXxx メソッドを使って利用者定義の明示的又は暗黙の強制型変換演算

子を実装する。

CLS

(フレームワーク)  強制型変換演算が提供されている場合,それらは FromXxx 及び

ToXxx

として提供されなければならず,更に,省略可能な op_Implicit 及び op_Explicit

も提供しなければならない。CLS フレームワークは,これらの強制型変換演算を提供すること

が推奨される。 

10.4 

命名パターン 

第 章も参照。

CTS は,特性又はイベントの命名を定義しない一方,CLS は順守すべきパターンを規定する。

イベント用:

個々のイベントは,

そのイベントの通知に使われる委譲型を選択又は定義することによって生成される。

そして,イベント名に基づく名前及び固定された識別情報をもつ三つのメソッドが生成される。次の例で

は,EventHandler という名前の委譲型を使用する Click という名前のイベントを定義する。

EventAdd

,イベント用のハンドラを追加するために使われる

パターン: void add_<EventName> (<DelegateType> handler)

例: void add_Click (EventHandler handler);

EventRemove

,イベント用のハンドラを削除するために使われる

パターン: void remove_<EventName> (<DelegateType> handler)

例: void remove_Click (EventHandler handler);

EventRaise

,発生したイベントを通知するために使われる

パターン: void family raise_<EventName> (Event e)

特性用:

個々の特性は,取得子から返却される型及び(もしあれば)取得子の仮引数の型を決定することによっ

て生成される。そして,特性及びこれらの型の名前に基づいた名前の二つのメソッドが生成される。次の


63

X 3016

:2010 (ISO/IEC 23271:2006)

例では,

二つの特性を定義する。

仮引数をもたず System.String を返却する Name 及び System.Object

の仮引数をもち System.Object を返却する Item である。Item は添字指定された特性と呼ばれ,それ

は引数をとることを意味し,そのうえ,添字をもつ配列であるかのように利用者に見せることができる。

PropertyGet

,特性の値を読み出すために使われる

パターン: <PropType> get_<PropName> (<Indices>)

例: System.String get_Name ();

例: System.Object get_Item (System.Object key);

PropertySet

,特性の値を変更するために使われる

パターン: void set_<PropName> (<Indices>, <PropType>)

例: void set_Name (System.String name);

例: void set_Item (System.Object key, System.Object value);

10.5 

例外 

CLI は例外処理モデルを提供する。例外処理は 12.4.2 で導入される。CLS 合致のフレームワークは外部

可視例外を定義及び送出できるが,送出されるオブジェクトの型には制約がある。

CLS

規則 40  送出されるオブジェクトは,System.Exception 又はそれを継承した型でなければなら

ない。しかし,CLS 合致のメソッドは,他の例外型が伝ぱ(播)しないようにすることを要求しない。

注記   

CLS

(使用側)  規定された型ではないオブジェクトの送出又は捕そく(捉)を扱う必要はな

CLS

(拡張側)  System.Exception 又はそれを継承した型のオブジェクトの送出を扱わな

ければならない。他の型のオブジェクトを送出する必要はない。

CLS

(フレームワーク)  System.Exception でもそれを継承する型でもないオブジェクト

を外部に公開してはならない。 

10.6 

カスタム属性 

言語間で一貫したカスタム属性の参照を提供することを言語に許可するために,基底クラスライブラリ

は CLS で定義された次の規則に従う。

CLS

規則 41  属性は System.Attribute 又はそれを継承した型でなければならない。

注記   

CLS

(使用側)  規定された型ではない属性を提供する必要はない。

CLS

(拡張側)  カスタム属性の作成を提供しなければならない。

CLS

(フレームワーク)  System.Attribute でもそれを継承した型でもない属性を外部に

公開してはならない。 

特定の属性クラスの使用は,その属性クラスに属性を置くことによって,様々な方法で制約を課すこと

が で き る 。 System.AttributeUsageAttribute は , こ れ ら の 制 約 を 指 定す るた めに 使わ れる 。

System.AttributeUsageAttribute

による制約は次のとおりとする。

−  どんな種類の構築要素(型,メソッド,アセンブリなど)も,それらに適用される属性をもてる。既

定 で は , 属 性 ク ラ ス の イ ン ス タ ン ス は , 任 意 の 構 築 要 素 に 適 用 で き る 。 こ れ は ,

System.AttributeUsageAttribute

の ValidOn 特性の値を設定することで指定される。組み合


64

X 3016

:2010 (ISO/IEC 23271:2006)

   

わせることができる構成要素がある。

−  属性クラスの複数インスタンスは,与えられた一部のメタデータに適用できる。既定では,任意の与

えられた属性クラスの一つのインスタンスだけが,単一メタデータ項目に適用できる。属性の

AllowMultiple

特性は,要求値を指定するために使用される。

−  型に適用されるとき,その属性を継承しない。既定では,型に付随した任意の属性は,その型から派

生する型に継承されることを推奨する。属性クラスの複数インスタンスが許可されている場合,その

継承は,上位クラスから継承された属性と,明示的に下位クラス型に適用される属性との和集合を実

行する。複数インスタンスが許可されていない場合,下部クラスに直接適用される型の属性が,上位

クラスによって供給される属性を上書きする。これは,System.AttributeUsageAttribute の

Inherited

特性に要求値を設定することで指定される。

注記  これらは CLS 規則であり,CTS 自身の一部ではないから,ツールには,任意の与えられたメタ

データ項目に適用する意図のあるカスタム属性を明示的に指定することを要求される。すなわ

ち,メタデータを生成するコンパイラ又はその他のツールは,AllowMultiple 及び Inherit

規則を実装しなければならない。CLI は自動的に属性を提供しない。CLI での属性の利用は,

第 章でも規定される。

10.7 

総称型及び総称メソッド 

10.7.1

から 10.7.6 において,総称型及び総称メソッドに対する CLS 規則を規定する。

10.7.1 

入れ子になった型仮引数の再宣言 

CLS 合致のフレームワークによって移出される任意の型で,それが総称型内に入れ子になった場合,そ

れを囲んでいる型の総称仮引数のすべてが,それらが宣言された位置と同じ位置に,その入れ子型の総称

仮引数として宣言する。

(入れ子型は,新しい総称仮引数を導入することもできる。

)したがって,総称型

内に入れ子になった CLS 合致の任意の型は,それ自身,総称型とする。このように再宣言された総称仮引

数は,新しく導入された総称仮引数のどれよりも先行していなければならない。

例  次の C#のソースコードを例として示す。

public class A<T> {

  public class B { }

  public class C<U, V> {

    public  class  D<W>  {  }

  }

}

public class X {

  public class Y<T> { }

}

これに対応する ILAsm のコードは次のようになる。

.class ... A`1<T> ... {

// T is introduced

  .class ... nested ... B<T> ... { }

// T is redeclared

  .class ... nested ... C`2<T,U,V> ... {

//

T

is

redeclared;

U

and

V are introduced

    .class ... nested ... D`1<T,U,V,W> ... { }

//

T,

U,

and

V

are

redeclared; W is introduced


65

X 3016

:2010 (ISO/IEC 23271:2006)

  }

}

.class ... X ... {

  .class ... nested Y`1<T> ... { }

// Nothing is

redeclared; T is introduced

}

総称仮引数の再宣言は,仮引数の位置の一致を基準にしており,仮引数の名前の一致を基準に

していない。

再宣言される総称仮引数の名前は,再宣言されたものと同じ名前である必要はない。

例えば,次のようになる。

.class ... A`1<T> ... {

// T is

introduced

  .class ... nested ... B<Q> ... { }

// T is

redeclared (as Q)

  .class ... nested ... C`2<T1,U,V> ... {

// T is

redeclared (as T1); U and V are introduced

    .class ... nested ... D`1<R1,R2,R3,W> ... { }

// T1, U, and V

are redeclared (as R1, R2, and R3); W is introduced

  }

}

したがって,CLS 合致のフレームワークは,次の型を開示しなければならない。

語い(彙)名 

総称仮引数の個数 

再宣言された総称仮引数

導入された総称仮引数 

A<T> 1

(T)

0 1

T

A<T>.B

1 (T)

1 T

0

A<T>.C<U,V>

3 (T,U,V)

1 T

2 U,V

A<T>.C<U,V>.D<W>

4 (T,U,V,W)

3 T,U,V

1 W

X 0 0  0

X.Y<T>

1 (T)

0

1 T

CLS

規則 42  入れ子型は,少なくとも囲んでいる型と同じ数の総称仮引数をもたなければならない。入

れ子型の総称仮引数は,囲んでいる型の総称仮引数の位置に対応する。

注記   

CLS

(使用側)  この規則に反する型を利用する必要はない。

CLS

(拡張側)  利用側と同様。総称型内に入れ子になる型の定義を採用する拡張側は,外部

に対して可視な型に対してもこの規則に従わなければならない。

CLS

(フレームワーク)  この規則に反する型を開示してはならない。

10.7.2 

型名及び項数符号化 

CLS 合致の総称型名は,"名前[`項数]"という形式で符号化される。ここで,[...]は抑音アクセント文字(ア

クサングラーブ)"`"及び項数がともに省略可能であることを示す。符号化された名前は,次の規則に従う。

1)

名前は,"`"を含まない ID(

第 章参照)でなければならない。

2)

項数は,ゼロ又は空白を先行させない符号なし十進数として指定する。


66

X 3016

:2010 (ISO/IEC 23271:2006)

   

3)

通常の総称型に対する項数は,その型で宣言された型仮引数の個数とする。

4)

入れ子になった総称型に対する項数は,新しく導入された型仮引数の個数とする。

例  次の C#のソースコードを例として示す。

public class A<T> {

  public class B { }

  public class C<U, V> {

    public  class  D<W>  {  }

  }

}

public class X {

  public class Y<T> { }

}

これに対応する ILAsm のコードは次のようになる。

.class ... A`1<T> ... {

// T is introduced

  .class ... nested ... B<T> ... { }

// T is redeclared

  .class ... nested ... C`2<T,U,V> ... {

//

T

is

redeclared;

U

and

V are introduced

    .class ... nested ... D`1<T,U,V,W> ... { }

//

T,

U,

and

V

are

redeclared; W is introduced

  }

}

.class ... X ... {

  .class ... nested Y`1<T> ... { }

// Nothing is

redeclared; T is introduced

}

CLS 合致のフレームワークは,次の型を開示しなければならない。

語い(彙)名 

総称仮引数の個数 

再宣言された

総称仮引数 

導入された 
総称仮引数 

符号化された

メタデータ 

A<T>

1 (T)

0

1 T

A`1

A<T>.B

1 (T)

1 T

0

B

A<T>.C<U,V>

3 (T,U,V)

1 T

2 U,V

C`2

A<T>.C<U,V>.D<W>

4 (T,U,V,W)

3 T,U,V

1 W

D`1

X 0

0

0

X

X.Y<T>

1 (T)

0

1 T

Y`1

メタデータ内に符号化された型名は,それを囲んでいる型を明示的に言及しないが,CLI 及び

自己反映型名文法は,次のような詳細情報を含む。


67

X 3016

:2010 (ISO/IEC 23271:2006)

語い(彙)名 

符号化されたメタデータ CLI 

自己反映 

A<T> A`1

A`1

A`1[T]

A<T>.B B

A`1/B

A`1+B[T]

A<T>.C<U,V> C`2

A`1/C`2

A`1+C`2[T,U,V]

A<T>.C<U,V>.D<W> D`1

A`1/C`2/D`1

A`1+C`2+D`1[T,U,V,W]

X X

X

X

X.Y<T> Y`1

X/Y`1

X+Y`1[T]

CLS

規則 43  総称型の名前は,入れ子でない型で宣言された型仮引数の個数,又は入れ子型で新たに宣

言された型仮引数の個数を,上で定義した規則で符号化する。

注記   

CLS

(使用側)  この規則に反する型を利用する必要はない。

CLS

(拡張側)  利用側と同様。総称型の定義を採用する拡張側は,外部に対して可視な型に

対してもこの規則に従わなければならない。

CLS

(フレームワーク)  この規則に反する型を開示してはならない。

10.7.3 

型制約再宣言 

CLS フレームワークは,総称型が,その基底クラス及び実装したすべてのインタフェースにおける総称

仮引数に存在する任意の制約を明示的に再宣言するということを保証しなければならない。CLS 拡張側及

び CLS 使用側は,満足させる必要がある制約の集合を決定するために,問題とされる特定の型を検査でき

ることが望ましい。

CLS

規則 44  総称型は,基底型又はインタフェースに対する任意の制約が,総称型の制約を満足させる

ことを保障するのに十分な制約を再宣言しなければならない。

注記   

CLS

(使用側)  この規則に反する型を利用する必要はない。制約を検査する利用側は,適用

可能な制約を決定するのにインスタンス化している型を見ることだけを必要とする。

CLS

(拡張側)  利用側と同様。総称型の定義を採用する拡張側は,この規則に従わなければ

ならない。

CLS

(フレームワーク)  この規則に反する型を開示してはならない。

10.7.4 

制約型の制限事項 

CLS

規則 45  総称仮引数に対する制約として利用される型は,それら自身が CLS 合致でなければなら

ない。

注記   

CLS

(使用側)  この規則に反する型を利用する必要はない。

CLS

(拡張側)  利用側と同様。総称型の定義を採用する拡張側は,CLS 合致を検査するとき,

この規則に従わなければならない。また,この規則に反する構文を提供する必要はない。

CLS

(フレームワーク)  この規則に反する型を開示してはならない。

10.7.5 

フレームワーク及び入れ子型のアクセス可能性 

CLI の総称は,総称型宣言及びその総称型のすべてのインスタンス化を,同じアクセス可能性の有効範


68

X 3016

:2010 (ISO/IEC 23271:2006)

   

囲をもつように扱う。しかし,言語がもつアクセス可能性規則は,これとは異なってもよい。ある言語は,

CLI のアクセス可能性モデルに従った選択をし,他の言語では,より限定的な事前インスタンス化モデル

を利用することができる。すべての CLS 言語で消費できるようにするには,CLS フレームワークは,保守

的な事前インスタンス化モデルのアクセス可能性を考慮して設計されなければならない。さらに,入れ子

型を公開したり,総称型の特定な別のインスタンス化を基にした限定公開メンバへのアクセスを要求した

りしてはならない。

これは,

ファミリアクセス可能性をもつ入れ子型を含んでいる識別情報に影響がある。

開いた総称型は,

ファミリアクセス可能性をもつ入れ子の総称型の特定なインスタンス化を含んでいる識別情報をもつフィ

ールド又はメンバを開示してはならない。総称基底クラス又は総称基底インタフェースの特定のインスタ

ンス化を拡張している非総称型は,ファミリアクセス可能性をもつ入れ子の総称型の異なるインスタンス

化を含んでいる識別情報をもつフィールド又はメンバを開示してはならない。

例  次の C#のソースコードを例として示す。

public class C<T> {

  protected class N { … }

  protected void M1(C<int>.N n) { … }

// Not CLS-compliant – C<int>.N not accessible form within C<T> in all

language

  Protected void M2(C<T>.N n) { … }

// CLS-compliant – C<int>.N accessible inside C<T>

}

public class D : C<long> {

  protected void M3(C<int>.N n) { … }

// Not CLS-compliant – C<int>.N not accessible in D(extends C<long>)

  protected void M4(C<long>.N n) { … }

// CLS-compliant - C<long>.N is accessible in D(extends C<long>)

}

これに対応する ILAsm のコードは次のようになる。

.class public ... C`1<T> ... {

  .class ... nested ... N<T> ... { }

  .method family hidebysig instance void M1(class C`1/N<int32> n) ...

{ }

  // Not CLS-compliant – C<int>.N not accessible form within C<T> in

all language

  .method family hidebysig instance void M2(class C`1/N<!0> n) ... { }

  // CLS-compliant – C<int>.N accessible inside C<T>

}

.class public ... D extends class C`1<int64> {

  .method family hidebysig instance void M3(class C`1/N<int32> n) ...

{ }

    // Not CLS-compliant – C<int>.N not accessible in D(extends C<long>)


69

X 3016

:2010 (ISO/IEC 23271:2006)

  .method family hidebysig instance void M4(class C`1/N<int64> n) ...

{ }

  // CLS-compliant - C<long>.N is accessible in D(extends C<long>)

}

CLS

規則 46  インスタンス化された総称型内の,入れ子型を含め,そのメンバの可視性及びアクセス可

能性は,その総称型宣言全体ではなく,特定のインスタンス化された総称型の有効範囲にあるとみなさな

ければならない。そのようにみなすことによって,CLS の可視性及びアクセス可能性の規則 12 を適用す

る。

注記   

CLS

(使用側)  この規則に反する型を利用する必要はない。

CLS

(拡張側) CLS 合致を決定するとき,アクセス可能性に対するより制約のある記法を使

用しなければならない。

CLS

(フレームワーク)  この規則に反するメンバを開示してはならない。

10.7.6 

フレームワーク及び抽象メソッド又は仮想メソッド 

CLS フレームワークは,CLS の拡張側に,そのフレームワークを利用するために,総称メソッドの上書

き又は実装を要求するライブラリを開示してはならない。これは,仮想総称メソッド又は抽象総称メソッ

ドが合致でないことを暗に意味しない。むしろ,CLS フレームワークは,適切な既定の動作をもつ具体的

な実装も提供しなければならないことを意味する。

CLS

規則 47  個々の抽象総称メソッド又は仮想総称メソッドには,既定の具体的な非抽象の実装が存在

しなければならない。

注記   

CLS

(使用側)  影響なし。

CLS

(拡張側)  総称メソッドを上書きする構文を提供する必要はない。

CLS

(フレームワーク)  適切な具体的な実装を提供することなしに,この規則に反する総称

メソッドを開示してはならない。

11 

共通言語仕様規則の集約 

この箇条で,参照用に CLS 規則の完全な集合を集約した。これらの規則は,

“外部可視”項目すなわち,

それら自身のアセンブリの外部に可視な型及び公開のアクセス可能性,ファミリアクセス可能性又は“フ

ァミリ又はアセンブリ”アクセス可能性をもつ型のメンバにだけ適用することを思い起こしてほしい。さ

らに,項目は System.CLSCompliantAttribute を使って CLS 合致であるか又は合致でないかを明示

的に印付けできる。CLS 規則は,CLS 合致と印付けされた項目にだけ適用する。

1) CLS

規則は,定義の行われるアセンブリの外部からアクセス可能又は可視である型の部分に適用さ

れる(7.3 参照)

2) CLS

合致でない型のメンバは CLS 合致に印付けされてはならない(7.3.1 参照)

3)

ボックス化値は,CLS 合致ではない(8.2.4 参照)

4)

アセンブリは,識別子の開始文字及び継続文字の集合を規定する Unicode Standard 3.0 の技術文書 15


70

X 3016

:2010 (ISO/IEC 23271:2006)

   

の附属書 7 に従わなければならない。これは,http://www.unicode.org/unicode/reports/tr15/tr15-18.html

で入手できる。識別子は,Unicode 正規化形式 C が定義する正規形式でなければならない。CLS の

目的に対して,二つの識別子は,

(Unicode のロケールを意識しない 1 対 1 小文字対応付けが規定す

るとおりに)それら識別子を小文字に対応付けたものが同じ場合に同じとする。すなわち,二つの

識別子が CLS において異なっていると考えられる場合,それらは,単に大文字と小文字とが異なっ

ている以上に異なっている。しかし,継承された定義を上書きするときに,CLI は,元の宣言の正

確な符号化が使用されることを要求する(8.5.1 参照)

5) CLS

合致の有効範囲で導入されるすべての名前は,それら名前が同一であって多重定義によって解

決される場合を除いて,種類とは独立に異なっていなければならない。すなわち,CTS は,一つの

型が一つのメソッド及び一つのフィールドに対して同じ名前を使用することを許すが,CLS は許さ

ない(8.5.2 参照)

6) CTS

では異なる識別情報は区別可能だが,CLS では,フィールド及び入れ子になった型は,識別子

の比較だけによって異なっていなければならない。

(識別子の比較によって)同じ名前をもつメソッ

ド,特性及びイベントは,単に返却値の型だけ以外によって異なっていなければならない。ただし,

CLS 規則 39 で規定した場合を除く(8.5.2 参照)。

7)  enum

の基礎となる型は,

組込みの CLS 整数型でなければならない。

フィールドの名前は,

“value__”

でなければならず,そのフィールドは,RTSpecialName と印付けされなければならない(8.5.2 

照)

8)  System.FlagsAttribute

第 章参照)カスタム属性が存在する又は存在しないによって示さ

れる二つの異なる種類の enum が存在する。一つは,名前付き整数値を表現し,もう一つは,名前

付きでない値を生成するために結合可能な名前付きビットフラグを表現する。enum の値は,指定

された値に制限されない(8.5.2 参照)

9)  enum

のリテラル静的フィールド(8.6.1 参照)は,enum それ自体の型をもたなければならない(8.5.2

参照)

10)

アクセス可能性は,継承されたメソッドを上書きしても変化してはならない。ただし,

“ファミリ又

はアセンブリ”アクセス可能性をもつ異なるアセンブリから継承されたメソッドを上書きする場合

を除く。この場合,ファミリアクセス可能性になる(8.5.3.2 参照)

11)

識別情報に出現するすべての型は,CLS 合致でなければならない。インスタンス化された総称型を

構成するすべての型は,CLS 合致でなければならない(8.6.1 参照)

12)

型及びメンバの可視性及びアクセス可能性は,そのメンバそれ自体が可視であってアクセス可能な

ときにはいつでも,メンバの識別情報内の型が可視であってアクセス可能でなければならないとい

うようになっていなければならない。例えば,アセンブリの外部で可視である公開メソッドは,そ

のアセンブリ内でだけ可視な型の実引数をもっていてはならない。あらゆるメンバの識別情報の中

で使用されるインスタンス化された総称型を構成する型の可視性及びアクセス可能性は,そのメン

バ自体が可視及びアクセス可能なときはいつでも,可視及びアクセス可能でなければならない。例

えば,アセンブリの外で可視なメンバの識別情報の中に存在するインスタンス化された総称型は,

型がそのアセンブリ内部だけで可視な総称実引数をもってはならない(8.6.1 参照)

13)

リテラルであって静的な値は,フィールド初期化メタデータ(

第 章参照)を用いて指定される。

CLS 合致のリテラルは,そのリテラルと厳密に同じ型(又はそのリテラルが enum である場合は基

礎となる型)

のフィールド初期化メタデータで指定される値をもたなければならない(8.6.1.2 参照)


71

X 3016

:2010 (ISO/IEC 23271:2006)

14)

型付けされた参照は,CLS 合致ではない(8.6.1.3 参照)

15)  vararg

制約は CLS の一部ではなく,CLS が提供する呼出し規約だけを標準の管理下呼出し規約と

する(8.6.1.5 参照)

16)

配列は,CLS 合致の型をもつ要素をもち,配列のすべての次元は,0 の下限をもつ。項目が配列で

あるという事実及び配列の要素型だけが,多重定義を区別する目的で必要となる。多重定義が二つ

以上の配列型に基づいている場合,要素型は名前付きの型でなければならない(8.9.1 参照)

17)

管理外ポインタ型は,CLS 合致ではない(8.9.2 参照)

18) CLS

合致のインタフェースは,それを実装するために非 CLS 合致のメソッドの定義を要求してはな

らない(8.9.4 参照)

19) CLS

合致のインタフェースは,静的メソッドを定義してはならないし,フィールドを定義してもな

らない(8.9.4 参照)

20) CLS

合致のクラス,値型及びインタフェースは,CLS 合致でないインタフェースの実装を要求して

はならない(8.9.6.4 参照)

21)

オブジェクト構築子は,継承されたインスタンスデータへのアクセスが発生する前に,その基底ク

ラスのクラス構築子を呼び出さなければならない。これは,値型には適用されない。値型は,構築

子をもつ必要はない(8.9.6.6 参照)

22)

オブジェクト構築子は,オブジェクトの生成の一部として以外では呼び出されてはならないし,オ

ブジェクトは,2 回初期化されてはならない(8.9.6.6 参照)

23)  System.Object

は,CLS 合致とする。あらゆる他の CLS 合致クラスは,一つの CLS 合致クラス

から継承されなければならない(8.9.9 参照)

24)

特性の getter メ ソ ッド 及び setter メ ソッド を実装 するメ ソッドは, メタデ ータの 中に

SpecialName

と印付けられなければならない(

第 章及び 8.11.3 参照)。

25)

この規則は,もはや使用しない。

注記  この規格の以前の版では,この規則は,“特性及びそのアクセス操作子のアクセス可能性は,

同じでなければならない。

”と規定されていた。この規則を取り除くことによって,例えば,

setter

へのアクセスを制限しながら,getter へのアクセスを公開できる。

26)

特性及びそのアクセス操作子は,すべて静的,すべて仮想又はすべてインスタンスでなければなら

ない(8.11.3 参照)

27)

特性の型は,getter の返却値型でなければならず,setter の最後の実引数の型でなければなら

ない。特性の仮引数の型は,getter の仮引数の型でなければならず,setter の最後の仮引数以

外のすべての仮引数の型でなければならない。

これらの型のすべては,

CTS 合致でなければならず,

管理下ポインタであってはならない。すなわち,参照によって渡されてはならない(8.11.3 参照)

28)

特性は,固有の名前付けパターンを守らなければならない(10.4 参照)

。CLS 規則 24 で参照された

SpecialName

属性は,適切な名前比較においては無視されなければならず,識別子規則を守らな

ければならない。特性は,getter メソッド,setter メソッド又はその両方をもたなければなら

ない(8.11.3 参照)

29)

イベントを実装するメソッドは,メタデータの中に SpecialName と印付けられなければならない

8.11.4 参照)

30)

イベント及びそのアクセス操作子のアクセス可能性は,同一でなければならない(8.11.4 参照)

31)

イベントのための add メソッド及び remove メソッドは,両方とも存在するか,両方とも存在しな


72

X 3016

:2010 (ISO/IEC 23271:2006)

   

いかのいずれかでなければならない(8.11.4 参照)

32)

イベントのための add メソッド及び remove メソッドは,それぞれ,その型がイベントの型を定義

する一つの仮引数をもたなければならず,System.Delegate から派生していなければならない

8.11.4 参照)

33)

イベントは,固有の名前付けパターンを守らなければならない(10.4 参照)

。CLS 規則 29 で参照さ

れた SpecialName 属性は,適切な名前比較においては無視されなければならず,識別子規則を守

らなければならない(8.11.4 参照)

34) CLS

は,カスタム属性の符号化の部分集合だけを許す。これらの符号化で出現しなければならない

ものは,System.Type,System.String,System.Char,System.Boolean,System.Byte,

System.Int16

,System.Int32,System.Int64,System.Single,System.Double 及び

CLS 合致の基底整数型に基づく列挙型だけとする(9.7 参照)。

35) CLS

は,公開の可視である必す(須)修飾子(modreq,

第 章参照)を許さないが,CLS が理解

しない任意選択修飾子(modopt,

第 章参照)は許す(9.7 参照)。

36)

大域的に静的なフィールド及びメソッドは,CLS 合致ではない(9.8 参照)

37)

特性及びメソッドだけを多重定義できる(10.2 参照)

38)

特 性 及 び メ ソ ッ ド は , そ の 仮 引 数 の 個 数 及 び 型 に だ け 基 づ い て 多 重 定 義 で き る 。 た だ し ,

op_Implicit

及び op_Explicit という名前の変換演算子は,それらの返却型に基づいて多重定

義できる(10.2 参照)

39)  op_Implicit

又は op_Explicit のいずれかが提供されている場合,その強制型変換に対する代

替手法を提供しなければならない(10.3.3 参照)

40)

送出されるオブジェクトは,System.Exception 又はそれを継承した型でなければならない。し

かし,CLS 合致のメソッドは,他の例外型が伝ぱ(播)しないようにすることを要求しない(10.5

参照)

41)

属性は System.Attribute 又はそれを継承した型でなければならない(10.6 参照)

42)

入れ子型は,少なくとも囲んでいる型と同じ個数の総称仮引数をもたなければならない。入れ子型

の総称仮引数は,囲んでいる型の総称仮引数の位置に対応する(10.7.1 参照)

43)

総称型の名前は,入れ子でない型で宣言された型仮引数の個数,又は,入れ子型で新たに宣言され

た型仮引数の個数を,上で定義した規則で符号化する(10.7.2 参照)

44)

総称型は,基底型又はインタフェースに対する任意の制約が,総称型の制約を満足させることを保

障するのに十分な制約を再宣言しなければならない(10.7.3 参照)

45)

総称仮引数に対する制約として利用される型は,それら自身が CLS 合致でなければならない(10.7.4

参照)

46)

インスタンス化された総称型内の,入れ子型を含め,そのメンバの可視性及びアクセス可能性は,

その総称型宣言全体ではなく,特定のインスタンス化された総称型の有効範囲にあるとみなさなけ

ればならない。そのようにみなすことによって,CLS の可視性及びアクセス可能性の規則 12 を適

用する(10.7.5 参照)

47)

個々の抽象総称メソッド又は仮想総称メソッドには,既定の具体的な非抽象の実装が存在しなけれ

ばならない(10.7.6 参照)

48) 

一つの型の中で宣言された二つ以上の CLS 合致のメソッドが同じ名前をもち,かつ,ある特定の型

のインスタンス化集合に対して,

同じ仮引数及び返却値型をもつ場合,

これらすべてのメソッドは,


73

X 3016

:2010 (ISO/IEC 23271:2006)

それらの型のインスタンス化において意味的に同じでなければならない。

12 

仮想実行システム 

仮想実行システム(VES)は管理下コードを実行するための環境を提供する。これは,組込みデータ型

の集合を直接提供し,関連付けられた計算機モデル及び状態,制御フローの構築要素の集合並びに例外処

理モデルをもった仮想計算機を定義する。VES の目的は,CIL 命令集合を実行するための要件を提供する

ことである(

第 章参照)。

12.1 

提供されるデータ型 

CLI は,表 6  CLI で直接提供されるデータ型で示されるデータ型を直接提供する。すなわち,これら

のデータ型は,CLI 命令集合を使って操作することができる(

第 章参照)。

表 6CLI で直接提供されるデータ型 

データ型 

定義 

int8

8 ビットの 2 の補数符号付き値。

unsigned int8

8 ビットの符号なし 2 進値。

int16

16 ビットの 2 の補数符号付き値。

unsigned int16

16 ビットの符号なし 2 進値。

int32

32 ビットの 2 の補数符号付き値。

unsigned int32

32 ビットの符号なし 2 進値。

int64

64 ビットの 2 の補数符号付き値。

unsigned int64

64 ビットの符号なし 2 進値。

float32

32 ビット IEC 60559:1989 浮動小数点数。

float64

64 ビット IEC 60559:1989 浮動小数点数。

native int

プラットフォーム固有の大きさの 2 の補数符号付き値。

native unsigned int

プラットフォーム固有の大きさの符号なし 2 進値,管理外ポインタ。

F

プラットフォーム固有の大きさの浮動小数点数(VES 内部用,使用者に対して
非可視)

O

管理下メモリへのプラットフォーム固有の大きさのオブジェクト参照。

&

プラットフォーム固有の大きさの管理下ポインタ(管理下メモリ内を指すこと
が可能)

CLI モデルは,評価スタックを使用する。メモリから評価スタックに値を複写する命令は“loads”と

する。スタックからメモリに値を複写し戻す命令は“stores”とする。

表 6  CLI で直接提供されるデー

タ型にあるデータ型の完全な集合は,メモリ内で表現できる。しかし,評価スタック上に格納される値,

すなわち,int32,int64,native int に対する操作において,CLI はこれらの部分集合だけを取り扱

う。さらに,CLI は,内部評価スタック上の浮動小数値を表現するための内部データ型を取り扱う。内部

データ型のサイズは,実装依存とする。評価スタック上の浮動少数値の取扱いに関する更なる情報につい

ては,12.1.3 及び

第 章を参照。短数値(int8,int16,unsigned int8,及び unsigned int16)

は,ロードされるときに拡大化され,格納されるときに縮小化される。これは,数値及びオブジェクト参

照に関して,メモリセルが 1,2,4 及び 8 バイトであるが,スタック上に位置するときは,4 又は 8 バイ

トの幅をもっていると仮定した計算機モデルを反映している。利用者定義の値型は,メモリ位置又は大き

さの制限をもたないスタック上に現れることができる。それらの組込みの演算は,それらのアドレスの計

算及びスタックとメモリとの間での複写だけとする。

(4 又は 8 バイトの整数値を単に取り扱うのではなく)短数値を特別に取り扱う CLI 命令は,次の命令

だけとする。


74

X 3016

:2010 (ISO/IEC 23271:2006)

   

−  メモリからのロード命令及びメモリへの格納命令: ldelem,ldind,stelem,stind

−  データ変換: conv,conv.ovf

−  配列の生成: newarr

符号付き整数型(int8,int16,int32,int64 及び native int)並びにそれぞれの符号なし整数

型(unsigned int8,unsigned int16,unsigned int32,unsigned int64 及び native unsigned

int

)の違いは,整数のビットをどのように解釈するかだけとする。符号なし整数が符号付き整数と異な

る扱いをする演算(例えば,比較演算又はオーバフローを生じる演算)では,整数を符号なしとして扱う

命令(例えば,cgt.un 及び add.ovf.un)が個別にある。

この命令集合設計は,CLI からプラットフォーム固有のコードへのコンパイラ(例えば JIT)及び CIL

のインタプリタを,それらがより少ない個数のデータ型を内部的に追跡できるようにすることによって,

単純化する(12.3.2.1 参照)

次に示すように,CIL 命令は,その演算対象の型を規定しない。代わりに,CIL は演算対象の型の経過

を保持する。これは,データの流れに基づき,次に示すスタックの一貫性要件に支えられて行われる。例

えば,単一の add 命令は,スタックにある二つの整数又は二つの浮動小数点数を加算する。

12.1.1 

プラットフォーム固有の大きさ:native intnative unsigned int及び

プラットフォーム固有の大きさの型(native int,native unsigned int,O 及び&)は,値の大

きさの選択を遅らせるための CLI 内の機構とする。

これらのデータ型は CLI 型として存在するが,

CLI は,

特定の CPU に対する固有の大きさにそれぞれを対応付ける

(例えば,

データ型 I は Pentium 処理系では int32

に対応付けるが,IA64 処理系では int64 に対応付けられるであろう。

。したがって,CLI が初期化され,

そのアーキテクチャが知られている場合,大きさの選択は JIT コンパイル時又は実行時まで遅らされる。

これは,

フィールド及びスタックフレームオフセットが,

コンパイル時に知られていないことを意味する。

フィールドのオフセットが初期の段階で計算されない Visual Basic のような言語では,これは困難ではな

い。C 又は C++のような言語のように,ソースコードがコンパイルされるときに大きさを知っていなけれ

ばならない場合,それらが 8 バイト占有する保守的な仮定が受け入れられることがある(例えば,コンパ

イル時に記憶域を配置する場合)

12.1.1.1  native unsigned int

型としての管理外ポインタ 

注記  C のような言語では,プラットフォーム固有のコードにすべてコンパイルするとき,ポインタ

の大きさがコンパイル時に知られていて,管理下オブジェクトがない場合,固定の大きさの符

号なし整数型(unsigned int32 又は unsigned int64)をポインタとして利用できる。し

かし,コンパイル時に選択されたポインタの大きさは不利な点をもっている。コンパイル時に

ポインタが 32 ビットの大きさをもつと選択されれば,たとえ,64 ビット計算機で実行させて

もアドレス空間は 4 ギガバイトに制限される。さらに,32 ビットコードに渡し戻されるポイン

タは常に 32 ビット内に適合させるように,64 ビット CLI は特別なはからいを必要とする。コ

ンパイル時にポインタを 64 ビットとして選択されると,そのコードは 32 ビット計算機で実行

できるが,どのデータ構造内のポインタも CLI で必要とされる大きさの 2 倍になる。

他の言語では,データ型の大きさをコンパイル時に必要としない場合,コンパイル時から,

CLI 初期化時にポインタの大きさの選択を遅らせることが望ましい。その場合,同じ CLI コー

ドは,そのアプリケーションが必要とする大きなアドレス空間を扱うことができる。一方,大

きなアドレス空間を必要としないアプリケーションに対して 32 ビットポインタの大きさに対

する利点を得ることもできる。


75

X 3016

:2010 (ISO/IEC 23271:2006)

native unsigned int

型は,VES での管理外ポインタを表現するために使われる。メタデータは,

管理外ポインタに強い型付けを行う方法で表現されることを許している。しかし,これらの型は VES で利

用される native unsigned int 型に変換される。

12.1.1.2 

管理下ポインタ型:及び

O

データ型は,CLI によって管理されるオブジェクト参照を表現する。その結果,指定された操作の個

数が大きく制限される。特に,参照は,O データ型が参照型を操作することを示す操作(例えば,ceq 及

び ldind.ref)又はメタデータの参照を許可することを示す操作(例えば,call,dsfld 及び stfld)

にだけ,使う。

&データ型(管理下ポインタ)は O 型に類似しているが,オブジェクトの内部を指し示す。すなわち,

管理下ポインタはオブジェクトの内部にあるフィールド又は配列の内部の要素を指し示すことが許される。

オブジェクト又は配列の先頭を指し示すことは許されない。

オブジェクト参照(O)及び管理下ポインタ(&)は,それらが参照するデータが移動することがあるか

ら,ごみ集めの間に変更されうる。

注記  要約すると,オブジェクト参照すなわち O 型はオブジェクトの外側すなわちオブジェクトの全

体を参照する。しかし,管理下ポインタすなわち&型はオブジェクトの内部を参照する。VES

内では,参照されるオブジェクトのフィールドの受渡しが,仮引数の型を表現するために&型

を使って表現されるから,&型は,ソース言語では  "参照渡し型"  と呼ばれることがある。

より柔軟に管理下ポインタを使えるように,評価スタック,静的変数及び管理外メモリといった CLI ご

み集め子の制御の下にない領域を指し示すことも許される。これは,管理外ポインタ(U)が使われるの

と同じ数多くの方法で使用することも許される。すべてのコードが正当性検証可能である場合,正当性検

証の制限は,評価スタック上の値への管理下ポインタが,それが指し示す位置の生存が長く続かないこと

を保障する。

12.1.1.3 

移植性:メモリ内のポインタの格納 

calli

,cpblk,initblk,ldind.*及び stind.*を含む幾つかの命令は,スタックの先頭のアドレ

スを期待する。このアドレスがメモリ内に格納されたポインタから派生されている場合,重要な移植性の

考慮すべき事柄がある。

1)

プラットフォーム固有の大きさの整数又はポインタ位置(native int 型,O 型,native unsigned

int

型又は&型)にポインタを格納するコードは常に完全に移植性がある。

2)  8

バイト整数(int64 型又は unsigned int64 型)にポインタを格納するコードは移植性がある

よ う に す る こ と が で き る 。 し か し , こ の こ と は , そ れ が ポ イ ン タ と し て 使 用 さ れ る 前 に ,

conv.ovf.un

命令がメモリ形式からポインタに変換するために使われることを要件とする。また,

このことは 32 ビット計算機では実行時例外を発生させることがある。

3)

メモリにポインタを格納するときに,任意の短整数を使用するコード(int8,unsigned int8,

int16

,unsigned int16,int32,及び unsigned int32)には,32 ビット計算機上で正しく

動作する unsigned int32 又は int32 を利用していたとしても,一切移植性はない。

12.1.2 

短整数データ型の処理 

CLI は,4 バイト整数又は 8 バイト整数のいずれかをもつ評価スタックであるが,1 バイト整数及び 2 バ

イト整数も取り込むメモリモデルを定義する。正確を期すならば,次の規則を CLI モデルの一部とする。

−  1 バイト又は 2 バイトの位置(実引数,局所,フィールド,静的,及びポインタ)からのロードでは,

4 バイト値に拡張する。既知の型(例えば,局所変数)の位置でのロードでは,アクセスされている


76

X 3016

:2010 (ISO/IEC 23271:2006)

   

型が,符号拡張(符号付きの位置)又はゼロ拡張(符号なし位置)のいずれでロードするかを決定す

る。ポインタの逆参照(ldind.*)については,命令それ自身が,その位置の型を識別する(例えば,

ldind.u1

は符号なし位置を示し,ldind.i1 は符号付き位置を示す。

−  1 バイト位置又は 2 バイト位置に格納すると,その大きさに合わせるために切捨てが起こり,オーバ

フローエラーの保障はない。特殊な命令(conv.ovf.*)は,格納する前にオーバフローを検査する

ために利用できる。

−  メソッド呼出しは,評価スタックからそのメソッドの実引数に値が代入される。したがって,実引数

が仮引数より大きい場合,まさに他の格納で起こるような切捨てが発生する。

−  メソッドからの返却は,値を不可視な返却変数に代入するから,返却される値の型がメソッドの返却

型より大きい場合,同様に格納の時の切捨てが発生する。この返却変数の値が評価スタック上に積ま

れるから,そこで,他のロードに時に発生する符号拡張又はゼロ拡張が発生する。拡張の後の切捨て

は,計算される値を変更なしに単に残すのとは同じではない。

これらの規則が対象とする計算機に固有の規約で正確なモデル化を確実に行うことは,CIL からプラッ

トフォーム固有の機械語命令への変換の責任とする。例えば,CLI は,短整数実引数の切捨てが呼出し位

置で発生するのか又は対象とするメソッド内で発生するのかは規定しない。

12.1.3 

浮動小数点数データ型の処理 

浮動小数点数計算は,IEC 60559:1989 で規定されたように処理されなければならない。この規格は,浮

動小数点数の符号化,基本操作及び基本変換の定義,丸め制御並びに例外処理について規定する。

この規格は,特別な値,NaN(非数)

,正の無限大(+infinity)及び負の無限大(–infinity)を定義する。

これらの値は,オーバフローの状態で返却される。一般的な原則は,制限のない値をもつ演算が非数を返

す一方,制限内の値をもつ演算が適切な無限大を返すことである。詳細は,IEC 60559:1989 による。

注記  次の例は,最も一般的に直面する事例を示している。

X rem 0 = NaN

0 *  正の無限大  = 0 *  負の無限大 = NaN

(X / 0) =  正の無限大,if X>0

                            NaN,if X=0

                負の無限大,if X < 0

NaN op X = X op NaN = NaN :  すべての演算について

(正の無限大) + (正の無限大) =  (正の無限大)

X / (正の無限大) = 0

X mod (負の無限大) = -X

(正の無限大) - (正の無限大) =  NaN

注記  この規格は非正規化浮動小数点数の振る舞いについて規定していない。また,そのような表現

を生成しなければならないとき又は生成すべきかどうかについても規定していない。この規格

も,IEC 60559:1989 を順守する。さらに,この規格は生成された NaN(非数)の正確なビット

パターンへのアクセス方法及び NaN を 32 ビット表現と 64 ビット表現との間の変換に対する振

る舞いについても規定していない。この振る舞いのすべては,意図的に実装固有として残して

いる。

比較のために,無限大値は,有限値との比較の時には,非常に大きな値をもつ妥当な符号付きの値のよ

うに振る舞う。NaN は,比較のための順序化はされない(clt,clt.un 参照)


77

X 3016

:2010 (ISO/IEC 23271:2006)

IEC 60559:1989

標準は,通常の状況にない場合(オーバフロー,不正な演算対象など)に例外が送出さ

れることを許可しているが,CLI はこれらの例外を生成しない。その代替手段として,CLI は NaN,正の

無限大及び負の無限大を返却値に使う。また,利用者に,結果が NaN,正の無限大及び負の無限大である

かどうかの例外を生成することを許可する命令 ckfinite を提供している。

IEC 60559:1989

が定義している丸めモードは,CLI によって“最近値への丸め”

“Round to Nearest”

)に

設定されなければならない。CLI もクラスライブラリも,この設定を変更するための機構を提供していな

い。CLI 規格適合処理系は,この設定に対する外部インタフェースに対する弾力性をもたせる必要はない。

すなわち,浮動小数点演算を実行する前にモードを再設定する必要はなく,初期設定の一部で設定されて

いるモードに依存させることができる。

整数変換に対して,CLI で提供されている既定の操作は“ゼロ方向への切捨て”とする。クラスライブ

ラリは,他の三つの伝統的な操作[最も近い整数を得る round(最近値への丸め)

,より大でない最大の整

数を得る floor(切捨て)

,より小でない最小の整数を得る ceiling(切上げ)

]のいずれかを利用して浮動小

数点数から整数への変換を許可するように供給される。

浮動小数点数(静的,配列の要素及びクラスフィールド)の記憶域の場所は,固定の大きさとする。提

供される記憶域の大きさは float32 及び float64 とする。それ以外の場所(評価スタック上の実引数,

返却値及び局所変数)の浮動小数点数は,内部の浮動小数点数型を使って表現される。このそれぞれのイ

ンスタンスにおいて,変数又は式の名目上の型は float32 又は float64 のいずれかであって,その値は付加

的な範囲及び/又は精度をもった内部的な表現になり得る。内部的な浮動小数点表現の大きさは実装依存

であり,様々にできるが,その精度は,表現されている変数又は式と少なくとも同じ大きさの精度をもた

なければならない。float32 又は float64 から内部表現への暗黙の拡大変換は,その型が記憶域からロ

ードされるときに実行される。その内部表現は,通常,ハードウェアに応じた固有の大きさである。すな

わち,それは操作上の効率的な実装のために要求された大きさである。その内部表現は次のような仕組を

もっていなければならない。

−  内部表現は,名目上の型と同じかそれより大きい精度及び範囲をもたなければならない。

−  内部表現への変換及び内部表現からの変換は値を保持していなければならない。

注記  このことは,float32(又は float64)から内部表現への暗黙の拡大変換の後の,内部表現

から float32(又は float64)への明示的な変換は,もともとの float32(又は float64)

の値と同一値にすることを意味する。

注記  この設計は,浮動小数点数が記憶域の場所に置かれるまで,CLI がプラットフォーム依存の高

性能な表現を選択することを許可している。例えば,利用者が要求する以上の精度を提供する

ハードウェアのレジスタ上に浮動小数点数を残しておくことができる。同時に,CIL 生成器は,

変換命令を利用して言語に特有な規則に沿って操作することを強制できる。

内部表現が名目上の型以上の範囲及び/又は精度をもつ浮動小数点の値が記憶域の場所に置かれるとき,

自動的に記憶域の型への強制型変換が行われる。これは,精度の消失又は範囲外の値(非数,正の無限大

又は負の無限大)の生成をともなうことができる。しかし,変更が行われていない状態で記憶域の場所か

ら再ロードされる場合には,その値は将来の利用のために内部表現内に残ってもよい。残された値が,別

名によるアクセス及び別の実行スレッド(12.6 参照)の影響を考慮し,後続のロード時にも妥当であるこ

とを保障するのはコンパイラの責任とする。その内部表現が,それに関連する型で正確に表現可能としな

けばならないとき,余分な精度をもたせ,明示的な変換(conv.r4 又は conv.r8)の実行が後続すると

いう自由は許可されない。


78

X 3016

:2010 (ISO/IEC 23271:2006)

   

注記  特定の記憶域型に変換できない値を検出するために,変換命令(conv.r4 又は conv.r8)を

使い,その後で ckfinite を使って無限大値の検査を行うことができる。特定の記憶域型に変

換するときにアンダフローを検出するために,ゼロとの比較がその変換の前と後とで要求され

る。

注記  float32 又は float64 より大きな内部表現の使用は,一見無関係に見える開発者のコードの

変更によって計算誤差が生じることがある。その結果は,内部表現(例えば,レジスタ内)か

らスタック上の場所に流出した値にできる。

12.1.4 CIL

命令及び算術型 

注記  この細分箇条は参考情報であり規定ではない。

数値を扱う CIL 命令の多くは,評価スタック(12.3.2.1 参照)上から演算対象を取り,これらの入力は,

VES が理解する関連型をもっている。結果として,add のような単一の演算は,任意の数値データ型の入

力をもつことができる。すべての命令が,演算対象の型のすべての組合せを取り扱うわけではない。加算

及び減算以外の 2 項演算は,両方の演算対象が同じ型であることを要求する。加算及び減算では,管理下

ポインタ(型&及び O)に整数を加える又は減じることが許可される。詳細は,

第 章による。

数値:これらの命令は整数及び浮動小数点数の両方を扱う。整数は符号付きとして扱う。単純算術計算,

条件分岐及び比較命令がある。

整数:これらの命令は整数だけを扱う。ビット操作及び符号なし整数の除算及び剰余算がある。

浮動小数点数:これらの命令は浮動小数点数だけを扱う。

特殊:これらの命令は,整数及び/又は浮動小数点数を扱うが,異なる大きさ及び符号なし整数を特別

に扱う変異形である。オーバフロー検出をともなう整数演算,データ変換命令,評価スタックとメモリの

他の場所(12.3.2 参照)との間でデータを移送する操作がある。

符号なし/順序なし:整数を符号なしとして扱い,浮動小数点数を特に順序なしと(より大きい又は順

序なしで分岐するように)みなす,特別な比較及び分岐命令がある。

ロード定数:ロード定数(ldc.*)命令は,int32,int64,float32 又は float64 型の定数をロー

ドするのに使われる。プラットフォーム固有の大きさをもつ定数(native int 型)は,conv.i 又は

conv.u

を使って(int64 からの変換は移植性がない)int32 から変換されることによって生成される。

表 7  数値種類の CIL 命令には,命令の種類ごとに,数値を扱う CIL 命令を示す。“.*”で終わる命令

は,

(データの大きさ及びそのデータが符号付き又は符号なしで扱われるかどうかに基づいて)

その命令の

すべての変異形を示す。

“[.s]”は,これらの命令の長形式及び短形式の両方を意味する。


79

X 3016

:2010 (ISO/IEC 23271:2006)

表 7−数値種類の CIL 命令 

add 

数値

div 

数値

add.ovf.* 

特殊

div.un 

整数

and 

整数

ldc.* 

ロード定数

beq[.s] 

数値

ldelem.* 

特殊

bge[.s] 

数値

ldind.* 

特殊

bge.un[.s] 

符号なし/順序なし

mul 

数値

bgt[.s] 

数値

mul.ovf.* 

特殊

bgt.un[.s] 

符号なし/順序なし

neg 

整数

ble[.s] 

数値

newarr.* 

特殊

ble.un[.s] 

符号なし/順序なし

not 

整数

blt[.s] 

数値

or 

整数

blt.un[.s] 

符号なし/順序なし

rem 

数値

bne.un[.s] 

符号なし/順序なし

rem.un 

整数

ceq 

数値

shl 

整数

cgt 

数値

shr 

整数

cgt.un 

符号なし/順序なし

shr.un 

特殊

ckfinite 

浮動小数点数

stelem.* 

特殊

clt 

数値

stind.* 

特殊

clt.un 

符号なし/順序なし

sub 

数値

conv.* 

特殊

sub.ovf.* 

特殊

conv.ovf.* 

特殊

xor 

整数

12.1.5 CIL

命令及びポインタ型 

注記  この細分箇条は参考情報であり規定ではない。

注記  オブジェクトのポインタを追跡できること及び到達可能でなくなったオブジェクトを回収する

(すなわち,ごみ集めによってメモリ管理を提供する。

)ことができることを要求する CLI の

実装がある。この処理は,

ワーキングセットを削減するためにオブジェクトを移動させるから,

移動したオブジェクトのポインタすべてが変更される。これを適切に動作させるために,オブ

ジェクトへのポインタはある方法でだけ利用できる。O(オブジェクト参照)及び&(管理下ポ

インタ)データ型が,これらの制約に対する形式とする。

オブジェクト参照の使用は,CIL で堅く制限されている。これは,ほぼ例外なく“仮想オブジェクト命

令”で使われる。これは,オブジェクトを扱うために特殊に設計された命令である。さらに,オブジェク

ト参照を扱う CIL の基本命令がわずかにある。特に,オブジェクト参照は,次のことができる。

1)

受け渡されるメソッドの実引数が,評価スタック上へロードされる(ldloc,ldarg)

。そのスタッ

クからそのホーム場所へ格納される(stloc,starg)

2)

評価スタックを複製化する又は評価スタックから取り出す(dup,pop)

3)

データ型が異ならない他のオブジェクト参照との等価性を検査する(beq,beq.s,bne,bne.s,

ceq

4)

管理外コードの型についてだけ,管理外メモリからロード及び管理外メモリへの格納を行う

(ldind.ref,stind.ref)

5)  null

参照の生成(ldnull)

6)

値を返却する(ret)


80

X 3016

:2010 (ISO/IEC 23271:2006)

   

管理下ポインタは,更に,次の基本操作をもつ。

1)

管理下ポインタを返却する,バイト単位での整数の加算及び減算(add,add.ovf.u,sub,

sub.ovf.u

2)

同じ配列の要素の間のバイト数を返却する,それぞれの要素を指す二つの管理下ポインタの減算

(sub,sub.ovf.u)

3)

二つの管理下ポインタに基づいた符号なしの比較及び条件分岐(bge.un,bge.un.s,bgt.un,

bgt.un.s

,ble.un,ble.un.s,blt.un,blt.un.s,cgt.un,clt.un)

管理下ポインタに関する算術演算は,同じ配列の要素に対するポインタに対した使用することだけを意

図された演算とする。管理下ポインタに対する他の算術演算の動作は規定しない。

注記  メモリ管理主体はプログラムとは非同期に実行され,管理下ポインタを変更するから,個々の

オブジェクトの間隔及びそれらの相対位置を変更できる。

12.1.6 

集約データ 

注記  この細分箇条は参考情報であり規定ではない。

CLI は集約データを扱う。これは,部分部品(配列,構造体又はオブジェクトインスタンス)をデータ

項目にもつが,値を複写することで渡される。この部分部品に管理下メモリへの参照を含めることができ

る。集約データは値型を使って表現され,二つの方法でインスタンス化することができる。

ボックス化:オブジェクトとして,実行時に完全な型情報をもち,通常 CIL メモリ管理主体によって

ヒープ上に割り当てられる。

ボックス化解除:

“値型インスタンス”として,実行時に型情報をもたず,ヒープ上には直接割り当て

られない。ヒープ上の大きな構造体の一部,すなわちクラスフィールド,ボックス化された値型のフ

ィールド又は配列の要素にすることができる。また,局所変数又は入力実引数の配列(12.3.2 参照)

に置くこともできる。さらに,クラスの静的変数若しくは静的メンバ,又は他の値型の静的メンバと

して割り当てることもできる。

値型のインスタンスが,メソッド実引数として規定され,メソッド呼出しで複写されるから,

(クラスの

ボックス化されたインスタンス)オブジェクトという意味での同一性をもたない。

12.1.6.1 

値に対するホーム 

注記  この細分箇条は参考情報であり規定ではない。

データ値のホームは,それを再利用できるように格納された場所とする。CLI は,次のホーム場所を直

接取り扱う。

−  入力実引数

−  メソッドの局所変数

−  オブジェクト型又は値型のインスタンスフィールド

−  クラス,インタフェース又はモジュールの静的フィールド

−  配列の要素

個々のホーム場所について,ホーム場所のアドレスを(実行時に)計算する方法及びホーム場所の型を

(JIT コンパイル時に)計算する方法がある。これらは

表 8  ホーム場所のアドレス及び型として整理する。


81

X 3016

:2010 (ISO/IEC 23271:2006)

表 8−ホーム場所のアドレス及び型 

ホームの型 

実行時のアドレス計算 JIT 時の型決定 

実引数

値渡し実引数用の ldarga 又は参照渡し実引数用の ldarg。 メソッド識別情報。

局所変数

値渡し局所用の ldloca,又は,参照渡し局所用の ldloc。 メソッドヘッダ内の局所識別情報。

フィールド

ldflda

 

クラス,インタフェース又はモジュー

ル内のフィールド型。

静的

ldsflda

 

クラス,インタフェース又はモジュー

ル内のフィールド型。

配列の要素

1 次元で添字が 0 から始まる配列用の ldelema 又はインス
タンスメソッド呼出しアドレス。 

配列の要素型。

ホームに加え,組込み値が二つの方法(すなわち,ホーム抜き。

)で存在できる。

1)

定数値(通常 ldc.*命令を使って CIL 命令列に組み込まれる。

2)

メソッド又は CIL 命令による返却時の評価スタック上の中間値。

12.1.6.2 

値型インスタンスに対する操作 

注記  この細分箇条は参考情報であり規定ではない。

値型インスタンスは,その生成,実引数としての受渡し,値としての返却並びに局所,フィールド及び

配列要素への格納及びそれらからの抽出(すなわち,複写)を行うことができる。クラスのように,値型

は静的メンバ及び非静的メンバ(メソッド及びフィールド)の両方をもつことができる。しかし,実行時

に型情報をもち込まないから,値型インスタンスは system.Object 型の項目に対して置換可能ではない。

この点において,組込み型 int32,int64 などのように振る舞う。値型インスタンスと Object インス

タンスとの間の変換を行う二つの操作がある。これらは,ボックス化及びボックス化解除である。

12.1.6.2.1 

値型インスタンスの初期化 

注記  この細分箇条は参考情報であり規定ではない。

値型インスタンスの初期化に対する選択肢が三つある。ホームのアドレスのロード(

表 8  ホーム場所

のアドレス及び型参照)及び initobj 命令(局所変数に対して,メソッドヘッダでのゼロ初期化ビット

を設定することによってもなされる。

)の使用によって,それを 0 にできる。ホームのアドレスをロード(

8

  ホーム場所のアドレス及び型参照)し,次に構築子を直接呼び出すことによって,利用者定義の構築

子を呼び出すこともできる。また,ホーム内にある既存のインスタンスを,12.1.6.2.2 で規定するように複

写できる。

12.1.6.2.2 

値型インスタンスのロード及び格納 

この細分箇条は,すべて参考とする。

評価スタック上に値型をロードする方法が二つある。

−  ldarg,ldloc,ldfld 又は ldsfld 命令を使って,適切な型をもつホームから値を直接ロードする。

−  値型のアドレスを計算し,次に ldobj 命令を使う。

同様に,評価スタックから値型を格納する方法が二つある。

−  starg,stloc,stfld 又は stsfld 命令を使って,適切な型のホームに値を直接格納する。

−  値型のアドレスを計算し,次に stobj 命令を使う。

12.1.6.2.3 

値型の引数渡し及び返却 

注記  この細分箇条は参考情報であり規定ではない。

値型は,他の値を扱うのと全く同じように扱われる。


82

X 3016

:2010 (ISO/IEC 23271:2006)

   

−  値型を値渡しするために,単純に他の任意の実引数と同じように ldloc,ldarg などを使ってスタッ

ク上にロードする又は値型を返却するメソッドを呼び出す。値渡しされた値型仮引数にアクセスする

ために,そのアドレスを計算する ldarga 命令,又は,評価スタック上に値をロードする ldarg 命

令を使う。

−  値型を参照渡しするために,通常行うように値型のアドレスをロードする(

表 8  ホーム場所のアド

レス及び型参照)。参照渡しされた値型仮引数にアクセスするためには,値型のアドレスをロードする

ldarg 命令を使い,次に評価スタック上に値型をロードする ldobj 命令を使う。

−  値型を返却するために,単に空の評価スタック上に値をロードし,次に ret 命令を実行する。

12.1.6.2.4 

メソッド呼出し 

注記  この細分箇条は参考情報であり規定ではない。

値型に対する静的メソッドは,通常のクラスに対する静的メソッドと違いなく扱われる。すなわち,そ

のメソッドのクラスとして,その値型を指定しているメタデータトークンで call 命令を使う。非静的メ

ソッド(すなわち,インスタンス及び仮想メソッド)は,値型を扱う。しかし,特殊な取扱いが与えられ

る。

(値型ではなく)参照型の非静的メソッドは,その参照型のインスタンスである this ポインタを期待

する。参照型のインスタンスは識別性をもち,this ポインタがその識別性を表現するから,これは参照

型に対して意味がある。しかし,値型はボックス化されるときにだけ識別性をもつ。この点を扱うために,

値型の非静的メソッド上の this ポインタは,通常の値渡し仮引数ではなく,値型の参照渡し仮引数とする。

値型の非静的メソッドは,次の方法で呼び出されてよい。

−  値型のボックス化解除されたインスタンスが与えられると,コンパイラはオブジェクトの厳密な型を

静的に把握する。call 命令は,第 1 仮引数(this ポインタ)として,そのインスタンスのアドレス

を受け渡す関数を呼び出すために使われる。call 命令で使われるメタデータトークンは,そのメソ

ッドのクラスとして値型自身を指定しなければならない。

−  値型のボックス化されたインスタンスが与えられると,次の三つの場合が考慮される。

−  インスタンス又は仮想メソッドが値型自身に導入される。インスタンスのボックス化解除を行い,

そのメソッドのクラスとして値型を使って,直接,そのメソッド呼出しを行う。

−  上位クラスから継承した仮想メソッド。callvirt 命令を使い,必要に応じて System.Object,

System.ValueType

又は System.Enum クラスのメソッドを指定する。

−  値型で実装されるインタフェース上の仮想メソッド。callvirt 命令を使い,そのインタフェース

型のメソッドを指定する。

12.1.6.2.5 

ボックス化及びボックス化解除 

注記  この細分箇条は参考情報であり規定ではない。

ボックス化及びボックス化解除は,概念的に値型インスタンスと System.Object との間で(高水準言

語でも見られる)キャストすることと同等とする。しかし,これはデータ表現を変更するから,ボックス

化及びボックス化解除は,参照型のキャスト(isinst 及び castclass 命令)ではなく,様々な大きさ

の整数の拡大及び縮小(conv 及び conv.ovf 命令)に似ている。ボックス化命令は,インスタンスを複

写 し , 新 し く 割 り 当 て た オ ブ ジ ェ ク ト に そ れ を 埋 め 込 む こ と に よ っ て , 値 型 イ ン ス タ ン ス を

System.Object

に変換する(常に型安全な)拡大操作である。ボックス化解除は,(厳密な型が値型で

ある)System.Object を値型インスタンスに変換する(実行時例外が発生する可能性がある)縮小操作

である。これは,インスタンスを複写せずに,埋め込まれた値型インスタンスのアドレスを計算すること

によってなされる。


83

X 3016

:2010 (ISO/IEC 23271:2006)

12.1.6.2.6 

値型に対する castclass 及び isinst 

注記  この細分箇条は参考情報であり規定ではない。

値型インスタンスへ及び値型インスタンスからキャストすることは許可されていない(同等な操作はボ

ックス化及びボックス化解除である。

。しかし,ボックス化のとき,System.Object 型の値が特定のク

ラスのボックス化表現であるかどうかを知るために,isinst 命令を使うことができる。

12.1.6.3 

非透過クラス 

注記  この細分箇条は参考情報であり規定ではない。

アドレス算術操作及び間接参照操作によって直接操作される内容である複数バイトのデータ構造を提供

する言語がある。この機能を提供するには,CLI は,データメンバに関する情報をもたずに,指定された

大きさをもつ値型の生成を許可する。これらの非透過クラスのインスタンスは,他の任意のクラスのイン

スタンスと正確に同じ方法で扱われるが,ldfld,stfld,ldflda,ldsfld 及び stsfld 命令は,そ

れらの内容にアクセスするために利用してはならない。

12.2 

モジュール情報 

CLI PE ファイル形式の詳細は,第 章で与える。CLI は PE ファイル内で定義された個々のメソッドに

ついての次の情報に依存する。

−  すべての例外ハンドラを含む,メソッド本体を構成している命令

−  メソッド識別情報。これは,返却値型,並びに,それぞれの実引数及び実引数の個数,順序,仮引数

渡しの規約及び実引数の個々の組込み型を指定する。また,プラットフォーム固有の呼出し規約(単

にプラットフォーム固有のコードにだけ影響を与え,CIL 仮想呼出し規約には影響を与えない。

)も指

定する。

−  例外処理配列。この配列は,例外がフィルタ処理され,捕そく(捉)される範囲を線引きする情報を

もつ(

第 章及び 12.4.2 参照)。

−  メソッドが要求する評価スタックの大きさ。

−  メソッドが要求する局所配列の大きさ。

− CLI に よ っ て 局 所 変 数 及 び 予 備 メ モ リ 領 域 が 初 期 化 さ れ る こ と が 望 ま し い か ど う か を 示 す

localsinit

フラグ(localloc 参照)

−  局所変数配列の識別情報の形式における局所変数の型(

“局所識別情報”という。

さらに,ファイル形式は,そのファイルの移植性の度合いを示すことができる。記述できる一種類の制

約がある。

−  整数に対する特殊な 32 bit 長の制約。

コード実行上に制限があることを示すことによって,CLI クラスローダは,支援できないアーキテクチ

ャ上での移植性のないコードの実行を防ぐことができる。

12.3 

計算機状態 

CLI の設計目標の一つは,CIL コード生成器からメソッド呼出しフレームの詳細を隠ぺいすることであ

る。これは,CLI(CIL コード生成器ではない)が,最も効率的な呼出し規約及びスタック配置を選択する

ことを許可している。この抽象化を達成するために,呼出しフレームは CLI 内に統合される。次の計算機

状態の定義は,これらの設計選択を反映している。ここで,計算機状態とは,主に,大域的状態及びメソ

ッド状態からなる。

12.3.1 

大域的状態 

CLI は,多重同時実行スレッドの制御(ホストオペレーティングシステムで提供されるスレッドと同じ


84

X 3016

:2010 (ISO/IEC 23271:2006)

   

である必要はない。

,多重管理下ヒープ及び共有メモリアドレス空間を管理する。

注記  スレッドの制御は,多少単純化すると,メソッド状態の単一のリンクリストとしてみなすこと

ができる。ここで,メソッド呼出し命令によって,新しい状態が生成され,現在の状態にリン

クされる – スタックに基づく呼出し手順の従来のモデルである。このスレッド制御のモデルは

tail

.,jmp 又は throw 命令の操作を正しく定義しないことに注意する。

図 2  計算機状態モデルに,計算機状態モデルを例示する。これには,スレッド制御,メソッド状態及

び共有アドレス空間内の多重ヒープを含んでいる。別の図として

図 3  メソッド状態で示すメソッド状態

は,スタックフレームの抽象化である。実引数及び局所変数はメソッド状態の一部であるが,任意の管理

下ヒープに格納されたデータを参照する Object 参照を含むことができる。一般に,実引数及び局所変数

は,実行しているスレッドに対してだけ可視である。その一方,インスタンスフィールド及び静的フィー

ルド,並びに配列の要素は多重スレッドに対して可視にでき,その値の変更は副作用とみなされる。

図 2−計算機状態モデル 


85

X 3016

:2010 (ISO/IEC 23271:2006)

図 3−メソッド状態 

12.3.2 

メソッド状態 

メソッド状態は,実行しているメソッド内の環境(従来のコンパイラ用語では,

“呼出しスタックフレー

ム”と呼ばれる情報のスーパーセットに対応する。

)を記述する。CLI メソッド状態は,次の項目で構成さ

れる。

−  命令ポインタ(IP)

。これは,CLI によって実行される,現在のメソッド内の次の CIL 命令を指す。

−  評価スタック。このスタックは,メソッドに入るまで空とする。その内容は,そのメソッドに対して

完全に局所的であり,呼出し命令の間,維持される(すなわち,そのメソッドが別のメソッドを呼び

出した場合,その別のメソッドが返却された後,その評価スタックの内容は,まだ存在する。

。評価

スタックは,アドレス指定できない。いつでも,削減された型の集合のどれが,CIL 命令ストリーム

内の特定の位置で,任意のスタックの場所に格納されるかを導出することができる(12.3.2.1 参照)

−  (添字が 0 から始まる)局所変数配列(添字が 0 から始まる。

。局所変数の値は,

(評価スタックに対

するのと同じ意味で)メソッド呼出しの間,維持される。局所変数は任意のデータ型を保持できる。

しかし,特定のスロットは,型に対する一貫した方法(型システムは 12.3.2.1 に規定される。

)で使わ

れなければならない。局所変数は,メソッドに対する localsinit フラグ(12.2 参照)が設定されて

いる場合,メソッドに入る前に 0 で初期化される。個々の局所変数のアドレスは,ldloca 命令を使

って取得できる。

−  実引数配列。現在のメソッドの入力実引数の値(添字 0 から始まる)

。これらは,論理的な添字によっ

て読込み及び書出しができる。実引数のアドレスは,ldarga 命令を使って取得できる。実引数のア

ドレスは,可変長実引数並びを型安全に繰返し処理と組み合わせて使われる arglist 命令によって

も暗黙的に取得される。

−  メソッド情報ハンドル。これは,メソッドに関する読込み専用の情報を含む。特に,メソッドの呼出

し識別情報,その局所変数の型及びその例外処理に関するデータを保持する。

−  局所予備メモリ領域。CLI は局所予備メモリ領域(localloc)からオブジェクトを動的に割り当て

る命令を含む。局所予備メモリ領域内に割り当てられたメモリはアドレス指定可能とする。局所予備

メモリ領域に割り当てられたメモリは,メソッドの文脈が終了すると回収される。

−  返却状態ハンドル。このハンドルは,現在のメソッドからの返却におけるメソッド状態を再格納する

ために使われる。一般的に,これはそのメソッドの呼出し元の状態である。これは,従来のコンパイ

ラ用語での動的リンクに対応する。

−  セキュリティ記述子。この記述子は管理下コードに対して直接アクセスできないが,セキュリティの

上書きを記録するために,CLI セキュリティシステムによって使われる(assert,permit-only 及


86

X 3016

:2010 (ISO/IEC 23271:2006)

   

び deny)

メソッド状態の四つの領域である入力実引数配列,局所変数配列,局所予備メモリ領域及び評価スタッ

クは,論理的に異なった領域であるかのように規定される。CLI 規格適合処理系は,基本となる対象とす

るアーキテクチャ上の従来のスタックフレームとして保持する又は他の同等な表現記述を利用することで,

これらの領域をメモリの一つの隣接した配列に対応づけることもできる。

12.3.2.1 

評価スタック 

個々のメソッド状態に関連する評価スタックが存在する。CLI 命令の多くは,評価スタックから実引数

を取り出し,その評価スタック上に返却値を置く。他のメソッドの実引数及びその返却値も,その評価ス

タック上に置かれる。手続呼出しがなされると,その呼び出されるメソッドに対する実引数が,そのメソ

ッドの入力実引数配列(12.3.2.2 参照)となる。これは,メモリの複写,又は,単に二つのメソッドによ

る二つの領域の共有を要件にできる。

評価スタックは,値型のボックス化解除されたインスタンスを含む任意のデータを保持できるようにス

ロットで構成される。プログラムのある任意の時点でのスタックの型状態(スタックの深さ及びスタック

上の各要素の型)は,すべての可能性のある制御フローのパスに対して同一でなければならない。例えば,

未知の回数分の繰返しがあり,個々の繰返しの時にスタック上に新しい要素を積むプログラムは禁止され

る。

一般的に,CLI は 12.1 で規定された型の完全集合を扱う一方,CLI は特別な方法で評価スタックを扱う。

スタック上の型を詳細に追跡する JIT コンパイラがある一方,

CLI は次の一つの値を要求するだけとする。

−  int64,8 バイト符号付き整数。

−  int32,4 バイト符号付き整数。

−  native int,対象とするアーキテクチャに,より都合がよい 4 バイト又は 8 バイトのいずれかの符

号付き整数。

−  F,浮動小数点数値(float32,float64 又は基礎となるハードウェアで提供されている別の表現。

−  &,管理下ポインタ。

−  O,オブジェクト参照。

−  *,“一時ポインタ”。これは,単一のメソッドの本体内でだけ使われ,管理外メモリ内であることが

分かっている値を指す(詳細は,CIL 命令集合仕様を参照。*型は CLI 内で内部的に生成され,利用者

によって生成されない。

−  利用者定義の値型。

他の型は,次の技術を組み合わせて合成される。

−  他のメモリ位置にある短整数型は,評価スタック上にロードされるとき,ゼロ拡張又は符号拡張され

る。これらの値は,そのホーム場所に格納され戻されるときに丸められる。

−  異なる大きさの間及び符号付き,符号なしの間で,オーバフローの検出を伴い又は伴わずに,数値変

換を実行する特別な命令がある。

−  スタック上の整数を符号なしであるかのように扱う特殊な命令がある。

−  メモリ管理主体のヒープ(例えば,ldloca,ldarga 及び ldsflda)内を指さないことを保障した

ポインタを生成する命令は,管理下ポインタ(&型)又は管理外ポインタ(native unsigned int

型)が期待されている場所ならば,どこでも使用できる一時ポインタ(*型)を生成する。

−  メソッドが呼び出されるとき,管理外ポインタ(native unsigned int 又は*型)は管理下ポイン

タ(&型)が要求される仮引数に対応させることが許されている。しかし,メモリ管理主体が管理下


87

X 3016

:2010 (ISO/IEC 23271:2006)

ポインタを失わせてもよく,その逆は許されていない。

−  管理下ポインタ(&型)は,管理外ポインタ(native unsigned int)が正当性検証可能でなく,

実行時例外を生成することがあるにもかかわらず,それに明示的に変換できる。

12.3.2.2 

局所変数及び実引数 

個々のメソッド状態の一部は,局所変数を保持する配列及び実引数を保持する配列とする。評価スタッ

クと同様に,

これらの配列の個々の要素は,

任意の単一のデータ型又は値型のインスタンスを保持できる。

両方の配列とも 0 から始まる(すなわち,最初の実引数又は局所変数は 0 と番号付けされる。

。局所変数

のアドレスは ldloca 命令を使って計算され,実引数のアドレスは ldarga 命令を使って計算できる。

個々のメソッドに関連するメタデータは,次を指定する。

−  メソッドに入ったとき,局所変数及び予備メモリ領域メモリが初期化されるかどうか。

−  個々の実引数の型及び実引数配列の長さ(可変長の実引数並びについては 12.3.2.3 を参照)

−  局所変数の型及び局所変数配列の長さ。

CLI は対象のアーキテクチャに対して適切な詰め物を挿入する。すなわち,64 ビットアーキテクチャで

ある場合,すべての局所変数は 64bit 境界に整列でき,その他のアーキテクチャでは 8 ビット,16 ビット,

及び 32 ビットの境界に整列できる。CIL 生成器は,配列内での局所変数のオフセットに対するどんな仮定

もしてはならない。実際,CLI は局所変数配列内の要素を順序化し直すことができ,実装ごとにそれぞれ

異なる方法で順序化することが許されている。

12.3.2.3 

可変長の引数並び 

CLI は未知の長さ及び型の実引数並びを受け取るメソッド(“可変個引数メソッド”)を実装するのに,

クラスライブラリと組み合わせて動作する。これらの実引数へのアクセスは,そのライブラリにある

System.ArgIterator

と呼ばれる型安全反復子(

第 章参照)を通して行う。

CIL は,実引数反復子を扱うのに特殊な arglist という命令を提供する。この命令は,実引数の個数

が可変個取ると宣言されたメソッド内でだけ利用できる。これは,System.ArgIterator オブジェクト

に対する構築子によって必要とされる値を返却する。基本的に,arglist で生成された値は,メソッドに

渡された実引数並びのアドレスと,提供された実引数の個数及び型を指定する実行時のデータ構造との両

方へのアクセスを提供する。これは,クラスライブラリが,利用者に可視である反復機構を実装するため

に十分である。

CLI の視点から,可変個引数メソッドは,他のメソッドと同じように実引数の配列をもっている。しか

し,配列の初期部分だけが固定化された型集合をもつ。また,これらだけが ldarg,starg 及び ldarga

命令を使って直接アクセスできる。実引数反復子は,配列内での冒頭部及び残りの実体との両方へのアク

セスを許可する。

12.3.2.4 

局所予備メモリ領域 

個々のメソッド状態の一部は,局所予備メモリ領域とする。メモリは,localloc 命令を使って局所予

備メモリ領域から明示的に割り当ててよい。局所予備メモリ領域内のすべてのメモリは,メソッドを抜け

ると回収され,これが局所予備メモリ領域メモリを回収する唯一の方法とする(このメソッド呼出しの間

に割り当てられた局所メモリを解放するための命令は存在しない。

。局所予備メモリ領域はコンパイル時

に大きさ又は型が未知であり,プログラマが管理下ヒープ内で割り当ててほしくないオブジェクトを割り

当てるために使われる。

局所予備メモリ領域はメソッドの生存期間の間,縮退できないから,言語実装系では,一般的な目的で

メモリ割当てのために局所予備メモリ領域を使用できない。


88

X 3016

:2010 (ISO/IEC 23271:2006)

   

12.4 

制御フロー 

CIL 命令集合は,ある CIL 命令から次の命令までの通常の制御の流れを代替する豊富な命令集合を提供

する。

−  メソッド内で使われる条件分岐及び無条件分岐命令。これは保護範囲境界をまたがない転送を提供す

る(12.4.2 参照)

−  新しい実引数を計算し,既知の又は計算された目的のメソッドに,それら及び制御を転送するメソッ

ド呼出し命令(12.4.1 参照)

−  メソッド呼出しを実行する前に,そのスタックフレームを放棄すべきメソッドを示す tail 呼出し前

置子(12.4.1 参照)

−  メソッドからの返却。必要に応じて値を返す。

−  現行メソッド実引数を既知の又は計算された目的のメソッドに転送するメソッド飛越し命令(12.4.1

参照)

−  例外関連命令(12.4.2 参照)

。これらには,例外を初期化する命令,保護領域外へ制御の転送,フィル

タ処理,catch 節又は finally 節を終了させる命令を含む。

CLI は,メソッド内での制御の転送を扱う一方,次のような順守しなければならない制約事項がある。

1)

例外処理機構を通らずに,catch ハンドラ又は finally 節に入る制御の転送は一切許可されない

12.4.2 参照)

2)

保護区域の外への制御の転送は 12.4.2 で規定されている。

3)  ret

命令によって返却値が取り出された後,評価スタックは空でなければならない。

4)

スタック上の個々のスロットは,メソッド本体内で与えられた任意の場所に到達することが許可さ

れている場合,その制御の流れに関係なく,その場所では同じデータ型をもたなければならない。

5) JIT

コンパイラが効率的にスタック上に格納されるデータ型を追跡できるように,スタックは,無

条件での制御転送(br,br.s,ret,jmp,throw,endfilter,endfault 又は endfinally)

の後の命令の時点では,通常,空でなければならない。メソッド内の先頭に近い位置で,その命令

に前方分岐してきた場合,その命令の時点でスタックは空であってはならない。

6)

メソッドの終端に単に“通り抜け”(12.4.2.8.1)する制御は許可されない。すべてのパスは,ret

命令,

throw

命令,

jmp

命令,

(又は tail.が先行する call 命令,

calli

命令,

若しくは callvirt

命令)のいずれか一つで終了しなければならない。

12.4.1 

メソッド呼出し 

CIL コード生成器で生成される命令は,CLI のそれぞれの実装ごとに異なるプラットフォーム固有な呼

出し規約を利用するために十分な情報を含んでいる。すべてのメソッド呼出しは,次のとおりメソッド状

態領域(12.3.2 参照)を初期化する。

1)

入力された実引数配列は,呼出し元によって要求された値に設定される。

2)

局所変数配列は,Object 型及びオブジェクトを保持する値型のフィールドに対して常に null を

もつ。さらに,localsinit フラグがメソッドヘッダで設定されている場合,その局所変数配列は,

すべての整数型に対して 0 に,すべての浮動小数点数型に対して 0.0 に初期化される。値型は,CLI

によって初期化されない。正当性検証されたコードは,メソッドの入口コードの一部として初期化

子の呼出しが供給される。

3)

評価スタックは空とする。

12.4.1.1 

呼出し元記述子 


89

X 3016

:2010 (ISO/IEC 23271:2006)

呼出し元は,インタプリタ又は JIT コンパイラが任意のプラットフォーム固有の呼出し規約を合成でき

るような付加的な情報を規定する。すべての CIL 呼出し命令(call,calli 及び callvirt)には,呼

出し元の記述を含む。この記述は,二つの形式の一つをとることができる。より単純な形式は,calli 命

令で利用され,次の情報を提供する“呼出し元記述”とする。これは,単独な呼出し識別情報に対するメ

タデータトークンとして表現される。

−  渡されている実引数の個数

−  個々の実引数のデータ型

−  実引数が呼出しスタック上に置かれていた順序

−  利用されるプラットフォーム固有の呼出し規約

より複雑な形式は,call 及び callvirt 命令で利用され,呼出し命令の呼出し先に対する識別子をも

つ呼出し元記述を補強する“メソッド参照”とする。これは,methodref メタデータトークンである。

12.4.1.2 

呼出し命令 

CIL は,新しい実引数の値を呼出し先のメソッドに転送するために使われる三つの呼出し命令をもつ。

通常の状況の下では,呼び出されたメソッドは,終了し,呼び出しているメソッドに制御を返す。

−  call は,CIL が結合される時点で,呼出し先アドレスが固定化されるときに使われるように設計され

ている。この場合,メソッド参照は命令内に直接置かれる。これは,C 言語の静的関数の直接呼出し

に相当する。これは,静的メソッド,インスタンスメソッド又はインスタンスメソッド本体内の(静

的に既知の)スーパークラスのメソッドを呼び出すために利用できる。

−  calli は,呼出し先のアドレスが実行時に計算されるときに使われるように設計されている。メソッ

ドポインタはスタック上に渡され,この命令は呼出し元記述だけを含む。

−  callvirt は,呼び出されるメソッドを決定するために(実行時にだけ既知になる)オブジェクトの

厳密な型を利用する。この命令は,メソッド参照を含むが,特定のメソッドは呼出しが実際に起きる

まで計算されない。これは,下位クラスのインスタンスを提供することを許可し,その下位クラスに

対する適切なメソッドを呼び出すことを許可する。callvirt 命令は,インスタンスメソッドとイン

タフェース上のメソッドとの両方に対して利用される。

第 章の CTS 仕様及び CIL 命令集合仕様を

参照。

さらに,これらの個々の命令は,tail 命令前置子を直前に置いてもよい。これは,呼び出したメソッ

ドがこのメソッド呼出しで終了(及び,呼び出されたメソッドによって返却される値を返却)することを

規定する。この tail 前置子は,JIT コンパイラが(呼出しが,非信頼コードから信頼コードへの呼出しで

ある場合,そのフレームはセキュリティ上の理由によって完全に放棄することはできない。

)呼出しを行う

前に,呼出し側のメソッド状態を放棄することを命令する。呼び出されたメソッドが ret 命令を実行する

とき,制御は呼び出したメソッドではなく,そのメソッドが戻る場所に戻る(通常,呼出し側の呼出し元

である。

。tail 命令は,呼出し側のフレームの生存期間を短くするから,実引数として管理下ポインタ

(型&)を渡すことは安全ではないことに注意する。

最後に,tail.が置かれた場合に対して最適化を指示する二つの命令がある。

−  その二つとは,methodref トークン又は methoddef トークンが後続する jmp 命令であり,それぞ

れは,現在のメソッドの状態が放棄されないことが望ましいこと,その実引数は,呼出し先のメソッ

ドにそのまま損なわれずに転送されるのが望ましいこと,及びその制御は呼出し先に転送されるのが

望ましいこと,を指示する。呼び出しているメソッド識別情報は,呼出し先メソッドの識別情報に正

確に一致しなければならない。


90

X 3016

:2010 (ISO/IEC 23271:2006)

   

12.4.1.3 

計算された呼出し先 

メソッド呼出し先は,CIL 命令列に直接記号化される(call 命令及び jmp 命令)か,計算される

(callvirt 命令及び calli 命令)かのいずれかにできる。callvirt 命令の呼出し先アドレスは,メ

ソッドトークン及び第 1 実引数(this ポインタ)の値に基づいて CLI によって自動的に計算される。メ

ソッドトークンは,第 1 実引数のクラスの直接基底クラスの仮想メソッドを参照しなければならない。CLI

は,要望されるメソッドの実行を提供する,第 1 実引数のクラスのより近い基底クラスを位置付けること

によって,正しい呼出し先を計算する。

注記  実装は,ここで暗黙的に線形検索より効率的に行わせることを前提にしてもよい。

calli

命令に関して,CIL コードは呼出し先アドレスを計算すること及びそれをスタックに積むことに

責務をもつ。これは,通常,早い段階で ldftn 又は ldvirtfn 命令を使って行われる。ldftn 命令は,

メソッドを指定する CIL 列内にメタデータトークンを含み,その命令はそのメソッドのアドレスをスタッ

クに積む。ldvirtfn 命令は,CIL 列内の仮想メソッド及びスタック上のオブジェクトに対するメタデー

タトークンをとる。これは,callvirt 命令に対して,上に記述したのと同じ計算を実行するが,メソッ

ドを呼び出すのではなく,スタック上にその結果である呼出し先を積む。

calli

命令は,メソッドを呼び出すために使われることが推奨されるプラットフォーム固有の呼出し規

約に関する情報を含む呼出し元記述を含む。正当な CIL コードは,呼び出されているメソッドに対する呼

出し規約に一致する calli 命令内に指定される呼出し規約を規定しなければならない。

12.4.1.4 

仮想呼出し規約 

CIL は,JIT によってプラットフォーム固有の呼出し規約に変換される“仮想呼出し規約”を提供する。

JIT は,対象とするアーキテクチャに対する最適のプラットフォーム固有の呼出し規約を決定する。これ

は,レジスタの使用,局所的変数ホーム,値呼出しでの大きなオブジェクトの複写規約(対象とする計算

機に基づいて,何が“大きい”とするかを決定することも同様。

)の詳細を含めて,プラットフォーム固有

の呼出し規約は計算機ごとに異なっていることが許される。これは,プラットフォーム固有の呼出し規約

に従って渡される実引数の場所及び順序に一致させるために,JIT が CIL 仮想スタック上に置かれた値を

再整列化することも許す。

CLI は,すべてのメソッドに対して単一で一律な呼出し規約を使う。この規約を,適切なプラットフォ

ーム固有の呼出し規約に変換するのは,JIT 機構の責務とする。呼出し命令(call,calli 若しくは

callvirt

,又は,tail.が先行するいずれか)の時点でのスタックの内容は,次のとおりとする。

1)

呼び出されているメソッドがインスタンスメソッド(クラス若しくはインタフェース)又は仮想メ

ソッドである場合,call 命令の時点で,this ポインタがスタック上の最初のオブジェクトとする。

Object

(ボックス化された値型を含む)に対するメソッドでは,this ポインタは型 O(オブジェ

クト参照)とする。値型に対するメソッドでは,this ポインタは参照渡し仮引数として与えられ

る。すなわち,その値はインスタンスへのポインタ(管理下&若しくは管理外*のポインタ,又は

native int

)とする。

2)

残りの実引数は,左から右の順番でスタック上に置かれる(すなわち,語い(彙)順で最も左にあ

る実引数が,スタック上の最下部にある。this ポインタがあれば,その直後となる。

12.4.1.5 では,

実装することが推奨されている三つの仮引数渡し規約(値渡し,参照渡し及び型付け参照)の個々

の方法について規定する。

12.4.1.5 

仮引数渡し 

CLI は,三つの種類の仮引数渡しを提供する。すべては,メソッド識別情報の一部としてメタデータ内


91

X 3016

:2010 (ISO/IEC 23271:2006)

で指示される。メソッドに対する各仮引数は,それ自身の仮引数渡しの規約をもっている(例えば,第 1

仮引数は値による渡しにし,その他の仮引数は参照渡しにすることができる。

。仮引数は,次の方法の一

つで渡されなければならない(次の詳細定義を参照。

−  値渡し。これは,オブジェクトの値が,呼出し元から呼出し先に渡される。

−  参照渡し。これは,データのアドレスが,呼出し元から呼出し先に渡される。したがって,その仮引

数の型は管理下ポインタ又は管理外ポインタとする。

−  型付けされた参照。これは,データ型の実行時の表現が,そのデータのアドレスと一緒に渡される。

したがって,仮引数の型は,この目的のために特別に提供された。

これらの規約に従うのは,CIL 生成器の責務とする。正当性検証は,仮引数の型が渡された値の型に一

致することを検査する。それ以外では,呼出し規約の詳細は分からない。

12.4.1.5.1 

値渡し仮引数 

組込み型(整数,浮動小数点数など)では,呼出し元が,その呼出しの前にスタック上にその値を複写

する。オブジェクトに対して,そのオブジェクト参照(型 O)がスタック上に積まれる。管理下ポインタ

(型&)又は管理外ポインタ(native unsigned int 型)については,そのアドレスが呼出し元から呼

出し先に渡される。値型については,12.1.6.2 を参照する。

12.4.1.5.2 

参照渡し仮引数 

参照渡し仮引数は,C++の参照仮引数又は PASCAL の var 仮引数と同等とする。実引数として変数,フ

ィールド又は配列の要素の値を渡すのではなく,そのアドレスを渡す。そして,対応している仮引数の任

意の代入が,対応している呼出し元の変数,フィールド又は配列の要素を実際に変更する。この作業の多

くは,高水準言語によってなされ,値を渡すためにアドレスを計算する必要性及び値の参照又は更新のた

めの間接参照の使用を利用者から隠ぺいしている。

参照による値の受渡しは,その値がホーム(12.1.6.1 参照)をもち,その値は,渡されるホームのアドレ

スであることを要求する。定数及び評価スタック上の中間値は,それらがホームをもたないから,参照渡

し仮引数として渡すことはできない。

CLI は,参照渡し仮引数を扱う命令を提供する。

−  ホーム位置のアドレスの計算(

表 8  ホーム場所のアドレス及び型参照)。

−  これらのアドレスポインタを通して組込みデータ型のロード及び格納(ldind.*,stind.*,ldfld

など)

−  値型の複写(ldobj 及び cpobj)

メソッド呼出しに結びついた生存期間をもつアドレス(例えば,局所変数及び実引数)が存在する。こ

れらは,その生存期間の外側から参照されてはならない。また,そのため,その生存期間を最後に超えた

位置に格納されることもない。CIL はこの制約を強制されない(及び強制できない。

。CIL 生成器は,こ

の制約を強制しなければならず,そうでなければ,結果として CIL は正しく動作しない。正当性検証可能

8.8 参照)であるコードでは,参照渡し仮引数は,他のメソッドに渡されるか,又は適切な stind 命令

若しくは ldind 命令で参照されるだけでなければならない。

12.4.1.5.3 

型付けされた参照仮引数 

参照渡し仮引数及び値型は,静的型付け言語(C++,Pascal など)を提供するのに十分である。同様に,

これらが多様性メソッドに渡される前に,値型をボックス化する実行性能上の代償を払う動的型付け言語

(Lisp,Scheme,Smalltalk など)も提供する。残念ながら,引数として受け入れるデータ型を静的に制限

しないメソッドにボックス化解除されたデータを参照渡しすることが要求されている Visual Basic のよう


92

X 3016

:2010 (ISO/IEC 23271:2006)

   

な言語を提供するには十分ではない。これらの言語は,データのホームのアドレス及びそのホームの静的

型の両方を渡す一つの方法を要求する。これは,データがボックス化された場合に提供される正確な情報

であるが,ボックス化操作に要求されるヒープの割当ては要求されない。

型付けされた参照仮引数が,この要求に対応する。型付けされた参照仮引数は,標準の参照渡し仮引数

に非常に類似しているが,静的なデータ型が,そのデータのアドレスとともに渡される。参照渡し仮引数

のように,型付けされた参照仮引数に対応する実引数は,ホームをもつ。

注記  正当性検証及びメモリ管理主体がデータ型と対応するアドレスを知る必要があるという事実が

なければ,参照渡し仮引数は,データのアドレス及びその型の二つのフィールドをもつ標準の

値型として実装できたかもしれない。

通常の参照渡し仮引数のように,型付けされた参照仮引数はスタック上にあるホームを参照することが

できる。そして,そのホームは呼出しスタックによって制限される生存期間をもつ。すなわち,CIL 生成

器は参照渡し仮引数の生存期間を適切に検査しなければならない。そして,正当性検証は,参照仮引数に

対してなされるように,型付けされた参照仮引数の使用に関しても同じ制約を課す(12.4.1.5.2 参照)

型付けされた参照は,新しく型付けされた参照を生成する(mkrefany 命令を使って)又は既存の型付

けされた参照を複写するかのいずれかによって渡される。型付けされた実引数が与えられると,それが参

照するアドレスは refanyval 命令を使って抽出され,それが参照する型が refanytype 命令を使って抽

出される。

12.4.1.5.4 

仮引数対応 

与えられた仮引数は,その仮引数渡し規約で,すなわち,値渡し,参照渡し又は型付けされた参照,の

いずれか一つを使って渡すことができる。

単一の仮引数に対して,

これらの組み合わせることはできない。

その一方,一つのメソッドが,別々の仮引数に対して,別々の呼出し規約をもつことができる。

型付けされた参照として渡される仮引数は,実行時の型検査及び(値渡しである場合の)複写を行わず

に,参照渡し又は値渡しで渡してはならない。

参照渡し仮引数は,静的な型を附属させることによって型付けされた参照として渡すことができる。

表 9  仮引数渡し規約に,個々のデータ型に対して利用される仮引数渡し規約を示す。

表 9−仮引数渡し規約 

データ型 

引数渡しの方法 

データを送る方法 

呼び出されたメソッドに複写される。両側で型が静的に既知である。

参照

アドレスが呼び出されたメソッドに送られる。両側で型が静的に既知で
ある。

組込み値型 
(int,float など)

型付けされた参照

アドレスが,呼び出されたメソッドに型情報とともに送られる。

呼び出されたメソッドは,コピーを受け取る。両側で型が静的に既知で
ある。

参照

アドレスが呼び出されたメソッドに送られる。両側で型が静的に既知で
ある。

利用者定義値型

型付けされた参照

アドレスが,呼び出されたメソッドに型情報とともに送られる。

データの参照が呼び出されたメソッドに送られる。型は静的に既知であ
り,参照からクラスが利用できる。

参照

参照のアドレスが呼び出されたメソッドに送られる。型は静的に既知で
あり,参照からクラスが利用できる。

オブジェクト

型付けされた参照

参照のアドレスが,静的な型情報とともに呼び出されたメソッドに送ら
れる。クラス(すなわち,動的な型)は参照から利用できる。


93

X 3016

:2010 (ISO/IEC 23271:2006)

12.4.2 

例外処理 

例外処理は,例外オブジェクト及びコードの保護ブロックで CLI によって提供される。例外が発生した

とき,その例外を表現するオブジェクトが生成される。すべての例外オブジェクトは,あるクラスのイン

スタンスとする(すなわち,それらはボックス化された値型にできるが,ポインタ,ボックス化解除され

た値型などにはできない。

。利用者は,利用者自身の例外クラスを生成することができ,通常,それらは

System.Exception

第 章参照)の下位クラスである。

保護ブロックに対するハンドラが四種類ある。単一の保護ブロックは,それに結びついた正確に一つの

ハンドラをもたなければならない。

−  finally ハンドラ。これは,通常の制御フローによって又は処理対象でない例外によって発生するか

どうかに関係なく,このブロックが存在するときは,必ず実行されなければならない。

−  fault ハンドラ。これは,例外が発生したときに実行しなければならず,通常の制御フローが完了し

たときに実行しない。

−  catch ハンドラ。これは,指定されたクラス,又は,その下位クラスの任意の例外を処理する。

−  filter ハンドラ。これは,例外が,それに結びついたハンドラによって処理されるべきか又は次の

保護ブロックに渡すべきかどうかを決定するために,利用者が定義した CIL 命令集合を実行する。

保護区域,結びついたハンドラの型,並びに結びついたハンドラの位置,及び(必要に応じて)利用者

が提供するフィルタコードは,個々のメソッドに関連した例外ハンドラテーブルを通して記述される。例

外ハンドラテーブルの正確な形式は,

第 章に詳細を規定する。例外処理機構の詳細も第 章で規定する。

12.4.2.1 CLI

によって送出される例外 

CLI 命令は,個々の命令を実行する一部として,次の例外を送出できる。個々の命令の文書は,その命

令が送出できる例外のすべてを一覧にする。次に示した,はん(汎)用の ExecutionEngineException

はすべての命令によって生成されうる。

基本命令(

第 章参照)

−  System.ArithmeticException

−  System.DivideByZeroException

−  System.ExecutionEngineException

−  System.InvalidAddressException

−  System.OverflowException

−  System.SecurityException

−  System.StackOverflowException

オブジェクトモデル命令(

第 章参照)

−  System.TypeLoadException

−  System.IndexOutOfRangeException

−  System.InvalidAddressException

−  System.InvalidCastException

−  System.MissingFieldException

−  System.MissingMethodException

−  System.NullReferenceException

−  System.OutOfMemoryException

−  System.SecurityException


94

X 3016

:2010 (ISO/IEC 23271:2006)

   

−  System.StackOverflowException

System.ExecutionEngineException

は特殊とする。これは,任意の命令によって送出でき,CLI

内で意図しない矛盾を示す。正当性検証されたコードの排他的な実行は,CLI 規格適合処理系によってこ

の例外が送出される原因になることは一切ない。しかし,正当性検証されていないコード(CIL に合致し

たコードであっても)は,メモリを破壊した場合に送出される例外の原因になりうる。適合しない CIL 又

は適合しないファイル形式を実行するどんな仮定も,未規定の動作の原因となりうる。CLI 規格適合処理

系は,これらの状況に対するどんな規定も設ける必要はない。

‘MetaDataTokenNotFound.’のようなことに対する例外はない。CIL 正当性検証(

第 章参照)は,

命令を実行する前に,この矛盾を検出し,正当性検証違反とする。CIL が正当性検証しなければ,この種

の矛盾ははん(汎)用的な System.ExecutionEngineException を送出しなければならない。

例外は,CLI によっても送出される。また,throw 命令によって利用者コードからも送出される。いずれ

の例外も発生の源に関係なく,例外処理は同一とする。

12.4.2.2 

例外の下位クラス化 

CLI によって送出される例外のある種の型は,より多くの情報を利用者に提供するために下位クラス化

できる。

第 章での CIL 命令の仕様は,正常でない状況になったとき,例外のどれが実行環境によって送

出されるべきかを規定する。規格適合処理系は,その記述された型のオブジェクト又はその型の下位クラ

スのオブジェクトを送出してもよい。

注記  例 え ば , ckfinite 命 令 の 仕 様 で は , System.ArithmeticException 型 又 は

System.ArithmeticException

の下位クラスが CLI によって送出されることを要求してい

る。規格適合処理系は,単に,ArithmeticException 型の例外を送出してもよいが,プロ

グ ラ マ に 対 し て よ り 多 く の 情 報 を 提 供 す る た め に , 原 因 番 号 を も つ

NotFiniteNumberException

型の例外を送出することを選択してもよい。

12.4.2.3 

解決例外 

CIL は,参照,特に,インタフェース,クラス,メソッド及びフィールドを型付けることを許す。参照

が見つからなかった又は一致しなかった場合,解決エラーが発生する。解決例外は,CIL 命令からの参照,

基本クラスの参照,実装されたインタフェースの参照並びに,フィールド,メソッド及び他のクラスのメ

ンバ識別情報からの参照によって生成されうる。

最適化に関する拡張性を許すために,解決例外の検出は,早くてインストール時及び遅くて実行時に起

こればよいという自由度が与えられる。

CIL 命令を除いて,すべての参照から解決例外の検査が行われる最も遅い機会は,参照が行われている

型の初期化の一部とする(

第 章参照)。このような解決例外が検出された場合,その型の静的初期化子

があった場合,それは実行してはならない。

CIL 命令内で解決例外の検査が行われる最も遅い機会は,関連する CIL 命令の最初の実行の一部とする。

CIL 命令での解決例外の検査の実行を,可能な限り遅延させることを選択したとき,これらの例外は,そ

れが発生したら,VES がその CIL 命令に対して投げてよい他の任意の解決例外でない例外より前に送出し

なければならない。いったん,CIL 命令が解決エラーを送出する位置を通過する(例外が発生せずに完了

する又は解決例外でない例外を投げて完了する。

)と,その命令に引き続く実行は,解決例外を送出しては

ならない。

実装が,任意の参照から,その参照の種類に対する最も遅い機会より前の段階で解決例外の検出を行う

という選択しても,すべての解決例外を早期に検出することは要件ではない。


95

X 3016

:2010 (ISO/IEC 23271:2006)

早期に解決エラーを検出する実装は,任意の種類の参照の後で,クラス自身内,又は,型の推移的閉包

内で検出された解決例外の結果として,そのクラスのインストール,ロード又は初期化を行わないように

できる。

例えば,次のそれぞれが許されたシナリオである。インストレーションプログラムは,インストールさ

れている項目集合内での CIL 命令の解決エラーの検査の結果として,解決例外を送出できる(すなわち,

インストレーションが失敗する。

。実装は,参照されたクラス内の CIL 命令の解決エラーの検査結果とし

て,クラスのロードを失敗させることができる。実装として,CIL 命令内で解決例外をもつクラスをロー

ドすること及び初期化することが許されている。

次の例外は,解決例外とみなされる。

−  BadImageFormatException

−  EntryPointNotFoundException

−  MissingFieldException

−  MissingMemberException

−  MissingMethodException

−  NotSupportedException

−  TypeLoadException

−  TypeUnloadedException

例えば,参照されたクラスが見つからない場合,TypeLoadException が送出される。

(クラスが見つ

かり)参照されたメソッドが見つからない場合,MissingMethodException が送出される。矛盾なく使

われている一致したメソッドがアクセス可能で,宣言されたセキュリティポリシーに違反している場合,

SecurityException

が送出される。

12.4.2.4 

例外のタイミング及び選択 

CIL 命令によって送出される例外のある型は,その命令が実行される前に検出してよい。これらの場合,

送出する特定の時間を正確には定義できないが,その例外は,その命令の実行に遅延することなく送出す

ることが推奨される。例外のタイミングの緩和は,実装が任意のコードを実行する前(例えば,CIL から

プラットフォーム固有のコードへの変換を行う時点)に,例外を検出することを選択できるように提供さ

れる。

エラー条件を検出する時点と,関連する例外を送出する時点の間に差がある。エラー条件は,早期に検

出できる(例えば,JIT の時)

。しかし,その条件は,例外を送出する(例えば,原因の命令の実行時)ま

で,その通知を遅延させてもよい。

次の例外が,実行時より前に送出できる例外とする。

−  MissingFieldException

−  MissingMethodException

−  SecurityException

−  TypeLoadException

さ ら に , ク ラ ス の 初 期 化 が い つ 発 生 す る か に つ い て は , 完 全 に は 規 定 さ れ な い 。 特 に ,

System.TypeInitialzationException

が送出されるときの保障はない。

メソッド呼出しで二つ以上の例外の条件が生じた場合,どの例外が送出されるかは規定されない。

12.4.2.5 

例外処理の概要 

例外処理の詳細は,

第 章の例外処理仕様を参照。


96

X 3016

:2010 (ISO/IEC 23271:2006)

   

実行可能なコード内の個々のメソッドは,例外処理情報の配列(空のこともある。

)と結びつけられる。

この配列の個々の要素は,保護ブロック,そのフィルタ及びそのハンドラ(catch ハンドラ,filter ハ

ンドラ,finally ハンドラ,又は,falut ハンドラでなければならない。

)を記述する。例外が発生する

と,CLI は,この配列から,次の条件を満たす最初の保護ブロックを検索する。

−  現在の命令ポインタを含む保護区域

−  catch ハンドラブロック

−  その例外を処理するフィルタ

現在のメソッドに対して一致するものが見つからない場合,呼び出しているメソッドを順次,見つかる

まで検索していく。どれにも一致しなければ,CLI はスタックトレースをダンプし,プログラムを中止す

る。

注記  デバッガは,スタックの巻戻しを行う前に,ブレイクポイントのように,この状況に対して介

在し,取り扱うことができる。したがって,デバッガを通してスタックの検査は依然として利

用できる。

一致するものが見つかったら,CLI はスタックを,まさに位置付けられた場所まで戻され,このときに

finally

ハンドラ及び fault ハンドラを呼び出している。次に,発生した例外に対応した例外処理を開

始する。スタックフレームは,この 2 度目のスタック渡り歩きが起きた時か又は例外ハンドラが終了した

後かのいずれかで廃棄される。いずれになるかは,その処理ブロックに結びついた例外ハンドラ配列の要

素の情報に依存する。

注意すべき点が四つある。

−  例外ハンドラテーブル内での例外節の順序は重要である。ハンドラが入れ子になっている場合,最も

深い入れ子になった try ブロックは,それを囲んでいる try ブロックの前に来なければならない。

−  例外ハンドラは,局所変数及びその例外を捕そく(捉)しているルーチンの局所予備メモリ領域にア

クセスできる。しかし,例外が送出された時点での評価スタック上の中間結果は,どれも失われる。

−  例外を規定する例外オブジェクトは,CLI によって自動的に生成され,フィルタ又は catch 節に入り

次第,それは評価スタック上に最初の項目として積まれる。

−  filter ハンドラを除いて,例外の場所で実行を再開させることはできない。

12.4.2.6 

例外に対する CIL の支援 

CIL は,次のような特別な命令をもつ。

−  利用者定義例外の throw 及び rethrow。

−  保護ブロックを leave し,例外を送出せずに,メソッド内にある適切な finally 節を実行する。こ

れは,catch 節を抜けるためにも使われる。保護ブロックからの抜出しが,fault 節の呼出しを引き

起こすことはないことに注意する。

−  利用者提供の filter 節を終え(endfilter)

,例外を処理するかどうかを示す値を返却する。

−  finally 節(endfinally)を終え,スタックの巻戻しを続ける。

12.4.2.7 

保護ブロックの構文上の入れ子 

保護区域(

“try ブロック”ともいう。

)は,アドレス及び長さで記述される。trystart は保護される

最初の命令のアドレスとし,trylength は保護区域の長さとする。tryend は,保護される最後の命令の

直後のアドレスであり,trystart と trylength とで自明に計算される。ハンドラ領域は,アドレス及

び長さで記述される。handlerstart はハンドラの最初の命令のアドレスとし,handlerlength は,ハ

ン ド ラ 領 域 の 長 さ と す る 。 handlerend は ハ ン ド ラ の 最 後 の 命 令 の 直 後 の ア ド レ ス で あ り ,


97

X 3016

:2010 (ISO/IEC 23271:2006)

handlerstart

と handlerlength とで自明に計算される。

どのメソッドも,それに関連する例外項目の集合をもつことができる。これを例外集合と呼ぶ。例外項

目は,次の構成物で構成される。

−  省略可能:  型トークン(扱われるべき例外の型)又は filterstart(利用者提供のフィルタコード

の最初の命令のアドレス)

−  必す(須):  保護ブロック。

−  必す(須):  ハンドラ区域。4 種類のハンドラ区域が存在する。catch ハンドラ,フィルタで選択し

たハンドラ,finally ハンドラ,及び fault ハンドラである。フィルタで選択したハンドラは,フ

ィルタの評価が真である場合に実行されるコードである。

例外項目が filterstart を含むならば,filterstart は,厳密に handlerstart より前に置く。

フィルタ領域は filterstart で指定された命令から,handlerstart で指定されるアドレスまで(そ

のアドレスは含まない。

)のすべての命令を含む。語い(彙)的にフィルタ内の最後の命令は,endfilter

でなければならない。filterstart がなければ,フィルタ領域は空とする(どの区域も重なりあわない。

互いの区域と重なり合うことができる単一の例外項目の二つの区域(保護ブロック,フィルタ,ハンド

ラ区域)はない。

例外集合内の例外項目の組合せのそれぞれに,次の一つが真でなければならない。

−  それらが入れ子になっている。一つの項目の三つすべての区域は,別の項目の単一の区域内になけれ

ばならない。さらに,囲んでいる区域はフィルタであってはならないという制約がある。

注記  フィルタ領域内から呼び出される関数は,例外処理を含んでいてもよい。

−  それらは互いに素である。二つの項目の六つすべての区域は,組合せごとに素である(アドレスが重

なり合わない。

−  それらは相互に保護する。保護ブロックは同じであり,他の区域は組合せごとに素である。この場合,

すべてのハンドラは,catch ハンドラ又はフィルタで選択したハンドラのいずれかでなければならな

い。ハンドラ区域の優先順序は,例外ハンドラテーブル内の順序によって決定される(

第 章参照)。

ファイル形式内への例外項目の符号化(

第 章参照)は,(catch ハンドラでも,fault ハンドラでも,

finally

ハンドラでもない)フィルタで選択したハンドラだけが唯一,フィルタをもつことができること

を保障する。

例外処理ブロックは,保護区域,フィルタ,catch ハンドラ,filter ハンドラ,falut ハンドラ又は

finally

ハンドラのいずれかとする。

12.4.2.8 

保護ブロック上での制御フロー制限 

12.4.2.8.1 

通り抜け 

命令 I1 は次のいずれか一つが真である場合,通り抜けが可能である。

−  命令 I1 が制御フロー命令でない(すなわち,制御フローが命令 I1 によって変化する唯一の方法は,

それが例外を送出する場合である。

−  命令 I1 が switch 分岐又は条件分岐である。

注記  通り抜けは,字句のない case である場合である。

−  命令 I1 がメソッド呼出し命令である。

注記 1  この細分箇条において,命令のとおり抜け可能性は,命令の型によって純粋に決定すること

ができる。

注記 2  多くの命令は,無条件分岐命令を実行した後に通り抜けと制御することが可能である。命令


98

X 3016

:2010 (ISO/IEC 23271:2006)

   

ret

,jmp,leave(.s),endfinally,endfault,endfilter,throw,及び rethrow

は,そうではない。呼出し命令は通り抜けと制御できる。これは,現在のメソッド内で実行

される次の命令は,呼出し命令の字面のうえで次の命令であるからである。この命令は,呼

出しからの戻った後に実行される。

注記 3  通り抜けに関する妥当性の決定は,字面によってなされる。制御フロー分析及びデータフロ

ー分析は要求されない。

フィルタ又はハンドラへの入りは,CLI 実行システムを通して達成される。つまり,フィルタ又はハン

ドラのブロック内に通り抜けする制御は妥当でない。このことは,フィルタ及びハンドラはメソッドの開

始時点に現れたり,又は通り抜けする制御を引き起こす任意の命令の直後に現れたりすることはできな

い。.

注記  条件分岐は,制御フロー上,複数の効果をもたらす。その一つが,制御フローを通り抜けにで

きることなので,フィルタ又はハンドラは,条件分岐の直後に現れることはできない。

保護ブロックへの入りは,評価スタックが空であるときに,通り抜けによって達成される。

保護ブロック,フィルタ又はハンドラからの出は,通り抜けを経由して達成することはできない。

12.4.2.8.2 

制御フロー命令 

制御フローに影響を与える命令は,それが保護ブロック,フィルタ及びハンドラでどのように利用され

ているかに基づく制約をもつ。特定の命令は,命令の型に依存する。この細分箇条は,次の条件の基づく

制約を規定する。

−  命令のソース。すなわち,この命令の開始アドレス。

−  命令のターゲット。

すなわち,

それに続いて実行されうる同じメソッド内のすべての命令のアドレス。

ただし,12.4.2.8.1 で規定した通り抜けを除く。命令がターゲット規則をもつならば,ターゲットの正

確な定義は,その規則に優先する。

命令のソース及び個々のターゲットに関し,そのアドレスを囲んだ個々の保護ブロック,フィルタ又は

ハンドラを考慮する。すべての規則が,囲んでいる保護ブロック,フィルタ又はハンドラ,命令のソース

及びすべてのターゲットに対して満足するなら,その命令は例外処理に関して妥当であるとする(明らか

に,命令は,依然として他の妥当性規則のすべてに従わなければならない。

。命令のソースがブロックの

最初である場合でさえ,その命令は,そのブロック内にあるとみなされる。

12.4.2.8.2.1  throw

(及び次の細分箇条に掲げていないすべての CIL 命令) 

ソース 

1)

ソースに関する制約はない。

ターゲット 

1)

ターゲットに関する制約はない。

12.4.2.8.2.2  rethrow: 

ソース 

1)  catch

ハンドラ内に囲まれていなければならない。

注記  catch ハンドラは,最も内側の囲んでいる例外処理ブロックである必要はない。例えば,catch

内にある finally 内に rethrow があってもよい。この場合,再送出される例外は,最も内側

の囲んでいる catch ハンドラによって捕獲された例外である。

ターゲット 

1)

ターゲットに関する制約はない。


99

X 3016

:2010 (ISO/IEC 23271:2006)

12.4.2.8.2.3  ret: 

ソース 

1)

保護ブロック,フィルタ又はハンドラに囲まれていてはならない。

注記 1  保護ブロック,フィルタで選択したハンドラ,又は catch ハンドラから戻るために,すべて

の例外処理ブロックの外側のアドレスに制御を移すために leave(.s)命令が必要である。そ

して,その制御が移ったアドレスに ret 命令が必要である。

注記 2  tail 前置命令は,ret 命令が後続する命令を必要とするから,保護ブロック,フィルタ又

はハンドラの内部から tail 呼出しは許されていない。

ターゲット 

1)

ターゲットに関する制約はない。

12.4.2.8.2.4  jmp: 

ソース 

1)

任意の保護ブロック,フィルタ又はハンドラ内に囲まれていてはならない。

ターゲット 

1)

ターゲットに関する制約はない。

12.4.2.8.2.5  endfilter: 

ソース 

1)

字面上フィルタ内の最後の命令として現れなければならない。

注記 1  endfilter に到達する制御フローが存在しない場合,例えば,フィルタ内で throw が行わ

れる場合であっても,endfilter は必要とする。

注記 2  字面上入れ子の規則では,フィルタの内部で別の例外処理エントリを入れ子にすることを禁

止している。つまり,endfilter 命令を囲んでいる最も内側の例外処理ブロックは,フィ

ルタでなければならない。

ターゲット 

1)

ターゲットに関する制約はない。

12.4.2.8.2.6  endfinally

及び endfault: 

ソース 

1)

保護ブロック,フィルタ又はハンドラを囲んでいる最も内側は,finally ハンドラ又は fault ハ

ンドラでなければならない。

注記 1  endfinally 及び endfault は,同じ CIL opcode  の別名の関係にある。通常,CIL  アセン

ブラでは,endfinally は finally ハンドラ内で使うこと,及び endfault は fault ハ

ンドラ内で使うことを要求するが,発行された命令は,いずれの名前を使っても同じである。

注記 2  finally ハンドラ又は fault ハンドラは,複数の endfinally/endfault を含むことがで

きる。finally ハンドラ又は fault ハンドラの内部で語い(彙)的に最後の命令が,

endfinally

/endfault である必要はない。事実,すべての制御フローのパスが,他の手段

で終了される場合,例えば,finally ハンドラ又は fault ハンドラが送出する場合,

finally

ハンドラ又は fault ハンドラは一切要求されなくてよい。

ターゲット 

1)

ターゲットに関する制約はない。

12.4.2.8.2.7 

分岐(brbr.s,条件分岐,switch


100

X 3016

:2010 (ISO/IEC 23271:2006)

   

ソース 

1)

分岐のソースが保護ブロック内,フィルタ内又はハンドラ内である場合,ターゲットは同一の保護

ブロック,フィルタ又はハンドラの内部に存在しなければならない。

ターゲット 

命令 br,br.s 及び条件分岐命令のターゲットは,指定されたアドレスとする。switch のターゲット

は,飛び先テーブル内に指定されたアドレスのすべてとする。

1)

分岐の任意のターゲットが保護ブロック内にある場合,その保護ブロック内の最初の命令である場

合を除いて,そのソースは同一の保護ブロック内に存在しなければならない。

2)

分岐のターゲットがフィルタ又はハンドラの内部にある場合,そのソースは,同一のフィルタ又は

ハンドラの内部に存在しなければならない。

注記  コードは,保護ブロックの最初の命令に分岐することはできるが,保護ブロックの途中に分岐

することはできない。

注記  条件分岐及び switch は,通り抜けとなる場合があるから,それらは通り抜けの規則にも従わ

なければならない。

12.4.2.8.2.8  leave

及び leave.s: 

ソース 

1)

ソースがフィルタ,fault ハンドラ又は finally ハンドラの内部に存在する場合,そのターゲッ

トは同一のフィルタ,fault ハンドラ又は finally ハンドラの内部に存在しなければならない。

注記  これは,leave(.s)命令によって,制御をフィルタ,fault ハンドラ又は finally ハンドラ

の外に移すことができないことを意味する。

2)

ソースが保護ブロック内に存在する場合,そのターゲットは同一の保護ブロック内,又は,それを

囲んでいる保護ブロック内に存在しなければならない。又は,互いに素の保護ブロックの最初の命

令でなければならない。任意の保護ブロックの内部に存在してはならない。

3)

ソースが catch ハンドラ又はフィルタで選択したハンドラ内に存在する場合,そのターゲットは,

同一の catch ハンドラ又はフィルタで選択したハンドラ内,それに関連する保護ブロック内,若し

くは,その catch ハンドラ又はフィルタで選択したハンドラを囲んでいる保護ブロック内に存在し

なければならない。又は,互いに素の保護ブロックの最初の命令でなければならない。任意の保護

ブロック内に存在してはならない。

注記  ソースが任意の例外処理ブロックの外側になる場合,その事実によって,そのターゲットに関

する制約は課せられないことを意味する。実際,例外処理の外側からの leave は,分岐のよう

に動作する。この時,評価スタックを空にする副作用をともなう。

ターゲット 

命令 leave(.s)  のターゲットは,命令 leave(.s)  で指定されたアドレスとする。

1)

ターゲットがフィルタ又はハンドラの内部に存在する場合,そのソースは同一のフィルタ又はハン

ドラの内部に存在しなければならない。

2)

ターゲットが保護ブロックの内部に存在する場合,その保護ブロックの最初の命令である場合を除

いて,そのソースは同一の保護ブロックの内部,又は関連する catch ハンドラ若しくはフィルタで

選択したハンドラの内部に存在しなければならない。

注記  明確に定義すると,ターゲットが保護ブロックの最初の命令である場合,そのソースはその保

護ブロックの外側に存在しえない。


101

X 3016

:2010 (ISO/IEC 23271:2006)

注記  これは,catch ハンドラ又はフィルタで選択したハンドラから,関連する保護ブロックへ制御

を移すことができることを意味する。

12.4.2.8.2.9 

 

例 1  次のコードを例として示す。

{

EX1:

 br

TryStart2

 .try

{

TryStart1:

.try

{

TryStart2:

  leave

End

}

finally

{

  endfinally

}

 }

 finally

 {

endfinally

 }

End:

 ret

}

EX1

での br TryStart2 命令を考える。これは,どの例外処理ブロックの内部にも含まれて

いないから,ソースに対する規則は適用されず,したがって,ソースに対する規則を満足する。

そのターゲットは,二つの保護区域の内部に含まれているから,ターゲットに対する規則が,そ

れぞれの保護区域に対して 1 回ずつ適用される。

最も外側の保護区域では,そのターゲットは最も外側の保護区域の最初の命令なので,分岐の

ターゲット規則 1 を満足する。分岐のターゲット規則 2 は適用されず,したがって,分岐のター

ゲット規則 2 を満足する。

最も内側の保護区域では,そのターゲットは,最も内側の保護区域の最初の命令なので,分岐

のターゲット規則 1 を満足する。分岐のターゲット規則 2 は保護区域に対して適用されず,した

がって,分岐のターゲット規則 2 を満足する。

例 2  次のコードを例として示す。

{

 ldc.i4.0


102

X 3016

:2010 (ISO/IEC 23271:2006)

   

EX2:

 brtrue

TryStart2

 .try

 {

TryStart1:

EX3:

br

TryStart2

.try

{

TryStart2:

  leave

End

}

finally

{

  endfinally

}

 }

 finally

 {

endfinally

 }

End:

 ret

}

EX2

での brtrue TryStart2  命令を考える。これは,どの例外処理ブロックの内部にも含ま

れないから,ソース規則は適用されず,したがって,ソース規則を満足する。そのターゲットは,

二つの保護区域の内部に含まれるから,ターゲット規則が,それぞれの保護区域に対して 1 回ず

つ適用される。

そのターゲットは,内側の保護ブロックの最初の命令なので,分岐のターゲット規則 1 は,内

側の保護ブロックに対して満足する。しかし,そのソースが外側の保護ブロックの内部に存在せ

ず,そのターゲットがそのブロックの最初の命令でもないから,分岐のターゲット規則 1 は,外

側の保護ブロックに対して満足しない。

したがって,EX2 での条件分岐命令は,例外処理の視点で妥当ではない。

次に,EX3  での br TryStart2  命令を考える。これは,一つの保護ブロックの内部に存在す

るから,ソース規則が,その保護ブロックに対して適用される。そのターゲットが,その保護ブ

ロックの内部に存在するから,分岐のソース規則 1 を満足する。そのターゲットは,二つの保護

区域の内部に含まれるから,ターゲット規則が,それぞれの保護区域に対して 1 回ずつ適用され

る。

外側の保護ブロックでは,ソースは外側の保護ブロックにも存在するから,分岐ターゲット規

則 1 を満足する。分岐のターゲット規則 2 は保護ブロックに適用されず,したがって,分岐のタ


103

X 3016

:2010 (ISO/IEC 23271:2006)

ーゲット規則 2 を満足する。

内側の保護ブロックでは,そのターゲットが内側の保護ブロックの最初の命令なので,分岐の

ターゲット規則 1 を満足する。分岐のターゲット規則 2 は保護ブロックには適用されず,したが

って,分岐のターゲット規則 2 を満足する。

したがって,EX3 での分岐命令は,例外処理の視点で妥当である。

例 3  次のコードを例として示す。

{

 .try

 {

newobj instance void [mscorlib]System.Exception::.ctor()

throw

AfterThrow:

leave

End

 }

 catch

[mscorlib]System.Exception

 {

.try

{

  newobj

instance

void

[mscorlib]System.Exception::.ctor()

  throw

}

catch

[mscorlib]System.Exception

{

EX4:

  leave

AfterThrow

}

leave

End

 }

End:

 ret

}

EX4

  での leave  命令を考える。これは,二つの catch ハンドラの内部に含まれるから,ソ

ース規則が,それぞれの領域に対して 1 回ずつ適用される。

外側の catch ハンドラでは,leave  のソース規則 1 及びソース規則 2 は catch ハンドラに適

用されず,したがって,それらの規則を満足する。そのターゲットが関連する保護区域の内部に

存在するから,leave  のソース規則 3 を満足する。

内側の catch ハンドラでは,leave  のソース規則 1 及びソース規則 2 は catch ハンドラに適

用されず,したがって,それらの規則を満足する。そのターゲットは,互いに素の保護区域の途

中に存在するから,leave のソース規則 3 を満足しない。


104

X 3016

:2010 (ISO/IEC 23271:2006)

   

したがって,EX4 での leave 命令は,例外処理の視点では妥当でない。しかし,説明の都合

上,そのターゲット規則についても考える。

そのターゲットは一つの保護区域の内部に存在するから,それを保護区域とみなした場合,タ

ーゲット規則が,その保護区域に対して適用される。leave のターゲット規則 1 は保護区域に提

供されず,したがって,leave のターゲット規則 1 を満足する。そのソースが,保護区域に関連

する catch ブロック内に存在するから,leave のターゲット規則 2 を満足する。

例 4  次のコードを例として示す。

{

 .try

 {

.try

{

  newobj

instance

void

[mscorlib]System.Exception::.ctor()

  throw

}

catch [mscorlib] System.Exception

{

EX5:

  leave

EndOfOuterTry

}

EndOfOuterTry:

//

leave

End

 }

 catch

[mscorlib]System.Exception

 {

leave

End

 }

End:

 ret

}

EX5

で leave 命令を考える。これは,保護区域の内部及び catch ハンドラの内部に含まれる

から,ソース規則が,それぞれに対して一度ずつ適用される。

保護区域では,

leave

のソース規則 1 及びソース規則 3 が,

その保護区域に対して適用されず,

したがって,それらを満足する。そのターゲットが同一の保護区域の内部に存在するから,leave

のソース規則 2 を満足する。

catch

ハンドラでは,leave のソース規則 1 及びソース規則 2 は適用されず,したがって,そ

れらを満足する。そのターゲットは,catch ハンドラを囲む保護区域の内部に存在するから,

leave

のソース規則 3 を満足する。


105

X 3016

:2010 (ISO/IEC 23271:2006)

そのターゲットは,一つの保護区域の内部に存在するから,それを保護区域とみなした場合,

ターゲット規則が,その保護区域に適用される。ターゲット規則 1 は,その保護区域には適用さ

れず,したがって,ターゲット規則 1 を満足する。そのソースが同一の保護ブロックの内部に存

在するから,ターゲット規則 2 を満足する。

したがって,EX5 での leave 命令は,例外処理の視点で妥当である。

12.5 

代理及び遠隔処理 

次のような場合,遠隔処理境界が存在する。すなわち,その境界をまたがって,オブジェクトの識別を

共有することができない場合である。例えば,二つのオブジェクトが共通のアドレス空間を共有できない

物理的に別々な計算機上に存在する場合,遠隔処理境界が,それらの計算機の間に存在する。これとは別

に,遠隔処理境界を生成する管理機構がある。

VES は,アプリケーションドメインと呼ばれる,同一オペレーティングシステムプロセス内で実行して

いるアプリケーションをそれぞれ分離する機能を提供する。一つのアプリケーションドメイン内にロード

される型は,別のアプリケーションドメイン内にロードされる同じ型とは区別され,オブジェクトのイン

スタンスはあるアプリケーションドメインから別のアプリケーションドメインに直接共有されてはならな

い。したがって,アプリケーションドメイン自身は遠隔処理境界を形成する。

VES は代理の概念に基づいた遠隔処理境界を実装する。代理は,境界の一方に存在し,他方のオブジェ

クトを表現するオブジェクトとする。代理は,解釈の目的のために,インスタンスフィールド及びメソッ

ドの参照を実際のオブジェクトへ移す。

代理の実装は,System.MarshalByRefObject から派生した型のインスタンスを自動的に提供される

第 章参照)。

12.6 

メモリモデル及び最適化 

12.6.1 

メモリ格納 

“メモリ格納”とは,CLI が操作する通常の処理メモリを意味する。概念的には,この格納は単純なバ

イト配列とする。この配列内の添字は,データオブジェクトのアドレスとする。CLI は ldind.*及び

stind.*

命令を通じてメモリ格納内のデータオブジェクトにアクセスする。

12.6.2 

境界調整 

組込みデータ型は,次に定義されているように,適切に境界調整されなければならない。

−  1 バイト,2 バイト及び 4 バイトデータは,それらが,それぞれ 1 バイト境界,2 バイト境界及び 4 バ

イト境界の位置に格納されたときが適切に境界調整されたとする。

−  8 バイトデータは,基礎とするハードウェアが,それに native int に対する原子的アクセスに要求

するのと同じ境界に格納されたとき,適切に境界調整されたとする。

すなわち,int16 及び unsigned int16 は偶数アドレスから開始する。int32,unsigned int32

及び float32 は 4 で整除することができるアドレスから開始する。int64,unsigned int64 及び

float64

は,対象とするアーキテクチャに応じて,4 又は 8 で整除することができるアドレスから開始す

る。プラットフォーム固有の大きさの型(native int,native unsigned int 及び&)は,常に自然

に境界調整される(アーキテクチャに応じて,4 バイト又は 8 バイト)

。外部で生成されたとき,可搬性の

あるコードがアーキテクチャ独立であることを保障するために,

これらは 8 バイト境界を使ってもよいが,

それらの自然なサイズに境界調整されることが推奨される。native int の大きさが 32bit であっても,

float64

は 8 バイト境界に境界調整されることを強く推奨する。

特別な前置命令 unaligned.  がある。これは,ldind,stind,initblk 又は cpblk 命令の直前に


106

X 3016

:2010 (ISO/IEC 23271:2006)

   

先行してよい。この前置命令は,そのデータが任意に境界調整してもよいことを示し,JIT には実際の境

界調整に関係なく,

その命令を効果的に正しく実行するコードを生成することを要求する。

さもなければ,

そのデータが適切に境界調整されず,unaligned.前置命令が指定されなければ,命令の実行は境界調整

されないメモリ障害又は不正なデータを生成できる。

12.6.3 

バイト順序 

2 バイト以上のデータ型に対して,バイト順序は対象の CPU に依存する。バイト順序に依存するコード

は,すべてのプラットフォーム上で動作しなくてもよい。PE ファイル形式(12.2 参照)は,そのファイル

が,特定の型のバイト順序に依存していることを示す印付けを許可する。

12.6.4 

最適化 

CLI 規格適合処理系は,単一のスレッドの実行において,そのスレッドによって生成される副作用及び

例外が CIL によって規定された順番で可視であることを保障する任意の技術を使ってプログラムを実行す

ることを許可している。このために,揮発性操作(揮発性読込みを含む)は可視の副作用をもたらす(揮

発性操作は可視の副作用をもたらすだけとするが,それは非揮発性参照の可視性にも影響をもたらすこと

に注意する。

。揮発性操作は 12.6.7 で規定する。あるスレッドに他のスレッドによって注入される例外に

対して保障される順序はない(このような例外は“非同期例外”と呼ばれ,

System.Threading.ThreadAbortException

がある。

注記  最適化コンパイラは,プログラムの見た目の振る舞いが変わらない範囲で,副作用及び同期例

外を再順序化することができる。この点を考慮し,上記のような規定となった。

注記 CLI の実装は,最適化コンパイラを使うことが許されている。例えば,CIL を,副作用及び同

期例外の順序を(個々の単一スレッドの実行内において)同じに維持したプラットフォーム固

有の計算機コードに変換するコンパイラを提供できる。

これは,ISO C++(評価順序点の組合せの間で再順序化が許されている。

)又は ISO Scheme(関数の実引

数の再順序化が許可されている。

)以上の強力な条件である。

最適化コンパイラは,メソッド内の緩和された例外に付加的な自由度を与える。メソッドは,種別 E の

例外に関して最も内側のカスタム属性

  System.Runtime.CompilerService.CompilerRelaxationsAttribute が存在し,種別 E の例外

を緩和すると指定した場合,例外に対して E-緩和とする。ここで,

“最も内側”というのは,メソッド,

そのクラス及びそのアセンブリを,この順番で検査することを意味する。

E-緩和列は,スレッドで実行される命令列とする。ここで,

−  可視な副作用又は例外を引き起こしている個々の命令は,E-緩和メソッド内に存在する。

−  この列は,重要な保護領域又はハンドラ領域の境界をまたぐことはない。非緩和メソッドに対する規

則に従って最適化された結果,存在しなくなりうる領域は,重要な領域ではない。

E-検査は,失敗によって種別 E の例外の送出を引き起こす CIL 命令によって実行される検査として定義

される。さらに,配列要素の値を設定又は取得するメソッド,若しくは,配列要素のアドレスを取得する

メソッドによって実行される型及び範囲の検査は,ここでの検査とみなされる。

CLI 規格適合処理系は,緩和された E-検査が失敗するような場合にだけ,プログラムの見た目の動作を

変更する場合に限り,他の検査及び命令列に関して,E-緩和列内の緩和された E-検査のタイミングの変更

を自由に行える。E-検査が,E-緩和列内で失敗した場合,次の規定に従う。

−  関連する残りの命令は,正当性検証可能性を失わないために,抑制されなければならない。その命令

が VES スタック上に値を積むことを期待された命令である場合,それに後続する命令で,その値を


107

X 3016

:2010 (ISO/IEC 23271:2006)

利用する命令はどれも実行してはならない。

− E-緩和列内のどの副作用も VES によって明白にされるかどうかは未規定とする。

− E-緩和列内で他の例外を送出しない限り,検査例外がその E-緩和列内でいつか送出される。複数の緩

和された検査に失敗したとき,どの例外が VES によって送出されるかは未規定とする。

注記  緩和された検査は正当性検証可能性を保全するが,必ずしも安全性を保証するわけではない。

緩和された検査例外を保留にし,後続のコードが実行するかもしれないから,プログラマは安

全性の確保を暗黙の検査に依存しないのが望ましい。その代わり,明示的な検査を利用し,安

全性に問題がある場合には例外を送出するのが望ましい。

注記  プログラマには,それぞれ別々の目標がある。精密な例外の動作を放棄することは許容できな

いプログラマもいれば,最適化こそが重要というプログラマもいる。プログラマは,自分自身

の意向を指定しなければならない。どの例外が時間的に正確であるべきかという意向はプログ

ラマごとに異なるから,例外の種類ごとに緩和しても,しなくてもよい。

注記  緩和された例外処理の背景及び実装に関する情報,並びにその例は第 章附属書 を参照。

12.6.5 

ロック及びスレッド 

スレッド制御の論理的な抽象化は,クラスライブラリ内の System.Threading.Thread オブジェクト

のインスタンスによって取り込まれる。System.Threading で始まるクラス(

第 章参照)は,この抽

象化に対して,利用者に可視な多くの支援を提供する。

スレッド実行をまたがった一貫性を生成するために,CLI は次の機構を提供する。

1)

同期化されたメソッド:スレッド横断的に可視であるロックは,同期化されたメソッドの本体への

入りを制御する。インスタンスメソッド及び仮想メソッドでは,ロックは this ポインタに結びつ

く。静的メソッドでは,ロックは,そのメソッドが所属する型に結びつく。そのロックは,論理的

なスレッド(

第 章の System.Threading,Thread を参照)によって取得され,同じスレッド

に何度でも入ってよい。最初のスレッドがそのロックを保持している間,他のスレッドによる入り

は禁止される。最初にロックを獲得したメソッド呼出しを抜け出すときに,CLI は,

(何が何でも)

ロックを解放しなければならない。

2)

明示的なロック及びモニタ:これらは,クラスライブラリ System.Threading.Monitor で提供

される。このクラスのメソッドの多くは,実引数として Object を受け付け,同期化されたメソッ

ドによって使われる同じロックに直接アクセスが許される。CLI は,ロックが同期化されたメソッ

ドによってだけ使われるとき,正しいプロトコルを保障する責任がある。利用者は,同じオブジェ

クトに対して明示的なモニタを使うとき,この責任を受け入れなければならない。

3)

揮発性読込み及び揮発性書出し:この CIL は,volatile.前置命令を含む。これは,続く操作が

12.6.7

で記述したスレッド間の可視性の制約をもって実行されることを規定する。さらに,クラス

ライ ブラリは 明示 的 な 揮発 性 読込 み ( System.Thread.VolatileRead ) 及 び 揮 発性 書 出 し

( System.Thread.VolatileWrite ) を 実 行 す る メ ソ ッ ド を 提 供 す る と と も に , 障 壁 同 期

(System.Thread.MemoryBarrier)を提供する。

4)

組込みの原子的読込み及び原子的書出し:適切に境界調整されたデータ型の読込み及び書出しのす

べては,原子的に行われることが保障される(12.6.6 参照)

5)

明示的な原子的操作:クラスライブラリは,System.Threading.Interlocked クラス内の原子

的な操作の何種類かを提供する。これらの操作(例えば,増加,減少,交換及び比較交換)は,暗

黙の獲得/解放操作で実行される。


108

X 3016

:2010 (ISO/IEC 23271:2006)

   

ロックの獲得(System.Threading.Monitor.Enter,又は,同期化されたメソッドに入ること)は,

揮発性読込み操作を暗黙に実行しなければならず,ロックの解放(System.Threading.Monitor.Exit,

又は,同期化されたメソッドから抜け出すこと)は,揮発性書出し操作を暗黙に実行しなければならない

12.6.7 参照)

12.6.6 

原子的読込み及び原子的書出し 

CLI 適合は,ある位置に対するすべての書出しアクセスが同じ大きさのとき,プラットフォーム固有の

ワードの大きさ(native int の大きさ)より長くない適正に境界調整されたメモリ位置への読込み及び

書出しアクセスは原子的であることを保障しなければならない(12.6.2 参照)

。原子的書出しは,書き出さ

れるビット以外を変更してはならない。明示的な配置制御(

第 章  インスタンスの配置制御  参照)が

既定の動作を変更するために使われなければ,自然のワードの大きさ(native int の大きさ。

)より長

いデータ要素は,適切に境界調整されなければならない。オブジェクト参照は,それがプラットフォーム

固有のワードの大きさに格納されているかのように扱われなければならない。

注記  クラスライブラリとして原子的な更新を提供した一部のメソッドを除いて,メモリの原子的な

更新(読込み─更新─書出し)を保障しない(

第 章参照)。“小さなデータ項目”(プラットフ

ォーム固有のワードの大きさより長くない項目。

)の原子的書出しは,小さなデータ項目の直接

書出しを提供しないハードウェア上で,原子的な読込み─更新─書出しを行うことを要求する。

注記  native int が 32 ビットのとき,ある実装が 8 バイトデータを 8 バイト境界に境界調整する

とき,原子的なアクセスの実行ができるとしても,その 8 バイトデータに原子的なアクセスを

する保障はない。

12.6.7 

揮発性読込み及び揮発性書出し 

ある命令に対する volatile.前置命令は,スレッド間のメモリ順序規則を保障しなければならない。

これらには,12.6.6 の規定によって保障される以外に,原子性を提供しない。

揮発性読込みは,

“獲得の意味規則”をもつ。これは,読込みが,CIL 命令列内でのその読込み命令の後

で起こるメモリの任意の参照より前に起こることが保障されることを意味する。

揮発性書込みは,

“解放の

意味規則”をもつ。これは,書出しが,CIL 命令列内のその書出し命令より前の任意のメモリ参照より後

に起こることが保障されること意味する。

CLI 規格適合処理系は,揮発性操作のこの意味規則を保障しなければならない。これは,すべてのスレ

ッドで,

他の任意のスレッドによって実行される揮発性書出しの実行順序を守ることを保障する。

しかし,

CLI 規格適合処理系は,すべてのスレッドの実行から見た揮発性書出しの単一の総合的な順序を提供する

ことを要求しない。

CIL をプラットフォーム固有のコードに変換する最適化コンパイラは,どの揮発性操作も削除してはな

らず,単一の操作に複数の揮発性操作を融合させてはならない。

注記  揮発性操作の従来の一つの使用方法は,直接メモリアクセスを通して可視であるハードウェア

レジスタをモデル化することである。この場合,その操作の削除又は融合は,プログラムの振

る舞いを変更してしまう。これらの点を考慮して,上記のような規則となった。

注記 CIL からプラットフォーム固有のコードへ変換する最適化コンパイラは,コードを再順序化す

ることができ,12.6 で規定された単一スレッドの意味規則と,揮発性操作のスレッド間の意味

規則との両方の保障を提供する。

12.6.8 

それ以外のメモリモデルの問題 

静的変数(PE ファイル内で RVA に割り当てられたものを除く。

第 章参照)及びオブジェクトに割り


109

X 3016

:2010 (ISO/IEC 23271:2006)

当てられるすべてのメモリは,

それらが使用者コードで可視になる前にゼロに設定されなければならない。

CLI 規格適合処理系は,マルチスレッド環境で適切な利用者による同期化がなくても,オブジェクトを,

非認証メモリアクセス及び不当な操作を発生させない方法で割り当てることを保障しなければならない。

特に,マルチプロセッサメモリシステム上では,明示的な同期化は,すべての関連するデータ構造(例え

ば,vtable ポインタ)が可視であることを保障することが要求される。VES は,この自動的な同期化の強

制又は非 fatal,非不正,利用者可視の例外内の同期化の欠如によるエラーの変換のいずれかに責任をもた

なければならない。

構築子内で実行されるすべての状態更新が,その構築子が完了する前に一様に可視にすることを CLI 規

格適合処理系に保障させることは明らかに要件ではない。CIL 生成器は,メモリ障壁又は揮発性書込み命

令に適切な呼出しを挿入することによってこの要件を保障できる。

第 章  メタデータ定義及び意味 

序論 

第 章は,メタデータを規定する。すなわち,メタデータの(ファイル形式としての)物理的な配置,

メタデータの(複数の表の集合及び表間の関係としての)論理的な内容及びメタデータの(仮想アセンブ

ラとしての ilasm から見た)意味を規定する。

概要 

第 章は,メタデータの意味及び構造に焦点をあてる。VES(仮想実行システム)のほとんどの操作を

定めたメタデータの意味を,

CIL のためのアセンブリ言語 ILAsm の構文を用いて記述する。ILAsm 構文は,

この規格の一部として,箇条 521 で与える。ILAsm のためのアセンブラの実装は,

第 章で記述される。

論理的構造及び物理的構造は,箇条 2225 に示す。

注記  メタデータの意味を ILAsm の構文を用いて記述する根拠は,アセンブリ言語をファイル中のメ

タデータ及びそのファイル中の CIL 命令を指定するための構文として扱うことによる。ILAsm

は,高水準言語を使わず,CLI のために直接書かれたプログラムを交換する手段を提供する。

また,例を示す簡便な方法も提供する。

メタデータの意味は,格納される実際の形式と独立に記述できる。これは,箇条 2225 に従

った記憶域形式で,記憶域の容量及びアクセス時間の両方を効率化できるよう設計できるから

重要となる。しかし,これは,意味記述にとって望ましい単純性を犠牲にする。

妥当性検証及び正当性検証 

妥当性検証は,ファイルの形式,メタデータ及び CIL に自己矛盾がないことを確認するために任意のフ

ァイル上で行う試験の集合を適用することをさす。これらの試験は,ファイルがこの規格の必す(須)規

定要件に適合することを保証する。CLI 規格適合処理系に非適合ファイルが与えられたときの振る舞いは,

未規定とする。

正当性検証は,CIL コード列がプログラムの論理アドレス空間の外側のメモリへのアクセスを許さない

ことを保証するために CIL 及びその関連するメタデータの両方の検査とする。妥当性検証試験と正当性検

証を組み合わせれば,アクセス許可されないメモリ又は他の資源へプログラムがアクセスできないことを

保証する。

第 章は,CIL 命令の適正,かつ,正当性検証可能な使用規則を規定する。さらに,第 章は,メタデ


110

X 3016

:2010 (ISO/IEC 23271:2006)

   

ータの内部整合性(その規則は,間接的ではあるが,

第 章の規定から得られる。)を評価するための規

則を参考として提供する。また,正当性検証アルゴリズムの規範の記述も含む。基礎となる型システムの

健全性の数学的証明は,可能であり,正当性検証要件のための基盤をも提供する。これらの規則を除けば,

この規格は,次を未規定のままとする。

−  (あるとすれば)そのようなアルゴリズムが,実行されることが望ましい時刻。

−  規格適合処理系が正当性検証を失敗した場合に行うことが望ましいことは,何か。

図 は,この関係を明らかにする(詳細は,次の段落で示す。)。

図 1−適切な CIL 及び正当性検証可能な CIL の間の関係 

図 では外部の円は,ILAsm 構文によって許されるコードをすべて含む。次の内円は,適正な CIL すべ

てのコードを表す。さらに,その内円は,すべての型安全なコードを表す。最後に,黒い最内円は,正当

性検証可能なコードをすべて含む(型安全なコードと正当性検証可能なコードとの間の相違の一つは,証

明可能性とする。VES 正当性検証アルゴリズムは,定義によって,正当性検証可能とする。しかし,より

深い分析ならば,真に型安全と証明できるとしても,その単純なアルゴリズムでは,拒否されるコードが

ありうる。

。プログラムが

第 章に記述された構文に従っても,第 章及び第 章で示された制限を順守

しなければ,そのコードは妥当ではないことに注意する。

正当性検証の処理は,非常に厳格とする。妥当性検証は通るが正当性検証に失敗するプログラムは,多

数ある。VES は,これらのプログラムが,アクセスが許されないメモリ又は資源へのアクセスをしないこ

とを保証することができない。それにもかかわらず,プログラム自体は,そのような資源にアクセスしな

いように正確に構築されているかもしれない。したがって,これらのプログラムを動作させることが安全

かどうかは,数学的証明の問題ではなく,信頼の問題となる。これは規格外の信頼制御管理事項になるが,

通常,CLI 規格適合処理系は,正当性検証不能コード(正当性検証を通っていない正当なコード。

)が実行

されることを許すことができる。通常,CLI 規格適合処理系は,正当性検証可能なコードの実行を許可し

なければならない。しかし,そのようなコードは,処理系で指定された追加的な信頼制御の対象となりう

る。

 

注記  この箇条は参考情報であり規定ではない。

4.1 

例 Hello World 

ILAsm の一般的な感じをつかむために,よく知られた“Hello world!”というあいさつ(挨拶)を出力す


111

X 3016

:2010 (ISO/IEC 23271:2006)

る次の簡単な例を考察する。このコードは,標準アセンブリ mscorlib(

第 章参照)の一部のクラス

System.Console

にある静的メソッド WriteLine を呼び出す。

例  (参考):

.assembly extern mscorlib {}

.assembly hello {}

.method static public void main() cil managed

{ .entrypoint

  .maxstack  1

  ldstr  "Hello  world!"

    call void [mscorlib]System.Console::WriteLine(class System.String)

  ret

}

.assembly

extern

宣言は,System.Console の定義を含む外部アセンブリ mscorlib を参照する。

2 行目の.assembly 宣言は,このプログラムのためのアセンブリの名前を宣言する(アセンブリは CLI

のための実行可能な内容の配備単位とする。

。.method 宣言は,大域メソッド main を定義し,それに続

く本体は,中かっこ({})で囲まれる。本体中の最初の行は,このメソッドがこのアセンブリ用の入口点

(.entrypoint)となることを示す。また,本体中の 2 行目(.maxstack)は,必要とするスタックの

スロットの数は多くても一つであることを指定する。

メソッド main は,わずか三つの手順 ldstr, call 及び ret だけを含む。命令 ldstr は,文字列定数

“Hello world!”をスタックに入れる。そして命令 call は(CIL の中の文字列リテラルは,標準クラ

ス System.String のインスタンスとなることに注意する。),その文字列をただ一つの実引数として

System.Console::WriteLine

を呼び出す。呼出し命令は,呼び出される側のメソッドの完全な呼出し

情報を含まなければならない。最後の命令 ret は,main から戻る。

4.2 

 

第 章は,CLI メタデータのほとんどの特徴のための総合的な例を含んでいる。多くの箇条及び細分箇

条が,何らかの機能の典型的な使用を示す例で締めくくる。これらの例は,すべて ILAsm アセンブリ言語

を用いて書かれている。さらに,

第 章は,ILAsm アセンブリ言語の中で書かれたプログラムのより長い

例を含んでいる。当然だが,例は,すべて規定ではない。

一般的な構文 

箇条 は,文法の大部分に共通の,ILAsm 構文について記述する。

注記  逆斜線(U+005C)は,日本語環境上では,円記号で表示される場合がある。

5.1 

一般的な構文記法 

第 章は,修正 BNF 構文記法の形式を使用する。5.1 は,この記法の概要とする。

終端記号は,等幅フォントで記述する(例  .assembly,extern,float64)

。しかしながら,区切

り文字だけからなる終端記号は,一重引用符でくく(括)る(例  ‘:’,‘[’,‘(’)

。構文の種類の名前は,

《》でくく(括)り(例  《クラス宣言》

,そのクラスの実際のインスタンスに置き替えられなければな

らない。角括弧(例  [《ファイル名》],[《浮動小数点数》])に置かれた項目は,省略可能とする。また,

“*”が後続する項目(例  《16 進バイト》*,[‘.’  《識別子》] *)は,ゼロ回以上現れることができる。

文字“|”は,その項目及びその横の項目のいずれか一方が受理可能とする(例  true | false)

。省略


112

X 3016

:2010 (ISO/IEC 23271:2006)

   

可能な項目は,英字順(より具体的には,ASCII 順で,大文字と小文字とを区別しない。

)で整列させられ

る。規則が省略可能な項で始まる場合,省略可能な項は,整列では考慮されない。

ILAsm は,大文字と小文字とを区別する言語とする。すべての終端記号は,第 章で規定されるのと同

じ文字で使用しなければならない。

   

《最上位》 ::= 《Int32》 |  float 《Float》 |

          floats  [

《Float》[, 《Float》]*] | else 《引用文字列》

のような文法は,次のすべてを妥当とする。

     12

     float  3

     float  –4.3e7

     floats

     floats  2.4

     floats  2.4,  3.7

     else  "Something  ¥t  weird"

しかし次のすべてを妥当ではないとする。

     else  3

     3, 4

     float  4.3,  2.4

     float  else

     stuff

5.2 

基本構文要素 

これらの種類は,入力における構文制約を記述して,メタデータの情報に論理的な制約を課す。

《Int32》は,10 進数又は“0x”から始まる 16 進数のいずれかであって,32 ビットで表現されなけれ

ばならない。

注記 ILAsm には,8 ビット又は 16 ビット整数定数という概念はない。その代わり,16.2 に見られる

int8(...)及び int16(...)のような定数が要求される状況において《Int32》を代用し,最小上位バ

イトだけを使用することを許す。

《Int64》は,10 進数又は“0x”から始まる 16 進数のいずれかで,64 ビットで表現されなければなら

ない。

《16 進バイト》は,0∼9,a∼f 及び A∼F の文字集合から成る 1 対の文字とする 16 進数とする。

《実数》は,他のすべての構文の種類用とは異なる浮動小数点数のための任意の構文的な表現とする。

第 章ではピリオド(.)は,整数部及び小数部を分離するために使用される。また,“e”又は“E”は,

指数と仮数とを分ける。ピリオド又は仮数区切り子のいずれか(しかし両方ではない。

)が,省略できる。

注記  完全なアセンブラは,さらに,無限大及び NaN(Not a Number:非数)のための構文を供給して

もよい。

《引用文字列》は,二重引用符(")に囲まれた文字列とする。引用文字列内では文字“¥”を,エスケ

ープ文字として使用できる。

“¥t”を,タブ文字として使用することができる。

“¥n”を,復帰改行文字と

して使用できる。また,文字“¥”に続く三つの 8 進数字を,その値をもつバイトを表すために使用できる。

“+”演算子を,文字列リテラルを連結するために使用できる。長い文字列は短く分割し,

“+”でつなぎ


113

X 3016

:2010 (ISO/IEC 23271:2006)

合わせることができる。別な使い方として,行の最後の文字として“¥”を使用する。その場合にはその文

字とそれに続く改行は,生成された文字列に入力されない。次の行の上の“¥”及び最初の非空白文字の間

のすべての空白文字(空白,改行,復帰文字及びタブ)も,無視される。

注記  《引用文字列》における二重引用文字を包含するためには,8 進エスケープ手順を使う。

   

次の結果としての文字列は,

“Hello World from CIL!”と等価とする

    

ldstr "Hello " + "World " +

    

"from CIL!"

及び

    

ldstr "Hello World¥

     ¥040from  CIL!"

注記  完全なアセンブラは,Unicode 符号化を使うのに必要な問題点のすべてに対処する必要がある。

第 章 8.5.1 を参照(特に CLS 規則 4)。

《一重引用符文字列》は,二重引用符の代わりに一重引用符(′)を用いることを除いて,

《引用文字列》

と同様とする。

注記  《一重引用文字列》における二重引用文字を包含するためには,8 進エスケープ手順を使う。

《ID》は,英字(A-Z,a-z)又は“_”

“$”

“@”

“`”

(抑音アクセント)

“?”のうちの一つで始まり,

任意の個数の英数字(A-Z,a-z,0-9)又は“_”

“$”

“@”

“`”

(抑音アクセント)及び“?”が続く一連

の隣接した文字列とする。

《ID》は,次の二通りでだけ使用される。

−  《ID》は,CIL 命令のラベルとして使用される(5.4 参照)

−  《ID》は,

《識別子》として使用される(5.3 参照)

5.3 

識別子 

識別子は,実体に名づけるために用いられる。単純識別子は,

《ID》と同等とする。しかしながら,ILAsm

構文は,Unicode 文字セット(

第 章参照)を用いて記述することができるあらゆる識別子の使用を認め

る。これを達成するために,識別子は,一重引用符内に置かれなければならない。これは,次の文法で要

約される。

《識別子》 ::=

《ID》

   |

《一重引用符文字列》

キーワードは,それが一重引用符内に現れるならば,そのキーワードは識別子として使用される場合に

限る(すべてのキーワードは,

第 章に示す。)。

《識別子》は,より大きな《識別子》を記述するためにドット(.)によって組み合わせることができる。

このように記述された《識別子》は,

《ドット名》と呼ばれる。

《ドット名》 ::= 《識別子》[‘.’《識別子》]*

注記  根拠としては,

“.”は,

《一重引用符文字列》構文を用いて《識別子》に含めることができるか

ら,

《ドット名》は,便宜的に提供されることによる。

《ドット名》は,

“.”が共通の文字と考

えられる文法(例えば完全限定型名)の中で使用される。

 

次は,幾つかの単純識別子を示す。

     A


114

X 3016

:2010 (ISO/IEC 23271:2006)

   

     Test

     $Test

     @Foo?

     ?_X_

     MyType`1

次は,一重引用符中の識別子を示す。

′Weird Identifier′

′Odd¥102Char′

′Embedded¥nReturn′

次は,ドットがついた名前を示す。

     System.Console

′My Project′.′My Component′.′My Name′

     System.IComparable`1

5.4 

ラベル及びラベルの並び 

ラベルは,プログラムの便宜をはかるために提供される。ラベルは,メタデータ中で符号化される数値

を表現する。ラベルによって表現される値は,典型的には現在のメソッドの始めからのバイト指定でのオ

フセットとする。ただし,正確な符号化は,論理的なメタデータ構造体中又は CIL ストリーム中のラベル

の場所に応じて異なる。ラベルがメタデータ中でどのように符号化されるかの詳細は,箇条 22 から 25 

示す。CIL 命令でのそれらの符号化については,

第 章で示す。

単純ラベルは,アドレスを表現する特殊な名前とする。構文的にはラベルは,

《識別子》と同等とする。

したがってラベルは,一重引用符で囲まれてもよいし,Unicode 文字を含むこともできる。

ラベルの並びは,コンマで分離され,単純ラベルの任意の組合せをとりうる。

《ラベル又はオフセット》::= 《識別子》 
《ラベル列》::= 《ラベル又はオフセット》 [‘,’《ラベル又はオフセット》]*

注記  実際のアセンブラでは,

《ラベル又はオフセット》の構文は,記号ラベルを要求せず,直接数値

を指定することがある。

ILAsm は,2 種類のラベル,すなわち,コードラベル及びデータラベルを区別する。コードラベルは,

末尾にコロン(

“:”)をつけ,実行される命令のアドレスを表現する。コードラベルは,命令の前に現れ,

ラベルの直後の命令のアドレスを表現する。コードラベル名は,メソッド中で 2 度以上宣言してはならな

い。

コードラベルとは対照的にデータラベルは,一つのデータ片の格納域を指定し,

コロン文字を含まない。

データラベルを,コードラベルとして使ってはならない。また,コードラベルを,データラベルとして使

ってはならない。データラベル名は,モジュール中で 2 度以上宣言してはならない。

《コードラベル》 ::= 《識別子》‘:’ 
《データラベル》 ::= 《識別子》

   

次は,命令 ldstr のアドレスを表現するコードラベル ldstr_label を定義する。

ldstr_label:

ldstr

 "A

label"

5.5 16

進バイトの並び 

バイト列は,一つ以上の 16 進バイト列からなる。


115

X 3016

:2010 (ISO/IEC 23271:2006)

《バイト列》::= 《16 進バイト》 [《16 進バイト》*]

5.6 

浮動小数点数 

浮動小数点数を指定するために二つの異なる方法がある。

1)

《実数》として指定する方法。

2)

括弧内に整数を伴ったキーワード float32 又は float64 を用いて指定する方法。その整数は,浮

動小数点数の 2 進数表現とする。例えば,float32(1)は 4 バイトで表現され,値は 1.401298E-45

となり,float64(1)は 8 バイトで表現され,その値は,4.94065645841247E-324 となる。

《Float32》  ::=

《実数》

| float32 ‘(’

《Int32》 ‘)’

《Float64》 ::= 
  《実数》

| float64 ‘(’

《Int64》 ‘)’

 

5.5

1.1e10

float64(128) 

//

注記 :これは整数 128 と同じビットをもつ 8 バイト値になる。

5.7 

ソース行情報 

メタデータは,変数の構文範囲,すなわち,ソース行番号と CIL 命令の対応付けに関する情報をもたな

い。それにもかかわらず,この情報を別な符号化の生成で使用するために,この情報を供給するためのア

センブラ構文を規定することは,有用となる。

.line

は,行番号,コロンが先頭についたけた数(省略可能)

,及び参照しているファイル名を指定す

る一重引用符文字列(省略可能)を,この順番でとる。

《外部ソース宣言》 ::= .line 《Int32》 [‘:’ 《Int32》 ]  [ 《一重引用符文字列》 ]

5.8 

ファイル名 

文法要素には,ファイル名を必要とするものもある。ファイル名は,“.”を正常な成分文字と考えた名

前とする。ファイル名用の構文は,基礎とするオペレーティング  システムの規定に従う。

《ファイル名》::=

箇条 

《ドット名》

5.3 

5.9 

属性及びメタデータ 

型及び型のメンバの属性は,型及び型のメンバの定義に記述的情報を付ける。最も共通の属性があらか

じめ定義されて,その属性に関連したメタデータに特有の符号化を行う(箇条 23 参照)

。さらに,メタデ

ータは,幾つかの異なる符号化を用いて,メタデータに利用者定義属性を付ける方法を提供する。

構文的には,ILAsm の中の属性を指定する方法は次とする。

− ILAsm に組み込まれた特殊な構文を使用する方法。

例えば

《クラス属性》

においてキーワード private

(非公開)は,型の可視属性が,定義しているアセンブリ内でだけアクセスを許可するように設定し

なければならないことを指定する。

− ILAsm のはん用構文を使用する方法。非終端記号《カスタム宣言》は,この文法について記述する(箇

条 21 参照)

。擬似カスタム属性と呼ばれる幾つかの属性については,この文法は結果としてメタデー

タ内の特殊な符号化の設定になる(21.2.1 参照)

−  セキュリティ属性は,特別に扱われる。XML で表現したセキュリティ属性の直接記述を可能にする特


116

X 3016

:2010 (ISO/IEC 23271:2006)

   

殊な構文が,ILAsm にはある(箇条 20 参照)

22.10 に記述された一つの共通機構を用いて,標準ラ

イブラリにおいて,又は,利用者に提供される拡張において定義される他のすべての属性は,メタデ

ー タ 中 で 符 号 化 さ れ る が , セ キ ュ リ テ ィ 属 性 ( セ キ ュ リ テ ィ 属 性 は , 直 接 的 又 は 間 接 的 に

System.Security.Permissions.SecurityAttribute

から継承しているという事実によって

区別される。

第 章参照)は,22.11 に記述されるように符号化されなければならない。

5.10 ilasm

ソースファイル 

ilasm への入力は,最上位の宣言の列とする。定義は次のとおりとする。

《IL ファイル》  ::=

細分箇条 

《宣言》*

5.10 

最上位の宣言のための完全な文法を,次に示す。箇条の欄又は細分箇条の欄に記載されている箇条番号

又は細分箇条番号の該当項目には,

この文法の対応する生成規則の詳細が含まれる。

これらの生成規則は,

“.”から始まる名前をもつ。この名前を,指令と呼ぶ。

《宣言》 ::=

細分箇条 

  .assembly

《ドット名》 ‘{’ 《アセンブリ宣言》* ‘}’

6.2 

| .assembly extern

《ドット名》 ‘{’ 《アセンブリ参照宣言》* ‘}’

6.3 

| .class

《クラスヘッダ》 ‘{’ 《クラスメンバ》* ‘}’

10 

| .class extern

《移出属性》 《ドット名》 ‘{’ 《外部クラス宣言》* ‘}’

6.7 

| .corflags

《Int32》

6.2 

| .custom

《カスタム宣言》

21 

| .data

《データ宣言》

16.3.1 

| .field

《フィールド宣言》

16 

| .file [nometadata]

《ファイル名》 .hash ‘=’ ‘(’ 《バイト列》 ‘)’

        [.entrypoint  ]

6.2.3 

| .method

《メソッドヘッダ》  ‘{’ 《メソッド本体項目》* ‘}’

15 

| .module [

《ファイル名》]

6.4 

| .module extern

《ファイル名》

6.5 

| .mresource [public | private]

《ドット名》 ‘{’ 《目録資源宣言》* ‘}’

6.2.2 

| .subsystem

《Int32》

6.2 

| .vtfixup

《vtfixup 宣言》

15.5.1 

|

《外部ソース宣言》

5.7 

|

《セキュリティ宣言》

20 

アセンブリ,目録及びモジュール 

アセンブリ及びモジュールは,CLI において,役割ごとに構築要素をまとめる。

アセンブリは,1 単位として配置された一つ以上のファイルの集まりとする。アセンブリは,次の四つ

を指定する目録を常に含む(6.1 参照)

−  アセンブリ用の版,名前,文化圏及びセキュリティ要件

−  このアセンブリに属する他のファイル(存在するなら)

。それらのファイルのそれぞれの暗号ハッシュ

情報も与える。目録自身は,常にアセンブリに属すファイルのメタデータ部分に存在している。

−  アセンブリから移出される,アセンブリの他のファイルにおいて定義された型。目録と同じファイル

に定義された型は,型自体の属性に基づいて移出される。

−  省略可能とするが,目録自体用のデジタル署名及びそれを計算するために用いる公開かぎ(鍵)

モジュールは,

第 章で規定された書式で実行可能な内容を含む単一のファイルとする。モジュールが


117

X 3016

:2010 (ISO/IEC 23271:2006)

目録を含んでいる場合,その目録は,アセンブリを構成するモジュール(目録自体を含む。

)も規定する。

アセンブリは,

そのすべての構成ファイル中に一つの目録だけを含むことができる。

(単に動的にロードさ

れるのではなく)実行されるアセンブリでは,目録は,入口点を含んでいるモジュール中に存在しなけれ

ばならない。

幾つかのプログラム言語は,名前空間の概念を導入していて,CLI は,この概念をメタデータ符号化技

術において採用する。

型名は,

それらが定義されるアセンブリに相対的な完全名によって常に指定される。

6.1 

モジュール,アセンブリ及びファイルの概要 

注記  この細分箇条は参考情報であり規定ではない。

図 は,参照の様々な形式を明確にする。

図 2−モジュール及びファイルへの参照 

八つのファイルが,各々の名前を,ファイルの下に伴って示されている。各々モジュールを宣言する六

つのファイルは,それらのまわりに追加の境界線をもっており,名前は M で始まる。他の二つのファイル

は,F で始まる名前をもっている。これらのファイルは,ビットマップのような資源ファイル又は CIL コ

ードを含まない他のファイルとすることができる。

ファイル M1 及び M4 は,モジュール宣言に加えてアセンブリ(すなわち,アセンブリ A 及び B)をそ

れぞれ宣言する。M1 及び M4 の中のアセンブリ宣言は,直線で示された他のモジュールを参照する。例

えば,アセンブリ A は,M2 及び M3 を参照する。また,アセンブリ B は M3 及び M5 を参照する。した

がって,両方のアセンブリは M3 を参照する。

通常,一つのモジュールは,一つのアセンブリにだけ属する。しかし,複数のアセンブリがモジュール

を共有することは,可能とする。アセンブリ A が実行時にロードされる場合,M3 のインスタンスは,ア

センブリ A のためにロードされる。アセンブリ B が,おそらくアセンブリ A と同時に,同じアプリケー

ション領域に読み込まれる場合,M3 は,両方のアセンブリに共有される。両方のアセンブリは,F2 も参

照する(同様の規則を適用する。

モジュール M2 は,点線で示すように F1 を参照する。A が実行される場合,結果として F1 は,アセン

ブリ A の一部として読み込まれる。したがって,ファイル参照は,アセンブリ宣言にも現れなければなら

ない。同様に,B が実行される場合,M5 は,B の一部になる別のモジュール M6 を参照する。したがって,

アセンブリ B は,更に,M6 に対してモジュール参照をもたなければならない。

6.2 

アセンブリの定義 

アセンブリは,メタデータに目録を含んでいるモジュールで規定される(22.2 参照)

。目録のための情報

は,文法の次の部分で生成される。


118

X 3016

:2010 (ISO/IEC 23271:2006)

   

《宣言》 ::=

細分箇条 

  .assembly

《ドット名》 ‘{’ 《アセンブリ宣言》* ‘}’

6.2 

| .assembly extern

《ドット名》 ‘{’ 《アセンブリ参照宣言》* ‘}’

6.3 

| .corflags

《Int32》

6.2 

| .file [nometadata]

《ファイル名》 .hash ‘=’ ‘(’ 《バイト列》 ‘)’

        [.entrypoint  ]

6.2.3 

| .module extern

《ファイル名》

6.5 

| .mresource [public | private]

《ドット名》‘{’ 《目録資源宣言》* ‘}’

6.2.2 

| .subsystem

《Int32》

6.2 

| …

指令.assembly は,目録を宣言し,どのアセンブリに現在のモジュールが属するかを指定する。モジ

ュールは,指令.assembly を多くても一つだけを含むことができる。

《ドット名》は,アセンブリの名前

を指定する。

注記  標準ライブラリアセンブリは,第 章で記述される。

注記  幾つかのプラットフォームは,名前の大文字と小文字とを区別しないので,大文字と小文字と

が異なるだけの名前をもつアセンブリを宣言すべきでない。

指令.corflags は,出力 PE ファイルの CLI ヘッダ中のフィールドを設定する(25.3.3.1 参照)

。CLI 規

格適合処理系は,このフィールドの値が 1 になっていることを期待しなければならない。後方互換性のた

めに,下位 3 ビットは,予約済みとする。この規格の将来の版は,8 と 65,535 の間の値に定義を供給する

かもしれない。実験的な使用及び非標準の使用は,65,535 を超える値を使用することが望ましい。

指令.subsystem は,アセンブリが(ライブラリとして別のプログラムに使用されるのではなく。

)直

接実行される場合に限り使用される。指令.subsystem は,PE ファイルヘッダに指定された値を格納す

ることによって,プログラムに必要なアプリケーション環境の種類を指定する(25.2.2 参照)

。任意の 32

ビット整数を供給できるが,CLI 規格適合処理系は,次の二つの取りうる値だけを尊重する必要がある。

−  値が 2 である場合,プログラムは,GUI をもっているアプリケーションに適切な取決めを適宜用いて

動作することが望ましい。

−  値が 3 である場合,プログラムは,キーボード入出力の操作をともなうアプリケーションに適切な取

決めを適宜用いて動作することが望ましい。

   

.assembly CountDown

{ .hash algorithm 32772

  .ver  1:0:0:0

}

.file Counter.dll .hash = (BA D9 7D 77 31 1C 85 4C 26 9C 49 E7 02 BE

E7 52 3A CB 17 AF)

6.2.1 

アセンブリ(《アセンブリ宣言》)に関する情報 

次の文法は,アセンブリに関して指定できる情報を示す。

《アセンブリ宣言》 ::=

記述

箇条又は
細分箇条

  .custom

《カスタム宣言》

カスタム属性を表す。

21 


119

X 3016

:2010 (ISO/IEC 23271:2006)

| .hash algorithm

《Int32》

指令.file の中で使用されたハッシュアルゴ
リズム。

6.2.1.1 

| .culture

《引用文字列》

このアセンブリの文化圏を表す。

6.2.1.2 

| .publickey ‘=’ ‘(‘

《バイト列》 ‘)’

起案者の公開かぎ(鍵)を表す。

6.2.1.3 

| .ver

《Int32》 ‘:’ 《Int32》 ‘:’

《Int32》 ‘:’ 《Int32》

主版,副版,ビルド及び改訂を表す。

6.2.1.4 

|

《セキュリティ宣言》

アクセス許可が必要か,望ましいか又は禁
止されているかを表す。

20 

6.2.1.1 

ハッシュ  アルゴリズム 

《アセンブリ宣言》 ::= .hash  algorithm 《Int32》 |  …

アセンブリが複数のファイルからなる場合(6.2.3 参照)

,そのアセンブリの目録は,自分自身以外の各々

のファイルに対して,その名前及びその内容の暗号ハッシュの両方を指定する。アルゴリズムは,指定さ

れたハッシュを計算するために用いる。そしてアルゴリズムは,アセンブリに含まれるすべてのファイル

に対して同じでなければならない。すべての値は,将来のために予約済みとする。さらに,CLI 規格適合

処理系は,SHA-1(

第  3. の FIPS-180-1 参照)ハッシュ関数を使用しなければならない。また,CLI

規格適合処理系は,32772(0x8004)の値を用いて,このアルゴリズムを指定しなければならない。

注記  根拠としては,SHA-1 が標準化のときに最良の広く利用可能な技術として選ばれたことによる

第 章参照)。すべての CLI 規格適合処理系は,実行可能なイメージの可搬性を保証するす

べてのアルゴリズムを実装することを要求するから,単一のアルゴリズムが選ばれた。

6.2.1.2 

文化圏 

《アセンブリ宣言》 ::= .culture 《引用文字列》 |  …

存在するならば,アセンブリが特殊な文化圏用に変更されたことを示す。ここで使用する文字列は,ク

ラス System.Globalization.CultureInfo で受理可能なものとして

第 章で規定されたものでなけ

ればならない。アセンブリ参照とアセンブリ定義との比較に使用された場合,これらの文字列は大文字と

小文字とを区別しないやり方で比較されなければならない(23.1.3 参照)

注記  文化圏の名前は,インターネット技術標準化委員会 RFC1766 の名前に従う。その書式は,

“<language>-<country/region>”とする。ここで,<language>は JIS X 0412-1 の中の小文字 2 文

字符号とし,<country/region>は,JIS X 0304 の大文字 2 文字の符号とする。

6.2.1.3 

起案者の公開かぎ(鍵) 

《アセンブリ宣言》 ::= .publickey ‘=’ ‘(’ 《バイト列》 ‘)’ | …

CLI メタデータは,アセンブリ作成者がアセンブリの暗号ハッシュを(SHA-1 ハッシュ関数を用いて)

計算し,次に,RSA アルゴリズム(

第 章参照)及び作成者が選択した  公開/秘密かぎ(鍵)対を用いて,

それを暗号化することを可能にする。この結果(すなわち,

“-SHA-1/RSA デジタル署名”

)は,RSA アル

ゴリズムによって要求されるかぎ(鍵)対の公開部とともにメタデータに格納されることを可能とする。

指令.publickey は,署名を計算するために使用された公開かぎ(鍵)を指定するために使用される。ハッシ

ュを算出するために,署名をゼロにしてハッシュを算出し,その結果を,署名に格納する。

標準ライブラリ(

第 章参照)のアセンブリはすべて公開かぎ(鍵)00 00 00 00 00 00 00 00 04 00 00 00 00

00 00 00 を使用する。このかぎ(鍵)はこの規格において標準公開かぎ(鍵)として知られている。

アセンブリ参照(6.3 参照)は,コンパイル時にこの情報のうちの幾つかを取り込む。実行時では,アセ

ンブリ参照に含まれていた情報は,アセンブリの目録からの情報とまとめることが可能であり,それによ

って,参照が生成された時(コンパイル時)及びそれが解決される時(実行時)に生成される両方のアセ

ンブリに,同じ秘密かぎ(鍵)の使用保証を可能とする。


120

X 3016

:2010 (ISO/IEC 23271:2006)

   

厳密な名前(SN)による署名処理は,このような署名処理において標準的なハッシュアルゴリズム及び

暗号アルゴリズムを使用する。PE ファイルの大部分を網羅する SHA-1 ハッシュが生成される。そのハッ

シュ値は,厳密な名前の秘密かぎ(鍵)で RSA 署名される。検証のために,公開かぎ(鍵)は,署名され

たハッシュ値と同様に PE ファイルに格納される。

PE ファイルは,次に示すものを除きすべてハッシュされる。

−  検証コード識別情報入口:PE ファイルは,検証コード署名をすることができる。検証コード識別情報

は,このディレクトリ入口によって規定される範囲の PE ファイルの内容及び PE ヘッダデータディレ

クトリ(25.2.3.3 における“証明書表”

)のオフセットが 128 バイト目の 8 バイトの入口に含まれる。

注記  規格適合の PE ファイルでは,この入口をゼロとする。

−  厳密な名前の BLOB:CLI ヘッダ(25.2.3.3 における“厳密名識別情報”

)におけるオフセットが 32 バ

イト目の 8 バイトの入口及び PE ファイルの中のこの RVA に含まれるハッシュデータの内容。入口が

ゼロである場合,厳密名識別情報との関連はない。

− PE ヘッダチェックサム  :PE ヘッダ Windows NT 特有フィールド(25.2.3.2 における“ファイルチェ

ックサム”

)におけるオフセットが 64 バイト目の 4 バイトの入口

注記  規格適合の PE ファイルでは,この入口をゼロとする。

6.2.1.4 

版番号 

《アセンブリ宣言》 ::= .ver 《Int32》 ‘:’ 《Int32》 ‘:’ 《Int32》 ‘:’ 《Int32》

| …

アセンブリの版番号は,四つの 32 ビット整数で指定する。この版番号は,コンパイル時に取り込まれ,

コンパイルされたモジュール内のすべてのアセンブリへの参照要素として使用されなければならない。

すべての標準アセンブリは,最後の二つの 32 ビット整数を 0 に設定しなければならない。個々の実装者

は,この規格の将来の版との競合を回避するために,最後の二つの 32 ビット整数を両方とも 0 に設定しな

いようにするように促されるが,この規格は,版番号の使用に他の要件を課さない。

この規格の将来の版は,

標準アセンブリのために指定された最初の二つの 32 ビット整数のうち一つ又は

両方を次の条件の場合には変更しなければならない。その条件とは,付加的な機能が加えられるか,その

実装のために VES に何らかの追加機能が必要となった場合とする。さらに,この規格の将来の版では,最

初の二つの 32 ビット整数のうち一つ又は両方を mscorlib アセンブリの指定のために変更しなければならな

い。これは,その版番号が,プログラムを動作するのに必要な実行エンジンの異なる版を識別するために

(もし望まれれば)使用できるようにする。

注記  規格適合処理系は,版番号を完全に無視できる。又は,参照付ける場合,厳密な一致を要求で

きる。又は,適切とみなされる他のどんな振る舞いも示すことができる。次に使用法を示す。

1)

版番号の 1 番目の 32 ビット整数は,主版番号とみなす。同じ名前をもつが異なる主版のア

センブリは交換可能ではない。例えば,後方互換性を想定することが可能でない製品の大

きな書換えの場合に,主版番号を変えることが適切だろう。

2)

版番号の 2 番目の 32 ビット整数は,副版番号とみなす。同じ名前及び主版をもつが異なる

副版のアセンブリは,著しい拡張だが後方互換性の意図を示す。副版番号を変えることは,

例えば,製品の小さな変更又は製品の新版に完全後方互換性がある場合に適切だろう。

3)

版番号の 3 番目の 32 ビット整数は,ビルド番号とみなす。また,ビルド番号だけ異なるア

センブリは,同じソースからの再コンパイルを表現する。例えばプロセッサ,プラットフ

ォーム又はコンパイラの変更のために,ビルド番号を変えることは適切だろう。


121

X 3016

:2010 (ISO/IEC 23271:2006)

4)

版番号の 4 番目の 32 ビット整数は,改訂番号とみなす。同じ名前,主版番号及び副版番号

をもつが,異なる改訂番号をもつアセンブリは,完全交換可能を意図する。改訂番号を変

えることは,例えば,以前に提供されたアセンブリのセキュリティホールを修復する場合

に適切だろう。

6.2.2 

目録資源 

目録資源は,アセンブリに関連したデータの名前付き項目とする。目録資源は,指令.mresource を用

いて導入される。指令.mresource は,その前にある宣言.assembly によって始まるアセンブリ目録に

目録資源を加える。

《宣言》 ::=

細分箇条 

.mresource [public | private]

《ドット名》‘{’ 《目録資源宣言》* ‘}’

| …

5.10 

目録資源が public と宣言された場合,目録資源は,アセンブリから移出される。目録資源は,private

と宣言された場合,移出されず,この場合,アセンブリの内部からだけ利用可能となる。

《ドット名》は,

資源の名前とする。

《目録資源宣言》 ::=

記述 

箇条又は 
細分箇条 

  .assembly  extern

《ドット名》

目録資源は,名前が《ドット名》の外

部アセンブリとする。

6.3 

| .custom

《カスタム宣言》

カスタム属性

21 

| .file

《ドット名》 at 《Int32》

目録資源は,ファイル《ドット名》中
のバイトオフセット《Int32》にある。

モジュールでないファイル(例えば添付テキストファイル)に格納された資源については,そのファイ

ルを,別途(最上位の).file 宣言(6.2.3 参照)を用いて,目録中で宣言しなければならない。また,バ

イトオフセットは,ゼロとしなければならない。同様に,別のアセンブリにおいて定義される資源は,指

令.assembly extern(6.3 参照)を用いて参照され,それは,別途(最上位の)指令.assembly extern

で定義されていなければならない。

6.2.3 

アセンブリに関係するファイル 

アセンブリは,他のファイル(例えば文書,実行の間に使用される他のファイル。

)に関係付けられる。

宣言.file は,

アセンブリの目録にそのようなファイルへの参照を加えるために使用される

21.19 参照)

《宣言》 ::=

細分箇条

  .file  [nometadata]

《 フ ァ イ ル 名 》  .hash = ‘(’ 《 バ イ ト 列 》  ‘)’

[.entrypoint]

| …

5.10 

この規格に従えばモジュールでないファイルの場合,属性 nometadata を指定する。nometadata と

して印がついているファイルは,どんな書式にもできる。それらは,純粋なデータファイルとみなす。

.hash

の後の《バイト列》は,そのファイル用に計算されたハッシュ値を指定する。VES は,このファ

イルをアクセスする前にこのハッシュ値を再計算しなければならない。そして,二つのハッシュ値が合わ

ない場合,VES の動作は未規定とする。このハッシュ値を計算するために使われるアルゴリズムは,.hash

algorithm

6.2.1.1 参照)で指定される。

指令.entrypoint が指定された場合,それは,多重モジュールアセンブリの入口点がこのファイルに

含まれることを示す。

6.3 

アセンブリの参照 


122

X 3016

:2010 (ISO/IEC 23271:2006)

   

《宣言》 ::=

細分箇条 

  .assembly  extern

《ドット名》 [  as 《ドット名》 ]  ‘{’ 《アセンブリ参

照宣言》* ‘}’

| …

5.10

アセンブリは,それが含んでいるファイルからの他のアセンブリへのすべてのアクセスを調停する。こ

れは,実行アセンブリの目録が,実行コードによって参照されるアセンブリのための宣言を含むことを要

求することによって,メタデータを通じて行われている。最上位の.assembly extern 宣言は,この目

的に使用される。省略可能な as 節は,ILAsm が同じ名前だが,版,文化圏などが異なる外部アセンブリを

指定するための別名を提供する。

.assembly

extern

で使用される《ドット名》は,大文字と小文字との区別も含めて,指令.assembly

によって宣言されるアセンブリの名前と正確に一致しなければならない(したがって,たとえ,アセンブ

リが,大文字と小文字との区別がないファイルシステム内のファイル内に格納されていても,メタデータ

の内部に格納された名前は,

大文字と小文字とを区別しなければならず,

正確に一致しなければならない。

《アセンブリ参照宣言》 ::=

記述 

箇条又は 
細分箇条 

  .hash  ‘=’  ‘(’

《バイト列》 ‘)’

参照されたアセンブリのハッシュ

6.2.3 

| .custom

《カスタム宣言》

カスタム属性

21 

| .culture

《引用文字列》

参照されたアセンブリの文化圏

6.2.1.2 

| .publickeytoken ‘=’ ‘(’

《バイ

ト列》 ‘)’

発行者の公開かぎ(鍵)の SHA-1 ハッシュの
下位 8 バイト

6.3 

| .publickey = ‘(’

《バイト列》 ‘)’

発行者の完全公開かぎ(鍵)

6.2.1.3 

| .ver

《Int32》 ‘:’ 《Int32》 ‘:’

《Int32》 ‘:’ 《Int32》

主版,副版,ビルド,及び改訂

6.2.1.4 

これらの宣言は,.publickeytoken が追加されている点を除いて.assembly 宣言のためのものと同

じとする(6.2.1 参照)

。.publickeytoken 宣言は,アセンブリ参照において,完全公開かぎ(鍵)の代

わりに,発行者の公開かぎ(鍵)の SHA-1 ハッシュの下位 8 バイトを格納するために使用される。

アセンブリ参照では,完全公開かぎ(鍵)又は 8 バイトの“公開かぎ(鍵)トークン”のいずれかを格

納できる。いずれも,コンパイル時にアセンブリに署名するために使用された同じ秘密かぎ(鍵)が,実

行時に使用されるアセンブリを署名したか検証するために使われる。いずれも存在しなくて構わない。ま

た,両方を格納することもできるが,これは,有用ではない。

CLI 規格適合処理系は,この妥当性検証を実行する必要はない。しかし,CLI 規格適合処理系は妥当性

検証の実行を許されている。また,CLI 規格適合処理系は,妥当性検証が失敗したアセンブリのロードを

拒絶できる。CLI 規格適合処理系は,更に,アセンブリ参照が完全公開かぎ(鍵)又は公開かぎ(鍵)ト

ークンのいずれかを含んでいなければ,アセンブリへのアクセス許可を拒絶できる。CLI 規格適合処理系

は,公開かぎ(鍵)又はトークンが使用されるかどうかとは別に,同じアクセス決定を下さなければなら

ない。

注記  根拠としては,アセンブリ参照に格納された公開かぎ(鍵)又は公開かぎ(鍵)トークンは,

参照されたアセンブリ及び実行時に実際につかわれるアセンブリが同じ公開かぎ(鍵)を所有

する実体によって生成されたことを保証するために使われることによる。また,すなわち,公

開かぎ(鍵)又はアセンブリ参照に格納された公開かぎ(鍵)トークンは,同じ目的を意図し

ていることを仮定することができる。完全な公開かぎ(鍵)は,暗号としてより安全である一

方,その参照に,より多くの記憶域を要求する。公開かぎ(鍵)トークンの使用は,妥当性検


123

X 3016

:2010 (ISO/IEC 23271:2006)

証処理を若干弱める一方,その参照を格納するために必要な領域を削減する。

注記  アセンブリの内容が,それが作成されて以来改ざんされていないことを検証するために,アセ

ンブリの自己識別性での完全公開かぎ(鍵)が使われ,アセンブリへの参照に格納された公開

かぎ(鍵)又は公開かぎ(鍵)トークンは使われない。

   

.assembly extern MyComponents

{ .publickeytoken = (BB AA BB EE 11 22 33 00)

  .hash = (2A 71 E9 47 F5 15 E6 07 35 E4 CB E3 B4 A1 D3 7F 7F A0 9C 24)

  .ver  2:10:2002:0

}

6.4 

モジュールの宣言 

すべての CIL ファイルはモジュールとする。また,ファイル名ではなくメタデータにもちこまれた論理

名によって参照される(22.30 参照)

《宣言》 ::=

細分箇条 

| .module

《ファイル名》

| …

5.10 

   

.module CountDown.exe

6.5 

モジュールの参照 

項目が,現在のアセンブリ内にあるが,目録を含んでいるものとは別のモジュールの一部である場合,

定義するモジュールは,指令.module extern を用いて,アセンブリの目録の中で宣言されなければな

らない。参照するアセンブリの指令.module extern の中で使用される名前は,定義するモジュールの

指令.module(6.4 参照)の中で使用される名前と厳密に一致しなければならない(22.31 参照)

《宣言》 ::=

細分箇条 

| .module extern

《ファイル名》

| …

5.10 

 

.module extern Counter.dll

6.6 

モジュール又はアセンブリの内部の宣言 

モジュール又はアセンブリの内部の宣言は,次の文法によって指定される。各項目についての詳しい情

報は,対応する箇条又は細分箇条で示す。

《宣言》 ::=

箇条又は 
細分箇条 

| .class

《クラスヘッダ》 ‘{’ 《クラスメンバ》* ‘}’

10 

| .custom

《カスタム宣言》

21 

| .data

《データ宣言》

16.3.1 

| .field

《フィールド宣言》

16. 

| .method

《メソッドヘッダ》 ‘{’ 《メソッド本体項目》* ‘}’

15. 

|

《外部ソース宣言》

5.7 

|

《セキュリティ宣言》

20 

| …


124

X 3016

:2010 (ISO/IEC 23271:2006)

   

6.7 

移出された型定義 

アセンブリ一つについて一つだけ存在する目録モジュールは,指令.assembly  を含む。アセンブリの

他のモジュールに定義された型を移出するには,アセンブリの目録中に登録しなければならない。次の文

法が登録の形式を定義する。

《宣言》 ::=

箇条 

  .class  extern

《移出属性》 《ドット名》 ‘{’ 《外部クラス宣言》* ‘}’

| …

《外部クラス宣言》 ::=

箇条 

  .file

《ドット名》

| .class extern

《ドット名》

| .custom

《カスタム宣言》

21

《移出属性》の値は,public 又は nested public でなければならない。また,型の可視性に一致し

なければならない。

例えば,アセンブリが二つのモジュール A.EXE 及び B.DLL からなると仮定する。A.EXE は目録を含ん

でいる。公開クラス Foo は B.DLL において定義済みとする。Foo を移出するために,すなわち,Foo を

他のアセンブリによって可視にし,他のアセンブリから使用可能にするためには,指令.class extern

が,A.EXE に含まれなければならない。反対に,A.EXE で定義された公開クラス Bar は,指令.class

extern

を必要としない。

注記  根拠としては,ツールは,アセンブリによって定義された型の全集合を決定する単一のモジュ

ール(目録モジュール)を取り出すことが望まれることによる。したがって,アセンブリ内の

他のモジュールからの情報も,目録モジュールの中で複写される。慣例によって,目録モジュ

ールはアセンブリとしても知られている。

型及び識別情報 

メタデータは,型の定義及び参照の両方の機構を供給する。箇条 10 は,インタフェース型,クラス型及

び値型に共通した,型定義のメタデータについて記述する。型参照に使用される機構は,二つの部分から

なる。

−  参照されるが

(典型的には)

現在のモジュールにおいて定義済みでない利用者定義型の論理的な記述。

生成された記述は,メタデータ中の表に格納される(22.38 参照)

−  様々な修飾子とともに一つ以上の型参照を符号化する識別情報。文法上での非終端記号《型》は,識

別情報の個別要素を記述する。識別情報の符号化は,23.1.16 で規定する。

7.1 

 

次の文法は,CLI システムの(ポインタ型を含む)すべての組込み型を規定する。さらに,CLI システ

ムにおいて定義できる利用者定義型のための構文も示す。

《型》 ::=

記述 

箇条又は
細分箇条

‘!’

《Int32》

0 から始まる添字によってアクセスさ
れる型定義の総称仮引数

9.1 

| ‘!!’

《Int32》

0 から始まる添字によってアクセスさ
れるメソッド定義の総称仮引数

9.2 

| bool

真理値。

7.2 


125

X 3016

:2010 (ISO/IEC 23271:2006)

| char

16 ビットの Unicode 符号点。

7.2 

| class

《型参照》

利用者定義の参照型。

7.3 

| float32

32 ビット浮動小数点数。

7.2 

| float64

64 ビット浮動小数点数。

7.2 

| int8

符号付き 8 ビット整数。

7.2 

| int16

符号付き 16 ビット整数。

7.2 

| int32

符号付き 32 ビット整数。

7.2 

| int64

符号付き 64 ビット整数。

7.2 

| method

《呼出し規約》 《型》 ‘*’

         ‘(’

《仮引数群》 ‘)’

メソッドポインタ。

14.5 

| native int

32 ビット又は 64 ビットの大きさがプラ
ットフォームに依存の符号付き整数。

7.2 

| native unsigned int

32 ビット又は 64 ビットの大きさがプラ
ットフォームに依存の符号なし整数。

7.2 

| object

第 章の System.Object を参照する。   

| string

第 章の System.String を参照する。   

|

《型》 ‘&’

《型》への管理下ポインタ。

《型》は,

管理下ポインタ型又は typedref であ
ってはならない。

14.4 

|

《型》 ‘*’

《型》への管理外ポインタ。

14.4 

|

《型》 ‘<’ 《総称実引数列》  ‘>’

総称型のインスタンス化

9.4 

|

《型》 ‘[’ [《範囲》 [‘,’《範囲》]*] ‘]’

省略可能な次元数及び省略可能な範囲
を指定した《型》の配列。

14.1

及び

14.2

|

《型》 modopt ‘(’ 《型参照》 ‘)’

呼出し側によって無視してもよいカス
タム修飾子。

7.1.1 

|

《型》 modreq ‘(’ 《型参照》 ‘)’

呼出し側が理解しなければならないカ
スタム修飾子。

7.1.1 

|

《型》 pinned

局所変数専用とする。ごみ集め子は,
参照された値を移動してはならない。

7.1.1 

| typedref

型 付 き 参 照 ( 例 え ば , 型

System.TypedReference

の値。

)は,

mkrefany

に よ っ て 生 成 さ れ ,

refanytype

又は refanyval によって使

用される。

7.2 

| valuetype

《型参照》

利用者定義の値型(ボックス化解除さ
れた状態。

13 

| unsigned int8

符号なし 8 ビット整数。

7.2 

| unsigned int16

符号なし 16 ビット整数。

7.2 

| unsigned int32

符号なし 32 ビット整数。

7.2 

| unsigned int64

符号なし 64 ビット整数。

7.2 

| void

無型。使用は,返却値の型又は void *
の一部としてだけ許可される。

7.2 

状況によっては,文法は,型の規定のためにやや単純な表現の使用を許す。すなわち,

“System.GC”

を,

“class System.GC”の代わりに使用することができる。このような表現は,型指定と呼ばれる。

《型指定》 ::=

細分箇条 

  ‘[’  [.module]

《ドット名》 ‘]’

7.3 

|

《型参照》

7.2 

|

《型》

7.1 

7.1.1 modreq

及び modopt 


126

X 3016

:2010 (ISO/IEC 23271:2006)

   

modreq

“必要な修飾子”

)及び modopt(

“省略可能な修飾子”

)を用いて定義されたカスタム修飾子は,

修飾子が宣言に附属されるのではなく,識別情報の一部となることを除いては,カスタム属性と同じとす

る(箇条 21 参照)

。各修飾子は,識別情報項目に型参照を関連させる。

CLI 自体は,必す(須)修飾子と省略可能な修飾子とを同じように扱わなければならない。[必す(須)

又は省略可能な]カスタム修飾子の追加分だけが異なる二つの識別情報は,一致するとみなされてはなら

ない。カスタム修飾子は,VES の操作にその他の効果は及ぼさない。

注記  根拠としては,必す(須)修飾子と省略可能な修飾子との相違が,メタデータを取り扱う CLI

以外のツール,

典型的にはコンパイラ及びプログラム解析にとって重要なことによる。必す

(須)

修飾子は,無視しないほうがよい修飾された項目への特殊な意味があることを示す。省略可能

な修飾子は,単に無視することができることを示す。

例えば,C プログラム言語の const 限定子は,const 限定型仮引数をもつメソッドの呼出

し側が,それを特に扱う必要はないから,省略可能な修飾子でモデル化できる。他方,C++に

おいてコピー仮引数は,呼出し側が仮引数のコピーを作るので,必す(須)修飾子として定義

されたカスタム属性を使って印をつけなければならない。

7.1.2 

アドレス固定(pinned 

アドレス固定された(pinned)識別情報符号化は,局所変数を記述する識別情報中だけに現れなけれ

ばならない(15.4.1.3 参照)

。アドレス固定された局所変数を備えたメソッドが実行している間,VES は,

局所参照オブジェクトを再配置してはならない。すなわち,CLI の実装がオブジェクトを移動するごみ集

め子を使用する場合,ごみ集め子は,活性アドレス固定局所変数が参照するオブジェクトを移動してはな

らない。

注記  根拠としては,管理外ポインタが管理下オブジェクトの参照をたぐるために使用された場合,

これらのオブジェクトはアドレス固定されていなければならないことによる。例えば,管理下

オブジェクトが,管理外データで操作するよう設計されたメソッドに渡された場合に,これは

起こる。

7.2 

組込み型 

CLI 組込み型は,基底クラスライブラリの中で定義された対応する値型をもつ。CLI 組込み型は,識別

情報において,それらの特殊な符号化(すなわち,はん用な valuetype《型参照》構文を使用しない符号化)

の使用によってだけ参照されなければならない。

第 章は,組込み型を規定する。

7.3 

利用者定義型(《型参照》)への参照 

利用者定義型は,型の完全名と解決有効範囲とを用いて参照されるか,又は同じモジュール中で型定義

が使用可能であれば,型定義を用いて参照される(箇条 10 参照)

《型参照》は,完全名及び解決有効範囲に対して使用される。

《型参照》 ::=

  [

《解決有効範囲》] 《ドット名》 [‘/’《ドット名》]*

《解決有効範囲》 ::=

  ‘[’  .module

《ファイル名》 ‘]’

| ‘[’

《アセンブリ参照名》’]’

《アセンブリ参照名》 ::=

細分箇条 

《ドット名》

5.1 


127

X 3016

:2010 (ISO/IEC 23271:2006)

次の解決有効範囲は,入れ子でない型について規定している。

−  現モジュール(及びアセンブリ)

。これは,最もありふれた場合で,解決有効範囲が指定されていない

省略時の場合とする。定義が参照と同じモジュールにありさえすれば,型は,定義として解決されな

ければならない。

注記  同じモジュール及びアセンブリ中の型を参照する型参照は,型定義を使用する方が,より良

く表現される。これが不可能(例えば compilercontrolled というアクセス可能性の入れ

子型を参照する場合)か,又は,都合の悪いところ(例えば幾つかの 1 回パスのコンパイラ

中)では,型参照を,使用できる。

−  異なるモジュール及び現アセンブリ。解決有効範囲は,構文的には記法[.module 《ファイル名》]  を

使用することによって表現されたモジュール参照とする。参照されたモジュール(6.4 参照)及び型(6.7

参照)が現アセンブリによって宣言されていて,その結果アセンブリの目録の中に登録されている場

合に限り,型は,定義として解決されなければならない。この場合,目録は,参照するモジュールで

物理的に保存されないことに注意する。

−  異なるアセンブリ。解決有効範囲は,構文的には記法[《アセンブリ参照名》]で表現されたアセンブ

リ参照でなければならない。参照されたアセンブリは,現アセンブリのための目録中で宣言されなけ

ればならず(6.3 参照)

,型は,参照されたアセンブリの目録の中で宣言されなければならない。また,

そのアセンブリから移出されるように,型が印付けされなければならない(6.7 及び 10.1.1 参照)

−  入れ子型については,解決有効範囲は,常に取囲み型とする。

10.6 参照)

。構文的には,これは,入

れ子型の名前から取囲み型名を分けるために斜線(

“/”

)を使用することで示される。

 

基底クラスライブラリの中で定義された型 System.Console は,mscorlib という名のアセン

ブリにある。

     .assembly  extern  mscorlib  {  }

     .class  [mscorlib]System.Console

現アセンブリでの x という名のモジュール中の C.D という名の型への参照。

     .module  extern  x

     .class  [.module  x]C.D

MyAssembly という名前の,別のアセンブリでの Foo.Bar という名の型の内部で入れ子になっ

ている C という名の型への参照。

     .assembly  extern  MyAssembly  {  }

     .class  [MyAssembly]Foo.Bar/C

7.4 

プラットフォーム固有なデータ型 

CLI の実装は,ある機能実行に必要なデータ型を規定する既存のオペレーティングシステム又は実行時

プラットフォーム上で行われることがある。メタデータは,CLI 組込み型及び利用者定義型が,どのよう

にしてプラットフォーム固有なデータ型との間で組み換えられることになっているかを規定することによ

って,これらのプラットフォーム固有なデータ型との間での処理を可能にする。この組換え情報は,

(キー

ワード marshal を用いて)指定できる。

−  プラットフォーム固有なデータ型が実は返却され,指定された CLI データ型へ組み換えされなければ

ならないことを示すメソッドの返却値の型。

−  呼出し側が提供する CLI データ型が指定されたプラットフォーム固有データ型へ組み換えられなけれ


128

X 3016

:2010 (ISO/IEC 23271:2006)

   

ばならないということを示すメソッドへの仮引数。

(仮引数が参照渡しである場合,更新される値は,

呼出しが完了するときに,プラットフォーム固有なデータ型から CLI データ型の中へ組み換え戻され

なければならない。

−  プラットフォームメソッドにオブジェクトを渡すどんな試みも,そのオブジェクトのコピーを作り,

フィールドを指定されたプラットフォーム固有データ型に取り替えなければならないことを示す利用

者定義型のフィールド。

(オブジェクトが参照渡しである場合,呼出しが完了するときに,更新される

値は,組み換え戻されなければならない。

次に示す表は,CLI によって採用されるすべてのプラットフォーム固有な型及びそれらの記述を与える。

(より完全な記述は,これらの型を符号化するために使用される実際の値を提供する,

第 章の enum

System.Runtime.Interopservices.UnmanagedType

の定義中で規定する。

)0∼63 までのすべての

符号化値は,CLI の既存の実装との後方互換性のために予約済みとする。値 64∼127 は,この規格及び関

連する規格で将来の使用するために予約済みとする。

プ ラ ッ ト フ ォ ー ム

固 有

型》::=

記述 

ク ラ ス ラ イ ブ ラ リ の

enum

UnmanagedType

での名

 

‘[’ ‘]’

プラットフォーム固有な配列。型及び大きさは,実
際に組み換えられた配列から実行時に決定される。

LPArray

|

bool

真理値とする。0 でない値は真を表し,0 は偽を表

す 4 バイトの整数値。

Bool

| float32

32 ビット浮動小数点数。

R4

| float64

64 ビット浮動小数点数。

R8

| [unsigned] int

プラットフォーム上でポインタを保持できる符号
付き又は符号なし整数

SysUInt

又は SysInt

| [unsigned] int8

符号付き又は符号なしの 8 ビット整数

U1

又は I1

| [unsigned] int16

符号付き又は符号なしの 16 ビットの整数

U2

又は I2

| [unsigned] int32

符号付き又は符号なしの 32 ビットの整数

U4

又は I4

| [unsigned] int64

符号付き又は符号なしの 64 ビットの整数

U8

又は I8

| lpstr

ナル文字で終端した ANSI  文字の配列へのポイン
タ。コードページは,実装固有とする。

LPStr

| lpwstr

ナル文字で終端した Unicode 文字の配列へのポイン
タ。文字符号化は,実装固有とする。

LPWStr

| method

関数ポインタ。

FunctionPtr

|  《プラットフォーム固有型》

‘[’ ‘]’

《プラットフォーム固有型》の配列。長さは,実際

の組み換えられた配列の長さによって実行時に決
定される。

LPArray

|  《プラットフォーム固有型》

‘[’

  《Int32》  ‘]’

長さが《Int32》の《プラットフォーム固有型》の

配列。

LPArray

|  《プラットフォーム固有型》

‘[’

    ‘+’  《Int32》  ‘] ’

実行時に要素の大きさが与えられる《プラットフォ

ーム固有型》の配列。

《Int32》は,実行時に配列

の要素のバイトサイズを含む(仮引数番号 0 から数
える。

)現メソッドへの仮引数を指定する。フィー

ルドではなくメソッドにだけ適用することができ
る。

LPArray

|  《プラットフォーム固有型》

‘[’

《Int32》  ‘+’ 《Int32》

‘]’

実行時に要素の大きさが与えられる《プラットフォ
ーム固有型》の配列。最初の《Int32》は,配列中
の要素の個数を指定する。第 2 の《Int32》は,ど

LPArray


129

X 3016

:2010 (ISO/IEC 23271:2006)

の仮引数が,

(仮引数番号 0 から数える。

)現メソッ

ドに配列中に追加する要素の個数を指定するかを

指定する。フィールドではなくメソッドにだけ適用
することができる。

 

.method int32 M1( int32 marshal(int32), bool[] marshal(bool[5]) )

メソッド M1 は,二つの実引数をとる。それらは,int32 及び五つの真理値の配列とする。

.method int32 M2( int32 marshal(int32), bool[] marshal(bool[+1]) )

メソッド M2 は,二つの実引数をとる。それらは,int32 及び真理値の配列とする。配列の中

の要素の個数は,最初の仮引数の値によって与えられる。

.method int32 M3( int32 marshal(int32), bool[] marshal(bool[7+1]) )

メソッド M3 は,二つの実引数をとる。それらは,int32 及び真理値の配列とする。要素の個

数は,最初の仮引数の値に 7 を加えたもので与えられる。

可視性,アクセス可能性及び隠ぺい 

第 章は,可視性及びアクセス可能性を規定する。メタデータは,これらの属性の他に,メソッド名隠

ぺいに関する情報を格納する。隠ぺいは,基底型から継承したどのメソッド名がコンパイル時の名前結合

に使用可能となるかを制御する。

8.1 

最上位の型の可視性及び入れ子型のアクセス可能性 

可視性は,最上位の型にだけ付けられる。また,同じアセンブリ内の型にだけ見えるか,どのアセンブ

リからも見えるかの二つの可能性だけがある。入れ子型(すなわち,別の型のメンバの型)については,

型を参照することが可能なメソッドの組を更に洗練するアクセス可能性をもつ。入れ子型は,七つのアク

セス可能性モード(

第 章参照)のどれでももてるが,それ自身の直接の可視属性はもたず,その代わり

に,取囲み型の可視性を代わりに使用する。

最上位の型の可視性が,そのすべてのメンバの名前の可視性を制御するから,入れ子型は,それを取り

囲む型よりも可視にはなりえない。すなわち,取囲み型が,アセンブリ内にだけ可視である場合,アクセ

ス可能性 public を備えた入れ子型も,依然としてそのアセンブリ内だけで使用可能とする。対照的に,

アクセス可能性 assembly をもつ入れ子型は,取囲み型がアセンブリの外部で可視であっても,アセンブ

リ内での使用に制限される。

すべての型の符号化を一貫性がありコンパクトにするために,最上位の型の可視性及び入れ子型のアク

セス可能性は,23.1.15 の論理モデルと同じ機構を用いて符号化される。

8.2 

アクセス可能性 

アクセス可能性は,メタデータ中で直接符号化される。例を 22.26 に示す。

8.3 

隠ぺい 

隠ぺいは,型の個別メソッドに適用するコンパイル時の概念とする。CTS(共通型システム,

第 章参

照)は,単一ビットによって,隠ぺいのための二つの機構のいずれかを指定する。

−  名前による隠ぺい(hide-by-name)

。これは,与えられた型への名前の導入が,同じ種類で同じ名前の

すべての継承されたメンバを隠ぺいすることを意味する。

−  名前及び識別情報による隠ぺい(hide-by-name-and-sig)

。与えられた型への名前の導入は,それが入れ

子型及びフィールドであるには,同じ種類であって,かつ,正確に同一の型であるすべての継承メン


130

X 3016

:2010 (ISO/IEC 23271:2006)

   

バを隠ぺいし,それがメソッド,特性及びイベントであるには,同じ種類であって,かつ,正確に同

じ識別情報であるすべての継承メンバを隠ぺいすることを意味する。

隠ぺいの実行時支援は,ない。CLI の規格合致合処理系は,すべての参照をあたかも名前が名前及び識

別情報による隠ぺいと印付けられるかのように扱う。名前による隠ぺいを望むコンパイラは,属性

newslot

15.4.2.3 参照)でメソッド定義を印付け,メソッド参照(15.1.3 参照)を解決するために使われ

る型を正確に選択することによって,それを実現できる。

総称性 

第 章で示したとおり,総称性によって,パターンを用いて型及びメソッドのファミリ全体を定義する

ことが可能となる。ここでパターンとは総称仮引数と呼ばれる場所取りを含む。総称仮引数は必要に応じ

て指定された型に置き換えられ,ファミリの全メンバは実際に要求された型でインスタンス化される。例

えば,class List<T>{}は リ スト と 成り 得る 全フ ァ ミリを表 現する 。すな わち,List<string>,

List<int>

及び List<Button>は三つの有効なインスタンス化を表す。しかし,次で示すとおり,CLS

合 致 の 名 前 で は , こ れ ら の 型 は class List`1<T>{} , List`1<string> , List`1<int> , 及 び

List`1<Button>

となる。

総称型は C<T>のように名前に引き続く<…>で区切られた総称仮引数からなる。同一有効範囲内において,

二つ以上の総称型を,同じ名前ではあるが異なる数の総称仮引数を用いて定義してはならない。しかし,

総称仮引数の個数に関するこのような意味での多重定義をソース言語レベルでは許容するために,CLS 規

則 43 では,複数の総称型名を一意な CIL 名に対応付けを定義している。この規則は,CLS 合致の名前で

は,一つ以上の総称仮引数をもつ型 C は,`n という形式の接尾辞をもたなければならないと定めている。

ここで n は(先行するゼロをもたない)十進整定数であり,C がもつ総称仮引数の個数を表現する。例え

ば,型 C,C<T>,及び C<K,V>は,CLS 合致の名前では,それぞれ C,C`1<T>,及び C`2<K,V>となる。

注記  すべての標準ライブラリは CLS 合致の名前をもつ。例えば

System.Collections.Generic.IEnumerable`1<T>

総称性について詳細な議論に移る前に,幾つかの新しい用語を次で定義する。

−  public class List`1<T> {}  は総称型定義とする。

−  <T>  は総称型並びとし,T は総称仮引数とする。

−  List`1<T>  は総称型とする。これは,少なくとも一つ総称仮引数をもつため,開型又は開総称型と

呼ばれることがある。本章では開型という用語を用いる。

注記  訳注:対応国際規格に誤りがあったため総称型を開型に訂正した。

−  List`1<int>  は,もはや非束縛総称仮引数をもたないため,閉総称型とする。

(これは,インスタ

ンス化された総称型又は総称型インスタンス化と呼ばれることがある。

)この章では,閉型という用語

を用いる。

−  総称性は,厳密に開でも厳密に閉でもない総称型を含むことに注意する。次の例における基底クラス

B が,厳密に開でも,厳密に閉でもない例である。. public class B`2<T,U> {}が与えられた下

での. public class D`1<V> extends B`2<!0,int32> {}。

−  総称型と通常の型との区別が必要な場合,後者を総称でない型と呼ぶ。

−  <int>  は,総称実引数並びとし,int は総称実引数とする。

−  この規格では,総称仮引数と総称実引数とを区別する。可能であれば,List`1<int>について語る

場合,

“int は総称仮引数 T に使われた型である。

という表現を用いる。

(自己反映計算においては,


131

X 3016

:2010 (ISO/IEC 23271:2006)

このような場合“T は int に束縛される。

”といわれることがある。

−  “(C1, …, Cn) T”は総称仮引数 T に対する総称仮引数制約とする。

注記  次の定義を考える。

class C`2<(I1,I2) S, (Base,I3) T> { … }

これは二つの総称仮引数 S 及び T をもつ,C と呼ばれるクラスを表現している。S は二つの

インタフェース I1 及び I2 を実装するよう制約が課されている。T はクラス Base から導出する

よう制約が課されるとともに,インタフェース I3 を実装するよう制約が課されている。

総称型定義内において,総称仮引数はその添字によって参照される。総称仮引数ゼロは,!0 として,総

称仮引数 1 は!1 として,という具合に参照される。同様に総称メソッド定義本体内において,総称仮引

数はその添字によって参照される。総称仮引数ゼロは,!!0 として,総称仮引数 1 は!!1 として,という

具合に参照される。

9.1 

総称型定義 

総称型定義は総称仮引数を含むものとする。各総称仮引数は,名前及び省略可能な制約の集合をもつこ

とができる。ここで制約とは,総称実引数が代入互換でなければならないような型とする。省略可能な異

なる記法も認められている(10.1.7 参照)

(次で用いられる!及び!!記法の説明に関しては 9.4 参照)総称

仮引数は,次の宣言の有効範囲の中に存在する。

−  制約の中(例  . class … C`1<(class IComparable`1<!0>) T>)

−  型に基づく定義が導出する任意の基底クラス(例  .class … MultiSet`1<T> extends class

Set`1<!0[]>

−  型に基づく定義が実装する任意のインタフェース(例  .class … Hashtable`2<K,D> implements

class IDictionary`2<!0,!1>

−  すべてのメンバ(インスタンスフィールド及び静的フィールド,メソッド,構築子,特性,並びにイ

ベント)ただし,入れ子クラスである場合を除く。

注記 C#では囲みクラスから入れ子クラスで用いられるために,総称仮引数を許可している。しかし,

この場合,必要とする付加的な任意の総称仮引数をメタデータの囲みクラス定義に加える。

総称型定義は静的メソッド,インスタンスメソッド,及び仮想メソッドを含んでもよい。

総称型定義は,次の制限を受ける。

−  総称仮引数は,それ単独では,基底クラス又は任意の実装されたインタフェースを指定するために用

いることはできない。したがって,例えば,.class … G`1<T> extends !0 は不当となる。しか

し,別の総称型の入れ子になっている場合,基底クラス又はインタフェースに総称仮引数を用いるこ

とは妥当となる。例えば,.class … G`1<T> extends class H`1<!0>及び.class … G`1<T>

extends class B`2<!0,int32>

はともに妥当となる。

注記  この根拠は次のとおりとする。この制限によって総称型はインスタンス化時ではなく定義時

に妥当かどうかを判定できる。例えば,.class … G`1<T> extends !0,において,どの

メソッドがどのメソッドを上書きするのかは分からない。なぜならば基底クラスに関する情

報は何も与えられていないからである。実際,T がクラスであるかどうかすら分からない。

そ れは 配列 か も し れ な い し , 又 は イ ン タ フ ェ ー スか もし れな い。 同様 に,.class …

C`2<(!1)T,U>

についても,基底クラス又はインタフェース定義に関する情報が何もないと

いう意味で,同じ状況にある。

− vararg メソッドは,総称型のメンバになることはできない。


132

X 3016

:2010 (ISO/IEC 23271:2006)

   

注記  この根拠は次のとおりである。これを制限とせずに実装するのは,非常に困難であろう。vararg

は CLI が対象とする言語の中で,非常に限られた範囲だけで使用されるため,総称型から

vararg メソッドを除外することとした。

−  総称仮引数を無視したとき,継承及びインタフェースの階層構造には,循環があってはならない。よ

り正確には,節が総称であってもよい(その場合,開の)クラス及びインタフェースであり,辺が次

で指定されるようなグラフとして定義する。

−  (総称であってもよい)クラス又はインタフェース D がクラス又はインタフェース B を拡張する又

は実装する場合,D から B へ辺を追加する。

−  (総称であってもよい)クラス又はインタフェース D がインスタンス化されたクラス又はインタフ

ェース B<type-1, 

, type-n>

を拡張する又は実装する場合,D から B へ辺を追加する。

−  このグラフが循環を含まない場合妥当とする。

注記  本アルゴリズムは,総称でない型に対する規則の自然な一般化となっている(第  8.9.9 

照)

9.2 

総称性及び再帰的継承グラフ 

注記  継承グラフは直接的に循環することはないが,親クラス又は親インタフェースから与えられイ

ンスタンス化されたものは,直接的又は間接的に循環依存関係になることがある。これらは,

許されるものもあれば(例 C : IComparable<C>)許されないものもある(例  class B<U>

が与えられた下での class A<T> : B<A<A<T>>>)。

各型定義は,有限インスタンス化閉包を生成しなければならない。インスタンス化閉包は次で定義され

る。

1)

単一の総称型定義を含む集合を生成する。

2)

上記の集合に次の条件を満たす総称型を加えていくことによって閉包を構成する。その条件とは,

その集合に含まれるすべての型の基底クラス及び実装されたインタフェースの型識別情報に参照さ

れるすべての総称型とする。この集合に入れ子になったインスタンス化を含める。したがって,参

照型 Stack<List<T>>は実際には,List<T>  及び Stack<List<T>>の両方として数える。

3)

次のグラフを構築する。

−  節はその集合の中の型の形式的な型仮引数とする。名前衝突を避けるために,必要に応じてラム

ダ計算のアルファ変換に相当する名前変換を用いる。

−  T が,参照される型 D<…, U, …>の U に置換される実際の型実引数として現れる場合,T から U

への展開しない辺(->)を付加する。

−  T が,参照される型 D<…, U, …>の U に置換される実際の型実引数のどこか内部に(ただし,型

実引数そのものとしてではなく)現れる場合,T から U への展開する辺(=>)を付加する。

展開する循環とは,少なくとも一つの展開する辺(=>)を含むインスタンス化閉包の中にある循環とする。

ここで定義した系のインスタンス化閉包が有限であることと,上記で構築されたグラフが展開する循環を

含まないこととは同値とする。

 

class B<U>

class A<T> : B<A<A<T>>>

上記の二つのクラスは(展開する辺=>及び展開しない辺->を用いて)次の辺を生成する。

T  ->   T   (参照される型 A<T>によって生成される。)


133

X 3016

:2010 (ISO/IEC 23271:2006)

T  =>  T   (参照される型 A<A<T>>によって生成される。)

T  =>  U   (参照される型 B<A<A<T>>>によって生成される。)

このグラフは,展開する循環を含むため,インスタンス化閉包は無限となる  。

 

class B<U>

class A<T> : B<A<T>>

上記のクラスは次の辺を生成する。

T -> T  (参照される型 A<T>によって生成される。)

T => U  (参照される型 B<A<T>>によって生成される。)

このグラフは,展開する循環を含まないため,インスタンス化閉包は有限となる。

 

class P<T>

class C<U,V> : P<D<V,U>>

class D<W,X> : P<C<W,X>>

上記のクラスは次の辺を生成する。

U -> X   V -> W   U => T   V => T (参照される型 D<V,U>及び P<D<V,U>>によって生成さ

れる。

W -> U   X -> V   W => T   W => T (参照される型 C<W,X>及び P<C<W,X>>によって生成さ

れる。

このグラフは,展開しない循環を含む(例えば U -> X -> V -> W -> U)が,展開する循環を含

まないため,インスタンス化閉包は有限となる。

9.3 

総称メソッド定義 

総称メソッド定義とは,総称仮引数並びを含むメソッド定義とする。総称メソッドは,総称でない型の

中に定義することも,総称型の中に定義することもできる。後者の場合,メソッドの総称仮引数は,その

所有者  の総称仮引数に付加されていなければならない。総称型定義である場合と同様,総称メソッド定義

上の各総称仮引数は,名前及び省略可能な制約の集合をもつ。

注記  訳注:所有者の定義は第 章 22.20 参照。

総称メソッドは,静的,インスタンス,又は仮想のいずれであってもよい。クラス構築子又はインスタ

ンス構築子(それぞれ.cctor 又は.ctor)は,総称であってはならない。

メソッドの総称仮引数は,識別情報及びメソッド本体の中,並びに総称仮引数制約の中をその有効範囲

とする。

注記  この識別情報はメソッドの返却値型を含む。次の例で示す。

.method … !!0 M`1<T>() { … }

!!0

は有効範囲にある。それは,宣言内のその仮引数に先行するにもかかわらず,M`1<T>

の総称仮引数である。

総称インスタンスメソッド(仮想及び仮想でないを問わない)は,総称型のメンバとして定義できるが,

この場合,総称型及び総称メソッドの両方の総称仮引数は,メソッド識別情報及びメソッド本体の中,並

びにメソッド総称仮引数の制約の中をその有効範囲とする

9.4 

総称型のインスタンス化 

《総称実引数群》は総称実引数並びを表現するために用いられる。


134

X 3016

:2010 (ISO/IEC 23271:2006)

   

《総称実引数群》::= 
    《型》      [‘,’    《型》 ]

型が総称仮引数を含まない場合,型は閉とする,そうでなければ開とする。

総称型定義が与えられたとき,インスタンス化された型を生成するために,総称型定義を総称実引数を

用いてインスタンス化することができる。

 

総称クラス MyList 及び値型 Pair に対する適切な定義が与えられているものとすると,これ

らを次のとおりインスタンス化することができる。

newobj instance void class MyList`1<int32>::.ctor()

initobj valuetype Pair`2<int32, valuetype Pair<string,int32>>

 

ldtoken  !0

// !0 = generic parameter 0 in generic

type definition

castclass  class  List`1<!1>

// !1 = generic parameter 1 in generic

type definition

box

!!1

   //

!!1 = generic parameter 1 in generic

method definition

インスタンス化における総称実引数の個数は,型定義又はメソッド定義において指定される総称仮引数

の個数と一致しなければならない。

CLI では,総称型の部分的なインスタンス化を提供していない。さらに,総称型は,メタデータ識別情

報の blob 内では,いかなる箇所でもインスタンス化されないまま現れてはならない。

次の種類の型は,

(総称型又は総称メソッドの)インスタンス化において実引数として用いることはでき

ない。

− Byref 型(例  System.Generic.Collection.List`1<string&>  は妥当ではない。

− CIL 評価スタックの中を指すことが可能なフィールドを含む値型

(例  List<System.RuntimeArgumentHandle>)

− void(例  List<System.Void>は妥当ではない。

管理外ポインタ型(例  int32*)は,総称型及び総称メソッドの総称実引数として用いることができ

る。

注記  根拠は次のとおりである。Byref 型が総称実引数として使用できないのは,幾つかの,実際には

ほとんどの,インスタンス化が妥当でないためである。例えば,byref は,フィールド型又はメ

ソッド返却値の型に使うことができないため,List`1<string&>  の定義において,型!0 を

もつフィールド又は!0 の型を返すメソッドのいずれも宣言することができない。

インスタンス化された型のオブジェクトは,その厳密な型を実行時に再現するために十分な情報(型及

びその総称実引数の個数を含む)をもち合わせていなければならない。

注記  根拠は次のとおりである。この制約は,自己反映計算  (System.Object::GetType)の場合と

同様,キャスト及びインスタンス検査を正しく実装するために要請されている。

9.5 

総称における変性 

CLI は,インタフェース及び委譲クラスの識別情報においてだけ,総称仮引数の共変性及び反変性を提

供する。


135

X 3016

:2010 (ISO/IEC 23271:2006)

記号“+”は,10.1.7 の構文で用いられ,共変性総称仮引数を示すために用いられるのに対し,

“-”は,

反変性総称仮引数を示すために用いられる。

注記  ここから参考情報であり規定ではない。

総称インタフェースがあるとし,例えば IA`1<+T>のように,その一つの総称仮引数が共変的であると

する。このとき,代入互換性の記法を用いて,GenArgB := GenArgA である場合に限り,すべてのイン

スタンス化は,IA`1<GenArgB> := IA`1<GenArgA>を満足する。したがって,例えば,型 IA`1<string>

のインスタンスは,型 IA`1<object>をもつ局所変数に代入することができる。

総称における反変性は,逆の意味合いで作用する。反変的なインタフェース IB`1<-T>があるとすると,

GenArgA := GenArgB

である場合に限り,IB`1<GenArgB> := IB`1<GenArgA>を満足する。

例  (構文は例示的に高水準言語のものを用いている。)

// Covariant parameters can be used as result types

interface IEnumerator<+T> {

T Current { get; }

 bool

MoveNext();

}

// Covariant parameters can be used in covariant result types

interface IEnumerable<+T> {

 IEnumerator<T>

GetEnumerator();

}

// Contravariant parameters can be used as argument types

interface IComparer<-T> {

bool Compare(T x, T y);

}

// Contravariant parameters can be used in contravariant interface types

interface IKeyComparer<-T> : IComparer<T> {

bool Equals(T x, T y);

int GetHashCode(T obj);

}

// A contravariant delegate type

delegate void EventHandler<-T>(T arg);

// No annotation indicates non-variance.  Non-variant parameters can

be used anywhere.

// The following type shall be non-variant because T appears in as a

method argument as

// well as in a covariant interface type

interface ICollection<T> : IEnumerable<T> {

void CopyTo(T[] array, int index);

int Count { get; }

}

注記  参考情報終わり


136

X 3016

:2010 (ISO/IEC 23271:2006)

   

9.6 

インスタンス化された型の代入互換性 

代入互換性については,

第 章 8.7 で定義されている。

 

Employee := Manager

と仮定する。

IEnumerable<Manager> eManager = ...

IEnumerable<Employee>  eEmployee  =  eManager;

     //

Covariance

IComparer<object> objComp = ...

IComparer<string>  strComp  =  objComp;

     //

Contravariance

EventHandler<Employee> employeeHandler = ...

EventHandler<Manager> managerHandler = employeeHandler; //

Contravariance

例  次が与えられているとする。

interface IConverter<-T,+U> {

  U  Convert(T  x);

}

IConverter<string, object> := IConverter<object, string>

となる。

次が与えられているとする。

delegate U Function<-T,+U>(T arg);

Function<string, object> := Function<object, string>

となる。

 

IComparer<object> objComp = ...

// Contravariance and interface inheritance

IKeyComparer<string> strKeyComp = objComp;

IEnumerable<string[]> strArrEnum = …

// Covariance on IEnumerable and covariance on arrays

IEnumerable<object[]> objArrEnum = strArrEnum;

IEnumerable<string>[] strEnumArr = ...

// Covariance on IEnumerable and covariance on arrays

IEnumerable<object>[] objEnumArr = strEnumArr;

IComparer<object[]> objArrComp = ...

// Contravariance on IComparer and covariance on arrays

IComparer<string[]> strArrComp = objArrComp;

IComparer<object>[] objCompArr = ...

// Contravariance on IComparer and covariance on arrays

IComparer<string>[] strCompArr = objCompArr;

9.7 

メンバ識別情報の妥当性 

型安全性を保証するため,共変性総称型及び反変性総称型のメンバの識別情報が整形式となるには,更

なる要請を課す必要がある。


137

X 3016

:2010 (ISO/IEC 23271:2006)

注記  ここから参考情報であり規定ではない。

−  共変性仮引数は,型定義における生産側(producer)

,読込み側(reader)又は取得側(getter)位置に

だけ現れることができる。すなわち,次の箇所とする。

−  メソッドの返却値の型

−  継承されたインタフェース

−  反変性仮引数は,消費側(consumer)

,書出し側(writer)

,又は設定側(setter)位置にだけ現れること

ができる。すなわち,次の箇所とする。

−  メソッドの実引数型

−  変性のない仮引数はどこに現れてもよい。

注記  参考情報終わり

ここで,共変性総称型定義及び反変性総称型定義が妥当となるとは何を意味するかを,形式的に定義す

る。

総称型定義:  総称型定義 G<var_1 T_1, 

, var_n T_n>

は,次の場合に妥当とする。G がインタフェー

ス,又は委譲型,かつ,S = <var_1 T_1, 

, var_n T_n>

に対して,次の各々が成り立つ場合に妥当とする。

ここで var_n  は,+,-,又はなしのいずれかとする。

−  各インスタンスメソッド及び仮想メソッド宣言は,S に対して妥当となる。

−  各継承されたインタフェース宣言は,S に対して妥当となる。

−  静的メンバ,インスタンス構築子,又は型自身の総称仮引数制約に対する制限がない。

注釈付きの総称仮引数 S = <var_1 T_1, 

, var_n T_n>

が与えられているものとする。ここでは,型定義の

各種構成要素が,S に関して妥当となるとは何を意味するかを定義する。反転演算は-S と書き,

“負を正に

反転すること及び正を負に反転すること”を意味すると定義する。

次を考慮する。

−  “S に関して妥当となる”は“共変性に振る舞う”と同義となる。

−  “-S に関して妥当となる”は“反変性に振る舞う”と同義となる。

−  “S 及び-S に関して妥当となる”は“変性なく振る舞う”と同義となる。

この最後の定義によって,型を共変性仮引数及び反変性仮引数にすることを禁止する効果があることに

注意する。すなわち,すべての総称仮引数の出現は,変性なしでなければならない。

メソッド:  メソッド識別情報 t meth(t_1,

,t_n)

は,S に対して,次のいずれかの場合妥当とする。

−  その返却値の型識別情報 t が S に関して妥当とし,かつ

−  各実引数型識別情報 t が-S に関して妥当とする。

−  各メソッド総称仮引数制約型 t_j -S に関して妥当とする。

注記  言い換えれば,返却値は共変性に振る舞い,実引数は反変性に振る舞う。総称仮引数に対する

制約も反変性に振る舞う。

型識別情報  型識別情報 t は,次のいずれかの場合に S に関して妥当となる。

−  総称でない型(例  通常のクラス又は値型)

−  総称仮引数 T_i。ただし,var_i が+又はなしである場合(すなわち,総称仮引数であって共変性又は変

化性なしと印付けされたもの)

−  配列型 u[]であって,かつ,が に関して妥当なもの。つまり配列型は共変性をもって振る舞う。

−  閉総称型 G<t_1,

,t_n>

であって,次を満たすもの

−  t_i が に関して妥当なもの。ここで G の i 番目の仮引数は共変性で宣言されているものとする。


138

X 3016

:2010 (ISO/IEC 23271:2006)

   

−  t_i -S に関して妥当なもの。ここで G の i 番目の仮引数は反変性で宣言されているものとする。

−  t_i が に関して及び-S に関して妥当なもの。ここで G の i 番目の仮引数は変化性なしで宣言されて

いるものとする。

9.8 

識別情報及び結合 

総称型のメンバ(フィールド及びメソッド)は,メタデータトークンを用いて CIL 命令で参照される。

ここでメタデータトークンは,表 MemberRef(22.25 参照)の入口を指定する。抽象的には,参照は次の

二つの部分からなる。

1)

メンバが宣言された型。この場合,インスタンス化された総称型定義。例  IComparer`1<String>

2)

メンバの名前及び(インスタンス化されていない)総称識別情報。例  int32 Compare(!0,!0)

インスタンス化されたときに,異なるメンバが同一の型をもつことは許されるが,MemberRef によって

区別することができる。

 

.class public C`2<S,T> {

  .field  string  f

  .field  !0  f

  .method instance void m(!0 x) {...}

  .method instance void m(!1 x) {...}

  .method instance void m(string x) {...}

}

閉型 C`2<string,string>は妥当とする。これはすべて同じ仮引数型で m と名前付けられた

三つのメソッド及び同じ型で f と名前付けられた二つのフィールドをもつ。これらは上記の

MemberRef 符号化を通してすべて区別される。

string C`2<string, string>::f

!0  C<string,  string>::f

void C`2<string, string>::m(!0)

void C`2<string, string>::m(!1)

void C`2<string, string>::m(string)

プログラム記述言語がこの種の多重定義をどのように解決するかは,各言語に委ねられた問題

とする。例えば,多くの言語では,この種の多重定義は禁止している。

9.9 

継承及び上書き 

メンバ継承は

第 章“メンバ継承”で定義されている。(上書き及び隠ぺいは,同じく第 章“隠ぺい,

上書き,及び配置”で定義されている。

)この定義は,総称型に対応して自然な方法で拡張される。特に,

あるメンバが,

基底クラス若しくは基底インタフェースから,

(静的メンバ若しくはインスタンスメンバに

ついては)メンバを隠ぺいするかどうか,又は(仮想メソッドについては)メンバを上書きするかどうか

を決定するためには,単に各総称仮引数をその総称実引数で置き換え,結果として生成されるメンバ識別

情報を比較する。

例  次でこの点について説明する。 

次の基底クラス B 及び派生クラス D の定義を仮定する。

.class B

{ .method public virtual void V(int32 i) { … } }


139

X 3016

:2010 (ISO/IEC 23271:2006)

.class D extends B

{ .method public virtual void V(int32 i) { … } }

クラス D 内で,D.V は継承されたメソッド B.V を上書きする。なぜならばそれらの名前と識別

情報が一致するからである。

この単純な例が,総称型に対応してどのように拡張されるかを見ることにする。また,クラス

D

は,どの総称インスタンス化されたクラスから派生されるかを見ることにする。次の例を考え

る。

.class B`1<T>

{ .method public virtual void V(!0) { … } }

.class D extends B`1<int32>

{ .method public virtual void V(int32) { … } }

.class E extends B`1<string>

{ .method public virtual void V(int32) { … } }

クラス D は B<int32>から派生される。さらに,B<int32>は,次のメソッドを定義する。

   public virtual void V(int32 t) { … }

ここで B の総称仮引数 T を,特定の総称実引数 int32 で置き換え単純化している。これはメ

ソッド D.V と(同じ名前及び識別情報であり)一致している。したがって,上記の総称型でない

場合の例と同じ理由によって,D.V は継承メソッド B.V を上書きする。

この例と B<string>から派生されたクラス E とを対比する。こちらの場合,B の T を string

で置き換えることで,B.V は次の識別情報を得る。

   public virtual void V(string t) { … }

この識別情報は,メソッド E.V とは異なるため,基底クラスの B.V メソッドを上書きするこ

とはない。

型定義が不当となるのは,基底クラスの総称実引数を置換した後,二つのメソッドが同じ名前及び同じ

識別情報(返却値型を含む)となるときとする。次でこの点について説明する。

 

.class B`1<T>

{ .method public virtual void V(!0 t)     { … }

  .method public virtual void V(string x) { … }

}

.class D extends B`1<string> { } // Invalid

クラス D は,B<string>から継承する二つのメソッドが同一の識別情報 void V(string)と

なるので,不当となる。

しかし,次の D は妥当となる。

.class D extends B`1<string>

{ .method public virtual void  V(string t)

{ … }

  .method  public  virtual  void  W(string  t)

  {  …

    .override  method  instance  void  class  B`1<string>::V(!0)

    …


140

X 3016

:2010 (ISO/IEC 23271:2006)

   

  }

}

総称メソッド(すなわち,それ自身の総称仮引数をともなうメソッド)を上書きする場合,総称仮引数

の個数は,上書きされるメソッドの総称仮引数の個数と完全に一致しなければならない。上書きされる総

称メソッドが,総称実引数に対する一つ以上の制約をもつ場合,次のことが言える。

−  上書きするメソッドは,同じ総称実引数に対してだけ制約をもつことができる。

−  総称実引数に対して上書きするメソッドによって指定される総称実引数に対する制約は,同じ総称実

引数に対して,上書きされるメソッドによって指定される制約よりも強いものであってはならない。

注記  上書きするメソッド本体の中で,その識別情報に直接指定される制約だけが適用できる。メソ

ッドが呼び出される場合,call 又は callvirt 命令内のメタデータトークンに関連付けられた制約

が,効力をもつ。

9.10 

明示的なメソッドの上書き 

型は,総称型であるかどうかにかかわらず,明示的な上書きを用いて,特定の仮想メソッドを(そのメ

ソッドがインタフェース又は基底クラスのいずれによって導入されたかにかかわらず。

実装することがで

きる(10.3.2 及び 15.1.4 参照)

上書きを司るこの規則は,総称型に対応して次のとおり拡張される。

−  実装するメソッドが総称でない型の一部,又は閉総称型の一部の場合,宣言するメソッドは,その型

の基底型の一部又はその型で実装されたインタフェースの一部でなければならない。

 

.class interface I`1<T>

{ .method public abstract virtual void M(!0) {}

}

.class C implements class I`1<string>

{ .override method instance void class I`1<string>::M(!0) with

method instance void class C::MInC(string)

  .method virtual void MInC(string s)

  {  ldstr  "I.M"

    call  void  [mscorlib]System.Console::WriteLine(string)

    ret

  }

}

−  実装する型が総称型の場合,宣言されるメソッドは,総称型でなければならず,かつ同じ個数のメソ

ッド総称仮引数をもたなければならない。

実装するメソッド及び宣言されるメソッドのいずれも,インスタンス化された総称メソッドであって

はならない。これは,インスタンス化された総称メソッドが,インタフェースメソッドを実装するた

めに用いることができないことを意味する。さらに,総称メソッドを特定の総称仮引数でインスタン

ス化する特別なメソッドを提供することができないことも意味する。

  次が与えられているとする。 

  .class  interface  I

{ .method public abstract virtual void M<T>(!!0) {}


141

X 3016

:2010 (ISO/IEC 23271:2006)

  .method public abstract virtual void N() {}

}

次のいずれの.override 文も許されない。

.class C implements class I`1<string>

{ .override class I::M<string> with instance void class C::MInC(string)

  .override class I::N with instance void class C::MyFn<string>

  .method virtual void MInC(string s) { … }

  .method virtual void MyFn<T>() { … }

}

9.11 

総称仮引数に対する制約 

総称クラス又は総称メソッドで定義された総称仮引数は,一つ以上の型(符号化については,22.21 

GenericParamConstraint 参照)及び一つ以上の特別な制約(10.1.7)による制約が課されている。総称仮引

数は,宣言された各制約に対し(ボックス化されたときに)代入互換性をもち,かつ指定されたすべての

特別な制約を満たす総称実引数によってだけインスタンス化されることができる。

総称仮引数制約は,総称型定義自身又は総称メソッド定義自身と少なくとも同一の可視性をもたなけれ

ばならない。

注記  総称仮引数に対するこれら以外の制限は存在しない。特に,次の使用は妥当とする。総称クラ

スの総称仮引数に対する制約は,その総称仮引数に対して,更に,そのクラスそれ自身に対し

ても,再帰的な参照を構成してよい。

.class public Set`1<(class IComparable<!0>) T> { … }

// can only be instantiated by a derived class!

.class public C`1<(class C<!0>) T> {}

.class public D extends C`1<class D> { … }

総称メソッドの総称仮引数に対する制約は,総称メソッド及び(総称であれば)その囲みク

ラスの両方の総称仮引数に対する再帰的な参照を構成することができる。その制約は,囲みク

ラス自身を参照することもできる。

.class public A`1<T> {

  .method public void M<(class IDictionary<!0,!!0>) U>() {}

}

総称仮引数制約は,総称仮引数であっても,配列のように総称でない型であってもよい。

.class public List`1<T> {

  // The constraint on U is T itself

  .method public void AddRange<(!0) U>(class IEnumerable`1<!!0> items)

{ … }

}

総称仮引数は複数の制約をもつことができ,多くても一つの基底クラスから継承され(何も制約が指定

されない場合,CLI は省略時解釈として  System.Object から継承され)

,更に,ゼロ個以上のインタフ

ェースを実装することができる。(クラス又はメソッドに制約を用いる場合の構文は,10.1.7 で定義され

る。

 


142

X 3016

:2010 (ISO/IEC 23271:2006)

   

次の宣言は,総称クラス OrderedSet<T>を示している。ここで総称仮引数 T は,クラス

Employee から継承されるとともに,インタフェース IComparable<T>を実装するように制約付

けされている。

.class OrderedSet`1<(Employee, class

[mscorlib]System.IComparable`1<!0>) T> { … }

注記  総称仮引数に対する制約は,総称仮引数がインスタンス化される可能性のある型だけを制限す

る。正当性検証(3

章参照)では,総称仮引数が制約に一致するように提供されると分かって

いるようなフィールド,特性,又はメソッドに対して,最初にボックス化(3

章参照)されて

いる場合又は callvirt 命令が constrained.接頭辞命令(3

章参照)で前置修飾されている

場合を除き,総称仮引数を通して,それらを直接アクセスすることも,呼び出すこともできな

いことを要請している。

9.12 

総称型のメンバへの参照 

注記  この細分箇条は参考情報とする。

型メンバを参照する CIL 命令は,インスタンス化された型のメンバへの参照を許可するように一般化さ

れる。

参照の中で指定された総称実引数の個数は,型の定義で指定された数と一致しなければならない。

メソッドを参照する CIL 命令は,インスタンス化された総称メソッドへの参照が許可されるように一般

化される。

10 

型の定義 

型(すなわち,クラス,値型及びインタフェース。

)は,モジュールの最上位で定義できる。

《宣言》 ::=

箇条 

  .class

《クラスヘッダ》 ‘{’ 《クラスメンバ》* ‘}’

10 

| …

この宣言によって生成された論理的なメ