X 3014
:2003 (ISO/IEC 14882:2003)
(
1)
まえがき
この規格は,工業標準化法第
12 条第 1 項の規定に基づき,社団法人情報処理学会(IPSJ)/財団法人日本
規格協会
(JSA)から,工業標準原案を具して日本工業規格を制定すべきとの申出があり,日本工業標準調査
会の審議を経て,経済産業大臣が制定した日本工業規格である。
制定に当たっては,日本工業規格と国際規格との対比,国際規格に一致した日本工業規格の作成及び日
本工業規格を基礎にした国際規格原案の提案を容易にするために,
ISO/IEC 14882:2003,Information
Technology―Programming languages―C++を基礎として用いた。
日 本 工 業 規 格
プ ロ グ ラ ム 言 語
序文 この規格は,
年
月に発行された
!
"##
の第
版を翻訳し,技術的内容及び規格票の様式を変更することなく作成した日本工業規格である。
なお,下線を施してある箇所は,この規格で定義する用語である。側線を施してある
参考は,原国際規格にはない
事項である。
総則
適用範囲 この規格は,プログラム言語
"##
の処理系に対する要件を規定する。処理系は,その第
要件と
して,
"##
を実装しなければならない。このため,この規格は,プログラム言語
"##
の定義もあわせて規定する。
その他の要件 及び 第
要件に対する緩和条項は,この規格の中で順次規定する。
プログラム言語
"##
は,
6
によるプログラム言語
"
に基づく。
"##
は,
"
が提供する機能に
加えて,幾つかのデータ型,クラス,テンプレート,例外,名前空間,インライン関数,演算子の多重定義,関数名
の多重定義,参照,空き領域管理用の演算子,及び 幾つかのライブラリを提供する。
引用規格
この規格の規定の一部となる規定をもった規格の一覧を,次に示す。
―
( 規格群全体)
$
%
備考
情報処理用語の規格
6
〜
が,この引用規格群と一致している。
―
6
プログラム言語
"
備考
***
!
"
が,この引用規格と一致している。
―
6
&'()*'()+
プログラム言語
"
( 追補
)
備考
***3
!
",
&'()*'()+
"
-
が,この引用規格と一致している。
―
6
!
国際符号化文字集合(
."/
)
第1部
体系及び基本多言語面
備考
((!
.0
!
' 1-2
"
33
"-
/
."/
&
3
4!
'
が,この引用規格と
一致している。
参考
関連規格を,次に示す。
―
(##*
4
5-1
1
!!
!!!
備考
この規格の旧番号は,
##*
であった。この規格は,
30
)#-
(((
!33
%
5
1
と一致している。
―
6
移植可能なオペレーティングシステムのインタフェース(
2/6
)
第
1部
応用プログラム向けのインタフェース(
&
)
[プログラム言語C]
備考
**#!
%
21
/!
-
2/6
/!
&11
&
7"
8 9
が,この引用規格と一致している。
―
6
移植可能なオペレーティングシステムのインタフェース(
2/6
)
第
2部
シェル及びユーティリティ
備考
**#!
%
21
/!
-
2/6
/
3
.!
が,この引用規格と一致している。
6
の
)
及び
6
&'()*'()+
の
)
によるライブラリを,この規格で
は標準
"
ライブラリ
と呼ぶ。
用語の定義
この規格で用いる主な用語の定義は,
によるほか,
〜
のとおりとす
る。
)
〜
)
だけで用いる用語については,
)
に定義する。
この規格の一部でだけ用いる用語は,それぞれ必要な箇所で定義する。そうした定義の対象となる用語は,下線に
よって示す。
実引数
関数呼出し式の括弧の中にコンマで区切られて並んだ式,関数形マクロ呼出しの括弧
の中にコンマで区切られて並んだ前処理字句の列,
の演算対象,又は テンプレート具現化の三角括弧の中にコ
ンマで区切られて並んだ型識別子 若しくは テンプレート名。
診断情報
処理系が出力する処理系定義の出力情報の一つ。
動的な型
左辺値式の表す左辺値が指す最派生オブジェクト(
)の型。
例 その静的な型が
:
クラス
"
へのポインタ
;
であるポインタ(
)
が,クラス
"
から派生した(
)ク
ラス
#
のオブジェクトを指していたとすると,式
!
の動的な型は,
:#;
となる。参照(
)も,同様
に扱う。
右辺値式の動的な型は,それの静的な型とする。
不適格プログラム
!"
適格プログラム(
)でない
"##
処理系への入力。
#
処理系定義の動作
!$
%
&
'
適格プログラムの構文単位と 正しいデータと
の組合せに対する,処理系に依存した動作であって,それぞれの処理系が文書で説明を用意しておかなければならな
い動作。
(
処理系限界
処理系がプログラムに課している制限。
)
文化圏固有動作
!
$
%
&
'
国,文化,言語などに依存した動作であって,それぞれの処理
系が文書で説明を用意しておかなければならない動作。
多バイト 文字
!%
&
翻訳環境 又は 実行環境での拡張文字集合の要素を表した
バイト
以上のバイト列。拡張文字集合は,基本文字集合をその部分集合としている(
参照)
。
*
仮引数
次のいずれかとする。
―
関数宣言 若しくは 関数定義の中,又は 例外処理部の
節の中で宣言され ,その関数 又は 例外処理
部が起動する際に値を受け取るオブジェクト 又は 参照
―
関数形式マクロの定義の中で,そのマクロ名に続く括弧の中にコンマで区切られて並んでいる識別子
―
テンプレート仮引数
呼出し情報
関数について,その多重定義解決(
)に用いる情報。基本的には,その関数
の仮引数の型の列。関数がクラスのメンバである場合は,関数自身の
0
修飾子 及び それを宣言しているクラスも含
める
。関数テンプレートの特殊化に対する呼出し情報では,テンプレート実引数の型も含める(
##
参照)
。
静的な型
式(
*
)の型。その式がもたらす結果の型として,実行時の意味を考慮せずにプ
ログラムを解析することで得られる。式の静的な型は,その式が位置するプログラムの形だけから決まり,プログラ
ムの実行中に変わることがない。
未定義の動作
$
%
&
'
間違いを含んだプログラム,間違ったデータ などに対して生じ うる
動作であって,この規格で要件を規定しない動作。この規格で動作を明示的に与えていない場合も,未定義の動作と
する。
参考
未定義の動作としては,次のものがありうる。
―
その状況を完全に無視し ,何が起きるかわからない。
―
翻訳段階 又は プログラムの実行段階で,その環境に沿っての動作をする( 診断情報を出して
もよいし,出さなくてもよい。)
。ただし ,その動作の様子については,文書を用意して説明し
ておく。
―
翻訳 又は 実行を終了する( 診断情報を出力する。)
。
間違いを含んだプログラムの多くは,未定義の動作を引き起こすことがない。それらに対しては,診断を
下すことを要求している。
注
〜
及び
にあるとおり,標準
ライブラリは,標準
ライブラリの部分集合となっている。
注
関数の呼出し情報には,返却値の型が含まれていない。多重定義の解決には,返却値の型が関与しないからである。
未規定の動作
$
%
&
'
適格プログラムと正しいデータとの組合せに対する動作であって,
処理系に依存する動作。処理系は,どんな動作が生じるかについて文書を用意する必要はない。
参考
多くの場合,どんな動作が生じ うるかについて,この規格の中で示唆する。
適格プログラム
+
!"
構文規則,診断対象の意味規則,及び 単一定義規則(
参照)
に従った
"##
プログラム。
処理系の適合
この規格の構文規則 及び 意味規則は,
:
診断を必要としない
;
と明記してある規則,及び
:
動作
は未定義とする
;
と明記してある規則を除いて,すべて診断対象規則
3!%
とする。
この規格は,
"##
処理系に対する要件を規定する。しかしながら,それらの要件は,多くの場合,プログラム,プ
ログラムの部分,又は プログラムの実行に対する要求事項の形をとる。こうした要求事項は,次の意味をもつ。
― プログラムがこの規格に示す規則に違反していない場合,適合する処理系は,その資源的な限界の範囲内
で,そのプログラムを受理し ,正しい実行
を行わなければならない。
― プログラムが診断対象でない規則に
カ所でも違反している場合,この規格は,そのプログラムに対する
処理系の処置に何らの要件もおかない。
― プログラムが診断対象規則に違反している箇所がある場合,適合する処理系は,それぞれの箇所ごとに,
少なくとも何らかの診断情報を出力しなければならない。ただし ,そのプログラムが診断対象でない規則
にも違反している場合は,この限りでない。
クラス 及び クラステンプレートに対しては,ライブラリ条項(
#
)でその定義を部分的に規定する。すなわち,
非公開メンバ(
)の定義は,規定しない。
( 適合する)処理系は,ライブラリ条項に従って非公開メンバの定義を
与え,クラス 及び クラステンプレートの定義を完成しなければならない。
関数,関数テンプレート,オブジェクト 及び 値に対しては,ライブラリ条項でその宣言を規定する。
( 適合する)
処理系は,ライブラリ条項に従ってその定義を与えなければならない。
ライブラリが定義する名前は,名前空間の有効範囲(
)
)をもつ。
"##
翻訳単位(
)では,そこに適切な標
準ライブラリのヘッダを取り込むことによって,これらの名前を使うことができる(
(
参照)
。
ライブラリの中の テンプレート,クラス,関数 及び オブジェクトは,外部結合(
#
)をもつ。
( 適合する)処理
系は,翻訳単位を結合して完全な
"##
プログラムを構成する際に,必要に応じて,標準ライブラリのこれらに対す
る定義を提供しなければならない(
参照)
。
処理系を,依存処理系
!3
1
と自立処理系
!3
1
とに分類する。依存
処理系は,
2/
の下で動作する処理系をいう。自立処理系は,
2/
の助けなしで動作する処理系をいう。依存処理系が
提供しなければならないライブラリは,そのすべてをこの規格で規定する。自立処理系が提供するライブラリは,処理
系定義とする。その提供するライブラリには幾つかの言語常備ライブラリが含まれていなければならない(
)
参照)
。
適合する処理系は,適格プログラムの動作を変えることがない限り,拡張(ライブラリ関数の追加を含む。)を行っ
てもよい。
( 適合する)処理系は,プログラムがこの規格で不適格であれば,こうした拡張を使っていても,診断情報
を出力しなければならない。診断情報を出力しさえすれば ,そうしたプログラムを翻訳し実行しても差し支えない。
#
この規格の構成
〜
(
にプログラム言語
"##
の仕様を規定する。そこでは,構文の仕様を
(
の記法で
与える。すべての構文の仕様は,便宜を図って,
附属書
3
に再掲する。
)
〜
)
( ライブラリ条項
%
!!
と呼ぶ。)に,標準
"##
ライブラリを規定する。そこでは,マクロ
(
(
),値(
),型(
及び
参照),テンプレート(
),クラス(
*
),関数(
#
) 及び オブジェク
ト(
)
)に対する定義を規定する。
附属書
4
に,適合する処理系の最小能力の推奨例を示す。
附属書
に,最初の版からの
"##
の変遷,及び
"##
と
"
言語との差異の詳細を示す。幾つかの
"##
の機能
は,こうした経緯との両立性を保つためだけに設けてある。
附属書
5
にこれらの機能を示す。
附属書
に,
"##
の識別子(
)に使える文字を,その国際文字名で示す。
この規格では,例を示す場合,字下げした太字の
例で始める。参考を示す場合,字下げした太字の参考で始める。
例と参考とは,互いに入れ子になることがある。
(
構文記法
この規格で用いる構文記法では,構文要素( 非終端記号)の名前を《日本語文字》でつづって表し ,
終端記号をタイプライタ体で表す。選択肢は,原則として,それぞれ単独の行として並べる。ただし,多数の選択肢
がある場合に,
:
次のいずれか
;
と明記した上で,選択肢を列挙することがある。このとき,
行に複数の選択肢を並
注
正しい実行
には,処理するデータにもよるが,未定義の動作も含まれる(
及び
参照)
。
べることもある。省略可能な終端記号 又は 非終端記号には,
:1;
を下付けする。例えば ,次のものは,波括弧の
中に式を
個書いたものか,波括弧だけを書いたものを表す。
式
構文要素名は,次の原則に従っている。
―
:
《…… 名》
;
は,文脈から意味が決まる識別子の使用に当てる(例えば,
《クラス名》《型定義名》など )
。
―
:
《…… 識別子》
;
は,文脈に依存しない識別子に当てる( 例えば 《修飾付き識別子》)
。
―
:
《…… 列》
;
は,区切りなしに並べたものに当てる( 例えば 《宣言列》は,宣言を並べたものを表す。)
。
―
:
《…… 並び》
;
は,コンマで区切って並べたものに当てる( 例えば ,
《式並び》は,式をコンマで区切っ
て並べたものを表す。)
。
)
,,
記憶モデル
"##
では,その基本の記憶単位をバイト
%
と呼ぶ。バイトは,基本実行文字集合の文
字を収めることができる大きさをもつ,一連のビット列とする。そのビット数は,処理系定義とする。その重みの最
も大きいビットを上位ビット
-3
%
と呼び,最も小さいビットを下位ビット
<-3
%
と呼ぶ。
"##
プログラムでは,その記憶として,連続したバイトからなる
個以上の列を使う。それぞれのバイトは,固有の番地
をもつ。
参考
型の表現は,
*
で規定する。
,,
オブジェクト モデル
"##
プログラムの構文単位は,オブジェクトを生成し,破壊し,参照し ,取り出
し ,加工する。オブジェクト
%
=
は,記憶域からなる。
参考
関数は,オブジェクトではない。オブジェクトと同様に記憶域を占有することもあるが,しないことも
ある。
オブジェクトは《定義》
3>
(
) 又は 《
<
式》
(
#
)が生成する。更に,必要に応じて処理系が生成す
る(
参照)
。オブジェクトの特性は,その生成時に決まる。オブジェクトは,名前
をもつことがある。オ
ブジェクトは,記憶域期間
!
3
(
)
)をもつ。記憶域期間は,そのオブジェクトの生存期間
(
)を左右する。オブジェクトは,型
1
(
*
)をもつ。オブジェクト型
%
=
1
とは,そのオブジェク
トを生成するのに用いた型をいう。オブジェクトには,多相のオブジェクトがある。多相オブジェクト
1
1
%
=
に対しては,実行時にそのオブジェクトの型が決定できるだけの必要な情報を処理系が生成する。多相でない
オブジェクトでは,そのオブジェクトの中の値の解釈が,それを取り出すのに用いる式
?1!!
の型によって定
まる。
オブジェクトが他のオブジェクトを包含することがある。この包含されたオブジェクトを,部分オブジェクト
! %-
%
=
と呼ぶ。部分オブジェクトには,メンバ部分オブジェクト
%
! %-%
=
(
*
),基底クラス部分オ
ブジェクト
%!
!!
! %-%
=
(
)及び 配列要素がある。他のオブジェクトの部分オブジェクトとなっていな
いオブジェクトを,総体オブジェクト
1
%
=
と呼ぶ。
それぞれのオブジェクト
に対して,
の総体オブジェクトとは,次で定まるオブジェクトをいう。
―
が総体オブジェクトの場合,
自身。
―
そうでない場合,
を包含しているオブジェクト(これは一意に定まる。)の総体オブジェクト。
クラス型の,総体オブジェクト,データメンバ(
*
) 又は 配列要素の型としては,基底クラス部分オブジェクト
のクラス型と区別するため,その最派生クラス
!
30
3
!!
を採択する。最派生クラス型のオブジェクトを,
最派生オブジェクト
!
30
3
%
=
と呼ぶ。
最派生オブジェクトは,それがビットフィールド(
*(
)である場合を除いて,ゼロでない大きさをもち,
バイト
以上の記憶域を占める。基底クラス部分オブジェクトは,大きさがゼロであることがある。
"
互換型(
2*
型,
*
参照)のオブジェクトは,一連のバイトからなる記憶域を占める。
参考
"##
は,種々の組込みの型とともに,既存の型を組み合わせて新しい型を構成する複数の手段を提供
する(
*
参照)
。
*
プログラムの実行 この規格では,意味を規定するのに,パラメタをもった非決定性の抽象機械を用いる。この
規格は,適合する処理系に対して,その構成方法に関する何らの要件も置かない。したがって,この抽象機械の構成
を模倣する必要もない。適合する処理系は,この抽象機械の外から見た動作(だけ )を模倣しなければならない。
注
は,
の略号である。
注
この規定は,
まるで
規則とも呼ばれることがある。処理系は,まるで すべての要件を満たしているように,プログラムの外
から見た動作をもたらすのであれば,この規格が規定する具体的要件そのものを無視して差し支えない。例えば,処理系は,式の値が使
われることがなく,しかもプログラムの外から見た動作に影響を与えるような副作用をもたないと帰結できるのであれば,その式の評価
を行わなくてもよい。
#
抽象機械の性質 及び 操作( 例えば ,
$
)を,処理系定義と規定することがある。これらは,抽象機械
のパラメタとなる。個々の処理系は,これらの性質に対して,その特性 及び 動作を記した文書を提供しなければな
らない。これらの文書によって,その処理系に呼応した抽象機械が定まる( 以後,これを呼応抽象機械と呼ぶ。)
。
抽象機械の特質 及び 操作( 例えば ,関数の実引数評価の順序)を,処理系依存と規定することがある。この規格
では,可能な限り,その許容可能な一連の動作を示す。これらは,抽象機械に非決定性をもたらす。呼応抽象機械で
は,したがって,特定のプログラムと入力の組合せに対して複数の実行列が生じ うる。
また,操作( 例えば ,空ポインタの参照はずしの効果)によっては,未定義と規定することもある。
参考 この規格は,未定義の動作を含むプログラムの動作に対して,何らの要件をおかない。
適合する処理系は,適格プログラムを実行した結果,同じプログラムと入力の組合せに対する呼応抽象機械がもた
らす実行列の一つと,外から見て同じ動作をもたらさなければならない。しかし,その実行列が未定義の操作を含む
場合,この規格は,適合処理系がそのプログラムと入力の組合せをどのように実行するかについて(その最初の未定
義の操作が生じる前の操作に関しても),何らの要件も置かない。
抽象機械の外から見た動作とは,揮発性データに関する読み書き,及び ライブラリ入出力関数
呼出しの系列を
いう。
揮発性左辺値(
)が指すオブジェクトの取出し ,オブジェクト一般の加工,ライブラリ入出力関数の呼出し ,
及び これらの操作を含んだ関数の呼出しを,副作用
!3-@
と呼ぶ。副作用は,実行環境の状態に変化をもたら
す。式の評価が副作用をもたらすこともある。実行列中の幾つかの点を特定して副作用完了点
!A
1
と呼
ぶ。副作用完了点では,その副作用完了点以前の操作すべての副作用が完了するまで,それ以後の操作の副作用が生
じてはならない。
関数の実行が始まると,その関数を呼び出した式の評価は,その関数が完了するまで休止する。
抽象機械がシグナルを受け取ってその処理を中断した場合,型
以外の型のオブジェクト
の値は,未規定とする。さらに,例外処理部が変更を加えた,
以外の型のオブジェクトの値
は,未定義とする。
ブロックに入るごとに,その自動記憶域期間(
)
)をもったオブジェクトを具体的に生成する。こうしたオブ
ジェクトは,そのブロックの実行中,及び そのブロックの( 関数の呼出し 又は シグナルの受取りによる)実行保留
の間存在し,最近に代入された値を保持する。
適合する処理系は,少なくとも次の要件を満たさなければならない。
―
副作用完了点では,揮発性オブジェクトが安定であること。すなわち,それ以前の評価が完了し ,以後の
評価がまだ始まっていないこと。
― プログラム終了時点では,ファイルに書き出したデータが,そのプログラムの抽象機械による実行結果の
一つと一致していること。
―
対話装置の入出力では,プログラムが入力待ちに入る前に,それに対する入力要求が表示されること。対
話装置が何であるかは,処理系定義とする。
他の式の部分式となっていない式を完結式
-?1!!
と呼ぶ。暗黙の関数呼出しを生じると規定する構文単
位は,ここでの式として扱い,完結式として扱う。
参考
"##
では,文脈によって《式》以外の構文単位から生じた完結式を評価することがある(
#
参照)
。
例えば ,
#
の《初期化子》の一つに次のものがある。
式並び
この構文単位は,その《式並び》を《実引数並び》としてコンストラクタ関数を呼び出す関数呼出しと
なる。同様に 《初期化子》の一つに次のものもある。
%
初期化子節
この構文単位も,
個の《代入式》を実引数としてコンストラクタ関数を呼び出す関数呼出しとなること
がある。この場合も,その関数呼出しは,完結式として扱う。
参考
完結式の評価は,その完結式の字句的な部分となっていない部分式の評価を含むことがある。例えば ,
注
処理系は,拡張としてライブラリ入出力関数を追加してもよい。これらを追加したときは,その呼出しも
外から見える動作
として
扱うことが望ましい。
注
抽象機械での操作の実行順序がすべて規定されているわけでない点に注意する必要がある。ここでの制約は,実際に目的プログラムが
生成された場合の,その実行順序での副作用だけを対象とする。ライブラリ入出力関数の呼出しから戻った時点で,その呼出しが引き起
こす外部の動作( 例えば,入出力動作自身)がまだ完了していなくても,その副作用が完了したものとして扱うことにも注意する必要が
ある。
注
すなわち,関数の実行が互いに切り混ざることはない。
(
省略時実引数の式(
(
)の部分式は,その省略時実引数を定義している式の中ではなく,その関数呼出
しの式の中で作り出される。
参考
演算子の評価順序の整理は,対象となる演算子が実際に結合律 又は 交換律を満たす場合
にだけ,通
常の数学規則に従って行ってよい。例えば ,次のプログラム片を考えてみる。
&
'!(((!'
%
)
*+,-.
)
)
/&
この式は,現れている演算子の順位から正確に次のとおりに振る舞う。
%
)
*+,-.
)
)
/&
したがって,和
)
*+-,.
に
を加え,その結果に
を加えたものを
に代入する。あふれで例外を
発生し ,しかも
型で表せる値が
7
#9
である計算機に対して,処理系は,この式を次の
いずれにも書き換えてはならない。
%
)
)
*+,-/&
%
)
)
*+,-/&
と
の値が
と
又は
と
である場合に,動作が違ってしまうからである。しかしながら,あ
ふれで例外を発生することがなく,あふれが生じても逆演算で元に戻せる計算機に対してなら,処理系は,
上に示した式をこれら
通りのいずれに書き換えても差し支えない。同じ結果が得られるからである。
完結式の評価完了時点は,それぞれ副作用完了点となる。
関数( インライン関数であるか否かによらない。)の呼出しに対しては( もしあれば )その実引数の評価の直後が
副作用完了点となる。実引数の評価は,その関数本体の式 又は 文の実行に先行する。返却値のコピーの後も副作用
完了点となる
。返却値のコピーは,その関数の外側のいかなる式の評価にも先行する。
"##
では,文脈によっ
て,その翻訳単位の中に関数呼出しの構文単位が現れていない場合にも,関数呼出しの評価を行うことがある。
例
<
式の評価では,
個以上の割付け関数 及び コンストラクタ関数を呼び出すことがある(
#
参照)
。
関数呼出しの構文単位が現れていない文脈で,変換関数(
)を呼び出すこともある。
関数呼出しでは,その関数を呼び出した構文が何であれ ,関数に入る時点 及び 関数から出る時点が副作用完了点と
なる。
次の式(
#
,
##
,
#(
及び
#
参照)を考える。
00
11
2
3
現れている組込み演算子の意味に従って評価を行う場合,それぞれ第
演算対象の評価の直後が副作用完了点となる。
告知
この規格で規定するプログラム言語
"##
は,次の本の
B
章
B
'
に基づく。
/ ! 1
+
"##
8
!3
3,
&333-C
!
%!
"1
,
/4)
---,
1
&
+D+E
この本は,更に次の本の
付録
3
に基づいている。
F
3
B
+
"
1
8 ,
-
G,
,
/4)
---,
1
&
+D+E
この規格のライブラリ条項は,次の本に基づく。
E
HE
+
*
/33
"##
8%
,
-G,
/4)
---,
1
E
HE
E
これらの書籍の著作権は,保護されている。
注
多重定義してある演算子は,結合律も交換律も満たさないものとして扱う。
注
この
完結式評価完了時点
の副作用完了点の後で,一時オブジェクトに対するデストラクタ関数の呼出しが起きる。その順序は,通
常,一時オブジェクトが生成されたのと逆順となる(
参照)
。
注
関数からの戻り時点での副作用完了点は,
では明示的に規定していない。完結式に対する副作用完了点と重複するから
である。しかし ,
では明確にしておく必要がある。
では,呼び出された関数がその実行を終了するのに,例外を送出するな
ど 複数の方法があるからである。
注
ここでは,組込み演算子(
)が対象となる。その演算子が正当な文脈で多重定義を受け,利用者が定義した関数を表している場合,
これらの式は,書かれた演算対象を実引数とする関数呼出しとなり,ここで示したような副作用完了点をもたない。
)
字句要素 プログラムの文字面を収めたものを,この規格では,ソースファイル
!
>
と呼ぶ。
個のソー
スファイルを,その前処理指令
によって取り込んだ(
(
参照)ヘッダ(
)
) 及び 他のソースファ
イルも込みにして,翻訳単位
!
と呼ぶ。ただし ,条件付き取込み前処理指令(
(
)によって省か
れた行は,除く。
参考
"##
プログラムは,そのすべてを同時に翻訳する必要はない。
参考 それまでに翻訳した翻訳単位 及び 具現化単位は,個別に保存しておくこともできれば,ライブラリと
してまとめて保存しておくこともできる。プログラムを構成する個々の翻訳単位は,例えば外部結合の識
別子をもつ関数の呼出し ,外部結合の識別子をもつオブジェクトの操作,データファイルの操作などを通
じて,相互に連絡する(
#
参照)
。翻訳単位は,別々に翻訳して,後で実行可能なプログラムへと結合す
ることもできる(
#
参照)
。
翻訳過程
翻訳過程における各構文規則の優先順位は,それぞれの段階に応じて次のとおりとする。
必要に応じて,処理系が定めた方法でソースファイルの物理的文字を基本ソース文字集合の文字に変換す
る( 行末表示は,改行文字に変換する。)。三つ組表示(
)を,対応する内部表現の単一文字に置き換
える。基本ソース文字集合(
)にない文字を,その文字を表す国際文字名に置き換える。
( 処理系は,
拡張文字が直にソースファイルに現れた場合と,その拡張文字を指名する国際文字名(すなわち,
45555
という記法)がソースファイルに現れた場合とを同等に扱う限り,どんな内部表現を用いてもよい。)
逆斜線の直後に改行文字が現れている箇所それぞれで,その逆斜線と改行文字の組を取り除き,物理的な
行を論理的な行にまとめる。この結果として国際文字名がそこに生じた場合,その動作は,未定義とする。
空でないソースファイルが改行文字で終わっていない場合,その動作は,未定義とする。空でないソース
ファイルが逆斜線に続く改行文字で終わっている場合,その動作は,未定義とする。
ソースファイルを,前処理字句(
) 及び 空白類( 注釈を含む。)の列に分解する。ソースファイルは,
部分的な前処理字句 又は 部分的な注釈で終わってはならない
。それぞれの注釈を,
個の空白文字に
置き換える。改行文字は,そのまま残す。改行文字以外の空白類の空でない列をそのまま残すか
個の空
白文字に置き換えるかは,処理系定義とする。ソースファイルの文字の列を前処理字句の列に分解してい
く処理は,文脈に依存する。
例
前処理指令
での
の扱いが参考になる。
前処理指令を実行し,マクロ呼出しを展開する。字句連結(
(
)の結果として国際文字名の構文に合
致する文字の列が生じた場合,その動作は,未定義とする。前処理指令
の実行では,そこで指
示されたヘッダ 又は ソースファイルに対して,それぞれ,
〜
の段階の処理を再帰的に行う。
#
文字リテラル 及び 文字列リテラルの中の,ソース文字集合の文字,逆斜線表記,及び 国際文字名それぞ
れを,実行文字集合(
及び
参照)の文字に変換する。
(
隣り合う( 通常の)文字列リテラルを連結する。隣り合うワイド 文字列リテラルを連結する。
)
この段階以降,字句を区切っている空白類は,意味をもたない。それぞれの前処理字句を字句に変換する
(
(
参照)
。この結果得られた字句の列を,構文解析 及び 意味解析をして翻訳する。
参考
ソースファイル( 翻訳前の )翻訳単位 及び 翻訳済みの翻訳単位を物理的なファイルとして
保持する必要はないし ,それぞれに
対
に対応する外部表現が必要なわけでもない。ここで
の規定は,概念上のものであって,具体的な実装を規定するものではない。
翻訳済み翻訳単位 及び 具現化単位
!
を結合する。
参考
これらの一部 又は 全部が,ライブラリの中にあることがある。
まず,それぞれの翻訳済み翻訳単位を調べ,必要な具現化の一覧表を作る。
参考
これには,明示的に要求されている具現化(
)
)も含まれる。
必要なテンプレートの定義を見つけ出す。このとき,これらの定義を含んだ翻訳単位のソースも必要であ
るかど うかは,処理系定義とする。
参考
処理系によっては,ここでソースを必要としないで済ますように,翻訳済み翻訳単位に十分
な情報を組み込んでいる。
注
処理系は,まるでこれらの段階を順に踏んでいるかのごとく振る舞わなければならないが,実際には,いくつかの段階を一緒にまとめ
て行ってもよい。
注
部分的な前処理字句は,例えば,
《ヘッダ名》にその終止文字
又は
がない場合など ,その終止文字列を必要とする複数文字からな
る字句がソースファイルの末尾に現れている場合に生じ うる。部分的な注釈は,閉じていない
注釈がソースファイルの末尾に現れて
いる場合に生じ うる。
必要な具現化すべてを行い,具現化単位を作り出す。
参考
これらは,翻訳済み翻訳単位と同等である。ただし ,具現化されていないテンプレートもテ
ンプレート定義も含んでいない。
*
外部オブジェクト 及び 外部関数への参照を解決する。ライブラリの構成要素を結合することで,その翻
訳の中に定義のない関数 及び オブジェクトの外部参照を解決する。こうして得られた翻訳出力を集め,実
行環境で実行するのに必要となる情報も添えて,実行形プログラムを作り出す。
文字集合
基本ソース文字集合
%!
!
!
の文字は,水平タブ ,垂直タブ ,改ページ文字 及
び 改行文字の四つの制御文字,空白文字,並びに 次に示す
個の図形文字の合計
文字とする。
$
6
"
7
#
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
5
J
K
.
L
+
*
M
/
-
,
N
O
P
Q
R
S
T
U
3
&
(
2
!
)
V
'
W
0
1
X
%
4
Y
Z
国際文字名
0
!
は,他の文字を指名するために用いる。
進四つ組
3
進数字
進数字
進数字
進数字
国際文字名
3
4
進四つ組
4G
進四つ組
進四つ組
国際文字名
4GAAAAAAAA
は,
6
!
での短縮名が
AAAAAAAA
である文字を指名する。国際文字名
4AAAA
は,
6
!
での短縮名が
....AAAA
である文字を指名する。国際文字名の
進値が
.+.
未満 若し くは
.,9
〜
.O9
である場合,又は 国際文字名が指名する文字が基本ソース文字集合の文字である場合,プログラムは不適格
とする。
基本実行文字集合
%!
?
!
及び 基本実行ワイド 文字集合
%!
?
<3-
!
は,それぞれ,基本ソース文字集合の文字すべて,警告文字・後退文字・復帰文字の三つの制御文字,及び す
べてゼロのビットからなる内部表現をもつナル文字
( 基本実行ワイド 文字集合ではナルワイド 文字
<3-
)を含む。それぞれの基本実行文字集合において,それぞれの文字は,非負の互いに異なる値を
もっていなければならない。基本ソース文字集合 及び 基本実行文字集合のそれぞれにおいて,上で掲げた表の
以
降のそれぞれの数字に対応する文字の値は,それの直前にある文字の値より
だけ大きくなければならない。実行文
字集合
?
!
は,基本実行文字集合をその部分集合とする文字集合とする。実行ワイド 文字集合
?
<3-
!
は,基本実行ワイド 文字集合をその部分集合とする文字集合とする。それぞれの実行
文字集合における文字の値は,処理系定義とする。それぞれの実行文字集合は,現地特性の文字を含んでいてもよい。
三つ組表示
他の処理に先立って,
表
に示すとおりに,特定の
文字の列を
個の文字に置き換える。これ
を三つ組表示
1
!A
と呼ぶ。
表
三つ組表示
三つ組
置換え
三つ組
置換え
三つ組
置換え
22%
22
S
22
22'
4
22
T
22
22Z
W
22[
1
22V
X
例
22%
2222
22[22[
2222
は,次に示すとおりに置き換わる。
ST
11
ST
三つ組表示は,
表
に示したものだけとする。三つ組表示を開始する
2
以外の
2
は,置き換えない。
注
ここでの基本ソース文字集合の文字の字形表示は,
文字集合に対応する
の部分文字集合の文字を意図してい
る。しかし,ソースファイルの文字から基本ソース文字集合の文字への変換( 翻訳過程の第
段)は処理系定義となっているから,それ
ぞれの処理系は,基本ソース文字集合の文字がソースファイルの上でどのように表現されるかを文書で示さなければならない。
*
前処理字句
前処理字句
3
ヘッダ名
識別子
前処理数
文字リテラル
文字列リテラル
前処理記号
これらのいずれにも当てはまらない単独の非空白類文字
それぞれの前処理字句は,字句(
(
)に変換したとき,キーワード,識別子,リテラル,演算子 又は 区切り子の
いずれかになっていなければならない。
前処理字句は,翻訳過程の第
〜
段における最小の字句要素とする。
《前処理字句》は,
《ヘッダ名》《識別子》,
《前処
理数》,
《文字リテラル》,
《文字列リテラル》《前処理記号》 及び これらに合致しない単一の《非空白類文字》のいずれ
かとする。文字
Z
又は
Y
が最後の分類に入る場合,その動作は,未定義とする。前処理字句は,空白類
<-!1
で区切られる。空白類は,注釈(
)
) 又は 空白類文字
<-!1
( 空白文字,水平タブ,改行文字,
垂直タブ 及び 改ページ文字)とする。空白類は,第
段までの翻訳過程において(それが現れていないことも含め )
前処理字句を分離する以上の働きをもつことがある(
(
参照)
。空白類は,ヘッダ名の一部として現れる場合,及び
文字リテラル 又は 文字列リテラルの引用符の中に現れる場合を除いて,前処理字句の部分となることがない。
ソース入力をある文字まで前処理字句に分割し終えた場合,次の前処理字句は,前処理字句のどれかに合致する最
長の文字の列とする。このとき,その先の字句解析が失敗するかど うかは考慮しない。
例 プログラム片
L8
は,
個の前処理字句( 字句としては,浮動小数点リテラルにも整数リテラルにもなら
ない。)として扱う。これを
L
と
8
とに分割すれば,正当な式( 例えば,
8
が
)L
に書き換わるマクロで
あった場合)になる可能性があるにもかかわらず,そうはしない。同様に,プログラム片
L8L
も,
8
がマク
ロ名であるかど うかによらず,
個の前処理字句( 字句としても正当な浮動小数点リテラル )として扱う。
例 プログラム片
)))))
は,
))
))
)
と分割する。これは,
及び
が組込みの型であったとすると,
増加演算子に関する制約に違反した式となる。
))
)
))
と分割すれば,正しい式となるが,そうはし
ない。
#
代替字句
幾つかの演算子 及び 区切り子に対して,代替字句
を設ける。
代替字句は,その綴り
の違いを除いて,言語のすべての面で,正規字句と完全に同等に振る舞う。代替字句は,
表
に示すとおりとする。
表
代替字句
代替
正規
代替
正規
代替
正規
U
00
0%
U
1
1%
3
S
11
W%
3
T
W
[
U3
X
[%
U3U3
0
(
字句
字句
3
識別子
キーワード
リテラル
演算子
注
代替字句には,
二つ組
及び 予約語がある。
二つ組
(
文字の組)という呼称は,必ずしも適切とはいえない。実際,前
処理字句の代替表現の一つに
があるし ,正規字句のいくつかも
文字の組となっている。それにもかかわらず,予約語ではない代
替字句は,
二つ組
と言い習わされている。
注
したがって,
と
とは,その
文字列化
値が相異なり,それぞれソース上での表現となる。しかし ,この違いを除けば,両者を
自在に置き換えることができる。
区切り子
《字句》は,
《識別子》,
《キーワード 》,
《リテラル》
,
《演算子》 及び 《区切り子》の
種類とする。空白文字,
水平タブ,垂直タブ,改行文字,改ページ文字 及び 注釈(これらをまとめて空白類と呼ぶ。)は,字句を分離する働
きだけをもつ。
参考
識別子,キーワード,数値リテラル 及び 英字を含んだ代替字句が隣接する場合,その間にそれらを分
離するための空白類が必要となる。
)
注釈
文字
'!
は,注釈を始める。この形の注釈は,
文字
!'
で終わり,入れ子にできない。
文字
''
も,
注釈を始める。この形の注釈は,次の改行文字で終わる。この形の注釈の中に改ページ文字 又は 垂直タブが現れる
場合,その後には,その注釈を終える改行文字までの間に空白類文字以外の文字が現れてはならない。ただし ,その
診断の必要はない。
参考
''
で始まる注釈の中で,
''
,
'!
及び
!'
は,特別の意味をもたず,他の文字と同様に扱われる。同様
に,
'!
で始まる注釈の中で,
''
及び
'!
は,特別な意味をもたない。
ヘッダ名
ヘッダ名
3
文字列
Y
A
文字列
Y
文字列
3
文字
文字列
文字
文字
3
改行文字 及び
を除くソース文字集合の文字
A
文字列
3
A
文字
A
文字列
A
文字
A
文字
3
改行文字 及び
Y
を除くソース文字集合の文字
前処理字句の《ヘッダ名》は,前処理指令
(
(
)の中にだけ現れることができる。それぞれの《ヘッ
ダ名》は,ヘッダ 又は ソースファイル名に変換する。その方法は,処理系定義とする。
文字
Z
若しくは
4
又は 文字の列
'!
若しくは
''
が《
A
文字列》 又は 《
文字列》に現れた場合,及び 文字
Y
が
《
文字列》に現れた場合,その動作は,未定義とする。
*
前処理数
前処理数
3
数字
(
数字
前処理数
数字
前処理数
非数字
前処理数
符号
前処理数
8
符号
前処理数
(
前処理数の字句は,字句要素の形として,整数リテラルの字句(
)及び 浮動小数点リテラルの字句(
)
をすべて包含する。
前処理数は,型も値ももたない。型 及び 値は,整数リテラル 又は 浮動小数点リテラルに変換し( 翻訳過程の第
段,
参照)終えてから付与する。
注
リテラルには,文字リテラル,文字列リテラル 及び 数値リテラルがある。
注
したがって,逆斜線表記に類似する文字列は,未定義の動作を引き起こす。
識別子
識別子
3
非数字
識別子
非数字
識別子
数字
非数字
3
次のいずれか
国際文字名
P
$
6
"
7
#
8
9
:
;
<
=
>
?
@
A
B
C
D
E
F
G
H
I
5
J
K
数字
3
次のいずれか
B
L
+
*
M
/
-
,
N
O
識別子は,その英字 及び 数字の列の長さに制限がない。国際文字名は,その
6
!
での符号化表現が
附
属書
に示すいずれかの範囲にある文字を指名していなければならない。大文字と小文字とを区別する。すべての文
字が意味をもつ。
さらに,識別子の幾つかは,
"##
処理系 及び 標準ライブラリでの用途に予約されている(
)
及び
参照)
ので,別の目的に用いてはならない。ただし ,その診断は,必要としない。
キーワード
表
に示す識別子は,キーワード として予約する( すなわち,翻訳過程の第
段で,常にキー
ワード として扱う。)
。
表
キーワード
$
さらに,演算子 及び 区切り子に対する
表
に示す代替表現(
#
)も,予約する。これらを別の目的に用いてはな
らない。
表
代替表現
注
リンカが拡張文字を受け付けないシステムでは,正当な外部識別子を構成するのに国際文字名を適当に符号化する必要がある。例えば,
国際文字名の
を他では使わない文字 又は 文字列に置き換える。この結果,拡張文字によって長大な外部識別子が生じることがある
が,
では,外部識別子の有効な長さについての翻訳限界を設けていない。
では,外部識別子を含めて,すべての識別子にお
いて大文字と小文字とを別の文字として扱う。
演算子 及び 区切り子
"##
プログラムの字句表現には,前処理での構文でも使い,字句の演算子 及び 区
切り子に変換しても使う,多くの前処理字句がある。
前処理記号
3
次のいずれか
S
T
3
3
U
U
U3
U3U3
&
3
(((
2
33
(
(!
)
V
!
'
U
W
0
1
X
[
%
)%
V%
!%
'%
U%
W%
0%
1%
%
%
%%
[%
%
%
00
11
))
VV
V!
V
P
P
P
P
それぞれの《前処理記号》は,翻訳過程の第
段で単一の字句に変換する(
参照)
。
リテラル
リテラルには,複数の種類がある。
リテラル
3
整数リテラル
文字リテラル
浮動小数点リテラル
文字列リテラル
真理値リテラル
整数リテラル
整数リテラル
3
進リテラル
整数接尾語
進リテラル
整数接尾語
進リテラル
整数接尾語
進リテラル
3
非零数字
進リテラル
数字
進リテラル
3
.
進リテラル
進数字
進リテラル
3
.
進数字
.5
進数字
進リテラル
進数字
非零数字
3
次のいずれか
L
+
*
M
/
-
,
N
O
進数字
3
次のいずれか
.
L
+
*
M
/
-
,
進数字
3
次のいずれか
.
L
+
*
M
/
-
,
N
O
注
この規格での
……リテラル
という用語は,
で
定数
と読んでいるものを表す。
6
"
7
#
8
9
整数接尾語
3
符号なし接尾語
倍長接尾語
倍長接尾語
符号なし接尾語
符号なし接尾語
3
次のいずれか
G
倍長接尾語
3
次のいずれか
?
整数リテラルは,数字の列からなり,小数点も指数部ももたない。整数リテラルには,その基数を示す先頭部分がつ
くこともあり,その型を指定する接尾語部分がつくこともある。数字列の最初の数字が最上位となる。
進
3
の整数リテラル( 基数が
)は,
.
以外の数字で始まる
進数字の列からなる。
進
の整数リテラル( 基数
が
)は,
.
で始まり
進数字の列が続く
。
進
?3
の整数リテラル( 基数が
)は,
.
又は
.5
で
始まり
進数字の列が続く。
進数字は,
進数字 及び
進値の
L.
から
L/
までを表す英字
〜
及び
6
〜
9
とする。
例
十二は,
L+
,
.LM
又は
.57
と書くことができる。
整数リテラルの型は,その形式,値 及び 接尾語部分によって決める。整数接尾語のつかない
進リテラルの場合,
その型は,
型,
型の順に見ていって,その値が表現可能な最初の型とする。値が
型でも表現で
きない場合,その動作は,未定義とする。整数接尾語のつかない
進リテラル 又は
進リテラルの場合,その型は,
型,
!3
型,
型,
!3
型の順に見ていって,その値が表現可能な最初の型とする。
整数接尾語が
又は
G
だけの場合,その型は,
!3
型,
!3
型の順に見ていって,その値が表
現可能な最初の型とする。整数接尾語が
又は
?
だけの場合,その型は,
型,
!3
型の順に見
ていって,その値が表現可能な最初の型とする。整数接尾語が
,
,
?
,
?
,
G
,
G
,
G?
又は
?G
の場合,その
型は,
!3
型とする。
許容されたど の型でも表現可能でない整数リテラルを含んだ翻訳単位がある場合,そのプログ ラムは,不適格と
する。
文字リテラル
文字リテラル
3
Z
文字列
Z
?
Z
文字列
Z
文字列
3
文字
文字列
文字
文字
3
一重引用符
Z
,逆斜線
4
及び 改行文字を除くソース文字集合の文字
逆斜線表記
国際文字名
逆斜線表記
3
単純逆斜線表記
進逆斜線表記
進逆斜線表記
単純逆斜線表記
3
次のいずれか
注
数字の
及び
は,
進数字でない。
4Z
4Y
42
44
4
4
4
4
4
4
4
進逆斜線表記
3
4
進数字
4
進数字
進数字
4
進数字
進数字
進数字
進逆斜線表記
3
4
進数字
進逆斜線表記
進数字
文字リテラルは,
文字 又は 複数文字を一重引用符でくくる( 例えば ,
ZZ
)。その前に英字
?
を置く( 例えば ,
?ZZ
)こともある。
?
を置かない通常の文字リテラルは,ナロー文字リテラルとも呼ばれる。
個の《
文字》をく
くった通常の文字リテラルは,
型をもち,その《
文字》の実行文字集合での符号数値に等しい値をもつ。
個
以上の《
文字》をくくった通常の文字リテラルを,多文字リテラル
という。多文字リテラ
ルは,
型をもつ。その値は,処理系定義とする。
文字
?
で始まる文字リテラル( 例えば ,
?ZZ
)を,ワイド 文字リテラルという。ワイド 文字リテラルは,
<
型
をもつ。
個の《
文字》をくくったワイド 文字リテラルは,その《
文字》の実行ワイド 文字集合での符号数
値に等しい値をもつ。
個以上の《
文字》をくくったワイド 文字リテラルの値は,処理系定義とする。
いくつかの非図形文字 並びに 一重引用符
Z
,二重引用符
Y
,疑問符
2
及び 逆斜線
4
は,
表
#
のとおりに表現す
ることができる。
表
#
逆斜線表記
名称
記号
表記
改行文字
A??9
4
水平タブ
;
4
垂直タブ
H
4
後退文字
"F
4
復帰文字
7E
4
改ページ文字
99
4
警告文字
"8?
4
逆斜線
4
44
疑問符
2
42
一重引用符
Z
4Z
二重引用符
Y
4Y
進数字
4
進数字
4
二重引用符
Y
及び 疑問符
2
は,それ自身を書いて表すことも,それぞれ《逆斜線表記》
4Y
及び
42
を書いて表
すこともできる。一重引用符
Z
及び 逆斜線
4
は,それぞれ逆斜線表記
4Z
及び
44
を書いて表すほかはない。
《単純
逆斜線表記》の逆斜線に続く文字が
表
#
に示したもの以外である場合,その動作は,未定義とする。
個の単純逆斜
線表記は,
個の文字を表す。
《
進逆斜線表記》
4
は,逆斜線に
個,
個 又は
個の
進数字を続け,その値の文字を指定する。
《
進
逆斜線表記》
4
は,逆斜線に
個以上の
進数字を続け,その値の文字を指定する。
進数字の個数に上限は
ない。
進数字の列 又は
進数字の列は,それぞれ,
進数字 又は
進数字でない文字が現れると終わる。文字
リテラルの値が,
型( 通常のリテラルの場合) 又は
<
型( ワイド 文字リテラルの場合)に対する処理系
定義の範囲に収まっていない場合,その動作は,未定義とする。
《国際文字名》は,それが指名している文字の,実行文字集合での符号数値に変換する。対応する符号数値が存在
しない場合,変換する先の数値は,処理系定義とする。
注
この型は,
バイトには収まらない文字からなる文字集合に用いることを意図している。
#
参考
翻訳過程の第
段では,ソース入力に拡張文字が現れると,それを国際文字名に置き換える。したがっ
て,すべての拡張文字は,国際文字名の形で扱うことになる。しかし ,同じ結果をもたらすなら,実際の
処理系は,独自の文字集合を使用して差し支えない。
浮動小数点リテラル
浮動小数点リテラル
3
小数点定数
指数部
浮動小数点接尾語
数字列
指数部
浮動小数点接尾語
小数点定数
3
数字列
(
数字列
数字列
(
指数部
3
符号
数字列
8
符号
数字列
符号
3
次のいずれか
)
V
数字列
3
数字
数字列
数字
浮動小数点接尾語
3
次のいずれか
9
?
浮動小数点リテラルは,整数部,小数点,小数部,
又は
8
,及び 必要に応じて符号を付けた整数の指数部からな
り,必要に応じて型を示す浮動小数点接尾語を置く。整数部 及び 小数部は,それぞれ,
進数字( 基数が
)の列
からなる。整数部 又は 小数部(の一方)は,省くことができる。小数点,又は
若し くは
8
及び それに続く指数
(の一方)は,省くことができる。整数部,省略可能な小数点 及び 省略可能な小数部は,その浮動小数点リテラルの
有効数値部
!>
1
となる。指数部は,もしあれば,有効数値部に乗じる
のべきを表す。乗じた値がその
型の表現可能な大きさの範囲内にある場合,結果は,それが表現可能な値であればその乗じた値とする。そうでなけ
れば ,その乗じた値に最も近い表現可能な値とする。このとき,小さいほうから最も近い値をとるか,大きいほうか
らとるかは,処理系定義とする。浮動小数点リテラルの型は,浮動小数点接尾語を置いて明示してない限り,
3 %
型とする。浮動小数点接尾語が
又は
9
である場合,その型は,
5
型とする。浮動小数点接尾語が
又は
?
であ
る場合,その型は,
3 %
型とする。指数部による
のべきを乗じた値がその型の表現可能な大きさの範囲内
にない場合,そのプログラムは,不適格とする。
文字列リテラル
文字列リテラル
3
Y
!
文字列
Y
?
Y
!
文字列
Y
!
文字列
3
!
文字
!
文字列
!
文字
!
文字
3
二重引用符
Y
,逆斜線
4
及び 改行文字を除くソース文字集合の文字
逆斜線表記
国際文字名
(
文字列リテラルは,文字の列(
で規定する。)を二重引用符でくくる( 例えば,
YE
E
E
Y
)
。その前に応じて英
字
?
を置く( 例えば,
?YE
E
E
Y
)こともある。
?
を置かない通常の文字列リテラルを,ナロー文字列リテラルとも呼ぶ。
通常の文字列リテラルは,
:
個の
の配列
;
型をもち,静的
!
記憶域期間(
)
)をもち,くくら
れた文字の列を初期値としてもつ。ここで,
は文字列の長さ( 後で規定する。)とする。文字
?
で始まる文字列リ
テラル( 例えば ,
?YY
)を,ワイド 文字列リテラルと呼ぶ。ワイド 文字列リテラルは,
:
個の
の配列
;
型をもち,静的記憶域期間(
)
)をもち,くくられた文字の列を初期値としてもつ。
それぞれの文字列リテラルを別々に置く( すなわち,重なりのないオブジェクトとして割り付ける)かど うかは,
処理系定義とする。
翻訳過程の第
段(
)で,隣り合うナロー文字列リテラルど うしを連結し ,隣り合うワイド 文字列リテラルど
うしを連結する。字句のナロー文字列リテラルとワイド 文字列リテラルとが隣り合う場合,その動作は,未定義とす
る。連結した文字列の中の文字は,それぞれ別々に扱う。
例
Y46Y
Y"Y
これを連結した後の文字列は,
個の文字
Z46Z
及び
Z"Z
からなる(
個の
進文字
Z46"Z
とはな
らない。)
。
必要な連結の後,翻訳過程の第
段(
)で,文字列を走査するプログラムがその終わりを検出できるように,す
べての文字列リテラルの終わりに
Z4.Z
を追加する。
文字列リテラルの中の,逆斜線表記 及び 国際文字名は,文字リテラル(
)の中と同じ意味をもつ。ただし,
一重引用符
Z
は,それ自身で表すことも逆斜線表記
4Z
で表すこともできるが,二重引用符
Y
には,
4
を前置しなけ
ればならない。ナロー文字列リテラルの中では,国際文字名が多バイト符号化
%
3
に従って複数の
文字要素に変換されることがある。ワイド 文字列リテラルの長さは,逆斜線表記,国際文字名 及び その他の文字の
総個数に,末尾に付加した
?Z4.Z
の分の
を加えた値とする。ナロー文字列リテラルの長さは,逆斜線表記 及び そ
の他の文字の総個数に,それぞれの国際文字名の多バイト符号化結果のバイト数( 少なくとも
)の総和,及び 末尾
に付加した
Z4.Z
の分の
を加えた値とする。
#
真理値リテラル
真理値リテラル
3
真理値リテラルとは,予約語の
及び
をいう。真理値リテラルの型は,
%
とする。真理値リテラル
は,左辺値をもたない。
基本概念
参考 ここでは,
"##
言語の基本概念を与える。オブジェクトと名前との違いを説明し ,それらが左辺値
0
とどのように関係しているかを説明する。宣言
3
及び 定義
3>
の概念を導入
し,
"##
での型
1
,有効範囲
!1
,結合
I
及び 記憶域期間
!
3
の概念を
提供する。プログラム実行の開始 及び 終了の機構を議論する。最後に,言語の基本型を説明し ,それら
から複合型
1
3
1
を構成する方法を列挙する。
ここでは,言語の特定部分だけに関係する概念は,扱わない。それらは,それぞれ,関係する箇条で扱う。
実体
には,値,オブジェクト,部分オブジェクト,基底クラス部分オブジェクト,配列要素,変数,関数,
関数インスタンス
!
,列挙子,型,クラスメンバ
!!
%
,テンプレート,及び 名前空間が
ある。
名前
は,実体 又は ラベル
%
(
((
及び
(
)を表す識別子(
)の挙用
!
をいう。変数
0
%
は,オブジェクトの宣言が作り出す。変数の名前は,そのオブジェクトを表す。
宣言
3
は,実体を表す名前をプログラムに導入する。ラベルを表す名前は,
文(
((
) 又は ラ
ベル付き文(
(
)がプログラムに導入する。
型,クラス,列挙体 又は テンプレートを表す名前もある。一般に,名前を含んだプログラムを構文解析するには,
名前がこれらの実体を表しているかど うかを調べる必要がある。この処理過程を,名前検索
I 1
(
)と
呼ぶ。
二つの名前は,次のいずれかの場合に等しいとする。
―
それらが同じ文字列からなる識別子である場合
)
―
それらが同じ演算子に対して利用者が多重定義した演算子関数の名前である場合
―
それらが同じ型に対して利用者が定義した変換関数の名前である場合
同じ識別子を複数の翻訳単位で使った場合,それぞれの翻訳単位で指定したその識別子の結合(
#
)にもよるが,
原則として,共通して同じ実体を表す。
宣言 及び 定義
宣言(
)
)は,翻訳単位に名前を導入したり,すでに宣言で導入されている名前を再宣言する。
宣言は,名前の解釈 及び 属性を指定する。
宣言は,次の場合を除いて,定義
3>
という。
―
関数本体(
)を指定せずに関数を宣言している場合
―
?
指定子(
)
) 又は 《結合指定》
(
)#
)を含んでいて,
《初期化子》も《関数本体》
(
)も
含んでいない場合
―
クラス宣言の中で静的データメンバ(
*
)を宣言している場合
―
型定義宣言(
)
)《
!
宣言》
(
)
) 又は 《
!
指令》
(
)
)の場合
例
次に示す宣言は,
個を除き,すべて定義となる。
&
''
を定義する。
%
L&
''
を定義する。
Q
)&
R
''
及び
を定義する。
F
Q
&
&
R
''
F
F33
及び
F33
を定義する。
5
Q
''
5
を定義する。
&
''
非静的なデータメンバ
を定義する。
&
''
静的なデータメンバ
を宣言する。
53
.
Q
R
''
5
のコンストラクタを定義する。
R&
533
%
L&
''
533
を定義する。
Q
R&
''
及び
を定義する。
A
Q
&
R
''
A
及び
A33
を定義する。
AL
%
A&
''
AL
を定義する。
5
5&
''
5
を定義する。
次に示す宣言は,定義とはならない。
&
''
を宣言する。
&
''
を宣言する。
&
''
を宣言する。
F&
''
F
を宣言する。
<&
''
<
を宣言する。
5
5&
''
5
を宣言する。
A33&
''
A33
を宣言する。
参考
状況によって,メンバ関数の,省略時コンストラクタ(
),コピーコンストラクタ(
),代入
演算子(
) 又は デストラクタ(
)を
"##
処理系が暗黙に定義することがある。
例
7
Q
&
''
標準ライブラリの
クラス(
+L(
参照)
R&
Q
7
&
7
%
&
%
&
R
この
7
に対して,処理系が必要な関数を暗黙に定義し ,次に示すのと同等な定義を与える。
7
Q
&
73
&
7
70
3
(
Q
R
70
%
70
Q
%
(&
!&
R
X7
Q
R
R&
注
宣言が《結合指定》の中の波括弧でくくった宣言列の内側にあっても,その宣言が定義であるかど うかには影響しない。
参考
クラス名は 《詳述型指定子》によって暗黙に宣言されることがある(
参照)
。
オブジェクトに対する定義が不完全型(
*
)のオブジェクトをもたらす場合,そのプログラムは,不適格とする。
単一定義規則
翻訳単位は,それぞれの変数,関数,クラス型,列挙型 又は テンプレートに対して,
個以上
の定義を含んでいてはならない。
式は,次のいずれかの場合を除いて,評価対象式
1
0
3
?1!!
という。
―
式が,汎整数定数式が必要な場所に書かれている。
―
式が,
!J
演算子(
#
)の演算対象となっている。
―
式が,
1
3
演算子の演算対象となっており,多相クラス型の左辺値を表していない。
オブジェクト 又は 非多重定義の関数は,その名前が評価対象式に現れていれば,挙用した
!3
という。仮想メン
バ関数は,それが純粋(
)でなければ,挙用したという。多重定義の関数は,評価対象式から参照されて多重定
義解決で選ばれれば ,挙用したという。
参考 この規定は,名前での関数呼出し(
#
),演算子多重定義(
),利用者定義の変換(
),位
置指定
<
式に対する割付け関数(
#
) 及び 省略時でない初期化(
#
)を網羅する。コピーコンス
トラクタは,その呼出しが処理系によって行われても,挙用したことになる。
クラスの割付け関数 又は 解放関数は,評価対象式の中の
<
式によっても挙用したことになる(
#
及び
#
参
照)
。クラスの解放関数は,評価対象式の中の
3
式によっても挙用したことになる(
##
及び
#
参照)
。クラ
スのコピー代入関数は,他のクラスに対して暗黙に定義されたコピー代入関数によっても挙用したことになる(
参照)
。クラスのコンストラクタの挙用は,
#
に規定する。クラスのデストラクタの挙用は,
に規定する。
プログラムには,そのプログラムで挙用したすべてのインラインでない関数 及び すべてのオブジェクトに対して,
ちょうど
個の定義がなければならない。この定義は,そのプログラムの中に直接含まれていてもよいし ,標準ライ
ブラリ 又は 利用者定義のライブラリにあってもよいし ,暗黙に定義されたもの(
,
及び
参照)であっ
てもよい。インライン関数は,挙用した翻訳単位ごとにちょうど
個の定義がなければならない。
クラスは,そのクラス型が完全であることを要求する形で挙用した場合,その挙用している翻訳単位の中にちょう
ど
個の定義がなければならない。
例
次の翻訳単位は,
5
の定義を含んでいないが,適格である。
5&
''
5
を構造型として宣言する。
5!
L&
''
5
をポインタ様式で挙用する。
5!
+&
''
5
をポインタ様式で挙用する。
参考
完全クラス型を要求する文脈については,宣言 及び 式に対する箇条で規定する。
次に示す場合には,クラス型
が完全であることを要求する。
―
型
のオブジェクトを定義する場合(
及び
#
参照)
―
型
のオブジェクトを参照する左辺値に対して,左辺値から右辺値への変換を行う場合(
参照)
―
式を型
に( 明示的にであれ暗黙にであれ )変換する場合(
,
#
,
#)
,
#*
及び
#
参照)
―
!
以外の型をもち,空ポインタ定数でない式を,暗黙の変換(
),動的キャスト(
#)
) 又は 静
的キャスト(
#*
)を用いて,
へのポインタ型 又は
への参照型に変換する場合
―
型
の式にクラスメンバアクセス関数を適用する場合(
##
参照)
―
型
の演算対象に
1
3
演算子(
#
) 又は
!J
演算子(
#
)を適用する場合
―
型
が返却値型 又は 実引数型である関数を定義する(
参照)場合 又は それを呼び出す場合(
#
参照)
―
型
の左辺値を代入する場合(
#)
参照)
クラス型(
*
),列挙型(
)
),外部結合をもつインライン関数(
)
),クラステンプレート(
),静的でない関
数テンプレート(
##
),クラステンプレートの静的なデータメンバ(
#
),クラステンプレート(
#
)
のメンバ関数,及び 指定のないテンプレート仮引数をもったテンプレート特殊化(
)
及び
#
参照)につい
ては,一つのプログラムの中に複数の定義があってもよい。ただし ,それぞれの定義が別々の翻訳単位にあり,しか
も,次に示す要件をすべて満たしていなければならない。
(ここで,複数の翻訳単位に定義がある実体の名前を
と
する。)
―
のそれぞれの定義は,字句の列として同じでなければならない。
―
のそれぞれの定義の中で,名前検索(
)の結果として互いに対応している名前は,
の定義の中で
定義された特定の実体,又は 多重定義の解決(
) 及び 部分テンプレート特殊化(
)の合致の
*
後での同一の実体を参照していなければならない。ただし ,名前が定値
!
オブジェクトを参照して
いて,内部結合 又は 結合なしである場合,そのオブジェクトが,
のすべての定義において同じ汎整数
型 又は 列挙型であり,定数式(
#*
)によって初期化されていて,その値( 番地ではなく)を挙用して
いるだけであり,しかもその値が
のすべての定義において等しいならば,この限りでない。
―
のそれぞれの定義の中で,参照されている多重定義の演算子,変換関数の暗黙の呼出し ,コンストラク
タ,
1
<
関数,及び
1
3
関数は,同じ関数 又は
の定義の中で定義された関数を参
照していなければならない。
―
のそれぞれの定義の中で,関数の( 明示的にであれ暗黙にであれ )呼出しの省略時実引数は,その字句
列が
の定義の中に現れたものとして扱う。すなわち,省略時実引数も,上に示した三つの要件を満たし
ていなければならない( 省略時実引数の部分式に省略時実引数が現れる場合には,それらに対しても再帰
的にこれらの要件を課す。)
。
―
が暗黙に宣言されたコンストラクタ(
)をもつクラスである場合,そのコンストラクタは,挙用し
ているそれぞれの翻訳単位で暗黙に定義されているものとして扱う。このそれぞれの翻訳単位での暗黙の
定義は,基底クラス 又は
のクラスメンバに対する同一のコンストラクタを呼び出さなければならない。
例
''
翻訳単位
L3
5
Q
5&
5
&
R&
5335
%
.
Q
R
#3
5
Q
R&
#
+&
''
#
は,
5
を呼び出す。
''
翻訳単位
+3
5
Q
5&
5
&
R&
5335
%
.
%
.
Q
R
#3
5
Q
R&
''
#
は,
5
を呼び出す。
''
#
の暗黙の定義は,単一定義規則に反している。
がテンプレートであり,複数の翻訳単位に定義がある場合,上に示した最後の四つの要件は,テンプレートを囲む
有効範囲の中からそのテンプレート定義で挙用した名前,及び 具現化点での依存する名前に適用する。
がこれら
すべての要件を満たす場合,プログラムは,
の定義が唯一つあるかのように振る舞う。要件を満たしていない場合,
その動作は,未定義とする。
宣言領域 及び 有効範囲
名前を導入する際にプログラム上で対象とする部分を,宣言領域
30
と呼ぶ。宣言領域は,その名前が正当
0
3
である最大の範囲を構成する。ここで,名前が正当であるとは,その
名前を修飾なしで使ってその同じ実体が参照できることをいう。一般に,特定の名前は,必ずしも一連なりにはなっ
ていないプログラム上の部分でだけ正当となる。こうした部分を,有効範囲
!1
と呼ぶ。宣言の有効範囲を規定
するのに,宣言の潜在有効範囲
1
!1
という概念を用いる。宣言の有効範囲は,その潜在有効範囲内に同
じ名前に対する宣言が他になければ ,潜在有効範囲に等しい。他の宣言がある場合,外側の( 包含している)宣言領
域にある宣言の有効範囲は,内側の( 包含される)宣言領域にある宣言の潜在有効範囲を除いたものとなる。
例
%
+M&
Q
%
&
%
M+&
R
識別子
は,
箇所で宣言して( さらに,
箇所で挙用して )いる。最初の
の宣言領域は,この例全体
となる。最初の
の潜在有効範囲は,最初の
の直後から始まり,このプログラムの終わりまで続く。し
注
省略時実引数の名前検索については,
で規定する。
かし ,その( 実際の)有効範囲は,
から
までを除いたものとなる。
の第
の宣言(
&
の直前にある
)の宣言領域は,
から
までの部分となる。しかし,その潜在有効範囲には,
の宣言が含まれない。
の第
の宣言の有効範囲は,その潜在有効範囲に等しい。
宣言は,そこで宣言している名前を,その宣言が現れている有効範囲に導入する。ただし,
3
指定子(
),
《詳述型指定子》
(
) 及び 《
!
指令》
(
)
)によってこの原則が外れることがある。
単一の宣言領域にあって,同じ修飾なしの名前を対象としている複数の宣言については,次の制約がある。
―
すべての宣言が同じ実体を参照しているか,すべての宣言が関数 又は 関数テンプレートを参照している
かでなければならない。
―
その中の一つの宣言だけが,型定義名でないクラス名 又は 列挙体名を宣言していて,しかも,他の宣言
がすべてその同じクラス 又は 列挙子を参照しているか,関数 又は 関数テンプレートを参照しているかで
なければならない。この場合,そのクラス名 又は 列挙体名は,隠ぺい状態(
)
)となる。
参考
名前空間名 又は クラステンプレート名は,宣言領域の中で唯一となっていなければならな
い(
)
及び
参照)
。
参考 これらの制約は,名前を導入する対象の宣言領域に適用する。この宣言領域は,宣言が現れている領域
と必ずしも一致しない。特に 《詳述型指定子》
(
) 及び 随伴宣言(
)は,それを囲んでいる名
前空間に名前( 可視でなくてもよい。)を導入することがある。こうした場合,これらの制約は,その名
前空間に適用される。局所的な
?
宣言(
#
)は,その宣言のある宣言領域に名前を導入するととも
に,それを囲んでいる名前空間にも名前( 可視でなくてもよい。)を導入することがある。こうした場合,
これらの制約は,この二つの領域ともに適用される。
参考
名前検索については,
に規定する。
宣言位置
名前の宣言位置
1
3
は,原則として,その完全な《宣言子》
(
)の直後であっ
て,その《初期化子》
( もしあれば )の直前をいう。
例
%
L+&
Q
%
&
R
この
番目の
は,自分自身の( 定まらない)値を使って初期化を行っている。
参考
局所的でない名前は,それを隠ぺいする局所的な名前の宣言位置まで可視のままでいる。
例
%
+&
Q
ST&
R
この宣言は,
個の整数からなる配列を宣言する。
列挙子の宣言位置は,その《列挙子定義》の直後とする。
例
%
L+&
Q
Q
%
R&
R
列挙子
は,定数
の値,すなわち
を使って初期化している。
クラスメンバは,その宣言位置の後で,そのクラスの有効範囲内で名前検索することができる。
参考 これは,そのクラスが不完全クラスであっても成り立つ。
例
5
Q
8
Q
$
%
L-
R&
S533$T&
''
B>
R
《詳述型指定子》を使って最初に宣言したクラスの宣言位置は,次のとおりとする。
―
:
《クラスキー》 《識別子》
&;
の形をした《詳述型指定子》の場合,この《詳述型指定子》は,その《識
別子》を,この宣言を含む有効範囲の中でのクラス名として宣言する。
―
:
《クラスキー》 《識別子》
;
の形をした《詳述型指定子》の場合,この《詳述型指定子》が,名前空間
有効範囲で定義される関数の《宣言指定子列》 又は 《仮引数宣言節》の中に現れているとき,この《詳
述型指定子》は,その《識別子》を,その宣言を含む名前空間での《クラス名》として宣言する。そうで
ない場合,随伴宣言でない限り,その《識別子》を,その宣言を含む最小の( クラスでも関数原型でもな
い)有効範囲内に宣言する。
参考
この《詳述型指定子》が列挙体を指している場合,その《識別子》は,すでに宣言してある
《列挙体名》を参照していなければならない。この《詳述型指定子》の《識別子》が《修飾付き
識別子》である場合,その《識別子》は,すでに宣言してある《クラス名》 又は 《列挙体名》
を参照していなければならない(
参照)
。
参考
随伴宣言は,それを囲む最小の名前空間のメンバとなっている関数 又は クラスを参照しはするが,その
名前空間に新しい名前を導入しはしない(
)
参照)
。ブロック有効範囲での,関数宣言 及び
?
指定子付きのオブジェクト宣言は,それを囲む名前空間のメンバを参照するだけで,その有効範囲に新し
い名前を導入しはしない。
参考 テンプレートの具現化位置については,
(
で規定する。
局所的な有効範囲
ブロック(
(
)内に宣言した名前は,そのブロックに局所的
であるという。そ
の潜在有効範囲は,その宣言位置(
)から始まり,その宣言領域の終わりまでとする。
関数定義(
)内の関数仮引数名の潜在有効範囲は,その宣言位置から始まる。その関数に《関数監視ブロック》
がある場合,潜在有効範囲は,それに付随する最後のハンド ラの終わりまで広がる。そうでない場合,その関数宣言
の最外側のブロックの終わりまで広がる。仮引数名は,その関数宣言の最外側のブロックでも 《関数監視ブロック》
に付随するハンド ラの最外側のブロックでも,再宣言してはならない。
例外宣言の中の名前は,そのハンド ラに局所的であるという。この名前は,その処理部の最外側のブロック
で再宣言してはならない。
《
初期化文》の中 並びに
文,
<
文,
文 及び
!<
文の《条件》の中で宣言した名前は,その
文,
<
文,
文 及び
!<
文(その本体となっている文も含む。)に局所的であるという。これらの名前は,その文
の以後の条件 及び その本体となっている文の最外側のブロック(
文にあっては,すべての最外側のブ ロック)で
再宣言してはならない(
(
参照)
。
関数原型有効範囲
関数宣言の中の仮引数の名前,又は 関数定義の宣言子ではない関数宣言子の中の仮引数
の名前( もしあれば )は,関数原型有効範囲をもつ。関数原型有効範囲は,それを囲む最小の関数宣言子の終わりま
で広がる。
関数有効範囲
ラベル(
(
)は,関数有効範囲をもつ。ラベルは,それが宣言してある関数の中であればど
こででも使うことができる。ラベルだけが,関数有効範囲をもつ。
#
名前空間有効範囲 《名前空間定義》の宣言領域は,その《名前空間本体》とする。
《原名前空間名》が表す潜
在有効範囲は,その《原名前空間名》をもった元の宣言領域の中に現れるそれぞれの《名前空間定義》の宣言領域を
連結したものとなる。
《名前空間本体》の中で宣言した実体を,その名前空間のメンバ
%
という。これらの
宣言がその名前空間の宣言領域に導入する名前を,その名前空間のメンバ名という。名前空間メンバ名は,名前空間
有効範囲をもつ。その潜在有効範囲には,その名前空間内の,その メンバの名前の宣言位置以降の部分が含まれる。
メンバの名前空間を指定した《
!
指令》
(
)
)それぞれに対して,そのメンバの潜在有効範囲には,そのメン
バの宣言位置に続くその《
!
指令》の,潜在有効範囲の部分が含まれる。
例
A
Q
&
Q
&
R
&
&
R
Q
%L&
R
''
の潜在有効範囲は,その宣言位置から
''
翻訳単位の終わりまでとなる。
A
Q
''
A33
を多重定義している。
Q
)&
''
は,名前なし名前空間にある。
R
&
''
誤り
3
二重定義
&
''
B>3
関数宣言の重複
''
B>3
A33
の定義
Q
&
''
A33
の呼出し
R
&
''
誤り
3
返却値型が違う。
R
名前空間のメンバは,その名前空間の名前 又は 《
!
指令》の中でそのメンバの名前空間を指名した名前空間の
名前に続く有効範囲解決演算子
33
(
#
)の後でも参照することができる(
参照)
。
翻訳単位の最外側の宣言領域も名前空間となり,大域的名前空間
%
!1
と呼ぶ。大域的名前空間で宣
言された名前は,大域的名前空間有効範囲( 大域的有効範囲ともいう。)をもつ。こうした名前の潜在有効範囲は,そ
の宣言位置(
)に始まり,その宣言領域である翻訳単位の終わりで終わる。大域的名前空間有効範囲をもつ名前
を,大域的
%
であるという。
(
クラス有効範囲
クラスの中で宣言した名前の有効範囲は,次の原則による。
クラスの中で宣言した名前の潜在有効範囲は,その名前の宣言子に続く宣言領域に加えて,そのクラスの
中( 入れ子になったクラスの中も含む。)の,すべての関数本体,省略時実引数 及び 《コンストラクタ初
期化子》を含む。
クラス
の中で挙用している名前
は,その文脈においても,再評価の際の
の完全な有効範囲におい
ても,同じ宣言を参照していなければならない。この規則に対する違反については,診断の必要はない。
クラスの中でそのメンバの宣言を並べ替えると,上の
) 及び
)の下で別の正当なプログラムとなる場
合,プログラムは,不適格とする。診断の必要はない。
メンバ関数の中で宣言した名前は,同じ名前に対する宣言で,その有効範囲がそのメンバ関数のクラスの
終わりまで 又は それ以上に広がっているものを隠ぺいする。
#
クラス定義の終わりまで広がる潜在有効範囲をもつ宣言は,その( クラスの)メンバ定義の宣言領域まで
もその潜在有効範囲に含む。これは,これらのメンバの定義が字句の列としてそのクラスの中にない場合
[静的データメンバ定義,入れ子になったクラス定義,メンバ関数定義(その関数本体も含む。コンストラ
クタ関数(
)の場合は 《コンストラクタ初期化子》
(
(
)も含む。)など ]にも成り立つ。更に,
その識別子に続くこれらの定義の宣言子の部分すべても 《仮引数宣言節》 及び すべての省略時実引数を
含めて,その潜在有効範囲に含む。
例
&
Q
%
L
R&
5
Q
ST&
''
誤り
3
は
33
を参照している。
''
再評価すると
533
を参照する。
Q
$&
R
''
B>3
533
&
Q
%
+
R&
R&
!
&
J
Q
&
''
誤り
3
は
33
を参照している。
''
再評価すると
J33
を参照する。
&
&
R&
<&
#
Q
<
<&
''
誤り
3
並べ替えが生じないにもかかわらず誤り。
R&
クラスメンバの名前は,次の場合にだけ挙用することができる。
―
そのクラス 又は そのクラスから派生したクラス(
)の有効範囲の中
―
そのクラス 又は そのクラスから派生したクラスの型をもつ式を演算対象とする演算子
(
(
##
)の直後
―
そのクラス 又は そのクラスから派生したクラスのオブジェクトへのポインタを演算対象とする演算子
V
(
##
)の直後
―
そのクラス 又は そのクラスから派生したクラスの名前を演算対象とする有効範囲解決演算子
33
(
#
)
の直後
)
名前の隠ぺい
名前は,入れ子になった宣言領域 又は 派生クラスの中で,それと同じ名前を明示的に宣言す
ると隠ぺい
3
することができる(
参照)
。
クラス名(
*
) 又は 列挙体名(
)
)は,同じ有効範囲の中で,同じ名前をオブジェクト,関数 又は 列挙子とし
て宣言すると隠ぺいすることができる。クラス名 又は 列挙体名と,オブジェクト,関数 又は 列挙子とが,同じ有効
範囲の中で( 順序を問わない。)宣言してある場合,そのクラス名 又は 列挙体名は,オブジェクト名,関数名 又は
列挙子名が可視である場所では常に隠ぺいされる。
メンバ関数定義の中で,局所的な名前の宣言は,そのクラスの同じ 名前をもつメンバの宣言を隠ぺいする(
(
参照)
。派生クラス(
)の中でのメンバの宣言は,基底クラスの同じ名前をもつメンバの宣言を隠ぺいする(
参照)
。
名前空間名で修飾した名前の名前検索において《
!
指令》によって可視にしようとした宣言も,その《
!
指
令》を含む名前空間の中の同じ名前に対する宣言によって隠ぺいされることがある(
参照)
。
名前は,有効範囲の中にあって隠ぺいされていないとき,可視
0!%
であるという。
名前検索
名前検索の規則は,文法がその文脈での名前の出現を許している限り,すべての名前[《型定義名》
(
)
)《名前空間名》
(
)
) 及び 《クラス名》
(
*
)を含む。]に対して一様に適用する。名前検索は,名前の
挙用をその名前の宣言(
)に結びつける。名前検索は,原則として,その名前に一意な宣言を結びつける。ただ
し ,その名前が関数名である場合は,複数の宣言を結びつけることがある。このとき,これらの宣言は,多重定義関
数(
)をなすと呼ぶ。多重定義解決(
)は,名前検索が成功してから行う。アクセス規則(
)は,名前
検索 及び 多重定義解決( 適用できるなら )が成功してはじめて適用する。名前検索,関数の多重定義解決( 適用で
きるなら ) 及び アクセス検査がすべて成功してはじめて,その名前の宣言から得た属性を用いて,その後の式の処
理(
#
)を行う。
式が現れた有効範囲の中で修飾なしの名前に対して名前検索を行うことを,
:
式の文脈での名前検索
;
と呼ぶ。
クラス(
*
)の補正クラス名も,名前の隠ぺい 及び 名前検索においては,そのクラスのメンバとして扱う。
参考
結合については,
#
で規定する。有効範囲,宣言位置 及び 名前の隠ぺいについては,
で規定する。
修飾なし名前の名前検索 ここでの名前検索は,いずれも,それぞれの分類ごとに示した順に有効範囲を調べ
ていって宣言を見つけ出す。名前に対する宣言が見つかった時点で,名前検索が終了する。宣言が見つからない場合,
そのプログラムは,不適格とする。
《
!
宣言》があると,その《
!
宣言》を囲む名前空間の中では,その《
!
宣言》で指名した名前空間の
宣言が可視となる(
)
参照)
。ここでの修飾なし名前の名前検索の規定においては 《
!
宣言》で示した名前空
間の宣言もこの囲む名前空間のメンバとして扱う。
関数呼出しとしての《後置式》で挙用している修飾なし名前の名前検索は,
で規定する。
参考 ( 構文解析の中での)式が関数呼出しとしての《後置式》であるかど うかの判定には,通常の名前検索
規則を適用する。
の規則は,式の構文上の解釈には影響しない。
例
&
6
Q
6
0&
&
6
Q
&
R
R&
式
は,
と同等な《キャスト式》となる。この式が関数呼出しではないことか
ら,実引数依存の名前検索(
)が適用されることはなく,したがって,随伴関数
を見つ
け出すこともない。
関数,クラス 及び 利用者宣言の名前空間の外側にある大域的有効範囲の中で挙用している名前は,その大域的有
効範囲の中で挙用に先立って宣言していなければならない。
関数定義 及び クラス定義の外側にある利用者宣言の名前空間の中で挙用している名前は,その名前空間の中 又は
その名前空間を囲む名前空間の中で挙用に先立って宣言していなければならない。
名前空間
(ここでは,
に大域的有効範囲も含めて考える。)のメンバである関数の《宣言子識別子》の後に現
れる関数定義の中で挙用している名前
は,次のいずれかでなければならない。
注
関数の《宣言子識別子》に続く修飾なしの名前を指す。こうした名前には 《仮引数宣言節》の中の型 若しくは 省略時実引数の名前,
又は 関数本体の中で挙用している名前がある。
―
挙用に先立って,挙用しているブロックの中 又は それを囲むブロック(
(
)の一つの中で宣言してある。
―
挙用に先立って,名前空間
の中で宣言してある。
―
が入れ子の名前空間である場合,挙用に先立って,
を囲む名前空間の一つの中で宣言してある。
例
6
Q
A
Q
&
R
R
633A33
Q
%
/&
''
の宣言を探すのには次の有効範囲を順に見ていく
''
L
633A33
の最外側のブロック有効範囲,挙用の前だけ
''
+
名前空間
A
の有効範囲
''
*
名前空間
6
の有効範囲
''
M
大域的有効範囲,
633A33
の定義の前だけ
R
クラス
の定義が,メンバ関数の本体の外側 又は 入れ子になったクラス定義の外側にある場合,その定義の中で
挙用している名前
は,次のいずれかを満たしていなければならない。
―
その挙用に先立ってクラス
の中で宣言してあるか,
の基底クラス(
)のメンバとして宣言して
ある。
―
がクラス
に入れ子になっている(
*)
)場合,
の中での
の定義に先立って宣言してあるか,
の
基底クラスのメンバとして宣言してある(この検索は,
を囲んでいるクラスにも最内側のものから順に
適用する。
―
が局所クラス(
*
)である場合,又は
が局所クラスに入れ子になったクラスである場合,クラス
の定義に先立って,その定義を囲んでいるブロックで宣言してある。
―
が名前空間
のメンバである場合,
が名前空間
のメンバであるクラスに入れ子になったクラスで
ある場合,又は 名前空間
のメンバである関数に局所クラスの中で,
が局所クラス 又は 入れ子になっ
たクラスである場合,クラス
の定義に先立って,名前空間
の中 又は
を囲む名前空間の一つの中
で宣言してある。
例
@
Q
"
Q
R&
R
A
Q
J
3
@33"
Q
5
Q
ST&
R&
R&
R
''
に対する宣言を探しに,次の範囲を順に調べる
''
L
クラス
A33J335
の中,
の挙用の前だけ
''
+
クラス
A33J
の中,
A33J335
の定義の前だけ
''
*
A33J
の基底クラスである
@33"
の中
''
M
名前空間
A
の中,
A33J
の定義の前だけ
''
/
大域的有効範囲,
A
の定義の前だけ
参考
随伴宣言が導入したクラス 又は 関数の宣言を検索する場合,囲んでいる最内側の名前空間有効範囲の
外側にある有効範囲は,対象としない(
)
参照)
。
参考
クラスの定義の中で挙用している名前に対する制約は,
(
で規定する。入れ子になったクラスの定
義の中で挙用している名前に対する制約は,
*)
で規定する。局所クラスの定義の中で挙用している名前
に対する制約は,
*
で規定する。
クラス
のメンバ関数(
*
)の定義の中で,関数の《宣言子識別子》の後に挙用している名前
は,次のい
ずれかを満たしていなければならない。
注
これは,その《クラス名》に続く修飾のない名前を指す。こうした名前の挙用は 《基底節》の中 又は クラス定義の中で生じる。
注
この検索は,
の定義が
の定義の中に入れ子になっている場合にも,
の定義が,
の定義を囲む名前空間の中に現れている場合
(
参照)にも,適用する。
注
これは,例えば,次の中に現れる修飾なしの名前を指す。
#
―
名前
は,その挙用に先立って,挙用しているブロック(
(
)の中 又は それを囲んでいるブロックの一
つの中で,宣言してある。
―
名前
は,クラス
のメンバ 又は
の基底クラスのメンバとなっている(
参照)
。
―
がクラス
に入れ子になったクラス(
*)
)である場合,名前
は,クラス
又は
の基底クラスの
メンバとなっている(この検索は,
を囲んでいるクラスにも,内側から順に適用する。
―
が局所クラス(
*
) 又は 局所クラスに入れ子になったクラスである場合,名前
は,クラス
の定
義に先立って,それを囲んでいるブロックの中で宣言してある。
―
が名前空間
のメンバである場合,
が名前空間
のメンバであるクラスに入れ子になったクラスで
ある場合,又は 名前空間
のメンバである関数に局所クラスの中で,
が局所クラス 又は 入れ子になっ
たクラスである場合,名前
は,そのメンバ関数の定義に先立って,名前空間
の中 又は
を囲む名
前空間の一つの中で宣言してある。
例
"
Q
R&
@
Q
A
Q
5
3
"
Q
&
R&
R
R
@33A33533
Q
%
L-&
R
''
の宣言を探して,次の有効範囲を順に調べる。
''
L
@33A33533
の最外側のブロック有効範囲,
の挙用の前だけ
''
+
クラス
@33A335
の有効範囲
''
*
@33A335
の基底クラス
"
の有効範囲
''
M
名前空間
@33A
の有効範囲
''
/
名前空間
@
の有効範囲
''
-
大域的有効範囲,
@33A33533
の定義の前だけ
参考
メンバ関数の定義の中で挙用する名前に対する制約は,
*
及び
*
で規定する。入れ子になったクラ
スの有効範囲の中で挙用する名前に対する制約は,
*)
で規定する。局所的クラスの定義の中で挙用する
名前に対する制約は,
*
で規定する。
随伴性を与えるクラスの中の,インライン関数としての随伴関数(
)の定義の中で挙用している名前に対する
名前検索は,メンバ関数の定義の中での名前に対する名前検索と同様に行う。随伴関数が随伴性を与えるクラスの中
で定義してあるのでなければ ,その随伴関数の定義の中での名前に対する名前検索は,名前空間のメンバ関数の定義
の中での名前に対する名前検索と同様に行う。
メンバ関数を指す随伴宣言の中で,関数宣言子の中で挙用していて《テンプレート識別子》の《テンプレート実引
数》の一部となっていない名前は,まず,そのメンバ関数のクラスの中で検索する。そこで見つからない場合,又は
その名前が《テンプレート識別子》の《テンプレート実引数》の一部である場合,検索は,随伴性を与えているクラ
スの定義の中での修飾のない名前に対する検索と同様に行う。
例
6
Q
6&
L6&
+&
R&
"
Q
"&
633L6&
''
仮引数の型は
6336
となる。
633+"&
''
仮引数の型は
"33"
となる。
R&
―
《仮引数宣言節》の中の型 又は 省略時実引数式の中
―
その関数本体の中
―
コンストラクタ定義の中の《メンバ初期化子》の式の中
注
メンバ関数がクラス
の定義の中で定義してあるか,メンバ関数がクラス
の定義を囲む名前空間有効範囲の中で定義してある場合
に,この名前検索を適用する。
(
関数の《仮引数宣言節》の中の省略時実引数(
(
)として挙用している名前,又は コンストラクタに対する《メ
ンバ初期化子》
(
(
)の《式》の中で挙用している名前 に対する名前検索の途中では,その関数の仮引数名は可
視とし ,その関数宣言を囲むブロック,クラス 又は 名前空間の有効範囲で宣言してある実体の名前を隠ぺいする。
参考
省略時実引数の中で挙用している名前に対する制約は,
(
で規定する。
《コンストラクタ初期化子》
の中で挙用している名前に対する制約は,
(
で規定する。
クラス
の静的データメンバの定義の中で( その静的メンバの《修飾付き識別子》の直後に )挙用している名前
(
*
)は,その名前が
のメンバ関数の中で挙用してある場合と同様の検索を行う。
参考
静的データメンバの定義の中で挙用している名前に対する制約は,
*
で規定する。
《関数監視ブロック》のハンド ラ(
#
)の中で挙用している名前は,その名前がその関数定義の最外側のブロッ
クで挙用してある場合と同様の検索を行う。特に,その関数の仮引数名は 《例外宣言》の中,及び その《関数監視ブ
ロック》のハンド ラの最外側のブロックの中で再宣言してはならない。関数定義の最外側のブロックの中で宣言して
ある名前は 《関数監視ブロック》のハンド ラの有効範囲に対する検索の対象とはしない。
参考 しかし,その関数の仮引数名は,検索の対象となる。
参考 テンプレート定義の中での名前検索は,
(
で規定する。
実引数依存の名前検索
関数呼出し(
#
)の《後置式》として挙用している修飾のない名前に対する名前
検索では,通常の修飾のない名前に対する名前検索(
)で対象としない名前空間も対象とすることがあり,可視
でない名前空間有効範囲の随伴関数宣言(
)も見つけ出すことがある。検索方法に対するこれらの変更は,その
実引数の型(テンプレートの《テンプレート実引数》では,その《テンプレート実引数》の名前空間)に依存する。
関数呼出しの実引数の型
に対して,それぞれ,
個以上の関連名前空間 及び
個以上の関連クラスを定める。全
体の関連名前空間 及び 関連クラスは,すべての実引数の型に対するもの( 及び テンプレートのそれぞれの《テンプ
レート実引数》の名前空間)の総体として定める。このとき,型を指定するのに用いている 型定義名 及び 《
!
宣
言》は,考慮しない。
に対する関連名前空間 及び 関連クラスは,次のとおりとする。
―
が基本型の場合,関連名前空間 及び 関連クラスは,なしとする。
―
がクラス型( 共用型を含む。)の場合,関連クラスは,そのクラスそのもの 並びに その直接 及び 間接
の基底クラスとする。関連名前空間は,関連クラスが定義してあるそれぞれの名前空間とする。
―
が列挙型の場合,関連名前空間は,その型が定義してある名前空間とする。関連クラスは,
がクラス
メンバのときそのメンバのクラスとし,それ以外のとき,なしとする。
―
が型
へのポインタ 又は 型
の配列の場合,
の関連名前空間 及び 関連クラスは,それぞれ,
の
関連名前空間 及び
の関連クラスとする。
―
が関数型の場合,関連名前空間 及び 関連クラスは,それぞれ,その関数の実引数型 及び 返却値型の,
関連名前空間 及び 関連クラスの総体とする。
―
がクラス
のメンバ関数へのポインタの場合,
の関連名前空間 及び 関連クラスは,その関数の実引
数型 及び 返却値型の,関連名前空間 及び 関連クラス 並びに
の関連名前空間 及び 関連クラスの総体
とする。
―
がクラス
のデータメンバへのポインタの場合,
の関連名前空間 及び 関連クラスは,それぞれ,そ
のデータメンバの型 及び
の,関連名前空間 及び 関連クラスとする。
―
が《テンプレート識別子》の場合,関連名前空間 及び 関連クラスは,そのテンプレートが定義してあ
る名前空間,メンバテンプレートであるときはそのメンバテンプレートのクラス,テンプレートの型仮引
数( テンプレートのテンプレート仮引数は除く。)に対する《テンプレート実引数》の型それぞれの関連
名前空間 及び 関連クラス,並びに テンプレートの《テンプレート実引数》として挙用しているメンバテ
ンプレートが定義してあるクラスの総体とする。
参考
テンプレートの実引数であっても型実引数でなければ ,関連名前空間には関与しない。
更に,その実引数が,多重定義された関数 及び/又は 関数テンプレートの集合に対する,名前 又は アドレ スの場
合,その実引数の関連名前空間 及び 関連クラスは,その集合の個々の構成員の関連名前空間 及び 関連クラス(すな
わち,関数 又は 関数テンプレートが定義されている名前空間 並びに 非依存の仮引数の型 及び 返却値の型の関連名
前空間)の総体とする。
修飾のない名前に対する通常の名前検索でクラスのメンバ関数が見つかった場合,関連名前空間 及び 関連クラス
は,用いない。そうでない場合,関数名に対する名前検索では,通常の名前検索で見つかった宣言に加えて,関連名
前空間 及び 関連クラスの中で見つかる宣言も合わせて検索の対象とする。
)
参考
実引数の型の関連名前空間 及び 関連クラスには,通常の修飾なし名前の名前検索ですでに検索対象と
した名前空間 及び クラスを含む。
例
AF
Q
Q
R&
&
R
AF33
&
Q
&
''
B>3
AF33
を呼び出す。
R
関連名前空間の中での検索は,その関連名前空間が修飾子(
)となっている場合の名前検索と同様に行う。
ただし ,次の特例をおく。
―
その関連名前空間の中の《
!
指令》は,すべて無視する。
―
関連名前空間の中で宣言してある名前空間有効範囲の随伴関数は,通常の名前検索において可視でないと
しても,それぞれの関連名前空間の中で可視として扱う(
参照)
。
修飾付き名前の名前検索
クラスメンバ 又は 名前空間メンバの名前は,そのクラス 又は 名前空間を指名す
る《入れ子名前指定子》に続く有効範囲解決演算子
33
(
#
)の直後でも参照することができる。有効範囲解決演算
子
33
に先立つ名前についての名前検索では,オブジェクト,関数 及び 列挙子の名前を無視する。見つかった名前
が《クラス名》
(
*
) 又は 《名前空間名》
(
)
)でない場合,そのプログラムは,不適格とする。
例
6
Q
3
&
R&
Q
6&
633
%
M+&
''
B>
6
&
''
不適格
3
6
は,型の名前でない。
R
参考
入れ子になったクラス(
*)
) 又は 入れ子になった名前空間のメンバを参照するのに,多重に修飾の付
いた名前( 例えば ,
AL33AL33A*33
)を使うことができる。
宣言の《宣言子識別子》が《修飾付き識別子》である場合,その宣言の中では,その《修飾付き識別子》の前で挙
用してある名前に対してはその宣言を囲む名前空間有効範囲の中で名前検索を行い,その《修飾付き識別子》の後で
挙用してある名前に対してはそのメンバのクラス 又は 名前空間の有効範囲の中で名前検索を行う。
例
5
Q
R&
7
Q
5
Q
R&
%
/.&
5
ST&
R&
5
733ST&
''
不適格
3
''
335
733S733
T&
に等価であり
''
7335
733S733
T&
には等価でない
単項の有効範囲解決演算子
33
(
#
)を前置した名前に対しては,挙用してある翻訳単位での大域的有効範囲の
中で名前検索を行う。この名前は,大域的有効範囲の中で宣言してあるか,その大域的有効範囲の中で《
!
指令》
によって可視となっている宣言による名前であるかのいずれかでなければならない(
参照)
。この
33
を使う
ことで,その識別子自身が隠ぺい
)
されていても,大域的な名前を参照することが可能となる。
《入れ子名前指定子》を含む《擬似デストラクタ名》
(
#
)の《型名》に対しては,その《入れ子名前指定子》
が指定している有効範囲の中で型の名前を検索する。次に示す形の《修飾付き識別子》で示してある《クラス名》に
対しては,その《入れ子名前指定子》が指定している有効範囲の中で型の名前を検索する。
33
入れ子名前指定子
X
クラス名
ただし 《入れ子名前指定子》が名前空間有効範囲を指定するものに限る。
33
入れ子名前指定子
クラス名
33
X
クラス名
例
7
Q
<&
R&
<L
<+&
!
&
!
&
V733<33X<&
''
<
は,
7
の有効範囲の中で検索する。
V<L33X<+&
''
<+
は,この後置式の有効範囲の中で検索する。
6
Q
X6&
R&
6
6"&
Q
6"
!&
V6"33X6"&
''
6
のデストラクタに対する明示的な呼出しとなる。
R
参考
演算子
(
及び
V
の直後での名前検索については,
#
に規定する。
クラスメンバ
《修飾付き識別子》の《入れ子名前指定子》がクラスを指名している場合,その《入れ子
名前指定子》の後ろに指定してある名前は,原則として,そのクラスの有効範囲の中で検索する(
参照)
。この
検索の結果として,その名前は,そのクラスの中 又は そのクラスの基底クラス(
)の一つの中の,
個以上のメ
ンバを表していなければならない。
参考
クラスメンバは,その潜在有効範囲の中であればいつでも《修飾付き識別子》を使うことによって参照
することができる(
(
参照)
。
ただし ,次の特例をおく。
― デストラクタ名の名前検索は,
に規定する。
―
《演算子関数識別子》の《変換型識別子》に対しては,クラスの有効範囲の中とともに,その《後置式》
全体が位置している文脈でも検索を行う。この両者の検索の結果として,同じ型を参照していなければな
らない。
―
《テンプレート識別子》の《テンプレート実引数》に対しては,その《後置式》全体が位置している文脈
での検索を行う。
《入れ子名前指定子》がクラス
を指し 《入れ子名前指定子》の後に指定された名前が
の中を名前検索したと
きに
の補整クラスであった場合(
*
参照),その名前は,クラス
のコンストラクタの名前として扱われる。こ
ういうコンストラクタの名前は,クラス定義の外に書かれるコンストラクタ定義の《宣言子識別子》の中でしか使っ
てはならない。
例
6
Q
6&
R&
"3
6
Q
"&
R&
6336
Q
R
"33"
Q
R
"336
&
''
型
6
のオブジェクト
6336
&
''
エラー
3
6336
は型名でない。
クラスメンバが,入れ子の宣言領域での同じ名前 又は 派生クラスのメンバの同じ名前によって隠ぺいされている
場合でも,そのクラスの名前に演算子
33
を添えた修飾を付ければ ,そのクラスメンバが名前検索で見つかる。
名前空間メンバ
《修飾付き識別子》の《入れ子名前指定子》が名前空間を指名している場合,その《入
れ子名前指定子》の後ろに指定してある名前は,その名前空間の有効範囲の中で検索する。ただし,
《テンプレート識
別子》の《テンプレート実引数》に対しては,その《後置式》全体が位置する文脈の中で名前検索を行う。
《修飾付き識別子》を
533
(
5
は利用者宣言の名前空間) 又は
33
(
5
は大域名前空間)とするとき,
5
の中の
の宣言のすべて,並びに
5
及び その挙用している名前空間の中に置いた《
!
指令》で指名している名前空間の推
移的閉包の中の
の宣言のすべてからなる集合を
とおく。ただし 《
!
指令》による推移的閉包を求めるに当
たっては,
5
を含めて,
の
個以上の宣言を含んでいる名前空間での《
!
宣言》を無視する。名前検索の途中で
は,どの名前空間も
度だけ検索する。
が空集合となる場合,そのプログラムは,不適格とする。そうではなくて,
*
がただ
個の要素をもつ場合,及び その参照の文脈が《
!
宣言》である(
)
参照)場合は,
を
に結び
つく宣言の集合とする。上のいずれでもない場合,その
の挙用が
の中からただ一つの宣言を選べるものでない
とき,そのプログラムは,不適格とする。
例
&
J
&
&
K
&
6
J&
&
&
&
"
K&
&
&
6"
6&
"&
&
6"33&
''
は
6"
で直接宣言してある。
''
したがって,
は
6"33
となり,
6"33
が選ばれる。
6"33L&
''
は
6"
で直接宣言してはないので,
''
再帰的に規則を
6
と
"
とに適用する。
''
名前空間
J
は検索の対象とならず,
''
J33
が見つかることはない。
''
は
633
"33
となり,
''
多重定義解決によって
633
が選ばれる。
6"33ZZ&
''
上と同様にして多重定義解決によって
"33
が選ばれる。
6"33))&
''
は
6"
で直接宣言してはないし,
''
6
でも
"
でも宣言してないので
''
再帰的に規則を
J
と
K
とに適用する。
''
は
となり,このプログラムは不適格となる。
6"33))&
''
は
6"
で直接宣言してはないので,
''
再帰的に規則を
6
と
"
とに適用する。
''
は
633
"33
となり,この挙用はあいまいである。
''
ので,このプログラムは不適格となる。
6"33L-(N&
''
は
6"
で直接宣言してはないし,
''
6
と
"
とでも直接宣言してはないので,
''
再帰的に規則を
J
と
K
とに適用する。
''
は
J33
K33
となり,
''
多重定義解決によって
K33
が選ばれる。
同じ宣言が
度以上見つかるのは(ただ一つの宣言が見つかっていることなので )あいまいといわない。
例
6
&
"
6&
7
6&
"7
"&
7&
"733))&
''
B>3
は
633
633
となる。
#
633&
"#
"&
#&
"#33))&
''
B>3
は
633
633
となる。
参照してある名前空間は高々
度しか検索しないから,次のプログラムは,適格となる。
例
"
&
6
"&
&
"
6&
633))&
''
B>3
は
6
で直接宣言してある。
は
633
となる。
"33))&
''
B>3
6
と
"
を(
L
度) 検索する。
は
633
となる。
633))&
''
B>3
6
と
"
を(
L
度) 検索する。
は
"33
となる。
"33))&
''
B>3
は
"
で直接宣言してある。
は
"33
となる。
修飾付きの名前空間メンバの名前検索の途中で,その名前のメンバの宣言が
個以上見つかり,その一つが《クラ
ス名》 又は 《列挙体名》を宣言し ,他の宣言が同じオブジェクト 又は 同じ列挙子を宣言するか,関数を導入してい
る場合,その《型名》でない名前が《クラス名》 又は 《列挙体名》を隠ぺいするのは,それらの宣言がすべて同一
の名前空間にある場合だけとする。
例
6
Q
Q
R&
&
&
R
"
Q
Q
R&
R
7
Q
6&
"&
%
733&
''
B>3
633
(
型)
%
733&
''
あいまい
3
633
なのか
"33
なのか不明。
R
名前空間メンバの宣言において,その《宣言子識別子》が次の形の《修飾付き識別子》である場合,その《修飾な
し識別子》は,その《入れ子名前指定子》が指定する名前空間のメンバの名前でなければならない。
入れ子名前指定子
修飾なし識別子
例
6
Q
"
Q
L&
R
"&
R
633L
Q
R
''
不適格
3
L
は
6
のメンバでない。
こうした名前空間メンバの宣言にあっても,その《入れ子名前指定子》の前半部分を《
!
指令》に頼ることは差
し支えない。
例
6
Q
"
Q
L&
R
R
7
Q
#
Q
L&
R
R
6&
733#&
"33L
Q
R
''
B>3
633"33L
を宣言する。
詳述型指定子
《詳述型指定子》を用いることによって,すでに宣言してある《クラス名》 又は 《列挙体
名》が型以外の識別子によって隠ぺいされている(
)
参照)場合であっても,その《クラス名》 又は 《列挙体
名》を参照することができる。このとき《詳述型指定子》の中の《クラス名》 又は 《列挙体名》は,単に《識別子》
であっても《修飾付き識別子》であってもよい。
《詳述型指定子》の中の名前が単に《識別子》である場合,その《詳述型指定子》全体が,次の形で現れているの
でなければ,その《識別子》は,
に従って検索する。
クラス種別
識別子
&
ただし ,その際に,宣言してある型以外の名前は,無視する。 この名前検索によって,
《型定義名》が見つかった場
合,その《詳述型指定子》を含むプログラムは,不適格とする。 その《詳述型指定子》が《列挙体名》を参照してい
て,この検索によってすでに宣言してある《列挙体名》が見つからない場合,その《詳述型指定子》を含むプログラ
ムは,不適格とする。その《詳述型指定子》が《クラス名》を参照していて,この検索によってすでに宣言してある
《クラス名》が見つからない場合,又は その《詳述型指定子》全体が,次の形で現れている場合,その《詳述型指定
子》は,その《クラス名》を導入する宣言となる(
参照)
。
クラス種別
識別子
&
《詳述型指定子》の中の名前が《修飾付き識別子》である場合,その名前は,その修飾に応じて
に従って検
索する。ただし,その際に,すでに宣言してある型以外の名前は,無視する。この名前検索で《型定義名》が見つかっ
た場合,そのプログラムは,不適格とする。この名前検索で,すでに宣言してある《クラス名》 又は 《列挙体名》が
見つかった場合,そのプログラムは,不適格とする。
例
A
Q
A!
A&
''
B>3
大域的有効範囲での
A
を参照している。
#!
#&
''
B>3
型
#
を大域的有効範囲に宣言し ,
''
メンバ
#
を宣言している。
R&
#
Q
A!
A&
''
B>3
大域的有効範囲での
A
を参照している。
33:&
''
誤り
3
:
は宣言されていない。
''
修飾のある型は導入できない
,(L(/(*
参照
。
:&
''
B>3
大域的有効範囲での( まだ )宣言されていない
''
:
を参照している。
R&
"
Q
#&
''
B>3
入れ子の
#
を宣言する。
33#!
#&
''
B>3
33#
を参照している。
"33#!
#&
''
B>3
入れ子の
#
を参照している。
33#&
''
B>3
大域的な
#
は随伴である。
#&
''
B>3
入れ子の
#
は随伴である。
#
Q
'!
(((
!'
R&
''
入れ子の
#
の定義である。
R&
#&
''
B>3
大域的有効範囲での
#
の再宣言
33#&
''
誤り
3
修飾のある型は導入できない
,(L(/(*
参照
。
"33#&
''
誤り
3
修飾のある型は導入できない
,(L(/(*
参照
。
"33#&
''
誤り
3
#
は宣言されていない。
"33#!
"&
''
B>3
入れ子の
#
を参照している。
#
クラスメンバアクセス
クラスメンバアクセス式(
##
)において,字句
(
又は
V
に続く《識別子》の直
後に
がある場合は,まずその識別子を検索し ,その
がテンプレート実引数並び(
)の始まりであるのか比
較演算子であるのかを決定する。この識別子は,まず,そのオブジェクト式のクラスの中で検索する。そこで見つか
らない場合,その《後置式》全体の文脈の中で検索を行う。その結果として,クラス 又は 関数テンプレートの名前
が見つからなければならない。オブジェクト式のクラスの中で検索してテンプレートが見つかった場合,続けてその
《後置式》全体の文脈の中で検索を行う。その結果に応じて,次のとおりとする。
―
名前が見つからなければ ,オブジェクト式のクラスの中での検索で見つかった名前を結果とする。
―
名前が見つかってもそれがクラステンプレートでなければ ,オブジェクト式のクラスの中での検索で見つ
かった名前を結果とする。
―
クラステンプレートの名前が見つかれば ,そのクラステンプレートの名前を結果とする。ただし ,その名
前は,オブジェクト式のクラスの中での検索で見つかったものと同じ実体を参照していなければならない。
そうなっていない場合,そのプログラムは,不適格とする。
クラスメンバアクセス(
##
)の《識別子式》が《修飾なし識別子》であり,そのオブジェクト式の型がクラス型
( 又は クラス型
へのポインタ)である場合,その《修飾なし識別子》は,クラス
の有効範囲で検索する。オ
ブジェクト式の型がスカラ型へのポインタである場合,その《修飾なし識別子》は,その《後置式》全体の文脈で検
索する。
その《修飾なし識別子》が
:X
《型名》
;
であり,そのオブジェクト式の型がクラス型
(又は クラス型
へのポイ
ンタ)である場合,その《型名》は,その《後置式》全体の文脈,及び クラス
の有効範囲で検索する。その結果,
その《型名》は 《クラス名》を参照していなければならない。両方の検索でともに見つかった場合,その名前は,と
もに同じ クラス型を参照していなければならない。オブジェクト式の型がスカラ型である場合,その《型名》は,そ
の《後置式》全体の文脈で検索する。
クラスメンバアクセス(
##
)の《識別子式》が,次の形で始まっている場合,
(字句
(
又は
V
に続く)その《ク
ラス名前空間名》は,その《後置式》全体の文脈,及び オブジェクト式のクラスの有効範囲の両者で検索する。
クラス名前空間名
33
(((
オブジェクト式のクラスの有効範囲での検索でだけ名前が見つかった場合,その名前は 《クラス名》を参照していな
ければならない。その《後置式》全体の文脈での検索でだけ名前が見つかった場合,その名前は 《クラス名》 又は
《名前空間名》を参照していなければならない。両者で名前が見つかった場合,その名前は,同じ 実体を参照してい
なければならない。
参考 《クラス名前空間名》の検索の結果は,その《修飾付き識別子》が表す実体がオブジェクト式のクラス
型のメンバであって,しかも
に従ってあいまいでなく定まるのであれば ,一意的にオブジェクト式
のクラス型の基底クラスとなっている必要はない。
例
6
Q
&
R&
"3
6
Q
R&
73
"
Q
R&
#3
"
Q
R&
83
7
#
Q
R&
93
6
Q
R&
Q
8
&
("33
%
.&
''
B>3
8
の中では
633
しかない。
9
&
(633
%
L&
''
B>3
633
は
9
のメンバである。
R
《修飾付き識別子》が次の形で始まっている場合,その《クラス名前空間名》は,大域的有効範囲の中で,
《クラス
名》 又は 《名前空間名》として検索する。
33
クラス名前空間名
33
(((
《入れ子名前指定子》がクラスの《テンプレート識別子》
(
)である場合,その《テンプレート実引数》は,そ
の《後置式》全体が現れている文脈の中で評価する。
その《識別子式》が《変換関数識別子》である場合,その《変換型識別子》は,その《後置式》全体が現れている
文脈の中でも,そのオブジェクト式のクラス( 又は ポインタ式が指しているクラス)の文脈の中でも,同じ型を表し
ていなければならない。
(
指令 及び 名前空間別名
《
!
指令》 又は 《名前空間別名定義》の中の《名前空間名》を検索す
る場合は 《名前空間名》だけを検索対象とする。
#
プログラム 及び 結合
プログラムは,
個以上の翻訳単位(
)を結合して構成する。
《翻訳単位》は,宣言
の列から成る。
翻訳単位
3
宣言列
名前は,他の有効範囲の中の宣言が導入した名前と同じ オブジェクト,参照,関数,型,テンプレート,名前空間
又は 値を表し うる場合,結合
I
をもつという。
―
名前が外部結合
?
I
をもつ場合,その名前が表す実体は,他の翻訳単位の有効範囲 又は 同
じ翻訳単位の他の有効範囲の名前で参照することができる。
―
名前が内部結合
I
をもつ場合,その名前が表す実体は,同じ翻訳単位の他の有効範囲の名
前で参照することができる。
―
名前が結合をもたない
I
場合,その名前が表す実体は,他の有効範囲の名前では参照すること
ができない。
名前空間有効範囲をもつ名前(
#
)は,次に示す場合,内部結合をもつ。
―
と明示的に宣言してある オブジェクト,参照,関数 又は 関数テンプレートの名前である場合
―
と明示的に宣言してある オブジェクト 又は 参照の名前であって,
と明示的に宣言してな
いし ,それまでに外部結合をもつとも宣言してない場合
―
名前なし共用体のデータメンバの名前である場合
名前空間有効範囲をもつ名前は,次に示す場合,外部結合をもつ。
―
オブジェクト 又は 参照の名前であって,内部結合をもたない場合
―
関数の名前であって,内部結合をもたない場合
―
名前付きクラス(
*
)の名前である場合 又は 型定義宣言で定義している名前なし クラスの名前である場
合[そのクラスは,結合を示すための型定義名をもつ(
)
参照)
。]
―
名前付き列挙体(
)
)の名前である場合 又は 型定義宣言で定義している名前なし列挙体の名前である場
合[その列挙体は,結合を示すための型定義名をもつ(
)
参照)
。]
―
外部結合をもった列挙体に属している列挙子の名前である場合
―
テンプレートの名前である場合[ただし ,関数テンプレートの名前であって内部結合をもつ名前は除く
(
参照)
。]
―
名前空間(
)
)の名前である場合(ただし ,名前なし名前空間の内部で宣言してあるときは除く。)
更に,クラス有効範囲の,メンバ関数,静的なデータメンバ,クラス 又は 列挙体の名前は,そのクラスの名前が
外部結合をもっている場合,外部結合をもつ。
大域的有効範囲で宣言してある関数の名前,及び 大域的有効範囲の
?
宣言で宣言してあるオブジェクトの名
前は,結合をもつ。その名前と同じ名前 及び 同じ型をもった結合をもつ実体の宣言が可視である場合(ただし ,囲
んでいる最内側の名前空間有効範囲の外側で宣言してある実体は除外する。),その大域的有効範囲での宣言は,それ
と同じ実体を宣言し ,それまでの宣言の結合を受け継ぐ。このとき,合致する実体が
個以上あるなら,そのプログ
ラムは,不適格とする。合致する実体が
個もなければ ,その大域的有効範囲の実体は,外部結合をもつ。
例
&
%
.&
''L3
Q
&
''
内部結合
&
''+3
は結合をもたない。
Q
&
''
内部結合
&
''*3
外部結合
R
R
このプログラムには,名前
をもったオブジェクトが
個ある。
―
大域的有効範囲の宣言( 行
''L
)での,内部結合をもつオブジェクト
―
行
''+
の宣言での,結合をもたない自動記憶域期間のオブジェクト。
―
行
''*
の宣言での,外部結合をもった静的記憶域期間をもつオブジェクト。
結合をもった実体のブロック有効範囲の宣言の中に他の宣言が見つからない場合,その実体は,囲んでいる最内側
の名前空間のメンバとする。しかし ,そのような宣言は,名前空間有効範囲にそのメンバ名を導入するのではない。
例
5
Q
Q
&
''
誤り
3
がまだ宣言されていない。
&
''
は名前空間
5
のメンバとなる。
R
Q
&
''
誤り
3
がまだ宣言されていない。
R
Q
'!
(((
!'
R
''
533
の定義
R
Q
'!
(((
!'
R
''
無関係な
の他の宣言
これらの規則に当てはまらない名前は,結合をもたない。更に,局所的な有効範囲(
)で宣言してある名前
は,特に規定したものを除いて,結合をもたない。
結合をもたない名前( 特に,局所的な有効範囲(
)で宣言したクラス 又は 列挙体の名前)は,結合をもった
実体を宣言するために挙用してはならない。宣言に型定義名が挙用してある場合,その型定義名が参照している型名
の結合を,その宣言の結合とする。
例
Q
#
6
Q
&
R&
''
結合なし 。
6
&
''
不適格
6
"&
"
&
''
不適格
R
この結果として,結合をもたない名前は,テンプレートの実引数として挙用することができない(
参照)
。
別の有効範囲で宣言してある二つの名前が同一である場合(
参照),その二つの名前は,次の条件を満たすとき,
同じ オブジェクト,参照,関数,型,列挙子,テンプレート 又は 名前空間を表す。
―
両者がともに外部結合をもつ場合 又は 両者ともに内部結合をもち,同じ翻訳単位の中で宣言してある場合
―
両者がともに同じ名前空間 又は 同じ クラス( 継承によらない)のメンバを参照している場合
―
両者がともに関数を表し ,その関数の型が多重定義という意味で一致している場合
―
両者がともに関数テンプレートを表し ,その呼出し情報(
##
)が同じである場合
型のすべての調整[その過程の中で,型定義名(
)
)は,その定義で置き換える。]の後で,対象とするオブジェ
クト 又は 関数を参照しているすべての宣言で指定している型は,同一でなければならない。ただし ,配列オブジェ
クトの宣言にあっては,その主配列の上限(
)の有無に違いがあってもよい。型の同一性に関するこの規則に対
する違反は,診断情報を必要としない。
参考
"##
ではない宣言へは 《結合指定》を用いることによって結合することができる(
)#
参照)
。
(
開始 及び 終了
(
関数
プログラムには,大域的な関数
が含まれていなければならない。この関数から,プログラ
ムの実行が始まる。自立処理系でのプログラムに関数
を定義する必要があるかど うかは,処理系定義とする。
参考
自立処理系においては,プログラムの開始 及び 終了は,処理系定義となる。開始では,少なくとも,静
的記憶域期間をもつ名前空間有効範囲のオブジェクトに対するコンストラクタを実行する。終了では,少
なくとも,静的記憶域期間をもつオブジェクトに対するデストラクタを実行する。
処理系は,関数
をあらかじめ定義しておいてはならない。関数
は,多重定義してはならない。その返却
値の型は,
とする。これを除いて,関数
の型は,処理系定義とする。処理系は,次に示すど ちらの形での
関数
の定義も受理できなければならない。
Q
'!
(
(
(
!'
R
!
ST
Q
'!
(
(
(
!'
R
後者の形の場合,
は,そのプ ログラムを環境の下で実行する際にプログ ラムに渡された実引数の個数とする。
が
でない場合,
S.T
から
SVLT
には,それぞれの実引数を表している
)+'4/
(ナル文字で終
端した多バイト文字列(
)
)
)の最初の文字を指すポインタが入っていなければならない。とくに,
S.T
は,そのプログラムを駆動するのに使われた名前を表す
)+'4/
の最初の文字を指すポインタ 又は
;
;
を指すポイ
ンタでなければならない。
の値は,非負でなければならない。
ST
の値は,
でなければならない。
参考
更に追加の引数を設ける場合は,
の後におくのが望ましい。
関数
は,プログラムの中で挙用してはならない(
参照)
。
の結合(
#
)は,処理系定義とする。
を
又は
と宣言してある場合,そのプログラムは,不適格とする。これらを除いては,名前
を予
約しない。
例 ( 大域的有効範囲でない)他の名前空間の中の実体に
という名前を付けてよいのと同様に,メンバ
関数,クラス 及び 列挙体に
という名前を付けてもよい。
(
)に宣言してある次の関数は,実行中のブロックを抜け出すことなくプログラムの実行を終了さ
せるので,自動記憶域期間をもつオブジェクトを解体しない(
参照)
。
&
静的記憶域期間をもつオブジェクトの解体中に
が呼び出された場合,その動作は,未定義とする。
の中の
文は,関数
を抜け出し(その際に自動記憶域期間をもったすべてのオブジェクトを解体
し ),その返却値を実引数として
を呼び出す働きをもつ。
文に出会うことなく制御が関数
の終わり
に達した場合,次の文の実行と同じ働きをもつ。
.&
(
(
非局所オブジェクト の初期化
静的記憶域期間をもつオブジェクト(
)
)は,他の初期化に先立ってゼロ
初期化を行う(
#
参照)
。ゼロ初期化 及び 定数式による初期化を総称して,静的初期化
!
J
と呼
ぶ。これら以外の初期化を,動的初期化
3
J
と呼ぶ。静的記憶域期間をもち定数式(
#*
)での
初期化をもつ
"
互換型
2*
1
(
*
)のオブジェクトは,動的初期化に先立って,その定数式による初期化を
行う。翻訳単位の中の名前空間で定義してあるオブジェクトは,静的記憶域期間をもち動的初期化を行う場合,その
翻訳単位の中で定義が現れている順に初期化を行う。
参考
集成体のメンバの初期化の順序は,
#
で規定する。局所的な静的オブジェクトの初期化は,
()
で規
定する。
処理系は,名前空間有効範囲の静的記憶域期間をもつオブジェクトの初期化について,静的に行うことが要件となっ
ていない場合でも,それらを静的初期化として行ってもよい。ただし,次の条件を満たす場合に限る。
―
その初期化を動的に行ったとき,名前空間有効範囲の静的記憶域期間をもつ他のオブジェクトがその初期
化以前にもっている値を変えることがない。
―
その初期化を静的に行ったとき,静的な初期化が要件となっているものを除き,すべてのオブジェクトを
動的に初期化したとして得られるのと同じ値を設定することになる。
参考 この結果として,オブジェクト
L
の初期化が,名前空間有効範囲の静的記憶域期間をもったオブジェ
クト
+
を参照していて,その
+
が潜在的に動的初期化を必要とし ,同じ翻訳単位の後ろで定義して
あるとすると,
L
の初期化に使われる値が,完全に初期化し 終えた
+
の値となる(
+
の初期化
が静的に行われた場合)か,単にゼロ初期化だけした
+
の値となるかは,処理系定義となる。
例
Q
L(.&
R
&
+
%
&
''
未規定
3
''
.(.
に静的初期化してもよいし ,
''
L(.
に動的初期化してもよい。
%
&
''
L(.
に静的初期化してもよい。
名前空間有効範囲のオブジェクトの動的初期化を,
の最初の文の前に行うかど うかは,処理系定義とする。た
だし,
の最初の文よりも後に行う場合でも,そのオブジェクトと同じ翻訳単位の中で定義してある関数 又は オ
ブジェクトの最初の挙用以前に行わなければならない。
例
''
V
9
L
V
Y(Y
Y(Y
"
&
6336
Q
(G&
R
''
V
9
+
V
Y(Y
6
&
''
V
9
*
V
Y(Y
Y(Y
6
&
"
&
Q
(G&
(G&
R
又は
の初期化が
に入る前に行われているか,
の中での
の最初の挙用まで後回しになっ
ているかは,処理系定義となる。とくに,
が
に入る前に初期化される場合,
が
の初期化で使わ
れる前,つまり
6336
が呼び出される前に
の初期化が行われているとは限らない。一方,
の初期化が
の最初の文以降まで後回しになる場合,
の初期化は,
6336
での挙用の前に行われる。
注
名前空間有効範囲で定義してあるオブジェクトに副作用をもった初期化がある場合,プログラムでそのオブジェクトが挙用してないと
しても,その初期化を行わなければならない(
参照)
。
)
局所的でない静的なオブジェクトのコンストラクタ 又は デストラクタが,受取りのない例外を送出して終わった
場合,その結果として,
(
(
)を呼び出す。
(
終了
静的記憶域期間をもった初期化済みのオブジェクト( 大域的有効範囲 又は 名前空間有効範囲で宣言し
てあるもの )に対しては,
からの戻り 又は
(
)の呼出しの結果として,そのデストラクタ(
)を
呼び出す。これらのオブジェクトは,そのコンストラクタ 又は 動的初期化が完了した順序の逆順に解体する。静的
初期化を行ったオブジェクトの解体は,そのオブジェクトに動的初期化を行うとした場合と同じ順に行う。配列型 又
は クラス型のオブジェクトの部分オブジェクトは,その構築の際に初期化を行った静的記憶域期間をもった局所オブ
ジェクトを解体するよりも前に,解体する。
すでに解体された静的記憶域期間をもつ局所オブジェクトが関数の中にあって,静的記憶域期間をもつオブジェク
トの解体の最中にその関数が呼び出された場合,制御がその解体された局所オブジェクトの定義を通過すれば ,その
プログラムの動作は,未定義とする。
の呼出しが生じたとき
(
,
参照)で登録した関数がある場合,それらの関数は,プロ
グラムの終了処理の中で呼び出す。この関数の呼出しについては,次の要件をおく。
―
関数の登録以前に初期化を行った静的記憶域期間をもつオブジェクトの解体は,登録した関数の呼出しが
完了してから行わなければならない。
―
関数の登録後に構築した静的記憶域期間をもつオブジェクトの解体は,登録した関数の呼出しまでに行わ
なければならない。
―
その構築中に関数の登録を行ったオブジェクトの解体は,そのオブジェクトが属している総体オブジェク
トの解体とともに,登録した関数の呼出しまでに行わなければならない。
で定義してある次の関数は,自動記憶域期間 又は 静的記憶域期間をもつオブジェクトのデストラクタ
を実行することもなく,
で登録した関数を呼び出すこともなしに,プログラムを終了させる。
&
)
記憶域期間 オブジェクトの特性の一つに記憶域期間
!
3
がある。記憶域期間は,そのオブジェ
クトを収める記憶域に対する最小保証生存期間を示す。記憶域期間は,そのオブジェクトを生成するのに用いた構文
規則によって,次のいずれかとなる。
―
静的記憶域期間
―
自動記憶域期間
―
動的記憶域期間
宣言(
)で導入され,処理系によって暗黙に生成(
)されたオブジェクトの記憶域期間は,静的記憶域期間
又は 自動記憶域期間となる。
(
#
)で作ったオブジェクトの記憶域期間は,動的記憶域期間となる。
記憶域種別指定子
及び
は,記憶域期間の種別決定に関与する。
記憶域期間の種別を,そのまま参照にも当てはめる。参照の生存期間とは,その参照を保持する記憶域の記憶域期
間のこととする。
)
静的記憶域期間
動的記憶域期間をもたず局所的でもないオブジェクトは,すべて静的記憶域期間をもつ。静
的記憶域期間をもつオブジェクトの記憶域は,そのプ ログラムの実行期間中,維持し続けなければならない(
(
及び
(
参照)
。
副作用のある初期化 又は デストラクタをもった静的記憶域期間のオブジェクトは,そのオブジェクトが使われて
いないとわかる場合であっても,プログラムから取り除いてはならない。ただし,それがクラスオブジェクト 又は そ
のコピーの場合には,
に従って取り除くことができる。
キーワード
を使うことによって,静的記憶域期間をもった局所変数を宣言することができる。
参考
局所静的変数の初期化は,
()
で規定する。局所静的変数の解体は,
(
で規定する。
キーワード
をクラス定義の中でクラスデータメンバに指定すると,そのデータメンバの記憶域期間は,静
的記憶域期間となる。
)
自動記憶域期間
又は
と明示宣言してある局所オブジェクト 及び
とも
とも
明示宣言していない局所オブジェクトは,自動記憶域期間をもつ。それらのオブジェクトの記憶域は,それを作成し
たブロックを抜け出るまで,維持し続けなければならない。
参考 それらのオブジェクトの初期化 及び 解体は,
()
で規定している。
副作用のある 初期化 又は デストラクタをもった自動記憶域期間の名前付きオブジェクトは,そのブロックの終わ
りに達するまで解体してはならない。そのオブジェクトが使われていないとわかる場合であっても,最適化処理でプ
ログラムから取り除いてはならない。ただし ,それがクラスオブジェクト 又は そのコピーの場合には,
に従っ
て取り除くことができる。
)
動的記憶域期間 オブジェクトは,プログラムの実行(
*
)中に《
<
式》
(
#
)を使って動的に生成する
ことができ,
《
3
式》
(
##
)を使って動的に解体することができる。
"##
処理系は,動的記憶域をアクセスし管
理する手段として,大域的な割付け関数
及び
ST
並びに 大域的な解放関数
及び
ST
を提供する。
標準ライブラリは,それらの大域的な割付け関数 及び 大域的な解放関数に対する省略時定義を提供する。大域的
な割付け関数 及び 大域的解放関数の中には,上書き可能なものもある(
参照)
。上書き可能な割付け関数 又
は 解放関数に対して,
"##
プログラムは,その定義を高々一つ与えることができる。その関数定義は,標準ライブ
ラリが提供する省略時定義版を置き換える(
)
参照)
。プログラムのそれぞれの翻訳単位での大域的有効範囲
に,次に示す割付け関数 及び 解放関数(
)が暗黙に宣言される。
!
33$P
33P
&
!
ST33$P
33P
&
!
&
ST!
&
これらの暗黙宣言は,
,
ST
,
及び
ST
という関数
名だけを導入する。
参考 これらの暗黙宣言は,
,
33
及び
33$
という名前を導入しないし,それらの
名前を宣言するために標準ライブラリが使う他のいかなる名前も導入しない。したがって,
という
ヘッダを取り込まないで 《
<
式》《
3
式》 又は 関数呼出しにおいて,それらの関数を使っても,
そのプログラムが不適格となることがない。しかし ,
,
33
又は
33$
を参照す
る場合には,適切なヘッダを取り込んでその名前を宣言しない限り,そのプログラムは不適格となる。
割付け関数 及び 解放関数は,いずれもクラスごとに宣言することができるし ,定義することができる(
#
参照)
。
"##
プログラム( 標準
"##
ライブラリを含む。)で定義するすべての割付け関数 及び 解放関数は,
)
及
び
)
の意味規則に合致していなければならない。
)
割付け関数
割付け関数は,クラスメンバ関数 又は 大域的関数でなければならない。割付け関数が大域的
有効範囲でない名前空間有効範囲で宣言されている場合,又は 割付け関数が大域的有効範囲で
と宣言してあ
る場合,そのプログラムは不適格とする。割付け関数の返却値の型は,
!
でなければならない。第
仮引数の型
は,
$
(
)でなければならない。第
仮引数は,附随する省略時実引数(
(
)をもっていてはならない。
第
仮引数の値は,割付け要求の大きさと解釈される。割付け関数は,関数テンプレートであってもよい。そのよう
なテンプレートでは,その返却値の型 及び 第
仮引数を,上に規定したとおりに宣言しなければならない( すなわ
ち,テンプレート仮引数の型を,返却値の型 及び 第
仮引数の型に使ってはならない。)
。テンプレート割付け関数
は,二つ以上の仮引数をもっていなければならない。
割付け関数は,要求しただけの記憶域を割り付けようとする。成功した場合,記憶域ブロックの先頭アドレスを返
す。その記憶域ブロックの大きさは,要求分以上でなければならない。割付け関数から戻った時点での記憶域の内容
は,何であってもよい。同じ割付け関数を何度か呼び出したときに割り付けられる記憶域の順序,連続性 及び 初期
値については,未規定とする。割付け関数が結果として返すポインタは,次のことができるように境界調整されなけ
ればならない。すなわち,そのポインタが,任意の完全オブジェクト型に変換することができ,かつ,
(その記憶域が
対応する解放関数呼出しによって明示的に解放されるまでの間)割り付けた記憶域内のオブジェクト 又は 配列をア
クセスするのに使うことができるように,境界調整されなければならない。要求された領域の大きさがゼロの場合で
あっても,その要求は成功しないことがある。成功した場合,返却する値は,空ポインタ値(
)としてはならず,
以前に返却した値
L
と異なっていなければならない。ただし ,その値
L
がすでに
に渡されてい
る場合,
L
と同じであってもよい。大きさゼロの要求に対する返却値のポインタを参照はずしした結果は,処理系依
存とする。
割付け関数は,記憶域割付けに失敗した場合,その時点で設定されている
(
)があればそれ
を呼び出すことができる。
参考 プログラムで用意した割付け関数は,関数
(
)を使って,その時点で設定さ
れている
のアドレスを得ることができる。
注
この規定は,
を実装するのに,実質的に
又は
を呼び出すだけでよいようにすることを意図し
ている。
では,大きさゼロの要求に対し空ポインタではない値を返すことが
言語と異なる。
*
空の《例外指定》
(
#
),すなわち
という指定で宣言してある割付け関数は,記憶域割付けに失敗した場合,
空ポインタを返さなければならない。その他の割付け関数は,記憶域割付けに失敗した場合,クラス
33
(
) 又は その派生クラスの例外を送出して失敗を示すだけとし ,それ以外のことをしてはならない。
大域的な割付け関数が呼び出されるのは,次のいずれかの場合に限る。
―
<
式(
#
)の結果としての呼出し
―
関数呼出し構文規則(
#
)を使った直接的な呼出し
―
呼び出した標準
"##
ライブラリ中の関数の呼出しからの間接的な呼出し
参考
特に,次に示す記憶域の割付けのために,大域的な割付け関数を呼び出すことはない。
―
静的記憶域期間(
)
)をもったオブジェクトの記憶域
―
型
(
#
)のオブジェクトの記憶域
―
<
式(
#
)で送出されたオブジェクトのコピーのための記憶域
)
解放関数
解放関数は,クラスメンバ関数 又は 大域的な関数でなければならない。解放関数が大域的有効
範囲ではない名前空間有効範囲で宣言してある場合,又は 大域的有効範囲で静的に宣言してある場合,プログラムは
不適格とする。
各解放関数は,
を返さなければならず,その第
仮引数の型は,
!
でなければならない。解放関数には,
二つ以上の仮引数があってもよい。クラス
の中に,仮引数が一つだけで名前が
というメンバ
解放関数がある場合,その関数が通常の( 位置指定なしの )解放関数となる。そのような
がクラ
ス
に宣言されていず,仮引数が二つだけの
というメンバ解放関数が宣言されており,その第
仮引数の型が
33$
(
)である場合,その関数が通常の解放関数となる。同様に,クラス
の中に,仮
引数が一つだけで名前が
ST
というメンバ解放関数がある場合,その関数が通常の( 位置指定なし
の )解放関数となる。そのような
ST
をクラス
に宣言していず,仮引数が二つだけの
ST
というメンバ解放関数が宣言されており,その第
仮引数の型が
33$
である場合,その関数が通
常の解放関数となる。解放関数は,関数テンプレートのインスタンスの一つとしてもよい。第
仮引数 及び 返却値
のど ちらも,テンプレート仮引数に依存していてはならない。
参考
すなわち,解放関数テンプレートは,その第
仮引数の型を
!
とし ,返却値の型を (ここで規定
したとおり)
としなければならない。
解放関数テンプレートは,二つ以上の関数仮引数をもたなければならない。具現化された関数は,その呼出し情報に
よらず,通常の解放関数になることはない。
標準ライブラリで提供される解放関数の中には,それに供給される第
実引数の値が空ポインタ値であってもよ
いものもある。その場合,その解放関数の呼出しの効果はない。そうでない場合,標準ライブラリの中の
!
に供給される第
実引数の値は,標準ライブ ラリの中の
$
又は
$
33
0
のいずれかを先行して呼び 出したときの返却値の一つでなければならず,
標準ライブ ラリの中の
ST!
に供給され る値は,標準ライブ ラリの中の
ST
$
又は
ST
$
33
0
のいずれかを先行して呼び出したときの返却
値の一つでなければならない。
標準ライブラリで提供される解放関数に設定した実引数が空ポインタ値(
)でない場合,その解放関数は,そ
の実引数のポインタが指す記憶域を解放し,解放された記憶域中のいずれかの部分を指しているすべてのポインタを
無効にする。無効になったポインタの値を使った場合,その効果( 解放関数に渡すことを含めて)は,未定義とする。
)
部分オブジェクト の記憶域期間
メンバの部分オブジェクト,基底クラスの部分オブジェクト 及び 配列要素
の記憶域期間は,それらを含む総体オブジェクトの記憶域期間と同じとする(
参照)
。
オブジェクト の生存期間 オブジェクトの実行時特性の一つとして,オブジェクトの生存期間がある。型
の
オブジェクトの生存期間の始まりは,型
の大きさをもち適切に境界調整された記憶域が,獲得された時点とする。
ただし ,
が自明でないコンストラクタ(
)をもつクラス型の場合には,コンストラクタ呼出しが完了していな
ければならない。型
のオブジェクトの生存期間の終わりは,次の時点とする。
―
が自明でないデストラクタ(
)をもつ場合には,そのデストラクタの呼出しが始まった時点
―
そうでない場合には,オブジェクトが占有している記憶域が,再利用された時点 又は 解放された時点
注
処理系によっては,システムが生成する実行時障害となる。
参考
配列オブジェクト 又は
"
互換型のオブジェクト(
*
)の生存期間は,適切な大きさに境界調整された
記憶域が獲得されたときに始まり,オブジェクト 又は 配列が占有している記憶域が再利用 又は 解放され
たときに終わる。基底部分オブジェクト 及び メンバ部分オブジェクトの生存期間は,
(
で規定する。
この規格全体を通して,オブジェクトの特性についての規定は,生存期間中のオブジェクトに対してだけ適用さ
れる。
参考
特に,オブジェクトの生存期間の開始前 及び 終了後については,
(
及び
)
で規定するとおり,
オブジェクトの使用に多くの制約がつく。構築中 及び 解体中のオブジェクトの動作は,オブジェクトの生
存期間が開始しまだ終了していないオブジェクトの動作と同じでないかもしれない。構築の段階 及び 解
体の段階におけるオブジェクトの動作は,
(
及び
)
で規定する。
オブジェクトが占有する記憶域を再使用することによって,又は 自明でないデストラクタをもっているクラス型の
オブジェクトの場合にそのデストラクタを明示的に呼び出すことによって,プログラムは,どんなオブジェクトもそ
の生存期間が終了したとみなしてよい。自明でないデストラクタをもつクラス型のオブジェクトの場合,プログラム
は,オブジェクトの占有する記憶域が再使用 又は 解放される前に,そのデストラクタを明示的に呼び出さなくても
よい。しかし ,デストラクタの明示的呼出しがなく,かつ記憶域を解放するための 《
3
式》
(
##
)が使われな
い場合,そのデストラクタは暗黙に呼び出されないので,そのデストラクタによって生じる副作用に依存するプログ
ラムの動作は,未定義とする。
オブジェクトの生存期間が開始していず,オブジェクトが占有する予定の記憶域の割付けが済んでいる場合
,
又は オブジェクトの生存期間は終了しているが,オブジェクトの占有する記憶域が再使用されていないか 又は 解放
されていない場合,オブジェクトがその後に作られる記憶域 又は それがあった記憶域の場所を指すポインタを使っ
てもよいが,制限付きでしか使えない。そのようなポインタが,割り付けられた記憶域(
)
)を指しており,そ
のポインタが型
!
であるように使われる場合は,適格とする。そのようなポインタの参照をはずすことができる
が,その左辺値は,次に示すように制限付きでしか使えない。オブジェクトが自明でないデストラクタのクラス型に
なるか 又は そうであった場合であって,そのポインタが 《
3
式》の演算対象に使われた場合,プログラムの動
作は,未定義とする。オブジェクトが
"
互換でないクラス型になるか 又は なっていた場合であって,次のいずれか
の条件を満たす場合,プログラムの動作は,未定義とする。
―
そのポインタを使って,静的でないデータメンバをアクセスしている,又は そのオブジェクトの静的でな
いメンバ関数を呼び出している。
―
そのポインタを,ある基底クラスの型へのポインタに暗黙に変換している(
参照)
。
―
そのポインタを,静的キャスト(
#*
)の演算対象に使っている(ただし ,
!
に変換している場合,
及び
!
に変換して最終的に
!
又は
!
に変換している場合は,除く。)
。
―
そのポインタを動的キャスト(
#)
)の演算対象に使っている。
例
"
Q
&
&
X"&
R&
#L
3
"
Q
&
R&
#+
3
"
Q
&
R&
"33
Q
#+&
''
記憶域の再使用,
!
の生存期間の終了
&
''
動作未定義
(((
%
''
B>3
自体は,正当なメモリを指している。
R
Q
!
%
$#L
)
$#+&
"!
%
#L&
V&
0&
''
B>3
は,正しいメモリを指している。
!
%
&
''
B>3
は,正しいメモリを指している。
V&
''
動作は未定義。
!
の生存期間は終わっている。
R
注
例えば,
互換でないクラス型の大域的なオブジェクトの構築の前(
参照)
同様に,次の時点では,元のオブジェクトを参照する左辺値は,制限付きでしか使えない。
―
オブジェクトの生存期間が始まる前であるが,そのオブジェクトが占有する記憶域が割り付けられた後の
時点
―
オブジェクトの生存期間が終了した後であるが,そのオブジェクトが占有する記憶域が再使用されるか 又
は 解放される前の時点
そのような左辺値が,割り付けられた記憶域(
)
)を参照している場合,その値に依存しない左辺値の特性を使
うことは,適格とする。左辺値から右辺値への変換(
)が,そのような左辺値に適用された場合,そのプログラ
ムの動作は未定義とする。元のオブジェクトが
"
互換でないクラス型になるか 又は 既になっていて,次のいずれか
の場合,そのプログラムの動作は未定義とする。
―
オブジェクトの静的でないデータメンバへアクセスするために,又は 静的でないメンバ関数を呼び出すた
めに,その左辺値を使っている。
―
その左辺値が,基底クラス型の参照のために暗黙に変換される(
参照)
。
―
その左辺値を,静的キャスト(
#*
)の演算対象に使っている(ただし,変換が結局は
0
又は
0
になる場合は除く。)
。
―
その左辺値を,動的キャスト(
#)
)の演算対象 又は
の演算対象に使っている。
オブジェクトの生存期間が終了した後であって,オブジェクトの占有記憶域を再使用したか 又は 元のオブジェク
トが解放される前に占有していた記憶域に新しいオブジェクトを作った場合,元のオブジェクトを指していたポイン
タ,元のオブジェクトを参照していた参照 及び 元のオブジェクトの名前は,自動的に新オブジェクトを参照するこ
とになる。さらに,それらのポインタ,参照 及び 名前は,新オブジェクトの生存期間が開始した後では,次の条件
をすべて満たす場合には,新オブジェクトの操作に使うことができる。
―
新オブジェクトの記憶域が,元のオブジェクトの占有記憶域に完全に重なっている。
―
新オブジェクトの型が,元のオブジェクトの型と( 最上位の
0
修飾子は除いて)同じである。
―
元のオブジェクトの型が定値修飾されていず,クラス型である場合には,定値修飾された型 又は 参照型
の非静的データメンバを含んでいない。
―
元のオブジェクトが,型
の最派生したオブジェクト(
)であり,新オブジェクトが型
の最派生し
たオブジェクトである( すなわち,基底クラスの部分オブジェクトではない。)
。
例
7
Q
&
&
70
%
70
&
R&
70
733%
70
Q
[%
0
Q
VX7
&
''
!
の生存期間が終了する。
7
&
''
型
7
の新オブジェクトを作る。
&
''
適格
R
!&
R
7
L&
7
+&
L
%
+&
''
適格
L(
&
''
適格
3
L
は,型
7
の新オブジェクトを参照する。
プログラムが,静的記憶域期間(
)
) 又は 自動記憶域期間(
)
)をもつ型
のオブジェクトの生存期間を
終了させ,かつ,
が自明でないデストラクタをもつ場合
,プログラムは,デストラクタを暗黙に呼び出すとき
に,元の型のオブジェクトが記憶域の同じ場所を占有していることを保証しなければならない。保証できない場合,
そのプログラムの動作は未定義とする。これは,例外発生によってブロックから出る場合にもあてはまる。
例
Q
R&
"
Q
X"
&
R&
注
すなわち,自動記憶域期間のオブジェクトならブロックから出る時点で,静的記憶域期間のオブジェクトならプログラムから出る時点
で,デストラクタを暗黙に呼び出すオブジェクトとする。
Q
"
&
0
&
R
''
ブロック出口での動作は未定義。
静的記憶域期間 若しくは 自動記憶域期間の定値オブジェクトが占有する記憶域,又は そのような定値オブジェク
トがその生存期間終了前に占有していた記憶域に,新オブジェクトを生成した場合,そのプログラムの動作は未定義
とする。
例
"
Q
"
&
X"
&
R&
"
&
Q
(X"
&
0
"&
''
動作は未定義。
R
*
型
参考 ここでは,型の表現に関して処理系に課せられる要件を示す。型には,基本型 及び 複合型の二つがあ
る。型は,オブジェクト(
),参照(
) 又は 関数(
#
)を記述する。
"
互換型
の任意のオブジェクト( 基底クラスの部分オブジェクトを除く。)では,そのオブジェクトが型
の値
を正しく保持しているか否かにかかわらず,そのオブジェクトを構成するバイトは,
型 又は
!3
型
の配列にコピーすることができる。
型 又は
!3
型の配列の内容をそのオブジェクトに逆にコピー
した場合,元のオブジェクトは,その元の値にならなければならない。
例
A
$
SAT&
&
''
は元の値に初期化される。
0
A
&
''
二つの
の呼出しの間で,
''
は変更され うる。
0
A
&
''
この時点で,
のスカラ型の部分
''
オブジェクトは,元の値をもつ。
"
互換型
では,
への二つのポ インタが異なるオブジェクト
及び
を指していて(ここで,
及
び
は基底クラスの部分オブジェクトではないとする。),
の値をライブラリ関数
を使って
に
コピーした場合,
は,
と同じ値をもたなければならない。
例
!
L&
!
+&
''
+
は,初期化されたオブジェクトを指すとする。
L
+
$
&
''
この時点で,
!L
の
7
互換型の部分オブジェクトの
''
それぞれは,対応する
!+
の部分オブジェクトと
''
同じ値になる。
型
のオブジェクト表現
%
=
1!
とは,
を
$
とするとき,型
のオブジェクトが占
める
個の
!3
型のオブジェクトの列のこととする。オブジェクトの値表現
0
1!
とは,
型
の値を保持するビットの集合のこととする。
"
互換の型の場合,値を決めるオブジェクト表現におけるビット
集合が値表現になる。ここで,個々の値とは,処理系で定義している値集合の中のある離散的要素とする。
オブジェクト型には,境界調整の要求(
*
及び
*
参照)がある。総体オブジェクト型は,バイト数を表わ
す処理系定義の整数値に境界調整される。オブジェクトは,そのオブジェクト型の境界調整の要求に合ったアドレス
に割り付けられる。
宣言はあるが定義のないクラス,大きさが未知な配列,又は 不完全要素型の配列を,不完全定義オブジェクト型と
呼ぶ
。不完全定義オブジェクト型 及び
0
3
型を,不完全型と呼ぶ(
*
参照)
。オブジェクトは,不完全型を
もつとして定義してはならない。
注
例えば,ライブラリ関数(
)
又は
を使ってコピーできる。
注
この規定は,
のメモリモデルを,
と互換にすることを意図している。
注
不完全定義オブジェクト型のインスタンスの大きさ 及び 配置は,不明とする。
クラス型( 例えば
5
)は,翻訳単位中のある時点で不完全型であっても,後で完全型になることがある。こ
こで,型
5
は,両方の時点で同じ型とする。配列オブジェクト宣言された型は,不完全クラス型の配列であっ
てもよく,従って不完全型でありうる。そのクラスの型が翻訳単位の後の時点で完全型になった場合,その配列の型
は,完全型となる。ここで,その配列型は,二つの時点で同じ型とする。配列オブジェクト宣言された型は,翻訳単位
のある時点では大きさ未知の配列であってもよく,したがって不完全型でありえ,後で完全型になってもよい。ここ
で,それらの配列型は,二つの時点で異なる型(
:
境界値不明の配列
;
及び
:
要素の配列
;
)とする。大きさ未
知の配列へのポインタ型,又は 大きさ未知の配列の
宣言によって定義された型は,完全型にはなりえない。
例
5&
''
5
は,不完全型。
5!
&
''
は,不完全型へのポインタ。
ST
&
''
の型は,不完全型。
GA>6ST
&
''
GA>6
は,不完全型。
GA>6!
&
''
は,不完全型へのポインタ。
GA>6!!
&
Q
))&
''
不適格
3
5
は,不完全。
))&
''
不適格
3
不完全型。
))&
''
B>3
GA>6!
の大きさは既知。
R
5
Q
&
R&
''
5
は,ここで完全型になる。
SL.T
&
''
ここで
型は,完全になる。
R
5
&
Q
%
0
&
''
B>3
型は
Y5
へのポインタ
Y
%
0
&
''
不適格
3
型が異なる。
))
&
''
B>3
5
は完全。
))
&
''
不適格
3
GA>6
は,完全にはなりえない。
R
参考
宣言 及び 式に対する規則において,ど ういう文脈で不完全型が禁じられているかが規定されている。
オブジェクト型は,関数型,参照型 及び
0
3
型のいずれでもない型(
0
修飾があってもよい。)とする。
算術型(
*
),列挙型,ポインタ型,及び メンバへのポインタ型(
*
),並びに それらの
0
修飾付きのも
のを,スカラ型と呼ぶ。スカラ型,
"
互換構造体型,
"
互換共用体型(
*
),及び それらの型の配列,並びに それ
らの
0
修飾付き版を,
"
互換型と呼ぶ。
二つの型
及び
が同じ型の場合,
及び
は,配置互換な型と呼ぶ。
参考
配置互換な列挙体については,
)
で規定する。配置互換な
"
互換構造体 及び
"
互換共用体について
は,
*
で規定する。
*
基本型
文字(
)として宣言されたオブジェクトの大きさは,処理系定義である基本文字集合のすべての
要素を格納するのに十分なだけ大きくなければならない。その集合の一つの文字が文字オブジェクトに格納される場
合,その文字オブジェクトの整数値は,その文字に対応する
文字リテラルの値と等しい。
オブジェクトが負の
値をもてるか否かは,処理系定義とする。文字には,
又は
を明示的に宣言することができる。単な
る文字型(
),符号なし文字型(
) 及び 符号付き文字型(
)は,三つの別々の型
とする。それら三つは,同一量の記憶域を占有し,同一の境界調整要求(
*
)がある。すなわち,それらのオブジェ
クト表現は,同一になる。文字型では,オブジェクトを表現するすべてのビットが,値表現に関わる。符号なし文字
型では,値表現できるビットパタンのいずれもが数を表現する。この要件は,その他の型には当てはまらない。処理
系は,単なる文字型オブジェクトの値を,符号付き文字型 又は 符号なし文字型のど ちらと同じにしてもよい。ど ち
らにするかは,処理系定義とする。
符号付き整数型には,
:
;
,
:
;
,
:;
及び
:
;
の四つがある。これらの型の記憶
域は,右にあるほうが大きいか等しい。単なる
の記憶域の大きさ
は,実行環境のハード ウェア機構から自然
に決まる。その他の符号付き整数型は,特殊な要件を満たすために提供される。
注
すなわち,
ヘッダで定義されている
!
から
!"#
の範囲のすべての値をとるのに十分な大きさ
符号付き整数型のそれぞれに対し ,対応する符号なし 整数型( ただし ,型は異なる。)が 存在する。すなわち,
:
;
,
:
;
,
:
;
及び
:
;
のそれぞれは,対応す
る符号付き整数型と同じ大きさの記憶域 及び 境界調整要求(
*
)をもつ
。すなわち,符号付き整数型のそれぞ
れは,対応する符号なし整数型と同じオブジェクト表現をもつ。符号付き整数型の負でない値のとる範囲は,対応す
る符号なし整数型の部分的な範囲にあり,対応する符号付き整数型の値表現と符号なし整数型の値表現とは,同じで
なければならない。
と宣言された符号なし 整数は,
を法
3
とする算術規則に従わなければならない。ここで,
は,整数という特定の大きさの値表現に使うビット数とする。
独立した一つの型として
<
型がある。その値は,提供されている現地特性クラス(
)で規定している
最大拡張文字集合に含まれるメンバのすべてを,別々のコード で表現できるものとする。
<
型の大きさ,符号の
有無 及び 境界調整要求は,汎整数型のいずれかと等しく,その汎整数型のことを
<
型が基礎とする型と呼ぶ。
%
型の値は,
又は
のいずれかとする。
参考
%
型には,
,
,
又は
という型 及び 値は,ない。
%
型の値は,汎整数型の一つとして扱う。
%
型の値は,汎整数昇格に用いられる(
#
参照)
。
%
型,
型,
<
型,符号付き整数型 及び 符号なし整数型をまとめて,汎整数型と呼ぶ
。汎整数型
は,その同義語として整数型とも呼ぶ。汎整数型の表現は,純粋に
進数計算法に従った値を与える。
例 この規格では,汎整数型の表現として,
の補数,
の補数 及び 符号付き絶対値表現を許している。
浮動小数点型には,
5
型,
3 %
型 及び
3 %
型の三つがある。
3 %
型は,
5
型と同じ 又は そ
れ以上の精度をもち,
3 %
型は,
3 %
型と同じか それ以上の精度をもつ。
5
型の値集合は,
3 %
型
の値集合の部分集合になっており,
3 %
型の値集合は,
3 %
型の値集合の部分集合になっている。浮動小
数点型の値表現は,処理系定義とする。汎整数型 及び 浮動小数点型をまとめて,算術型と呼ぶ。標準テンプレート
(
)の特殊化によって,算術型のそれぞれに対し ,その処理系での最大値 及び 最小値が得ら
れる。
0
3
型の値の集合は,空とする。
0
3
型は,不完全型であって完全型になることはありえない。
0
3
型は,値を返
さない関数の返却値の型として用いる。すべての式は,
0
という型に明示的に変換することができる(
#
参
照)
。
0
3
型の式は,次のいずれかの場合を除いて,使ってはならない。
―
式文(
(
)の一つ
―
コンマ式の演算対象(
#
)の一つ
―
23
演算子の第
演算対象 又は 第
演算対象(
#(
)
―
の演算対象
―
返却値の型が
である関数の
文(
((
)中の式
参考
処理系によっては,二つ以上の基本型が同じ値表現をもつと決めている場合があるが,そうであっても,
それらの基本型は,別々の型とする。
*
複合型
複合型は,次のいずれかの方法で作ることができる。
―
既存の型のオブジェクトを要素とする配列(
参照)
―
既存の型の仮引数をもち,
,既存の型への参照,又は 既存の型のオブジェクトの,いずれかを返す関
数(
#
参照)
―
,又は 既存の型のオブジェクト 若しくは 関数(それらはクラスの静的メンバを含む)へのポインタ
(
参照)
―
既存の型のオブジェクト 又は 関数への参照。
―
種々の型のオブジェクトの並び,型・列挙体・これらのオブジェクトを操作するための関数の集まり(
*
),
及び これらの実体へのアクセスに対する制限事項の集まり(
)から構成されるクラス(
*
参照)
―
共用体,すなわち,異なる複数の型をそれぞれ異なる回数だけもつことのできるクラス(
*#
参照)
注
型とそれを指し示す型指定子との対応関係については,
で規定している。
注
これは,符号なしの算術はあふれないことを意味する。なぜならば,演算結果の値が符号なし整数型で表現できない場合には,演算結
果の値を符号なし整数型で表現できる最大値より
大きい数を法とした剰余が演算結果になるからである。
注
この規格で
値が未定義と規定しているとき( 例えば,初期化していない自動記憶期間の変数の値を調べようとしたとき),
$
でも
%
でもないことがありうる。
注
したがって,列挙体(
)は,汎整数ではない。しかし,列挙体は,
に規定するように,
型,
型,
型 及び
型に昇格できる。
注
整数についての
進数字の
!
及び
を使った位取り表現であって,多くの場合にそれぞれの位の値を加算した値を与える。それぞれ
の位の値は,そのビットに,最下位では
を,以後 順次
のべき乗を乗じたものとする。ただし,最上位のビットは例外となっている。
#
―
名前付きの定数値の集まりからなる列挙体。個々の列挙体は,それぞれが異なる列挙型となる(
)
参照)
。
―
静的でないクラスメンバ
へのポインタ。これは,一つのクラスの複数のオブジェクトの中にある特定
の型のメンバを指し示す(
参照)
。
ここで述べた複合型を作る方法は,再帰的に実行できるが,その制約を,
,
,
#
及び
に規定
する。
型
のオブジェクトへのポインタを,
:
へのポインタ
;
と呼ぶ。
例
型オブジェクトへのポインタは,
:
へのポインタ
;
,クラス
のオブジェクトへのポインタは,
:
へのポインタ
;
と呼ぶ。
静的メンバへのポインタを除いて,単に
:
ポインタ
;
と書いたら,それは メンバへのポインタではない。不完全型へ
のポインタも許されるが,そのポインタを使ってできることには制約がある(
*
参照)
。オブジェクトポインタ型の
正当な値は,記憶(
)
)内のあるバイトのアドレ ス 又は 空ポインタのいずれかとする。型
のオブジェクトがア
ドレス
に置かれている場合,アドレス型
を値とする型
0
!
のポインタは,その値がどのようにして得られた
かにかかわらず,そのオブジェクトを指す
1
という。
参考
例えば,配列(
#)
)の最後の次の要素のアドレスは,そのアドレスに置かれたかもしれない配列要素の
型とは関係ないオブジェクトを指すと見なす。
ポインタ型の値表現は,処理系定義とする。配置互換な型については,それらの
0
修飾版へのポインタ,及び
0
修
飾のない版へのポインタは,同じ値表現 及び 同じ配置要求をもつ。
0
修飾付き(
*
) 又は
0
修飾なしの型
!
(
へのポインタ)のオブジェクトは,型が判らないオブ
ジェクトを指すのに使うことができる。
!
( 型
!
のオブジェクト )は,あらゆるオブジェクトへのポインタ
が保持できなければならない。
0
修飾付き 又は
0
修飾なしの
!
は,
0
修飾付き 又は
0
修飾なしの
!
と
同じ値表現 及び 同じ境界調整要求をもつ。
*
'
修飾子
*
及び
*
で説明した型は,
0
修飾なしの型であった。
0
修飾なしの完全オブジェクト型,
0
修飾なしの不完全オブジェクト型 及び 型
には,それぞれ
0
修飾付きの版が三つ,すなわち,
!
修飾版
,
0
修飾版 及び
!-0
修飾版がある。オブジェクト型という用語(
)には,オブジェクト生成時に
指定される
0
修飾子も含まれる。
《宣言指定子列》の中に
!
指定子があると,
!
修飾オブジェクト型のオブ
ジェクトの宣言となる。そのオブジェクトを定値オブジェクトと呼ぶ。宣言指定子の列の中に
0
指定子がある
と,
0
修飾オブジェクト型のオブジェクトの宣言となる。そのオブジェクトを揮発性オブジェクトと呼ぶ。宣言
指定子列の中に両方の
0
修飾子があると,
!
0
修飾オブジェクト型のオブジェクトの宣言となる。そのオ
ブジェクトを定値揮発性オブジェクトと呼ぶ。ある型の
0
修飾付き版 及び
0
修飾なし版は,別の型とするが,同
じ値表現 及び 同じ境界調整要求をもつ(
*
参照)
。
複合型(
*
)は,複合化される前の型の
0
修飾(があったとしてもそれ )によって
0
修飾されることがない。
配列型に
0
修飾を付けた場合,その
0
修飾は,配列要素の型には影響するが,配列の型自体には影響しない(
参照)
。
!
修飾されたクラスオブジェクトの場合,その中の非静的で,変更不可で,かつ非参照のデータメンバのそれ
ぞれは,
!
修飾される。
0
修飾されたクラスオブジェクトの場合,その中の非静的で非参照のデータメンバ
のそれぞれは,
0
修飾される。
!
0
修飾クラスのメンバも同様とする。
0
修飾付きの関数型について
は,
#
及び
*
で規定する。
0
修飾には( 部分)順序があって,ある型が他の型に対してより
0
修飾されているという言い方ができる。その順
序関係を,
表
(
に示す。
表
(
と
の順序関係
0
修飾なし
0
修飾なし
0
修飾なし
注
静的クラスメンバは,オブジェクト 又は 関数であり,静的クラスメンバへのポインタは,オブジェクト 又は 関数への通常のポイン
タとなる。
注
同じ値表現 及び 同じ境界調整制約をもつことは,関数の実引数,関数からの返却値 及び 共用体のメンバとして,交換可能であるこ
とを意味する。
(
この規格では,型を記述するのに,
0
( 又は
0
,
0
など )という記法を用いる。この記法は,任意の
0
修飾
子の集合すなわち,
,
,
,又は 空集合のいずれか一つを表している。配列型
に付けた
0
修飾は,その要素の型に作用するから,
が配列型の場合に
:0
;
は,要素がそのように修飾されてい
る配列を意味する。
0
修飾付きの配列型ど うしでは,その要素の型の
0
修飾を基にして,より多く( 又は より少な
く)
0
修飾されているという言い方ができる。
左辺値と右辺値
すべての式は,左辺値 又は 右辺値のいずれかをもたらす。
左辺値は,オブジェクト 又は 関数を参照する。クラス型 又は
0
修飾付きのクラス型の式の場合,右辺値式がオ
ブジェクトを参照することがある。
参考
組込み演算子 及び 組込み関数の呼出しの中には,左辺値をもたらすものがある。
例
8
がポインタ型の式の場合,
!8
は,
8
が指すオブジェクト 又は 関数を参照する左辺値になる。
もう一つの例を示す。
0
&
この関数は左辺値を生じるので,
の呼出しは,左辺値式となる。
参考
組み込み演算子の中には,演算対象として左辺値を要求するものがある。
例
組み込み代入演算子のすべては,左側演算対象として左辺値を要求する。
また,組み込み演算子の中には,右辺値を生じるものと,右辺値を要求するものとがある。
例
単項 及び
項の演算子
)
は,右辺値の実引数を要求し ,右辺値を結果としてもたらす。
個々の組み込み演算子に対しては,それぞれが左辺値演算対象を必要とするか否か,左辺値を生じるか否
かを,
#
に規定する。
参照を返さない関数の呼出し結果は,右辺値とする。利用者定義演算子は,関数であり,その演算子が左辺値を必
要とするか否か 又は 左辺値をもたらすか否かが,仮引数 及び 返却値の型によって決まる。
非参照型へのキャストの結果によって生じる一時的オブジェクトをもつ式は,右辺値とする(これには,関数記法
(
#
)を使ったオブジェクトの明示的生成の場合も含む。)
。
右辺値を要求する文脈に左辺値が現れた場合,その左辺値は,必ず右辺値に変換される(
,
及び
参照)
。
参照の初期化(
#
) 及び 一時的変数(
)に対しても,特定の文脈での左辺値 及び 右辺値の動作を規定
する。
クラスの右辺値は,
0
修飾付きの型をもっていてもよい。非クラスの右辺値は,常に
0
修飾なしの型をもってい
なければならない。右辺値は,常に完全型 又は
0
3
型をもっていなければならない。左辺値は,それらの型に加え
て不完全型をもつこともできる。
オブジェクトの左辺値は,そのオブジェクトを変更するために必須とする。ただし ,ある状況においては,クラス
の型の右辺値もまた,それが指しているものを変更するのに使用できる場合がある。
例 オブジェクトに対して呼び出されるメンバ関数(
*
)は,そのオブジェクトを変更できる。
関数は変更できないが,関数へのポインタは変更できる。
不完全型へのポインタは,変更できる。プログラムのある時点で指している型が完全型である場合,そのポインタ
の指すオブジェクトも変更できる。
!
修飾された式の参照先を,その式を通して変更してはならない。ただし ,それがクラス型であって,変更可
能な構成要素をもつ場合には,その構成要素を変更することができる(
)#
参照)
。
式を使用してその式が参照するオブジェクトを変更することができる場合,その式を変更可能と呼ぶ。変更可能で
ない左辺値式 又は 右辺値式を介してオブジェクトを変更しようとした場合,そのプログラムは不適格とする。
次にあげる型以外の左辺値を介し,あるオブジェクトの格納値をアクセスしようとするプログラムの動作は,未定
義とする。
―
そのオブジェクトの動的な型
―
そのオブジェクトの動的な型の
0
修飾付き版
―
そのオブジェクトの動的な型に対応する 符号付きの型 又は 符号なしの型
―
そのオブジェクトの動的な型の
0
修飾付き版に対応する 符号付きの型 又は 符号なしの型
注
例えば,コンストラクタを呼び出す式 及び クラス型を返す関数を呼び出す式は,オブジェクトを参照する。処理系によってはそのよ
うなオブジェクト上のメンバ関数を呼び出すことができるが,それらの式が,左辺値であるわけではない。
注
この列挙は,オブジェクトが別名をもちうるか状況ともちえない状況を明らかにすることを意図している。
)
―
ある集成体 又は 共用体の型であって,そのメンバが上記のいずれかであるもの( 部分集成体 又は 含まれ
る共用体に対しては,再帰的に成り立つものを含む。)
―
そのオブジェクトの動的な型のある基底クラス型になっている型(
0
修飾があってもよい。)
―
型 又は
!3
型
標準変換
組込みの型に対して定められている暗黙の変換を,標準変換と呼ぶ。ここでは,そのような変換のす
べてを列挙する。標準変換手順とは,次の順で実行される標準変換の手順とする。
―
次のうち高々一つの変換
左辺値から右辺値への変換
配列からポインタへの変換
関数からポインタへの変換
―
次のうち高々一つの変換
汎整数昇格
浮動小数点数昇格
汎整数変換
浮動小数点変換
#
浮動小数点
-
整数変換
(
ポインタ変換
)
メンバへのポインタ変換
真理値変換
―
高々一つの修飾変換
参考
実行される標準変換手順は,空であってもよい。すなわち,変換なしの場合もありうる。
標準変換手順は,式に対して実行し ,その式を目的の型に変換する。
参考
次に示す構文の場合,ある型をもつ式が別の型に暗黙に変換される。
―
演算子の演算対象に使われた場合。目的の型は,その演算子の演算対象に対する要件によって
決まる(
#
参照)
。
―
文 又は 繰返し文(
(
及び
(#
参照)の条件の中で使われた場合。目的の型は,
%
型と
なる。
―
!<
文の式の中で使われた場合。目的の型は,汎整数となる(
(
参照)
。
―
初期化の値を与える式として使われた場合( 関数呼出しの実引数として使われる場合,及び
文の式として使われた場合を含む。)。目的の型は( 一般に )初期化される実体の型と
なる(
#
及び
#
参照)
。
式
が型
に暗黙変換できる必要十分条件は,宣言
:
%&;
が適格なこととする(
#
参照)
。ただし,
は,新
しい一時変数の名前とする。暗黙変換の効果は,この宣言によって一時変数を宣言し初期化した後,その一時変数を
変換の結果として使うのと同じとする。変換の結果は,
が参照型(
)の場合左辺値となり,そうでない場合右
辺値となる。式
は,この初期化で左辺値として使われる場合を除いて,左辺値として使われることはない。
参考
利用者定義された型については,利用者定義の変換も同様に扱われる(
参照)
。一般に,暗黙変換
手順(
)では,標準変換手順の後に利用者定義の変換が続き,さらに他の標準変換手順が続く。
文脈によっては,ある種の変換が抑止されることがある。例えば ,左辺値から右辺値への変換は,単項
演算子
0
の演算対象に対して実施しない。個々の例外については,該当の演算子 及び 構文の記述の中で
規定する。
左辺値から右辺値への変換
関数でも配列でもない型
の左辺値(
)は,右辺値に変換することができる。
が不完全型の場合,この変換が必須となるプログラムは,不適格とする。左辺値が参照するオブジェクトが型
の
オブジェクトでなく,
から派生した型のオブジェクトでもない場合,又は オブジェクトが初期化されていない場
合,この変換が必須となるプログラムの動作は,未定とする。
がクラス型でない場合,変換後の右辺値の型は,
の
0
修飾なし版とする。そうでない( クラス型の )場合,変換後の右辺値の型は,
とする。
変換結果の右辺値は,左辺値が指すオブジェクトの中に保持される値とする。左辺値から右辺値への変換が
$
注
では,クラスの右辺値は(オブジェクトなので)
"#
修飾付き型となりうる。これは,
$
%
&!!
と異なる。
$
%
&!!
では,
左辺値でないものは,
"#
修飾付き型をもたない。
(
#
)の演算対象の中で行われる場合,参照されるオブジェクトの中の値は,アクセスされない。この演算子は,
演算対象を評価しないからである。
参考
にも規定がある。
配列からポインタへの変換
:
型
の
要素からなる配列
;
という型 又は
:
型
の要素数未知の配列
;
という
型の 右辺値 又は 左辺値は,
:
型
へのポインタ
;
という型の右辺値に変換することができる。その結果は,その配
列の最初の要素へのポインタとする。
ワイド 文字列リテラルではない文字列リテラル(
)は,型
:
へのポインタ
;
の右辺値に変換することが
できる。ワイド 文字列リテラルは,型
:
へのポインタ
;
の右辺値に変換することができる。いずれの場合も,
その結果は,配列の先頭要素へのポインタとする。この変換は,適切なポインタの標的の型が明示的に存在する場合
にだけ適用され,左辺値から右辺値への変換が必要な場合には適用されない。
参考 この変換は,推奨しない( 附属書
5
参照)
。
多重定義の解決(
)における順位付けでは,この変換は,修飾変換(
)の前に行われる配列からポイン
タへの変換と考える。
例
YY
は,配列からポインタへの変換として,
:
へのポインタ
;
に変換されてから,修飾変換
によって
:
へのポインタ
;
となる。
関数からポインタへの変換
関数型
の左辺値は,型
:
へのポインタ
;
の右辺値に変換することができる。こ
の変換の結果は,その関数へのポインタとする。
参考
関数が多重定義されている場合の追加規則を
に規定している。
修飾変換
型
:
;
の
0
修飾が型
:
;
の
0
修飾よりも多い場合,型
:
へのポインタ
;
の右辺値
は,型
:
へのポインタ
;
の右辺値に変換することができる。
型
:
;
の
0
修飾が型
:
;
の
0
修飾よりも多い場合,型
:
という型の
のメンバへのポ インタ
;
の右辺値は,型
:
という型の
のメンバへのポインタ
;
の右辺値に変換することができる。
参考
関数型( メンバ関数へのポインタ型に使われる場合を含む。)が
0
修飾されることはない(
#
参照)
。
次の規則に従い,多重レベルのポインタに対しては,最上位レベルを除いて
0
修飾子を付けることができる
。
二つのポインタ型
と
とが同類であるとは,次の条件を満たす型
及び 整数
が存在することをいう。
―
が,
への
ポインタへの……
ポインタへの
ポインタとし ,かつ,
―
が,
への
ポインタへの……
ポインタへの
ポインタとする。
ここで,
は,
,
,
又は 空のいずれかとする。ポインタ型の中の先頭を除いた
組の
0
修飾子,上の例では,ポインタ型
の中の
,
,……,
の
組の
0
修飾子を,ポインタ型
の
0
修飾情報と呼ぶ。ポインタ型
の式をポインタ型
に変換できる必要十分条件は,次の条件のすべてが成立
することとする。
―
それらのポインタ型が同類である。
―
すべての
について,
に
がある場合,
にも
がある。
についても同
じとする。
―
と
とが異なる場合,
のすべての
について,
に
がある。
参考 プログラムが
!!
型のポインタを
!!
型のポインタに代入できたとすると(すなわち,次の例
の
''L
の行が許可されたとすると ),プログラムは,不注意にも
オブジェクトを変更できてしまう
( 次の例の
''+
の行で変更できてしまう。)
。
例
Q
%
ZZ
;
!
;
!!
%
&
;
''L3
許可されない。
!
%
&
;
!
%
Z7Z
;
''+3
定値オブジェクトの変更となる。
R
メンバへの多重レベルのポインタ型( メンバ先多段ポインタ型と呼ぶ。),又は ポインタ 及び メンバへのポインタ
型から成る混合多重レベルのポインタ型( メンバ先ポインタ混在多段ポインタ型と呼ぶ。)は,次の形式とする。
注
この変換は,非静的メンバ関数には適用されない。非静的メンバ関数を参照する左辺値はありえないからである。
注
これらの規則は,変換において定値安全性が保存されることを保証している。
*
への
付きポインタ
への‥‥
付きポインタ
への
付きポインタ
ここで,
は,ポイン
タ 又は メンバへのポインタとし ,
は,ポインタ型でもメンバへのポインタ型でもない型とする。
二つのメンバ先多段ポインタ型,又は 二つのメンバ先ポインタ混在多段ポインタ型(それらを,
及び
とす
る。)が同類であるとは,次の条件をともに満たす型
と整数
が存在する場合とする。
―
が,
への
ポインタ
への‥‥
ポインタ
への
ポインタ
となって
いる。
―
が,
への
ポインタ
への‥‥
ポインタ
への
ポインタ
となって
いる。
メンバ先多段ポインタ型が同類の場合,並びに メンバ先ポインタ混在多段ポインタ型が同類の場合に
0
修飾子を
付加する規則は,ポインタ型が同類の場合と同じとする。
#
汎整数昇格
型,
!3
型,
!3
型,
!
型 及び
!3
!
型のいずれかの
右辺値は,その型の値すべてが
型で表現できる場合には,
型の右辺値に変換することができる。そうでない場
合,元の右辺値は,
!3
型の右辺値に変換することができる。
<
型(
*
) 又は 列挙型(
)
)の右辺値は,次にあげる型のうち,その元となる型のすべての値を表現で
きる型の中で最も左にある型の右辺値に変換することができる。
,
,
,
汎整数のビ ットフィールド(
*(
)の右辺値は,そのビ ットフィールド の値すべてを
型で表現できる場合には,
型の右辺値に変換することができる。そうでない場合,ビットフィールド のすべての値が
!3
型で表現
できる場合には,
!3
型に変換することができる。ビットフィールドが更に大きい場合には,汎整数昇格は,
行われない。ビットフィールドが列挙型をもつ場合,昇格のためには,ビットフィールドは,その列挙型のとらない
別の値として扱われる。
%
型の右辺値は,
型の右辺値に変換することができる。
は,
になり,
は,
になる。
これらの変換を,汎整数昇格と呼ぶ。
(
浮動小数点昇格
5
型の右辺値は,
3 %
型の右辺値に変換することができる。値は変わらない。
この変換を,浮動小数点昇格と呼ぶ。
)
汎整数変換
整数型の右辺値は,別の整数型の右辺値に変換することができる。列挙型の右辺値は,整数型の右
辺値に変換することができる。
目的の型が符号なしの型の場合,結果の値は,元の整数の値に合同な最小の符号なし整数になる( すなわち,符号
付きの型の表現に使うビット数を
とすると,
を法とした剰余になる。)
。
参考
の補数表現では,この変換は概念的なものとなり,ビットパターンの変更はない( 丸めがない場合)
。
目的の型が符号付きの型の場合,その値が目的の型( 及び ビットフィールド の幅)で表現できる場合には,値は変
化しない。そうでない場合,結果の値は,処理系定義とする。
目的の型が
%
型の場合については,
で規定する。元の型が
%
型の場合,
は
に,
は
に変
換される。
汎整数昇格に許される変換は,汎整数変換とはいわない。
浮動小数点変換
浮動小数点型の右辺値は,別の浮動小数点型に変換することができる。元の値が目的の型にお
いて正確に表現できる場合には,変換の結果は,正確な値表現となる。元の値が,目的の型で表わし うる値の二つの
隣接した値の中間にある場合,変換結果は,ど ちらかの値とする。ど ちらが選択されるかは,処理系定義とする。そ
うでない場合の挙動は,未定義とする。
浮動小数点昇格に許される変換は,浮動小数点変換とはいわない。
*
浮動小数点数と汎整数の間の変換
浮動小数点型の右辺値は,整数型の右辺値に変換することができる。その変
換は,切り捨て変換とする。つまり,小数部分を切って捨てる。切り捨てた値が,目的の型で表現できない場合,そ
の挙動は未定義とする。
参考
目的の型が
の場合については,
に規定する。
整数型 又は 列挙型の右辺値は,浮動小数点型の右辺値に変換することができる。結果の値は,目的の型で表せる
場合,正確な値となる。そうでない場合,目的の型で表される隣接した二つの値の間に位置するとき,ど ちらかの値
となる。ど ちらの値になるかは,処理系定義とする。
参考
汎整数の値が,浮動小数点の値で正確に表現できない場合,精度が劣化する。
元の型が
の場合,
値は
に変換され,
値は
に変換される。
#
ポインタ変換 ゼロと評価される右辺値をもつ整数型の汎整数定数式(
#*
)を,空ポインタ定数と呼ぶ。空
ポインタ定数は,ポインタ型に変換することができる。その結果は,その型の空ポインタ値となる。空ポインタ値は,
オブジェクト先ポインタ型 又は 関数先ポインタ型のどんな値とも区別できる値とする。同じ型の二つの空ポインタ
値は,比較で等しくなるものでなければならない。空ポインタ定数から,
0
修飾付きの型へのポインタへの変換は,
単一の変換となり,ポインタ変換の後で修飾変換(
)を行うことはない。
がオブジェクト型の場合,型
:
へのポインタ
;
の右辺値は,型
:
へのポインタ
;
の右辺値に変換する
ことができる。
:
へのポ インタ
;
から
:
へのポインタ
;
への変換結果は,あたかもそのオブジェクトが,
型
の最派生したオブジェクト(
)であるかのように( すなわち,ある基底クラスの部分オブジェクトとしてで
はなく),型
のそのオブジェクトがある記憶域の先頭位置を指すものとする。
をクラス型とし,
を
の基底クラス(
)とする場合,型
:
へのポインタ
;
の右辺値は,型
:
への
ポインタ
;
の右辺値に変換することができる。ただし ,
から基底クラス
をアクセスできない場合(
),又は
があいまいな場合(
),その変換を必須とするプログラムは,不適格とする。変換の結果は,派生クラスのオ
ブジェクトの中の基底クラスの部分オブジェクトへのポインタとする。空ポインタ値は,目的の型の空ポインタ値に
変換される。
メンバへのポインタの変換
空ポインタ定数(
)は,メンバ先ポインタ型に変換することができる。結果
は,その型の空メンバポインタ値とする。その空メンバポインタ値は,空ポインタ定数から作られたのではないメン
バ先ポインタのどんな値とも区別できる値とする。同じ型の二つの空メンバポインタ値は,比較で等しくなるもので
なければならない。空ポインタ定数から
0
修飾付き型のメンバへのポインタへの変換手順は,単一の変換とし ,メ
ンバへのポインタ変換の後に修飾変換(
)は行われない。
をあるクラス型とし ,
を
の派生クラス(
)としたとき,型
:
型
の
内メンバ先ポインタ
;
の右辺
値は,型
:
型
の型
内メンバ先ポインタ
;
の右辺値に,変換することができる。
が,アクセスできない場合
(
),あいまいな場合(
) 又は
の仮想基底クラス(
)となる場合,その変換を必須とするプログラム
は,不適格とする。変換の結果は,変換する前のメンバへのポインタと同じ メンバを参照するが,それが派生クラス
のメンバであるかのように基底クラスのメンバを参照する。結果は,
のインスタンス
の中のメンバを指す。結果
は,型
:
型
の
内メンバ先ポインタ
;
となるので,オブジェクト
への参照は,解除され うる。参照解除をし
た結果は,
内メンバ先ポインタが
の部分オブジェクト
と参照解除された場合と同じとなる。空メンバポイン
タ値は,目的の型の空メンバポインタ値に変換される。
真理値変換
算術型,列挙型,ポインタ型 及び メンバへのポインタ型の右辺値は,
%
型の右辺値に変換す
ることができる。ゼロという値,空ポインタ値 及び 空メンバポインタ値は
に変換され,その他の値はすべて
に変換される。
#
式
参考 ここでは,式の構文,式の評価順序 及び 式のもつ意味を規定する。式は,計算を指定する演算子 及び
演算対象の列から成る。式は,結果として値をもたらすが,副作用を生じることもある。
演算子を多重定義すること,すなわち,クラス型(
*
) 又は 列挙型(
)
)の式に演算子を適用すると
きの意味を多重に与えることができる。多重定義した演算子を使った場合,それは,
#
で規定するとお
り関数呼出しに変形される。多重定義した演算子については,その構文規則が
#
の規定に従うことを除
き,その演算対象の型,左辺値 及び 評価順序に対する要件は,関数呼出しの規則で代替される。演算子ど
うしの関係( 例えば ,
))
が
)%L
を意味すること )は,多重定義した演算子には保証されないし(
#
参照),
%
型の演算対象にも保証されない。
ここでは,個々の演算子について,多重定義していない型に適用したときの演算子の効果を規定する。演算子を多
重定義することによって,組込み演算子に対する規則を変えることがあってはならない。すなわち,この規格が個々
の演算子の適用対象と定めている型にその演算子を適用した場合の規則を,多重定義によって変えてはならない。し
かし ,組込み演算子も多重定義の解決に用いられ,その過程で,演算対象を組込み演算子にとって適切な型に変換す
る必要がある箇所では,利用者定義の変換が適用される。組込み演算子が選択された場合,演算対象に対してこうし
注
メンバへのポインタの変換( 基底クラスのメンバへのポインタから,派生クラスのメンバへのポインタへの変換)の規則は,オブジェ
クトへのポインタの変換(派生クラスへのポインタから,基底クラスのポインタへの変換)の規則が逆転したものになる(
及び
参照)
。この逆転によって,型の安全性を保証する。メンバへのポインタは,オブジェクトへのポインタ 又は 関数へのポインタではない
こと,及び そのようなポインタの変換規則は,メンバへのポインタには適用されないこと,に注意しなければならない。特に,メンバへ
のポインタは,
&
* に変換することができない。
#
た変換を適用した上で,ここでの規定に従ってその演算を施す(
及び
(
参照)
。
特に断らない限り,それぞれの演算子の演算対象間の評価順序,それぞれの式の中の部分式の評価順序 及び 副作
用の発生順序については,規定しない
。相続く二つの副作用完了点の間では,一つの式の評価によってスカラオ
ブジェクトの格納値が変わるのは,高々
回でなくてはならない。更に,直前の値は,次に格納すべき値を決定する
ためにだけアクセスされる。この要件は,完結式中の部分式の間で許されるどんな順序に対しても満たされなければ
ならない。そうでない場合,その挙動は未定義とする。
例
%
S))T&
''
挙動は規定しない。
%
,
))
))&
''
は,
O
になる。
%
))
)
L&
''
挙動は,規定しない。
%
)
L&
''
の値は,増える。
式の評価中に,数学的に定義されない結果が得られた場合,及び その型で表現可能な範囲にない結果が得られた場
合,その挙動は未定義とする。ただし ,その式が定数式(
#*
)の場合,そのプログラムは不適格とする。
参考
多くの既存の
"##
処理系は,整数オーバフローを無視する。ゼロでの除算,ゼロを除数とする余りの
計算,及び すべての浮動小数点例外の扱いは,処理系ごとに異なっているが,通常,それらの扱いをライ
ブラリ関数で調整することができる。
もとの型が
:
への参照
;
(
及び
#
)である式は,すべての解析に先立って,その型を
:
;
に調節し ,そ
の参照が表しているオブジェクト 又は 関数を指すようにして,その式を左辺値の式とする。
式がオブジェクトを指す場合,その式をオブジェクト式と呼ぶ。
演算対象として右辺値を必要とする演算子の演算対象に左辺値の式が現れた場合,その式は,次の標準変換のいず
れかを適用して右辺値に変換される。
―
左辺値から右辺値への標準変換(
)
―
配列からポインタへの標準変換(
)
―
関数からポインタへの標準変換(
)
参考
式を右辺値に変換するときに非クラス型の式の型から
0
修飾子を取り除くので,例えば,
!
型
の左辺値式を
型の右辺値式が必要なところで使うことができる。
算術型 又は 列挙型の演算対象をとる
項演算子の多くは,同様に変換を行って結果の型を得る。その目的は,二
つの演算対象に共通の型を得ることにあり,その共通の型が結果の型にもなる。その方法を,通常の算術変換と呼ぶ。
通常の算術変換は,次のとおりとする。
― ど ちらか一方の演算対象が
3 %
型の場合,他方を
3 %
型に変換する。
―
そうではなく,ど ちらか一方の演算対象が
3 %
型の場合,他方を
3 %
型に変換する。
―
そうではなく,ど ちらか一方の演算対象が
5
型の場合,他方を
5
型に変換する。
―
そうではない場合,演算対象の両方に汎整数昇格(
#
)を行う。
―
次に,ど ちらか一方が
!3
型の場合,他方を
!3
型に変換する。
―
そうではなく,ど ちらか一方が
型で他方が
!3
型の場合,
型が
!3
型
のすべての値を表現できるときは,
!3
型を
型に変換し,表現できないときは,両方の
演算対象を
!3
型に変換する。
―
そうではなく,ど ちらか一方が
型の場合,他方を
型に変換する。
―
そうではなく,ど ちらか一方が
!3
型の場合,他方を
!3
型に変換する。
参考 これらのいずれにもあてはまらないのは,両方の演算対象が
型の場合である。
浮動小数点型の演算対象の値 及び 式の結果が,型で必要とするよりも高い精度 及び 広い数値範囲で表現される
ことがある。しかし ,それによって型が変わることはない。
#
一次式
一次式には,リテラル,名前 及び 有効範囲解決演算子
33
で修飾した名前がある。
一次式
3
リテラル
式
注
演算子間の優先順位は,直接の規定を定めないが,構文規則から決まる。
注
その結果,
型,
'
"
型 又は 列挙型は,汎整数型の一つに変換される。
注
キャスト 及び 代入演算子は,
,
及び
に規定するとおり,それぞれに固有の変換を施す。
#
識別子式
識別子式
3
修飾なし識別子
修飾付き識別子
修飾なし識別子
3
識別子
演算子関数識別子
変換関数識別子
X
クラス名
テンプレート識別子
《リテラル》は 《一次式》の一つとする。その型は,その形式によって決まる(
参照)。文字列リテラルは,
左辺値とする。その他のすべてのリテラルは,右辺値とする。
キーワード
は,非静的メンバ関数(
*
)を呼び出したときの対象となったオブジェクトへのポインタを表
す。キーワード
は,クラスの非静的メンバ関数の本体(
*
)の内部,又は コンストラクタの《メンバ初期化
子》
(
(
)の内部でしか使ってはならない。その式の型は,その関数のクラスへのポインタとする(
*
参照)
。
ただし ,必要に応じて,クラス型に
0
修飾子を付けることがある。その式は,右辺値とする。
演算子
33
に続けて,
《識別子》《修飾付き識別子》 又は 《演算子関数識別子》を書いたものは《一次式》の一つと
する。その型は,
《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》の宣言における指定による。その結果は,
《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》が表す実体とする。その実体が関数 又は 変数の場合,結果
は,左辺値とする。その《識別子》,
《修飾付き識別子》 又は 《演算子関数識別子》は,大域的な名前空間有効範囲を
もつか 《
!
指令》
(
)
)によって大域的有効範囲において可視になっているかのいずれかでなければならない。
参考
33
を用いることによって,大域的名前空間で宣言された型,オブジェクト,関数,列挙子 又は 名前空
間を参照することができる。それらの識別子が隠ぺいされていても参照可能とする(
参照)
。
括弧で囲まれた式は,その括弧内の式と同一の型 及び 値をもつ一次子とする。括弧があることは,式が左辺値で
あるかど うかに影響を与えない。括弧で囲まれた式は,特に規定しない限り,その括弧内の式が使えるのと同じ文脈
かつ同じ意味で使うことができる。《識別子式》は 《一次式》の制限された形式とする。
参考 《識別子式》は,演算子
(
及び 演算子
V
の後ろに書いてもよい(
##
参照)
。
《識別子》は,それが適切に宣言(
)
)されている場合に 《識別子式》となる。
参考 《演算子関数識別子》は,
#
で規定する。
《変換関数識別子》は,
で規定する。
《テンプレー
ト識別子》は,
で規定する。
《クラス名》の前に
X
を書いたものは,デストラクタとする(
参
照)。非静的メンバ関数の定義の中では,非静的メンバを指す《識別子》は,クラスメンバアクセス式に
変換される(
*
参照)
。
《識別子式》の型は 《識別子》の型とする。その結果は,識別子が表す実体とする。実体が関数,変数 又は データメ
ンバの場合,その結果は,左辺値とする。
修飾付き識別子
3
33
入れ子名前指定子
修飾なし識別子
33
識別子
33
演算子関数識別子
33
テンプレート識別子
入れ子名前指定子
3
クラス名・名前空間名
33
入れ子名前指定子
クラス名・名前空間名
33
入れ子名前指定子
クラス名・名前空間名
3
クラス名
名前空間名
クラスを指す《入れ子名前指定子》の直後にキーワード
(
)があって(なくてもよい。),更にその
後に,そのクラス(
*
)のメンバの名前 又は そのクラスの基底クラス(
)のメンバの名前が続いたものが,
《修
飾付き識別子》となる。
《修飾付き識別子》に現れるクラスメンバに対する名前検索は,
に規定する。結果は,
そのメンバとし ,結果の型は,そのメンバの型とする。メンバが静的なメンバ関数 又は データメンバの場合,結果
#
は,左辺値とする。
参考
クラスメンバは,潜在的有効範囲(
(
)内の任意の位置で 《修飾付き識別子》を使って参照するこ
とができる。
《クラス名》
33
《クラス名》という形式を用い,その二つの《クラス名》が同じクラスを参照する形式をコンストラ
クタ(
)の記法とする。
《クラス名》
33
X
《クラス名》という形式を使う場合,その二つの《クラス名》は,同
じ クラスを参照しなければならない。この形式をデストラクタ(
)の記法とする。
参考
クラスを指す《型定義名》は,
《クラス名》となる(
)
参照)
。クラスの《メンバ指定》の外側にある
コンストラクタ定義 又は デストラクタ定義(
及び
)の中にある《識別子》として使う場合を
除き,クラスを指す《型定義名》を《修飾付き識別子》の中で使って,コンストラクタ 又は デストラク
タを参照してもよい。
名前空間(
)
)を指している《入れ子名前指定子》は,直後にその名前空間中のメンバ名が続いた場合(又は《
!
指令》によって可視となる名前空間のメンバの名前が続いた場合)《修飾付き識別子》とする。
《修飾付き識別子》に
現れる名前空間メンバの名前検索は,
で規定する。結果は,そのメンバとする。結果の型は,そのメンバの
型とする。そのメンバが関数 又は 変数の場合,結果は左辺値となる。
《修飾付き識別子》において 《識別子式》が《変換関数識別子》の場合,それの《変換型識別子》は,全体の《修
飾付き識別子》が現れる文脈,及び《入れ子名前指定子》が指すクラスの文脈の両方において,同じ型を表していな
ければならない。
クラスの非静的なデータメンバ 又は 非静的なメンバ関数を表す《識別子式》が使えるのは,次のいずれかの場合
だけとする。
―
オブジェクト式がそのメンバのクラス,又は そのクラスから派生したクラスを参照しているときに,クラ
スメンバアクセス(
##
)の一部として使う。
―
メンバへのポインタを形成するのに使う(
#
参照)
。
―
そのクラスの非静的関数 又は そのクラスから派生したクラスの非静的関数の本体の中で使う(
*
参照)
。
―
そのクラスのコンストラクタ 又は そのクラスから派生したクラスのコンストラクタの《メンバ初期化子》
の中で使う(
(
参照)
。
《テンプレート識別子》が《修飾なし識別子》として使えるのは,
)
,
)
及び
#
に規定する場合だけ
とする。
#
後置式
後置式は,左から右に結びついていく。
後置式
3
一次式
後置式
S
式
T
後置式
式並び
単純型指定子
式並び
33
入れ子名前指定子
識別子
式並び
33
入れ子名前指定子
テンプレート識別子
式並び
後置式
(
識別子式
後置式
V
識別子式
後置式
(
擬似デストラクタ名
後置式
V
擬似デストラクタ名
後置式
))
後置式
VV
P
型識別子
式
P
型識別子
式
P
型識別子
式
P
型識別子
式
式
型識別子
式並び
3
#
代入式
式並び
代入式
擬似デストラクタ名
3
33
入れ子名前指定子
型名
33
X
型名
33
入れ子名前指定子
テンプレート識別子
33
X
型名
33
入れ子名前指定子
X
型名
#
配列の添字付け
ある後置式の後ろに角括弧に囲まれた式が続く場合,それは後置式とする。前の式は,
:
へのポインタ
;
という型でなければならず,後の式は,列挙型 又は 汎整数型でなければならない。結果は,型
の
左辺値とする。その型
は,完全に定義されたオブジェクト型でなければならない
。 式
8LS8+T
は,
( 規定によっ
て )
!8L)8+
と同一とする。
参考
!
及び
)
の詳細は,
#
及び
#)
で規定し ,配列の詳細は,
で規定する。
#
関数呼出し
関数呼出しには,二つの種類,すなわち,通常の関数呼出し 及び メンバ関数(
*
)呼出しがあ
る
。関数呼出しの場合,後置式の後ろに括弧でくくられて,コンマで区切った式の並び(空であってもよい。)が
続く。そこに並んだ式が,その関数の実引数となる。通常の関数呼出しの場合,その後置式は,関数を参照する左辺
値(この場合,その後置式に対する関数からポインタへの標準変換(
)は,抑止される。),又は 関数型へのポイ
ンタのいずれかでなければならない。式を介して関数を呼び出す場合,その式の関数型に言語結合があり,それが呼
び出される関数の定義での関数型の言語結合と異なっているときは,その関数呼出しは,未定義とする(
)#
参照)
。
メンバ関数呼出しの場合,その後置式は,次のいずれかでなければならない。
―
暗黙のクラスメンバアクセス(
*
及び
*
) 又は 明示的なクラスメンバアクセス(
##
)であって,
その《識別子式》が関数メンバ名であるもの
―
メンバポインタ式(
##
)であって,ある関数メンバを選択するもの
その後置式にある最初の式をオブジェクト式といい,その呼出しは,そのオブジェクト式が指している 又は 参照して
いるオブジェクトのメンバに対して行われる。暗黙のクラスメンバアクセスの場合,その暗黙に想定されるオブジェ
クトは,
が指しているオブジェクトとする。
参考
という形式のメンバ関数呼出しは,
!(
と解釈される(
*
参照)
。
関数名 又は メンバ関数名の場合,その名前が多重定義(
)されていることもある。その場合,
の規則に従っ
て適切な関数が選択される。メンバ関数呼出しで呼び出す関数は,通常,オブジェクト式の静的な型に従って選択さ
れる(
参照)
。ただし,その関数が仮想関数であり,かつ《修飾付き識別子》を用いて指定していない場合,実際
に呼び出される関数は,オブジェクト式の動的な型の中で選択された関数の最終上書き関数(
)となる。
参考 ここで,その動的な型とは,そのオブジェクト式のその時点の値が指している 又は 参照しているオブ
ジェクトの型とする。そのオブジェクト式が,構築中 又は 解体中のオブジェクトを参照する場合の仮想
関数呼出しの挙動については,
)
で規定する。
呼び出される関数の宣言が,呼び出す側の有効範囲から見えない場合,そのプログラムは,不適格とする。
関数呼出しの式の型は,静的に( すなわち,キーワード
は無視して)選択した関数の返却値の型とする。
その型は,実際に呼び出される関数の型と異なっていることがある。その型は,完全オブジェクト型,参照型 又は
0
3
型のいずれかでなければならない。
関数が呼び出されたとき,個々の仮引数(
#
)は,対応する実引数によって初期化される(
#
,
及び
参照)
。関数が非静的メンバ関数の場合,その関数の中の
(
*
)は,この呼出しのオブジェクトへのポインタ
に初期化され,あたかも明示的型変換(
#
)が行われるかのように変換される。
参考 この変換に対するアクセス検査は,行われない。アクセス検査は( 暗黙的でもよいが )クラスメンバア
クセス演算子の中で行われる(
参照)
。
関数が呼び出されたとき,オブジェクト型の仮引数は,完全に定義されたオブジェクト型でなければならない。
参考 ただし,仮引数が不完全なクラス型へのポインタ 又は 参照であっても構わない。しかし,値渡しの仮
引数が不完全型であってはならない。
処理系は,仮引数の初期化において,対応する実引数に対して施す( 複数の)変換 及び/又は 仮引数の初期化用一時
変数の構築をうまく組み合わせて,余分な一時変数の構築を省いてもよい(
参照)
。仮引数の生存期間は,その
注
このことは,慣用的な書き方(
'()
)の中での添字演算子にもあてはまる。
注
静的なメンバ関数(
)は,通常の関数とする。
##
仮引数を定義している関数から戻る時点で終了する。個々の仮引数の初期化 及び 解体は,呼出し側の文脈中で行う。
参考 コンストラクタ,変換関数 又は デストラクタに対するアクセス検査は,呼び出す側で関数を呼び出す時
点で行われる。関数仮引数に対するコンストラクタ 又は デストラクタが例外を送出した場合,ハンド ラ
の探索は,呼び出す側の関数有効範囲の中から始まる。特に,呼び出される関数の中に《関数監視ブロッ
ク》
(
#
)があって,そこにその例外を処理できるハンド ラがあったとしても,そのハンド ラは,無視さ
れる。
関数呼出しの値は,呼び出された関数が返却する値とする。ただし ,仮想関数の呼出しにおいて,最終上書き関数の
返却値の型が,静的に選択される関数の返却値の型と異なる場合,最終上書き関数の返却値は,静的に選択される関
数の返却値の型に変換される。
参考
関数は,定値でない仮引数の値を変更できるが,仮引数が参照型(
)である場合を除いて,その変
更が実引数の値に影響を与えることはない。その参照が
!
修飾の型への参照である場合,実引数の値
を変更するには,
を用いてその定値性を消す必要がある。仮引数が
付きの参照型の場
合,必要に応じて一時オブジェクトが作られる(
)#
,
,
,
及び
参照)
。さらに,
ポインタの仮引数を介して,定値でないオブジェクトの値を変更することができる。
関数の宣言のしかたによって( 省略時実引数(
(
)を宣言して )その関数の定義で定めた仮引数の個数よりも
少ない実引数を指定することができるし [ 省略記号
(((
(
#
)を使うことによって]それよりも多い個数の実引
数を指定することもできる。
参考 このことは,省略記号(
(((
)がある場合を除いて,それぞれの実引数には,一つの仮引数が対応する
ことを意味する。
ある実引数に対応する仮引数がない場合でも,受取り側の関数の中で
(
)
)を呼び出すことによってそ
の実引数の値を得ることができるので,その実引数を渡すことができる。左辺値から右辺値への標準変換(
),配
列からポインタへの標準変換(
) 及び 関数からポインタへの標準変換(
)が,実引数の式に対して行われる。
その変換の後で,実引数の型が,算術型,列挙型,ポインタ型,メンバへのポインタ型 又は クラス型のいずれでもな
い場合,そのプログラムは,不適格とする。実引数の型が
"
互換でないクラス型(
*
)の場合,その挙動は未定義と
する。実引数の型が,汎整数昇格(
#
)の対象となる汎整数型 若しくは 列挙型,又は 浮動小数点昇格(
(
)の対
象となる浮動小数点型の場合,その呼出しの前に,実引数の値を昇格先の型に変換する。これらの昇格のことを,既
定の実引数昇格という。
複数の実引数の間の評価順序は,規定しない。実引数の式の評価によるすべての副作用は,関数に入る前に完了す
る。後置式 及び 実引数並びの評価の順序についても規定しない。
(
(
)という名の関数を除き,再帰呼出しを行うことができる。
関数呼出しは,その結果の型が参照の場合に限り,左辺値とする。
#
明示的型変換(関数的記法) 《単純型指定子》
(
)#
)の後に括弧で囲まれた《式並び》が続いた場合,そ
の《式並び》に与えられた値から,指定した型の値を構築する。その《式並び》がただ一つの式から成る場合,その
型変換の式は,対応するキャスト式(
#
)と同等とする( 規定の有無について同等とし,規定があれば,その意味に
おいて同等とする。)
。
《単純型指定子》がクラス型を指定している場合,そのクラス型は,完全でなければならない。
《式並び》に二つ以上の値を指定している場合,その型は,適切に宣言されたコンストラクタ(
#
及び
参照)
をもつクラスでなければならず,式
L
+
(((
は,
L
+
(((
という宣言と同等の効果をもつ。す
なわち,一時的変数
を導入し ,式の結果は,右辺値としての
の値となる。
が,配列でない完全オブジェクト型 又は
型(
0
修飾付きでもよい。)に対する《単純型指定子》
(
)#
)
のとき,式
は,指定した型の右辺値を作るが,その値は,値初期化される(
#
参照。ただし ,
の場合
は,初期化を行わない。)
。
参考
が
0
修飾付きの非クラス型の場合,結果となる右辺値の型を決めるとき,その
0
修飾子は,無視さ
れる(
参照)
。
#
擬似デスト ラクタの呼出し ド ット演算子
(
又は 矢印演算子
V
の後ろに《擬似デストラクタ名》を付けた
表現は,型名の表す非クラス型に対するデストラクタを表す。その結果は,関数呼出し演算子
の演算対象にしか
使ってはならず,その呼出し結果の型は,
型とする。その効果は,ド ット 又は 矢印の前にある《後置式》を評
価することだけとする。
ド ット演算子の左辺は,スカラ型でなければならない。矢印演算子の左辺は,スカラ型へのポインタでなければな
らない。そのスカラ型は,そのオブジェクトの型とする。
《擬似デストラクタ名》が示す型は,そのオブジェクト型と
#(
同じでなければならない。更に,次の形式の《擬似デストラクタ名》の中の二つの《型名》は,同じ スカラ型でなけ
ればならない。
33
入れ子名前指定子
型名
33
X
型名
そのオブジェクト型の
0
修飾なし版 及び 《擬似デストラクタ名》の指す型の
0
修飾なし版は,同じ型でなければ
ならない。
##
クラスメンバアクセス
後置式の後ろに,ドット
(
又は 矢印
V
があり,その後にキーワード
(
)
があり(ないこともある。),更に《識別子式》が続いた場合,それは一つの後置式とする。ド ット 又は 矢印の前の
後置式は,評価される
。その評価の結果が 《識別子式》と併せて,全体としての後置式の結果を決める。
第
の形(ド ット )の場合,最初の式(オブジェクト式)の型は,
( 完全型の)
:
クラスオブジェクト
;
でなければ
ならない。第
の形( 矢印)の場合,最初の式(ポインタ式)の型は,
( 完全型の )
:
クラスオブジェクトへのポイン
タ
;
でなければならない。これらの場合 《識別子式》は,そのクラスのメンバ 又は そのクラスの基底クラスのメン
バを指すものとしなければならない。
参考
クラスの名前は,クラス有効範囲内にある(
*
参照)ので,クラスの名前は,そのクラスの入れ子になっ
たメンバとしても扱える。
参考
#
で,演算子
(
及び 演算子
V
の後ろにある名前の検索方法を規定している。
8L
が型
:
クラス
へのポインタ
;
である場合,式
8LV8+
は,それと同等な形式
!8L(8+
に変換される。
##
のこの文以降では,第
の形(ド ット )の場合だけを取り上げて規定する
。
:
オブジェクト式
(
《識別子式》
;
を,
8L(8+
と略記する。式
8L(8+
の型 及び 左辺値の特性は,次のとおりに決まる。
##
のこの文以降では,
を使っ
て
付き 又は
なしの状況を表し ,
を使って
付き 又は
なしの状況を表し ,
を
使って
0
修飾子の任意の集合を表す(
*
参照)
。
8+
が型
:
への参照
;
をもつとして宣言した場合,
8L(8+
は,左辺値とし ,
8L(8+
の型は,
とする。そうでない
場合は,次による。
―
8+
が静的データメンバであり,
8+
の型が
であるとき,
8L(8+
は,左辺値とする。その式は,そのクラ
スの名前付きメンバを指す。
8L(8+
の型は,
とする。
―
8+
が非静的データメンバであり,
8L
の型が
:
;
であり,かつ
8+
の型が
:
;
であると
き,その式は,最初の式
8L
の指すオブジェクトの名前付きメンバを指す。
8L
が左辺値のとき,
8L(8+
は,
左辺値とする。
という記法を使って
と
との和集合を表わすこととする。すなわち,
又
は
が
のとき,
は
とする。同様に,
という記法を使って
と
の
和集合を表わすこととする。すなわち,
又は
が
のとき,
は
とする。
8+
が変更
可能なメンバの場合,
8L(8+
の型は,
:
;
とする。
8+
が変更可能でない場合,
8L(8+
の型は,
:
;
とする。
―
8+
が( 多重定義されているかもしれない)メンバ関数である場合,関数多重定義解決(
)によって,
8L(8+
が,静的メンバ関数 又は 静的でないメンバ関数のいずれを参照するかが決まる。
それが静的メンバ関数を参照しており,
8+
の型が
:
を返す関数
仮引数型並び
;
である場合,
8L(8+
は,左辺値とする。その式は,その静的メンバ関数を指す。
8L(8+
の型は,
8+
の型と同
じ ,すなわち
:
を返す関数
仮引数型並び
;
とする。
そうではなく,
8L(8+
が非静的メンバ関数を参照していて,
8+
の型が
:
を返す関数
仮引
数型並び
;
である場合,
8L(8+
は,左辺値とならない。その式は,非静的メンバ関数を指す。
その式は,メンバ関数呼出し(
*
)の左辺の演算対象としてだけ使える。
参考
式を囲む冗長な括弧は,無視される(
#
参照)
。
8L(8+
の型は,
:
を返す関数
仮引数型並び
;
とする。
―
8+
が入れ子型
!3
1
(
*
参照)である場合,その式
8L(8+
は,不適格とする。
―
8+
が メンバ列挙子であって
8+
の型が
である場合,式
8L(8+
は,左辺値ではない。
8L(8+
の型は,
と
する。
参考
:
クラスオブジェクト
;
は,構造体(
*
)であってもよいし,共用体(
*
)であってもよい。クラスに
ついては,
*
で規定する。
注
評価結果が全体の後置式の値を決めるのに必要ない場合でも(例えば《識別子式》が静的メンバを指す場合でも),評価が行われる。
注
*+
が型
クラス
へのポインタ
の場合,
*+
は,左辺値となる。
#)
#(
増加と減少
後置演算子
))
を作用させて得る値は,演算子を作用させる前の演算対象の値とする。
参考
得た値は,元の値のコピーとする。
この演算子の演算対象は,変更可能な左辺値でなければならない。演算対象の型は,算術型か,完全オブジェクト型
へのポインタかのいずれかでなければならない。結果を得た後で,そのオブジェクトの値は,
が加算された値に変
更する。ただし ,オブジェクトが
%
型の場合には,
を設定する。
参考 この使い方は,推奨されない( 附属書
5
参照)
。
結果は,右辺値とする。結果の型は,演算対象の型の
0
修飾なし版とする(
#)
及び
#)
参照)
。
後置演算子
VV
は,後置演算子
))
に類似して,その演算対象の値を減少させる。ただし ,その演算対象を
%
型
としてはならない点が異なる。
参考
前置演算子の増加 及び 減少は,
#
で規定する。
#)
動的キャスト
動的キャストの式
の結果は,式
を型
に変換した結果とする。
は,
完全クラス型へのポインタ 若しくは 参照,又は
:
へのポインタ
;
のいずれかでなければならない。動的キャ
ストの中で,型を定義してはならない。演算子
によって定値性を消してはならない(
#
参照)
。
がポインタ型である場合,
は,完全クラス型へのポインタの右辺値でなければならない。その結果は,型
の
右辺値とする。
が参照型である場合,
は,完全クラス型の左辺値でなければならない。その結果は,型
を参照
する左辺値とする。
要求された結果の型( 便宜上,ここではそれを
と呼ぶ。)と
の型とが同じ場合,又は
が
の型よりも多く
0
修飾されていることを除いて
と
の型とが同一である場合,その結果は ( 必要な場合には変換された )
と
する。
がポインタであって,
の値が空ポインタ値である場合,その結果は,型
の空ポインタ値とする。
"
を
#
の基底クラスとし ,
を
:
"
へのポインタ
;
とし ,かつ
が型
:
#
へのポインタ
;
である場合,その
結果は,
の指す
#
型オブジェクトの一意な
"
型部分オブジェクトへのポインタとする。同様に,
"
を
#
の基底クラ
スとし,
を
:
"
への参照
;
とし,かつ
が型
:
#;
である場合,その結果は,
が参照する
#
型オブジェクト
の一意な
"
型部分オブジェクト
の左辺値とする。ポインタ 及び 参照のど ちらの場合でも,
は,
と同じ
か それより多い
0
修飾でなければならず,
"
は,
#
のあいまいでない基底クラスとしてアクセス可能でなければな
らない。
例
"
Q
R
&
#
3
"
Q
R
&
#!
Q
"!
%
P"!
&
''
"!
%
&
と同等
R
上のいずれでもない場合,
は,多相型(
)へのポインタ 又は 多相型の左辺値のいずれかでなければならない。
が
:
へのポインタ
;
である場合,その結果は,
の指す最派生オブジェクトへのポインタとする。そうで
ない場合,実行時の検査を行い,
が指す 又は 参照するオブジェクトを,
が指す 又は 参照する型に変換できるか
ど うかを調べる。
その実行時の検査は,論理的には次のとおりに行う。
―
の指す( 又は 参照する)最派生オブジェクトの中で,
が型
のオブジェクトの公開基底クラスの部
分オブジェクトを指し ,かつ
の指す( 又は 参照する)部分オブジェクトから型
のオブジェクトが一
つだけ派生している場合,その結果は,
型オブジェクトへのポインタ( 又は それを参照する左辺値)と
する。
―
そうでない場合,
が最派生オブジェクトの公開基底クラスの部分オブジェクトを指し( 又は 参照し ),
最派生オブジェクトが
のあいまいでない公開基底クラスをもつ場合,その結果は,最派生オブジクトの
型部分オブジェクトへのポインタ( 又は それを参照する左辺値)とする。
―
上のいずれでもない場合,実行時の検査に失敗したとする。
ポインタ型へのキャストに失敗した場合のキャストの値は,要求される結果の型の空ポインタ値とする。参照型へ
のキャストに失敗した場合は,例外
を送出する(
#
参照)
。
例
6
Q
&
R&
注
が指す 又は 参照する最派生のオブジェクト(
)がこれ以外の
,
オブジェクトを基底クラスとしてもっていてもよいが,それら
は無視される。
#
"
Q
&
R&
#
3
6
"
Q
R&
Q
#
&
"!
%
"!0&
''
保護を破るためにキャストが必要。
6!
%
0&
''
公開の派生であり,キャスト不要。
#0
%
P#0
!
&
''
失敗
%
P6!
&
''
失敗
%
P"!
&
''
失敗
%
P6!
0
&
''
成功
%
P"!
0
&
''
失敗
R
8
3
#
"
Q
R
&
9
3
8
#
Q
R
&
Q
9
&
6!
%
0
&
''
成功
3
一意な
6
が見つかる。
#!
%
P#!
&
''
失敗
3
.
を生じる。
に二つの
''
#
型部分オブジェクトがある。
8!
%
8!
&
''
不適格
3
仮想基底からのキャスト。
8!
L
%
P8!
&
''
成功
R
参考
構築中 又は 解体中のオブジェクトに動的キャストを適用したときの挙動については,
)
で規定する。
#
型の識別
が《式》に作用したときの結果は,静的な型
33
(
#
) 若しくは
動的な型
33
の左辺値,又は
とする。ここで,
は,
33
から派
生した処理系定義のクラスとし,
#
に規定する動作を行うクラスとする
。この左辺値が参照するオブジェク
トの生存期間は,プログラム終了までとする。プログラム終了時に
オブジェクトのデストラクタが呼び出
されるか否かについては,規定しない。
が多相的クラス型(
)の左辺値の《式》に作用した場合,その結果は,その左辺値が参照する最派生オ
ブジェクト(
)
(すなわち動的な型のオブジェクト )の型を表す
オブジェクトの参照とする。その左辺
値の式がポインタに単項演算子
!
を適用して得られたもの
であって,そのポインタが空ポインタ値(
)の
場合,
をその式に作用させたときには,例外
(
#
)を送出する。
が多相的クラス型の左辺値以外の《式》に作用した場合,その結果は,その式の静的な型を表す
のオブジェクトの参照とする。左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
),及び
関数からポインタへの標準変換(
)は,その式には適用されない。式の型がクラス型の場合,そのクラスは,完
全に定義されていなければならない。その式の評価は,行われない。
が《型識別子》に作用した場合,その結果は,その《型識別子》の型を表す
のオブジェクトの
参照とする。
《型識別子》の型が参照型の場合,その
式の結果は,その参照型を表す
のオブジェク
トの参照とする。
《型識別子》の型がクラス型であるか,クラス型への参照である場合,そのクラスは,完全に定義
されていなければならない。型は,その《型識別子》の中で定義してはならない。
の演算対象になっている左辺値式 又は 《型識別子》の最上位の
0
修飾子は,常に無視される。
例
#
Q
(((
R
&
#
L
&
#
+
&
L
%%
+
&
''
となる。
#
%%
#
&
''
となる。
#
%%
+
&
''
となる。
#
%%
#0
&
''
となる。
ヘッダ
(
#
)を
を用いる前に取り込んでいない場合,そのプログラムは,不適格とする。
参考
解体中のオブジェクトに
を作用させたときの挙動については,
)
で規定する。
注
このクラスの名前としては,
(&&
%
を推奨する。
注
をポインタ型の式とするとき,
,
,
,
,
などが,これに当たる。
#*
#*
静的キャスト
静的キャストの式
の結果は,式
を型
に変換した結果とする。
が
参照型の場合,その結果は,左辺値とする。そうでない場合,その結果は,右辺値とする。静的キャストの中で,型
を定義してはならない。演算子
は,定値性を消してはならない(
#
)
。
静的キャスト
を使って式
を型
に明示的に変換することができるのは,一時的変数(
#
)
を導入した宣言
&
が適格となる場合とする。その明示的変換の効果は,一時的変数
を宣言し初期化した上
で,変換結果として
を使うことと同じとする。その結果は,
が参照型(
)の場合は左辺値とし ,そうでな
い場合は右辺値とする。式
は,
の初期化が
を左辺値として使っている場合かつその場合に限り,左辺値として
使われる。
そうでない場合,静的キャストは,次に列挙する変換のいずれかを行う。これらを除く明示的な変換は,静的キャ
ストによって行ってはならない。
すべての式は,明示的に型
:
;
に変換することができる。その式の値は,捨てられる。
備考 しかし,その値が一時的変数(
)のものである場合,その変数に対するデストラクタは,通常の時
点まで実行されず,その変数の値は,デストラクタを実行するために保持される。
左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
),及び 関数からポインタへの標準変
換(
)は,式には適用されない。
"
がクラス型であって,
#
が
"
の派生型(
)である場合,次の条件をすべて満たすときには,型
:
";
の左辺
値を,型
:
#
への参照
;
にキャストすることができる。
―
:#
へのポインタ
;
から
:"
へのポインタ
;
への正当な標準変換が存在する(
参照)
。
―
が,
と同じか 又は より多く
0
修飾されている。
―
"
は,
#
の仮想基底クラスではない。
その結果は,型
:
#;
の左辺値とする。型
:
";
の左辺値が,実際は型
#
のオブジェクトの部分オブジェクトで
ある場合,その左辺値は,型
#
を囲むオブジェクトを参照する。そうでない場合,キャストの結果は,未定義とする。
例
"
Q
R
&
#
3
"
Q
R
&
#
&
"
0
%
&
P#0
&
''
元のオブジェクト
への左辺値を生成する。
標準変換手順(
)の逆変換は,左辺値から右辺値への変換(
),配列からポインタへの変換(
),関数か
らポインタへの変換(
) 及び 真理値変換(
)を除き,静的キャストを明示的に使うことによって行うことが
できる。この静的キャストの演算対象にも,左辺値から右辺値への変換(
),配列からポインタへの変換(
),
関数からポインタへの変換(
) 及び 真理値変換(
)が適用される。この静的キャストは,定値性(
#
)
を消してはならない。更に,この静的キャストには,個々の場合に対しての追加規則を設ける。
汎整数型 又は 列挙型の値は,明示的に列挙型に変換することができる。元の値が変換先の列挙型の値の範囲内に
ある場合,その結果の値は元の値のままとする(
)
参照)
。そうでない場合,結果の列挙型の値は,未規定とする。
"
を基底クラスとし ,
#
を
"
の派生クラスとする。次の条件をすべて満たす場合,型
:
"
へのポインタ
;
の右辺
値は,型
:
#
へのポインタ
;
の右辺値に変換することができる。
―
:#
へのポインタ
;
から
:"
へのポインタ
;
への正当な標準変換が存在する。
―
が
と同じか 又は より多く
0
修飾されている。
―
"
が
#
の仮想基底クラスではない。
空ポインタ値(
)は,目的の型の空ポインタ値に変換される。型
:
"
へのポインタ
;
の右辺値が,実際に型
#
のオブジェクトの
"
型部分オブジェクトを指す場合,結果のポインタは,それを包む型
#
のオブジェクトを指す。そ
うでない場合,キャストの結果は,未定義とする。
"
を
#
の基底クラスとする。次の条件をすべて満たす場合,型
:
型の
#
のメンバへのポインタ
;
の右辺値は,
型
:
型の
"
のメンバへのポインタ
;
の右辺値に変換することができる。
―
型
:
型の
"
のメンバへのポインタ
;
から型
:
型の
#
のメンバへのポインタ
;
への正当な標準変換(
)
が存在する。
―
が
と同じか 又は より多く
0
修飾されている。
注
関数型( メンバ関数型へのポインタの中で使われる関数型を含む。)が
"#
修飾されることはない(
参照)
。
(
空メンバポインタ値(
)は,目的の型の空メンバポインタ値に変換される。クラス
"
が元のメンバを含む場合,
又は
"
が元のメンバを含むクラスの基底クラス 若しくは 派生クラスである場合,結果のメンバポインタは,元のメ
ンバを指す。そうでない場合,キャストの結果は,未定義とする。
参考
クラス
"
は,元のメンバを含んでいる必要はないが,メンバポインタの参照はずしの対象になっている
オブジェクトの動的な型は,元のメンバを含んでいなければならない(
##
参照)
。
型
:
へのポインタ
;
の右辺値は,型
:
へのポインタ
;
の右辺値に変換することができる。ここで,
はオブジェクト型とし,
は,
と同じか 又は より多く
0
修飾されているとする。オブジェクトへのポインタ
型の値は,
:
へのポインタ
;
に変換した後で元のポインタ型に戻すと,元の値に戻る。
#
強制キャスト
強制キャストの式
の結果は,式
を型
に変換した結果とす
る。
が参照型の場合,結果は左辺値とする。そうでない場合,結果は右辺値とし ,左辺値から右辺値への標準変換
(
),配列からポインタへの標準変換(
),及び 関数からポインタへの標準変換(
)を式
に対して行う。
強制キャスト内で,型を定義してはならない。強制キャストで明示的に行うことができる変換を次に列挙する。それ
ら以外の変換は,強制キャストで明示的に行うことはできない。
演算子
は,定値性を消すことがあってはならない。
参考
:
定値性を消すキャスト
;
については,
#
で規定する。ここでの制約に従っている限り,演算子
を使って,式をそれ自身の型にキャストしてもかまわない。
強制キャストが行う写像は,処理系定義とする。
参考
元の値と異なる表現を生じてもよいし ,同じままでもよい。
ポインタは,それを保持するのに十分な大きさをもつ任意の汎整数型に明示的に変換することができる。その写像
関数は,処理系定義とする。
参考
想定するマシンのアドレス機構を知っている人には驚くほどではないであろう。
汎整数型 又は 列挙型の値は,明示的にポインタに変換することができる
。ポインタは,十分な大きさの整数
(そういうものが処理系にあった場合)に変換した上で,同じポインタ型に戻すと元の値になる。そうでない場合,ポ
インタと整数との間の値の写像は,処理系定義とする。
関数へのポインタは,別の型の関数へのポインタに明示的に変換することができる。ある関数の定義で用いられた
関数型(
#
)とは異なる関数型へのポインタを介して関数呼出しを行った効果は,未定義とする。型
:
へのポ
インタ
;
の右辺値から型
:
へのポ インタ
;
(ここで
及び
は,関数型とする。)へのポインタ変換の結果は,
それを元の型に戻すと元のポインタ値に戻ることを除いて,未規定とする。
参考 ポインタ変換の詳細については,
で規定する。
オブジェクトへのポインタは,別の型のオブジェクトへのポインタに明示的に変換することができる
。型
:
へのポインタ
;
の右辺値から型
:
へのポインタ
;
へのポインタ変換(ここで,
及び
はオブジェクト型であっ
て,
の境界調整要求が
よりも厳しくないとする。)の結果は,それを元の型に戻したときに元の値に戻ること
を除いて,未規定とする。
空ポインタ値(
)は,目的の型の空ポインタ値に変換される。
及び
が,ともに関数型 又は ともにオブジェクト型である場合,型
:
型の
のメンバへのポインタ
;
の右
辺値は,型
:
型の
のメンバへのポインタ
;
に明示的に変換することができる
。空メンバポインタ値(
)
は,目的の型の空メンバポインタ値に変換することができる。その変換結果は,次の場合を除き,未規定とする。
―
型
:
メンバ関数へのポインタ
;
の右辺値を,別の型
:
メンバ関数へのポインタ
;
に変換し ,それを元の型に
戻した場合,元のメンバポインタ値に戻る。
―
型
:
型の
のメンバへのポインタ
;
の右辺値を,型
:
型の
のメンバへのポインタ
;
に変換し(こ
こで,
の境界調整要求は,
よりも厳し くないとする。),それを元の型に戻した場合,元のメンバ
ポインタ値に戻る。
型
:
へのポインタ
;
の式を,型
:
へのポインタ
;
に強制キャストで明示的に変換できる場合,型
の左辺値
の式は,型
:
への参照
;
にキャストすることができる。すなわち,参照の強制キャスト
0
は,組込み演算子
0
及び
!
を使った変換
!
!0
と同じ効果をもつ。結果は,元の左辺値と
注
汎整数の定数式(
)で値がゼロのものを変換すると,常に空ポインタ(
)となる。しかし ,それ以外の式で値がたまたまゼ
ロのものを変換しても,空ポインタとなるとは限らない。
注
それらの型は,強制キャストが定値性を消してはならないという全体としての制約を満たしている限り,その
"#
修飾子が異なってい
てもよい。
注
強制キャストが定値性を消してはならないという全体的な制約を満足している限り,
及び
は,その
"#
修飾子が異なっていて
もよい。
(
同じオブジェクトを参照する左辺値となるが,型は異なる。一時的変数を作らず,コピーも行わず,コンストラクタ
関数(
)もデストラクタ関数(
)も呼び出さない。
#
定値性キャスト
定値性キャストの式
の結果は,型
をもつ。
が参照型の場合,結
果は,左辺値とする。そうでない場合,結果は右辺値とし,左辺値から右辺値への標準変換(
),配列からポイン
タへの標準変換(
) 及び 関数からポインタへの標準変換(
)を式
に対して行う。定値性キャスト内で,型
を定義してはならない。定値性キャストで明示的に行うことができる変換を次に列挙する。それ以外の変換は,定値
性キャストで明示的に行ってはならない。
参考 ここでの制約を満たしている限り,
演算子を使って,式をそれ自身の型にキャストしても
よい。
二つのポインタ型
及び
について,
が,
へのポインタ
への…ポインタ
へのポイン
タ
であって,
が,
への
ポインタへの…
ポインタへの
ポインタである場合(こ
こで,
は,任意のオブジェクト型 又は
型とし ,
と
とが異なる
0
修飾であってもよい。),
型
の右辺値は,定値性キャストで明示的に
型に変換することができる。ポインタの定値性キャストの結果は,元の
オブジェクトを参照する。
へのポ インタが定値性キャストによって
へのポインタ型に明示的に変換できる場合( ここで
及び
は,共にオブジェクト型とする。),型
の左辺値は,
0
によって型
の左辺値に変換すること
ができる。定値性キャストの参照の結果は,元のオブジェクトを参照する。
データメンバへのポインタ,データメンバへの多重レベルポインタ 及び ポインタとデータメンバへのポインタと
が混合した多重レベルポインタ(
)に対する定値性キャストの場合についても,
の規則は,ポインタ
に対するのと同じとする。メンバへのポインタの
:
メンバ
;
という属性は,定値性キャストで加えたり落としたりす
る
0
修飾子を決める際には無視される。データメンバへのポインタの定値性キャストの結果は,データメンバへの
元の(キャスト前の )ポインタと同じ メンバを参照する。
空ポインタ値(
)は,目的の型の空ポインタ値に変換される。空メンバポインタ値(
)は,目的の型の空
メンバポインタ値に変換される。
参考 オブジェクトの型に依存するが,定値性キャストを使って定値修飾子
を落としてしまって得たデー
タメンバのポインタ,左辺値 又は ポインタを介して書込みを行なうと,未定義の動作(
)#
)を生じ
るかもしれない。
定値性を消すキャストの手順は,次による。ここで,
及び
は,型を示す。次の
及び
を二つのポイ
ンタ型とする。
は,
!
…
!
とし ,
は,ポインタ型ではないとする。
は,
!
…
!
とし ,
は,ポインタ型ではないとする。
を,
とする。
から
へのキャストによって定値性を消すことができる条件は,ある非ポインタ型
に対し ,
…
から
…
への暗黙の変換(
)が存在しない場合とする。
型
:
へのポインタ
;
の右辺値から型
:
へのポインタ
;
の右辺値へのキャストが定値性を消すことができる場
合,参照型にキャストして型
の左辺値から型
の左辺値にすることによって定値性を消すことができる。
型
:
型のデータメンバ
へのポ インタ
;
の右辺値から,型
:
型のデータメンバ
へのポインタ
;
の右辺値
へのキャストが定値性を消すことができるのは,型
:
へのポインタ
;
の右辺値から型
:
へのポインタ
;
の右辺値
へのキャストが定値性を消すことができる場合とする。
メンバへの多重レベルポインタ,ポインタと メンバへのポインタとが混合した多重レベルポインタ(
)に対し
て,
という
0
修飾子がキャストで消すことができるか否かを決めるとき,メンバへのポインタの
:
メンバ
;
と
いう属性は,無視される。
注
この変換を,英語では
(
(型の語呂合わせ)と言うことがある。
注
定値性キャストは,定値修飾子を落とす変換だけに制限されているのではない。
(
参考
0
修飾だけを変更する変換の中には,定値性キャストを使って実行できないものもある。例えば ,関数
へのポインタど うしの変換は,その変換によって未定義の動作を起こす値が生じるので,対象になってい
ない。同様の理由で,メンバ関数間の変換,特に,定値のメンバ関数へのポインタから,定値でないメン
バ関数へのポインタにする変換は,対象になっていない。
#
単項式
単項演算子をもつ式は,右から左に結びついていく。
単項式
3
後置式
))
キャスト式
VV
キャスト式
単項演算子
キャスト式
$
単項式
$
型識別子
<
式
3
式
単項演算子
3
次のいずれか
!
0
)
V
[
X
#
単項演算子
単項演算子
!
は,間接参照を行う。それが作用する式は,オブジェクト型へのポインタ 又は 関
数型へのポ インタでなければならず,結果は,その式が指すオブジェクト 又は 関数を参照する左辺値とする。式の
型が
:
へのポインタ
;
である場合,結果の型は,
とする。
参考
不完全型へのポインタは,
の場合を除き,参照をはずすことができる。得られた結果の左辺値
は,限られた方法で( 例えば ,参照を初期化するために )だけ使える。その左辺値は,右辺値に変換して
はならない(
参照)
。
単項演算子
0
の結果は,その演算対象へのポインタとする。演算対象は,左辺値 又は 《修飾付き識別子》でなけ
ればならない。演算対象が左辺値の場合,その式の型が
のとき,結果の型は,
:
へのポインタ
;
とする。特に,型
:
;
のオブジェクトのアドレスは,
:
へのポインタ
;
となる(
0
修飾子は変わらない。)
。演算対象が《修飾
付き識別子》の場合,メンバが型
の静的メンバのとき,結果の型は,単なる
:
へのポインタ
;
とする。メンバが
型
のクラス
7
の非静的メンバのとき,結果の型は,
:
型
のクラス
7
のメンバへのポインタ
;
とする。
例
6
Q
&
R&
"
3
6
Q
R
&
(((
0"33
(((
''
633!
という型をもつ。
参考
%
属性の非静的データメンバ(
)
)から成るメンバへのポインタは,その非静的データメンバ
に関する
%
指定子を反映しない。
メンバへのポインタが形成されるのは,明示的に
0
を使用し ,その演算対象を括弧なしの《修飾付き識別子》にし
たときにだけとする。
参考
すなわち,
《修飾付き識別子》に括弧をつけた式
0
《修飾付き識別子》
は,
:
メンバへのポインタ
;
と
いう型の式を形成しない。非静的メンバ関数を指す《修飾付き識別子》から型
:
メンバ関数へのポインタ
;
への暗黙の変換が存在しない( 関数への左辺値から
:
関数へのポインタ
;
(
)への変換は存在する。)の
で,
《修飾付き識別子》だけの場合も,
:
メンバへのポインタ
;
という型の式を形成しない。更に,
《修飾な
し識別子》の場合も,その修飾なし識別子のクラスの有効範囲内においてさえ,メンバへのポインタでは
ない。
不完全型のオブジェクトのアドレスを得ることができるが,そのオブジェクトの完全型がメンバ関数として
0
を宣言しているクラス型である場合には,その動作は未定義とする( 診断は,必要ない。)
。
0
の演算対象は,ビッ
トフィールド であってはならない。
多重定義関数(
)のアドレスは,どの版の多重定義関数が参照されるかが一意に決まる文脈でだけ得られる(
参照)
。
参考
文脈によって,演算対象が静的メンバ関数なのか非静的メンバ関数なのかが決まってしまうことがある
ので,文脈は,その式が型
:
関数へのポインタ
;
なのか型
:
メンバ関数へのポインタ
;
なのかを決めるのに
も影響を与える。
(
単項演算子
)
の演算対象の型は,算術型,列挙型 又は ポインタ型でなければならず,その結果は,実引数の値と
する。汎整数 又は 列挙体の演算対象に対しては,汎整数昇格が行われる。その結果の型は,昇格した演算対象の型
とする。
単項演算子
V
の演算対象の型は,算術型 又は 列挙型でなければならず,その結果は,符号を反転させた演算対象
の値とする。演算対象が汎整数 又は 列挙体の場合,汎整数昇格が行われる。符号なしの型の場合の符号反転の計算
は,
からの減算によって行われる。ここで
は,昇格した演算対象のビット数とする。結果の型は,昇格された
演算対象の型とする。
論理否定演算子
[
の演算対象は,暗黙に
%
型に変換される(
参照)
。その値は,変換された演算対象の値が
偽のとき真とし ,それ以外のとき偽とする。結果の型は
%
型とする。
X
の演算対象は,汎整数型 又は 列挙型でなければならず,結果は,演算対象の
の補数とする。汎整数昇格が行
われる。結果の型は,昇格した演算対象の型とする。
5
がクラス名の場合,単項式
X5
にはあいまい性がある。そ
のあいまい性は,
X5
をデストラクタの参照として扱うのではなく,むしろ
X
を単項の補数演算子として扱うことに
することによって解決される。
#
増加 及び 減少
接頭語
))
の演算対象には,
が加算される。ただし ,
%
型の場合には,
が設定さ
れる(この使い方は推奨されない。)
。演算対象は,変更可能な左辺値でなければならない。演算対象の型は,算術型
であるか,又は 完全に定義されたオブジェクト型へのポインタでなければならない。その値は,演算対象の新たな値
となる。それは,左辺値とする。
が
%
型でない場合,式
))
は,
)%L
と同等とする。
参考
変換については,加算(
#)
) 及び 代入演算子(
#)
)で規定している。
接頭語
VV
の演算対象には,
が減算される。演算対象は,
%
型であってはならない。接頭語
VV
の演算対象に
対する要件 及び その結果の特性は,この制限を除き,接頭語
))
と同じとする。
参考
後置式の増加,減少については,
#(
で規定している。
#
-"
演算子
演算子
$
によって,演算対象のオブジェクト表現のバイト数が得られる。演算対象は,
式 又は 括弧付きの《型識別子》のいずれかとする。式の評価は,行われない。演算子
$
は,次のいずれに対し
ても作用させてはならない。
―
関数 又は 不完全型である式
―
列挙子のすべてを宣言し終わっていない列挙型
―
これらの型の括弧付きの名前
― ビットフィールドを示す左辺値
$
,
$
及び
$
の値は,
とする。
$
をその他の基本
型(
*
)に作用させた結果は,処理系定義とする。
参考
特に
$
と
$
は,処理系定義とする。
参考 バイトについては
)
で規定し ,オブジェクト表現は
*
で規定する。
参照 又は 参照型に作用させた場合,その結果は,参照される型の大きさとする。クラスに作用させた場合,その
結果は,そのクラスのオブジェクトのバイト数とし ,その型のオブジェクトをある配列内に置くために詰め物が必要
であれば,その詰め物も含んだ値とする。最派生したクラスの大きさは,
以上とする(
参照)
。
$
を基底ク
ラス部分オブジェクトに作用させた結果は,その基底クラスの型の大きさとする
。配列に作用させた場合,結果
は,その配列の全体のバイト数とする。すなわち,
要素からなる配列の大きさは,
要素の大きさの
倍となる。
演算子
$
は,関数へのポインタには作用させてよいが,関数そのものには直接作用させてはならない。
左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
) 及び 関数からポインタへの標準
変換(
)は,
$
の演算対象には適用しない。
!J
式の中で,型を定義してはならない。
結果は,
!J
型の定数とする。
参考
$
は,標準ヘッダ
(
)の中で定義されている。
#
+
式
<
式は,
《型識別子》
(
) 又は 《生成型識別子》に作用させたとき,それらのオブジェクトを作
ろうとする。そのオブジェクトの型を,割付け型と呼ぶ。割付け型は,総体オブジェクト型でなければならず,抽象
クラス型 又は その配列としてはならない(
)
,
*
及び
参照)
。
参考
参照そのものは,オブジェクトではないので,参照を《
<
式》によって作ることはできない。
注
-%.
が
である必要はない。
注
基底クラス部分オブジェクトの実際の大きさは,その部分オブジェクトに
-%
を作用させた結果より小さくてもよい。それは,仮
想基底クラスであることと,基底クラス部分オブジェクトに対する詰め物要求がより緩いことによる。
(
参考 《型識別子》は,
0
修飾された型であってもよい。その場合《
<
式》によって作られるオブジェクト
は,
0
修飾された型になる。
<
式
3
33
生成位置指定
生成型識別子
生成初期化子
33
生成位置指定
型識別子
生成初期化子
生成位置指定
3
式並び
生成型識別子
3
型指定子列
<
宣言子
<
宣言子
3
ポインタ演算子
<
宣言子
直接
<
宣言子
直接
<
宣言子
3
S
式
T
直接
<
宣言子
S
定数式
T
生成初期化子
3
式並び
《
<
式》によって作られる実体は,動的記憶期間(
)
)をもつ。
参考 その実体の生存期間は,それが作られた有効範囲には,必ずしも制約されない。
実体が配列でないオブジェクトの場合,
《
<
式》は,作ったオブジェクトへのポインタを返す。配列の場合には,配
列の先頭要素へのポインタを返す。《
<
式》中の《生成型識別子》は 《
<
宣言子》が可能な限り長くつながった
列とする。
参考 これによって,宣言子の演算子(
0
,
!
,
S
T
)と,それらの式に当たる部分との間のあいまいさをなく
している。
例
!
&
''
構文エラー
3
!
と構文解析され,
''
!
とは解析されない。
ここで
!
は,ポインタ宣言子であって,乗算の
!
ではない。
参考 《
<
式》の《生成型識別子》中の括弧が,重大な効果を引き起こすことがある。
例
!SL.T
&
''
エラー
この式は,次のように結合されるので不適格とする。
!SL.T
&
''
エラー
そうではなくて,
演算子に明示的に括弧を付けた版は,複合型(
*
)のオブジェクトを
作るのに使うことができる。
!SL.T
&
この例は,
:
実引数がなくて
型を返却値とする
;
関数へのポインタが
個ある配列の割付
けを行う。
《型指定子列》は,クラス宣言 又は 列挙体宣言を含んでいてはならない。
割り付けたオブジェクトが配列の場合( すなわち,
《直接
<
宣言子》の構文を使う場合,又は 《生成型識別子》
若しくは 《型識別子》が配列型を示す場合)《
<
式》によって,配列の( 存在すれば )先頭要素へのポインタが得
られる。
参考
及び
SL.T
の型は,
!
になり,
STSL.T
の型は,
!SL.T
になる。
《直接
<
宣言子》中の《定数式》は,すべて汎整数定数式(
#*
)でなければならず,評価した値が正でなけれ
ばならない。
《直接
<
宣言子》中の《式》は,負でない値をもつ 汎整数型(
*
) 又は 列挙型でなければなら
ない。
例
が
型の変数である場合,
STS/T
は,
(
が,
《直接
<
宣言子》中の《式》に当たるので )
適格とする。しかし ,
S/TST
は,
(
が,
《定数式》ではないので )不適格とする。
が負の場
合,
STS/T
の効果は,未定義とする。
(#
《直接
<
宣言子》中の《式》の値がゼロの場合,割付け関数が呼び出され,要素のない配列が割り付けられる。
《
<
式》は,割付け関数(
)
)を呼び出し ,オブジェクトのための記憶域を確保する。
《
<
式》が例外を
送出して終了した場合,解放関数(
)
)を呼び出して記憶域を解放してもよい。その割付け型が配列ではない場
合,割付け関数の名称は,
とし,解放関数の名称は,
とする。その割付け型が配列
の場合,割付け関数の名称は,
ST
とし ,解放関数の名称は
ST
とする。
参考
処理系は,大域的割付け関数の省略時定義版を提供しなければならない(
)
,
及び
参照 )。
"##
のプログ ラムは,これらの関数を代替する定義(
)
) 及び/又は クラス固有の版
(
#
)をもつことができる。
《
<
式》が単項演算子
33
で始まる場合,割付け関数名の検索は,大域的有効範囲で行われる。そうではなくて,
割付け型がクラス型
又は その配列型の場合,割付け関数名の検索は,
の有効範囲内で行われる。この検索でそ
の名前が見つからなかったとき,又は 割付け型がクラス型でないときには,割付け関数名の検索は,大域的有効範囲
内で行われる。
《
<
式》は,必要とする領域の大きさを,型
33$
をもつ第
実引数として割付け関数に渡す。その実
引数は,生成するオブジェクトの大きさ以上でなければならない。オブジェクトが配列の場合に限り,生成するオブ
ジェクトの大きさよりも本当に大きくてもよい。
又は
の配列の場合《
<
式》の結果と割付け
関数が返すアドレスとの差は,生成する配列の大きさを超えない任意のオブジェクト型の中で最も厳しい境界調整要
求(
*
)の値の整数倍でなければならない。
参考
割付け関数は,どんなオブジェクト型に対しても,その型に適切に境界調整された記憶域へのポインタ
を返すと仮定されているので,配列割付けオーバヘッド に対するこの制約によって,文字配列を割り付け
た後で,そこに別の型のオブジェクトを配置しなおすという慣用手法が可能になる。
《生成位置指定》の構文は,付加的な実引数を割付け関数に供給するために使う。それが使われる場合,要求領域
量( 第
実引数) 及び 《
<
式》の《生成位置指定》部分の式( 第
実引数 及び その後続の実引数)から成る実引
数並びを組立てて作られる関数呼出しに対して,多重定義解決が実施される。その第
実引数は,
!J
型とし ,残
りの実引数は 《生成位置指定》中の式ごとの型となる。
例
―
の結果は,
$
の呼出しと同等になる。
―
+
の結果は,
$
+
の呼出しと同等になる。
―
S/T
の結果は,
ST$
!/
)
の呼出しと同等になる。
―
+
S/T
の結果は,
ST$
!/
)!
+
の呼出しと同等になる。
ここで,
及び
!
は,配列割付けオーバヘッド を表す負でない値とする( 値そのものは,未規定とす
る。)。
《
<
式》の結果は,
ST
の返却値から,この量だけ指し引いた値となる。このオー
バヘッドは,すべての配列の《
<
式》
(ライブラリ関数
ST33$
!
を参
照する場合も含む。)に適用され,位置指定割付け関数に対しても適用される。そのオーバヘッド の量は,
の呼出しごとに変わってもよい。
参考
割付け関数に空の《例外指定》
(
#
)
が宣言されていない場合,記憶域の割付けに失敗する
と,例外
が送出される(
#
及び
参照)
。失敗しなかった場合,空でないポインタ値
が返る。割付け関数に空の《例外指定》
が宣言されている場合には,記憶域割付けの失敗を空の
ポインタ値を返すことによって示し ,失敗ではないことを空でないポインタ値を返すことによって示す。
割付け関数が空を返した場合,初期化は行われていず,解放関数を呼び出されていず,
《
<
式》の値は,空になる。
参考
割付け関数が空ではない値を返した場合,その値は,そのオブジェクト用に確保された記憶域ブロック
へのポインタでなければならない。その記憶域ブロックは,適切に境界調整され要求の大きさをもつもの
としてよい。生成されたオブジェクトのアドレスは,オブジェクトが配列の場合には,そのブロックのア
ドレスに一致しないかもしれない。
型
のオブジェクトを作る《
<
式》は,そのオブジェクトを次のとおりに初期化する。
―
《生成初期化子》が省略されている場合
が,
(
0
修飾付きでもよいが )
"
互換でないクラス型( 又は その配列)のとき,オブジェク
トには,省略時の初期化がなされる(
#
参照)
。
が
!
修飾付きの型のとき,その基礎と
するクラス型は,利用者宣言された省略時コンストラクタをもっていなければならない。
そうでないとき,生成されるオブジェクトの値は,不定とする。
が
!
修飾付きの型 又は
(
0
修飾付きでもよい)
"
互換のクラス型( 又は その配列)であって,
!
修飾付きの型の
((
メンバを( 直接 又は 間接に )もつならば ,そのプログラムは,不適格とする。
―
《生成初期化子》が
:;
という形式の場合,値初期化がなされる(
#
参照)
。
―
《生成初期化子》が
:
《式並び》
;
という形式であって,
がクラス型の場合,
《式並び》を実引数と
して,適切なコンストラクタが呼び出される(
#
参照)
。
― 《生成初期化子》が
:
《式並び》
;
という形式であって,
が算術型,列挙型,ポインタ型,又は メ
ンバへのポインタ型であり,かつ 《式並び》が単一の式である場合,オブジェクトは,その式の( 必要な
らば変換された )値に初期化される(
#
参照)
。
―
いずれでもない場合,その《
<
式》は,不適格とする。
《
<
式》がクラス型のオブジェクト 又は その配列を作る場合,割付け関数,解放関数(
#
) 及び コンスト
ラクタ(
)に対し,アクセス制御 及び あいまい性制御が行われる。
《
<
式》がクラス型のオブジェクトの配列
を作る場合,デストラクタ(
)に対してもアクセス制御 及び あいまい性制御が行われる。
上で規定したオブジェクト初期化中のどこかで
例外を送出して終了した場合,適切な解放関数が見つかったと
きには,その解放関数が呼び出され,そのオブジェクトを構築しようとした記憶域を解放した後,その例外が《
<
式》の文脈で伝ぱ( 播)していく。あいまいなく合致する解放関数が見つからないときには,例外の伝ぱにおいて,
オブジェクトの記憶域の解放を実行しないことになる。
参考
呼び出された割付け関数が メモリを割り付けていない場合にはそれでよいが,そうでない場合には,結
果としてメモリリークが生じる。
《
<
式》が単項演算子
33
で始まる場合,解放関数名の検索は,大域的有効範囲で行われる。そうではない場合
であって,割付け型がクラス型
又は その配列である場合,解放関数名は,型
の有効範囲内で検索される。その
名前検索が失敗するか,又は 割付け型がクラス型 若しくは その配列でない場合,解放関数名は,大域的有効範囲内
で検索される。
位置指定解放関数の宣言が,位置指定割付け関数の宣言に合致する条件は,仮引数の個数が同じであって,仮引数
変換(
#
)を行った後で,第
仮引数を除くすべての型が同じになる場合とする。位置指定のない解放関数のすべ
ては,位置指定のない割付け関数に合致する。検索して一つだけの解放関数に合致した場合,その関数が呼び出され
る。そうでない場合,どの解放関数も呼び出されない。
《
<
式》が解放関数を呼び出すとき,割付け関数の返却値を,型
!
の第
実引数として渡す。位置指定解
放関数が呼び出されるとき,位置指定割付け関数に与えた付加的実引数の並びと同じもの,すなわち《生成位置指定》
構文で指定したのと同じ実引数の並びが渡される。処理系が割付け関数の呼出しの中でどの実引数のコピーを作る場
合も( 元と同じ値の )コピーを作って解放関数の呼出しに使ってもよいし ,割付け関数の呼出しの際に作ったコピー
を再利用してもよい。そのコピーをある場所で再利用しないとしても,別の場所でも再利用しないようにする必要は
ない。
割付け関数が,コンストラクタの実引数を評価する前に呼び出されるのか,コンストラクタの実引数を評価した後
でコンストラクタに入る前に呼び出されるかについては,未規定とする。割付け関数が空ポインタを返した場合,又
は 例外によって抜け出た場合に,コンストラクタの実引数を評価するか否かについても,未規定とする。
##
式
3
式は,
《
<
式》が作った最派生オブジェクト(
) 又は 配列を解体する。
3
式
3
33
キャスト式
33
S
T
キャスト式
第
の形式は,配列でないオブジェクト用とし,第
の形式は,配列用とする。演算対象の型は,ポインタ型 又は ポ
インタ型への単一の変換関数(
)をもつクラス型でなければならない。その結果の型は,
とする。
演算対象がクラス型の場合,演算対象がそのクラス型の単一の変換関数によってポインタ型に変換される。この
##
では,以後,その変換された演算対象を元の演算対象の代りに使うこととする。いずれの形式であっても,
の演算対象の値が空ポインタの場合,その演算の効果はない。第
の形式(オブジェクト用)の場合,
の演
算対象の値は,配列でないオブジェクト 又は 部分オブジェクト(
)へのポインタとし,そのようなオブジェクト
の基底クラスを表すもの(
)でなければならない。そうでない場合の動作は,未定義とする。第
の形式( 配列
用)の場合,
の演算対象の値は,その配列に対する先行した《
<
式》の結果のポインタ値でなければなら
ない
。そうでない場合の動作は,未定義とする。
注
それには《生成初期化子》の評価 及び/又は コンストラクタ呼出しを含んでいてもよい。
注
大きさがゼロでない配列の場合,この値は 《
'
式》で作った配列の先頭要素を指すポインタと同じとする。大きさがゼロの配列は,
先頭要素をもたない。
()
参考 これは 《
3
式》の構文は 《
<
式》で割り付けたオブジェクトの型に合致しなければならないこと
を意味しており《
<
式》の構文に合致するのではない。
参考
!
付きの型へのポインタを 《
3
式》の演算対象にしてもよい。
《
3
式》の演算対象とする前
に,そのポインタ式の定値性(
#
)をキャストで消す必要はない。
第
形式(オブジェクト用)において,演算対象の静的な型がその動的な型と異なる場合,その静的な型は,演算
対象の動的な型の基底クラスでなければならず,仮想デストラクタをもっていなければならない。そうでない場合の
動作は,未定義とする。第
形式( 配列用)において,オブジェクトの動的な型がその静的な型と異なる場合の動作
は,未定義とする。
《
3
式》内の《キャスト式》は,
回だけ評価する。
《
3
式》が処理系の解放関数(
)
)を呼び出し ,
《
3
式》の演算対象が空ポインタ定数でない場合,その解放関数は,ポインタが参照する記憶域を解放し,ポイン
タを無効にする。
参考
解放した記憶域を参照するポインタ値は,不定となる。
削除されるオブジェクトが削除時点で不完全な型であって,その完全クラスが自明でないデストラクタ 又は 解放
関数をもつ場合,その動作は,未定義とする。
《
3
式》は,削除されるオブジェクト 又は 配列要素に対するデストラクタが存在すれば ,それを呼び出す。
配列の場合,要素の解体は,アドレ スの降順に行われる( すなわち,そのコンストラクタの完了の逆順で行われる
(
(
参照)
。
《
3
式》は,解放関数(
)
)を呼び出す。
参考
処理系は,大域的解放関数として,非配列用の
(
)及び 配列用の
ST
(
)の省略時定義を提供している。
"##
プログラムは,これらの関数を代替する定
義(
)
) 及び/又は クラス固有の版(
#
)をもつことができる。
《
3
式》でキーワード
の前に単項演算子
33
が付いた場合,大域的解放関数が記憶域の解放に使われる。
解放関数 及び デストラクタの両方に対し ,アクセス制御 及び あいまい性制御を行う(
及び
#
参照)
。
#
明示的型変換(キャスト 記法)
:
《キャスト式》
;
という式の結果は,型
になる。
が参照型の場合,
結果は左辺値とし ,そうでない場合,結果は右辺値とする。
参考
がクラスでない
0
修飾型の場合,結果の右辺値の型を決定するときに,
0
修飾子は,無視される
(
参照)
。
明示的型変換は,関数形(
#
),型変換演算子(
,
,
及び
) 又は キャスト記法によって書くことができる。
キャスト式
3
単項式
型識別子
キャスト式
《キャスト式》の中で型を定義してはならない。
次の段落で規定していない型変換であって,利用者の明示的な定義がない型変換(
)は,不適格とする。
次のキャストで実行される変換は,いずれも明示的型変換のキャスト記法を使って実行することができる。
―
定値性キャスト(
#
)
―
静的キャスト(
#*
)
―
静的キャストに続く定値性キャスト
―
強制キャスト(
#
)
―
強制キャストに続く定値性キャスト
意味上の制約 及び 動作は,同じとする。明示的型変換が,上に示した変換のいくつかとして解釈できる場合,上方に
示してある側の変換として解釈する。そう解釈するとキャストが不適格となる場合であっても,その解釈を使う。あ
る変換が,静的キャストに続く定値性キャストという解釈のほかにも解釈できる場合,その明示的型変換は,不適格
とする。
例
6
QR&
<L
3
6
QR&
<+
3
6
QR&
#
3
<L
<+
QR&
6
!
#
!
Q
注
このことから,型
&
のオブジェクトはないので,型
&
のポインタを使ってオブジェクトを削除することはないといえる。
(
6!
&
''
不適格な静的キャストの解釈
R
キャスト記法を使ったキャストの演算対象は,型
:
不完全クラス型へのポインタ
;
の右辺値であってもよい。キャス
ト記法を使ったキャストの目的の型は,
:
不完全クラス型へのポインタ
;
であってもよい。その場合,継承関係が元の
クラスと目的のクラスとの間に存在したとしても,静的キャストとして解釈するか,強制キャストとして解釈するか
については,未規定とする。
これらの変換に加え,次にあげる静的キャスト 及び 強制キャストの演算(その後に定値性キャスト演算が続くこ
ともある。)は,その基底クラスの型がアクセスできない場合であっても,明示的型変換のキャスト記法を使って行っ
てもよい。
―
派生クラス型のオブジェクトへのポインタ 又は 派生クラス型の左辺値は,それぞれあいまいでない基底
クラス型へのポインタ 又は 参照に,明示的に変換してもよい。
―
派生クラス型のメンバへのポインタは,あいまいでなく仮想でない基底クラス型のメンバへのポインタに,
明示的に変換してもよい。
―
仮想でない基底クラス型のオブジェクトへのポインタ,仮想でない基底クラス型の左辺値 又は 仮想でな
い基底クラス型のメンバへのポインタは,それぞれ派生クラス型のポインタ,参照 又は メンバへのポ イ
ンタに,明示的に変換してもよい。
##
メンバポインタ演算子
メンバポインタ演算子
V!
及び
(!
は,左から右に結びついていく。
メンバポインタ式
3
キャスト式
メンバポインタ式
(!
キャスト式
メンバポインタ式
V!
キャスト式
項演算子
(!
は,第
演算対象(ここで
が完全定義されたクラス型であるとき,第
演算対象の型は,
:
のメ
ンバへのポインタ
;
でなければならない。)を,第
演算対象( 第
演算対象は,クラス
そのものであるか,
が
あいまいでなくアクセス可能な基底クラスになっているクラスでなければならない。)に結合する。結果は,第
演
算対象で指定された型のオブジェクト 又は 関数とする。
項演算子
V!
は,第
演算対象(ここで
が完全定義されたクラス型であるとき,第
演算対象の型は,
:
の
メンバへのポインタ
;
でなければならない。)を,第
演算対象( 第
演算対象は,型
:
へのポインタ
;
であるか,
:
があいまいでないアクセス可能な基底クラスとなっているクラスへのポインタ
;
でなければならない。)に結合す
る。その結果は,第
演算対象で指定された型のオブジェクト 又は 関数とする。
そのようなオブジェクトの動的な型が,そのポインタの参照するメンバをもたない場合,その動作は,未定義と
する。
0
修飾の制約 及び 演算対象の
0
修飾子を結び付けて結果の
0
修飾子を生成する方法は,
##
で規定した
8L(8+
の規則と同じとする。
参考
定値性クラスオブジェクトを変更するために,変更可能なメンバを参照しているメンバへのポインタを
使うことはできない。
例
F
Q
&
R&
F
&
F
:
:
!
%
0F33
&
''
は,
メンバ
F33
を参照する。
(!
%
NN
&
''
不適格:
は,定値オブジェクト
R
(!
又は
V!
の結果が関数の場合,その結果は,関数呼出し演算子
の演算対象としてしか使えない。
例
PPV!
P
P
L
.
&
この例では,
が指すオブジェクトがもつ,
の示すメンバ関数を呼び出す。
(!
式の結果は,第
演算対象が左辺値であり,第
演算対象がデータメンバへのポインタの場合に限り,左辺値とな
る。
V!
式の結果は,第
演算対象がデータメンバへのポインタの場合に限り,左辺値となる。第
演算対象が メン
バへの空ポインタ値(
)の場合,動作は未定義とする。
(*
#(
乗除演算子
乗除演算子
!
,
'
及び
U
は,左から右に結びついていく。
乗除式
3
メンバポインタ式
乗除式
!
メンバポインタ式
乗除式
'
メンバポインタ式
乗除式
U
メンバポインタ式
!
及び
'
の演算対象の型は,算術型 又は 列挙型でなければならない。
U
の演算対象の型は,汎整数型 又は 列挙
型でなければならない。通常の算術変換が,演算対象に対して行われ,結果の型が決まる。
項演算子
!
は,乗算を表す。
項演算子
'
は,商を生じ ,
項演算子
U
は,第
演算対象の第
演算対象による除算の剰余を生じる。
'
及び
U
の第
演算対象がゼロのときの動作は,未定義とする。そうでない場合,
'!
)
U
は,
と等しい。両方の演
算対象が負でない場合,その剰余は,負ではない。そうでない場合の剰余の符号は,処理系定義とする。
#)
加減演算子
加減演算子には
)
及び
V
があり,左から右に結びついていく。通常の算術変換が,算術型 又は 列
挙型の演算対象に対して行われる。
加減式:
乗除式
加減式
)
乗除式
加減式
V
乗除式
加算の場合,次のいずれかでなければならない。
―
両方の演算対象の型が,算術型 又は 列挙型である。
―
一方が完全に定義されたオブジェクト型へのポインタであって,他方が汎整数型 又は 列挙型のいずれか
になっている。
減算の場合,次のいずれかでなければならない。
―
両方の演算対象の型が,算術型 又は 列挙型である。
―
両方の演算対象が完全に定義された同じオブジェクト型への
0
修飾付きポインタ 又は
0
修飾なしポイン
タである。
―
左の演算対象が完全に定義されたオブジェクト型へのポインタであって,右の演算対象が汎整数型 又は 列
挙型である。
項演算子
)
の結果は,二つの演算対象の和とする。
項演算子
V
の結果は,第
演算対象から第
演算対象を減
じた結果とする。
これらの演算子においては,配列でないオブジェクトへのポインタは,配列要素の型としてそのオブジェクトの型
をもつ長さ
の配列の先頭要素へのポインタと同じ振る舞いをする。
あるポインタに汎整数型の式を加算する場合 又は あるポインタから汎整数型の式を減算する場合,その結果の型
は,そのポインタの型とする。そのポインタが,配列オブジェクトのある要素を指しており,配列が十分に大きい場
合,その結果は,結果の指す要素の添字と元の要素の添字との差分がその汎整数の式と等しくなるような隔たりの位
置にある要素を指すものとする。すなわち,式
がある配列オブジェクトの
"
番目の要素を指す場合,式
)A
( 又
は 等価の
A)
) 及び
VA
( ここで
A
の値は,
とする。)は,配列オブジェクトのそれぞれ
"
#
番目 及び
"
番目の要素(それらが存在すれば )を指すことになる。更に,式
が配列オブジェクトの最終要素を指してい
る場合,式
)L
は,その配列オブジェクトの最終要素の一つ先を指す。式
#
が配列オブジェクトの最終要素の一
つ先を指している場合,式
#VL
は,その配列オブジェクトの最終要素を指す。ポインタ演算対象 及び 結果が,と
もに同じ配列オブジェクトの要素 又は その最終要素の一つ先を指している場合,評価によってオーバフローを発生
させてはならない。そうでない場合の動作は,未定義とする。
同じ配列オブジェクトへの二つのポインタの減算をする場合,結果は,二つの配列要素を示す添字値の差分とする。
結果の型は,処理系定義の符号付き汎整数型とする。その型は,ヘッダ
(
)内の
で定義
された型と同じでなければならない。その他の算術オーバフローを伴う場合として,結果が提供された領域に入らな
い場合の動作は,未定義とする。すなわち,
及び
#
が,それぞれ配列オブジェクトの
"
番目と
番目の要素を指
している場合,式
V#
の値は,型
に適合する値
"
となる。更に,式
が配列オブジェクト内の
注
$
%
&!!
の改正版では,整数除算のアルゴ リズムは,
$
%
&!!
(プログラム言語
)
)の規定に従っている。そこでは,商
は,常にゼロに向かって丸められる。
)
要素 又は 最終要素の一つ先 を指し ,式
#
が同じ配列オブジェクトの最終要素を指している場合,
#)L
はその配
列オブジェクト内の要素を指さないが,
#)LV
の値は,
#V
)L
すなわち
V
V#)L
と同じ
値となり,式
が配列オブジェクトの最終要素の一つ先を指しているときにはゼロとなる。両方のポインタが同じ配
列オブジェクトの要素 又は 最終要素の一つ先を指していない場合の動作は,未定義とする。
この観点から,処理系は,
:
最終要素の一つ先
;
という要求を満たすために,オブジェクトの終点の後ろに
バイト
だけの余分(これが,プログラム内の他のオブジェクトと重なっていてもよい。)を必要とする。
#
シフト 演算子 シフト演算子
及び
は,左から右に結びついていく。
シフト式:
加減式
シフト式
加減式
シフト式
加減式
演算対象は,汎整数型 又は 列挙型でなければならず,汎整数昇格が行われる。結果の型は,左演算対象の昇格した
型とする。右演算対象の値が負のとき,又は 昇格した左演算対象のビット長と同じか大きいとき,その動作は,未定
義とする。
8L8+
の値は,
8L
を(ビットパタンとして解釈して)
8+
ビットだけ左にシフトさせ,残ったビットにゼロを埋め
た値とする。
8L
が符号なしの型の場合,結果の値は,
8L
に
の
8+
乗したものを乗じた値の,
G?BA:
@65)L
(
(
が
の場合) 又は
G<A
@65)L
(そうでない場合)を法とした剰余とする。
参考
定数
G?BA:
@65
及び
G<A
@65
は,ヘッダ
内に定義されている。
8L8+
の値は,
8L
を
8+
ビットだけ右にシフトして得られる値とする。
8L
が符号なしの型の場合,又は
8L
が符
号付きの型であって負でない値の場合,その結果の値は,
8L
を
の
8+
乗で割った商の整数部分とする。
8L
が符号付
きの型であって負の値の場合,結果の値は,処理系定義とする。
#*
関係演算子
関係演算子は,左から右に結びついていく。
例
は,
であって,
00
ではない。
関係式:
シフト式
関係式
シフト式
関係式
シフト式
関係式
%
シフト式
関係式
%
シフト式
演算対象の型は,算術型,列挙型,又は ポインタ型でなければならない。演算子
( 小なり),
( 大なり),
%
( 小なり 又は 等しい) 及び
%
( 大なり 又は 等しい)は,すべて
又は
を生じる。結果の型は,
%
型
とする。
算術型 又は 列挙型の二つの演算対象に対し ,通常の算術変換が行われる。二つのポインタ演算対象( 又は ポイン
タ 及び 空ポインタ定数)に対しては,それらを複合ポインタ型にするために,ポインタ変換(
) 又は 修飾変換
(
)が行われる。一方の演算対象が空ポインタ定数の場合,複合ポインタ型は,もう一方の演算対象の型とする。
そうでない場合,一方の演算対象が
:
へのポインタ
;
であって,もう一方が
:
へのポインタ
;
であると
き,その複合ポインタ型は,
:
へのポインタ
;
となる。ここで,
は,
及び
の和集合とする。そ
うでない場合,複合ポインタ型は,演算対象の一方の型と同類のポインタ型とし ,その
0
修飾情報は,二つの演算
対象の型の
0
修飾情報の和集合とする(
参照)
。
参考
すなわち,すべてのポインタは,空ポインタ定数と比較することができ,すべてのオブジェクトポイン
タは,
(
0
修飾付きでもよい )と比較することができる。
例
!&
!&
!!&
!
!&
注
ポインタ計算のもう一つの方式では,まずポインタを文字ポインタに変換する。その方式では,式の汎整数値を変換されたポインタに
加算する 又は それから減算する場合,まず元のポインタが指すオブジェクトの大きさを,その汎整数値に乗算する。そして,結果のポ
インタを,元のポインタの型に変換する。ポインタ減算の場合,文字ポインタの差分結果を,元のポインタが指すオブジェクトの大きさ
で除算する。ポインタ値にゼロを加算 又は 減算した場合,その結果は,元のポインタと同じとする。二つのポインタが同じオブジェク
トを指している場合,両ポインタがともに同じ配列の最終要素の一つ先を指している場合,又は 両ポインタとも空ポインタの場合,二
つのポインタの減算の結果は,型
&%%
に変換されたゼロとする。
)
Q
%
&
''
比較の前にともに
!
に変換される。
%
&
''
比較の前にともに
!
!
に変換される。
R
(ポインタ変換の後で )同じ型のオブジェクトへのポインタ 又は 関数へのポインタを比較することができ,次の結果
となる。
―
ポインタ
及び
が同じ型であり,同じオブジェクト 又は 関数を指している場合,同じ配列の最終要素
の一つ先を指している場合,又は ともに空ポインタの場合,
%
及び
%
は,
となり,
及び
は,
となる。
―
同じ型の
及び
が,異なるオブジェクト(ただし ,それらのオブジェクトは,ある同じオブジェクトの
メンバでもないし ,ある同じ配列の要素でもないとする。)を指している場合,別の関数を指している場
合,又は 一方だけが空ポインタの場合,
,
,
%
及び
%
の結果は,未規定とする。
―
二つのポインタが,ある同じオブジェクトの静的でないメンバを指している場合,又は そういうメンバの
部分オブジェクト 若しくは 配列要素を指している場合,さらにそれらが再帰的である場合,二つのメン
バがアクセス指定子ラベル(
)によって分離されていなくて,クラスが共用体でないときには,後で
宣言されたメンバへのポインタのほうが大きいとする。
―
二つのポインタが,ある同じオブジェクトの中の《アクセス指定子》のラベル(
)で分離されたデー
タメンバを指している場合の結果は,未規定とする。
―
二つのポインタが,ある同じ 共用体オブジェクトのデータメンバを指している場合,
( 必要ならば
!
に変換した後で )それらは等しい。二つのポインタが,ある同じ 配列の要素 又は 最終要素の一つ先を指
している場合,添字値の大きいオブジェクトへのポインタのほうが大きい。
―
その他のポインタ比較については,未規定とする。
#
等価演算子
等価式:
関係式
等価式
%%
関係式
等価式
[%
関係式
( 等しい)演算子
%%
及び ( 等しくない)演算子
[%
は,関係演算子と同じ意味規則の制約,変換 及び 結果の型
をもつが,演算子の優先順位( 低いこと ) 及び 真理値の結果だけは異なる。
参考
%%
は,
の真理値と
の真理値とが同じ場合に真となる。
同じ型のオブジェクト 又は 関数へのポインタは(ポインタ変換の後で )等価の比較ができる。同じ型の二つのポイン
タが等しくなるのは,両方とも空の場合,両方とも同じ関数を指している場合,又は 両方とも同じアドレス(
*
)
を指している場合であって,それらの場合に限る。
更に,メンバへのポインタど うし 又は メンバへのポ インタと空ポインタ定数とを比較することができる。メンバ
へのポインタ変換(
) 及び 修飾変換(
)が,それらのポインタを共通の型にするために実行される。一方の
演算対象が空ポインタ定数の場合,共通の型は,他方の演算対象の型とする。そうでない場合,共通の型は,演算対
象の一方の型と同類のメンバ型とし ,演算対象の型の
0
修飾の和集合を付けたものとする(
参照)
。
参考
すなわち,すべてのメンバへのポインタは,空ポインタ定数と比較することができる。
両方の演算対象が空の場合,比較結果は等しい。そうではなくて,一方だけが空の場合,比較結果は等しくない。そ
うでもなくて,ど ちらかが仮想メンバ関数の場合
,
結果は未規定とする。さらにそうでもない場合,メンバへのポ イ
ンタに対応するクラス型の仮想的なオブジェクトを用いて,それらの参照をはずしたとして,同じ最派生オブジェク
ト(
)の同じ メンバを指しているとき,又は 同じ部分オブジェクトを指しているとき,そのときに限り,比較結
果は等しい。
例
"
Q
&
R&
?
3
"
Q
R&
E
3
"
Q
R&
#
3
?
E
Q
R&
"33!
%
0"33&
)
?33!
%
&
E33!
%
&
#33!
%
&
#33!
%
&
%
%%
&
''
偽となる。
#
ビット 積演算子
ビット積式
3
等価式
ビット積式
0
等価式
通常の算術変換を行う。結果は,両演算対象のビットごとの
&)*
とする。この演算子は,汎整数型 及び 列挙型
にだけ作用する。
#
ビット 差演算子
ビット差式
3
ビット積式
ビット差式
W
ビット積式
通常の算術変換を行う。結果は,両演算対象のビットごとの排他的
2B
とする。この演算子は,汎整数型 及び 列
挙型にだけ作用する。
#
ビット 和演算子
ビット和式:
ビット差式
ビット和式
1
ビット差式
通常の算術変換を行う。結果は,演算対象のビットごとの
2B
とする。この演算子は,汎整数型 及び 列挙型にだ
け作用する。
#
論理積演算子
論理積式
3
ビット和式
論理積式
00
ビット和式
演算子
00
は,左から右に結びつく。演算対象は,ともに
%
型に暗黙に変換する(
参照)
。結果は,両方の演
算対象が真の場合に真とし ,そうでない場合に偽とする。
0
とは異なり,
00
は,左から右への評価を保証する。第
演算対象は,第
演算対象が偽のときには評価しない。
結果は,
%
型とする。第
の式についてのすべての副作用は,一時変数の解体(
L+(+
)を除き,第
の式を評価
する前に発生する。
##
論理和演算子
論理和式:
論理積式
論理和式
11
論理積式
11
演算子は,左から右に結びつく。演算対象は,ともに
%
型に暗黙に変換する(
参照)。ど ちらか一方の演
算対象が真の場合,真を返し ,そうでない場合,偽を返す。
1
とは異なり,
11
は,左から右への評価を保証する。第
演算対象は,第
演算対象の評価が真のときには評価しない。
結果は,
%
型とする。第
の式についてのすべての副作用は,一時変数の解体(
)を除き,第
の式を評価
する前に発生する。
#(
二択条件演算子
二択条件式:
論理和式
論理和式
2
式
3
代入式
二択条件式は,右から左に結びつく。第
の式は,暗黙に
%
型に変換する(
参照)
。それが真と評価された場
合,条件式の結果は,第
の式の値とし ,そうでない場合は,第
の式の値とする。第
の式についてのすべての副
作用は,一時変数の解体(
)を除き,第
の式 又は 第
の式を評価する前に発生する。第
の式 又は 第
の
式のど ちらか一方だけを評価する。
)
第
演算対象 又は 第
演算対象のいずれかが,型
(
0
修飾付きでもよい。)の場合,左辺値から右辺値への
変換(
),配列からポインタへの変換(
) 及び 関数からポインタへの変換(
)を,第
演算対象 又は 第
演算対象に対して行う。その結果は,次のいずれかになる。
―
第
演算対象 又は 第
演算対象のど ちらか( 両方ではない)が,例外送出(
#
)となる。結果は,他
方の型の右辺値となる。
―
第
演算対象 及び 第
演算対象の両方が型
の場合,結果は,型
の右辺値となる。
参考
両方の演算対象が送出式という場合も,こうなる。
そうでない場合,第
演算対象 及び 第
演算対象が異なる型をもち,ど ちらかが(
0
修飾付きでもよい。)クラ
ス型の場合,それらの演算対象のそれぞれ一方を他方の型に変換しようとする。型
をもつ演算対象式
8L
が,型
をもつ演算対象式
8+
に合致するように変換できるか否かを決める手順を次に示す。
―
8+
が左辺値の場合,
8L
が暗黙の変換(
)によって型
:
への参照
;
に変換できるならば ,その参照が
直接
8L
に結合(
#
)しなければならないという制約を条件として,
8L
を
8+
に合致するように変換で
きる。
―
8+
が右辺値の場合 又は 上の変換ができない場合,次の手順とする。
8L
及び
8+
がクラス型をもち,その基礎とするクラス型が同じであるか,一方が他方の基底ク
ラスである場合,
のクラスが
のクラスと同じ型 又は その基底クラスであり,かつ
の
0
修飾が
の
0
修飾と同じかそれより多いとき,
8L
を
8+
に合致するように変換でき
る。この変換が適用されるとき,
8L
は,元のクラスオブジェクト( 又は それの適切な部分オ
ブジェクト )をまだ参照している型
の右辺値に変更される。
参考
すなわち,コピーは作られない。
そうでない場合(すなわち,
8L
又は
8+
がクラス型でない場合,又は 両方ともクラス型である
が,それらの基礎とするクラスが同じでないか,一方が他方の基底クラスでない場合),
8+
を
右辺値に変換したとすると
8+
がもつ型( 又は
8+
がすでに右辺値のときには,その型)に
8L
を暗黙に変換できるならば,
8L
を
8+
に合致するように変換できる。
ここで述べた手順によって,第
演算対象を第
演算対象に合致するように変換できるか否か,及び 第
演算対象を
第
演算対象に合致するように変換できるか否かが決まる。両方の変換ができる場合,又は 一つの変換が可能であっ
てもその変換があいまいな場合,そのプログラムは不適格とする。ど ちらの変換もできない場合には,両方の演算対
象の変更は行わず,更に次の検査を行う。一つだけの変換が可能な場合,その変換を選択された演算対象に対して実
行する。この
#(
の以後の部分では,こうして変換された演算対象を,元の演算対象の代りに用いる。
第
演算対象 及び 第
演算対象が左辺値であって同じ型である場合,結果は,その型の左辺値とする。
そうでない場合,結果は,右辺値とする。第
演算対象 及び 第
演算対象が同じ型ではなく,ど ちらかが(
0
修
飾付きでもよい。)クラス型である場合,それらの演算対象に適用すべき複数の変換(もしあれば )を決めるために
多重定義解決が利用される(
及び
(
参照)
。多重定義解決が失敗した場合,プログラムは不適格とする。
そうでなければ ,こうして決まった変換が適用される。この
#(
の以後の部分では,こうして変換された演算対象
を,元の演算対象代りに用いる。
左辺値から右辺値への標準変換(
),配列からポインタへの標準変換(
) 及び 関数からポインタへの標準
変換(
)を,第
演算対象 及び 第
演算対象に対して行う。その変換の後で,次のいずれかとなる。
―
第
演算対象 及び 第
演算対象が同じ型となっている。この場合,結果はその型とする。
―
第
演算対象 及び 第
演算対象が算術型 又は 列挙型となっている。この場合,通常の変換を行い,共通
の型にする。結果は,その型とする。
―
第
演算対象 及び 第
演算対象が,ともにポインタ型となっているか,一方がポインタ型で他方が空ポ
インタ定数となっている。この場合,ポインタ変換(
) 及び 修飾変換(
)を行い,それらをその
複合ポインタ型(
#*
)に変換する。結果は,その複合ポインタ型とする。
―
第
演算対象 及び 第
演算対象が,ともに メンバへのポインタ型となっているか,一方が メンバへのポ
インタ型で他方が空ポインタ定数となっている。この場合,メンバへのポインタ変換(
) 及び 修飾
変換(
)を行い,それらを共通の型に変換する。その
0
修飾は,第
演算対象 及び 第
演算対象に
合致しなければならない。結果は,その共通の型とする。
#)
代入演算子 いくつかの代入演算子があり,それらのすべてが右から左に結びついていく。すべての代入演算
子について,左の演算対象は,変更可能な左辺値でなければならない。代入式の型は,左の演算対象の型とする。代
)
入演算の結果は,代入が行われた後の左の演算対象に格納された値とする。結果は,左辺値とする。
代入式
3
二択条件式
論理和式
代入演算子
代入式
送出式
代入演算子
3
次のいずれか
%
!%
'%
U%
)%
V%
%
%
0%
W%
1%
単純代入(
%
)の場合,左の演算対象の参照オブジェクトの値を右の式の値に置き換える。
左の演算対象がクラス型でない場合,右の式は,左の演算対象の
0
修飾なしの型に暗黙に変換する(
参照)
。
左の演算対象がクラス型の場合,そのクラスは,完全でなければならない。クラスの各オブジェクトへの代入は,
コピー代入演算子の定義に従う(
及び
#
参照)
。
参考
クラスオブジェクトの場合,一般的には,代入は,初期化と同じではない(
#
,
,
(
及び
参照)
。
代入演算子の左の演算対象が
を参照しているとき,演算は,その参照が表す型
のオブジェクトへの代入と
なる。
8L
$%
8+
という形の式の挙動は,
8L
の評価が
回しか行われないことを除き,
8L
%
8L
$
8+
と同じとする。
)%
及び
V%
の場合,
8L
の型が算術型であるか,
8L
が(
0
修飾付きでもよい。)完全に定義されたオブジェクトへのポイ
ンタであるかのど ちらかでなければならない。その他のすべての代入演算子の場合には,
8L
の型は,算術型でなけれ
ばならない。
オブジェクトに格納される値が,そのオブジェクトの記憶域と何らかの形で重なっている他のオブジェクトからア
クセスされる場合,完全に重なり合っていて,かつ二つのオブジェクトの型が同じでなければならない。そうでない
場合の動作は,未定義とする。
#
コンマ演算子 コンマ演算子は,左から右に結びつく。
式:
代入式
式
代入式
コンマで分離した二つの式を,左から右に評価し ,左の式の値を捨てる。左辺値から右辺値への標準変換(
),配
列からポインタへの標準変換(
) 及び 関数からポインタへの標準変換(
)は,左の式に適用しない。左の式
についてのすべての副作用は,一時変数の解体(
)を除き,右の式を評価する前に発生する。結果の型 及び 値
は,右の演算対象の型 及び 値とする。右の演算対象が左辺値の場合,結果は左辺値とする。
コンマが特殊な意味をもつ文脈[ 例えば ,関数の実引数並び(
#
)の中 及び 初期化子の並び(
#
)の中]の
場合,この箇条で規定するコンマ演算子は,括弧の中にだけ書くことができる。
例
%*
)+
&
この例は,三つの実引数をもち,第
実引数の値は,
となる。
#*
定数式
"##
では,いくつかの場所で,汎整数 又は 列挙体の定数に評価される式が要求される。その場所
は,配列上限(
及び
#
),
!
式(
(
),ビットフィールド 長(
*(
),列挙子初期化子(
)
),静的メ
ンバ初期化子(
*
), 及び 汎整数 又は 列挙体の非型のテンプレート実引数(
)とする。
定数式:
二択条件式
汎整数の《定数式》内に書くことができるのは,次に挙げるものだけとする。
―
リテラル(
)
―
列挙子
―
定数式によって初期化された汎整数型 又は 列挙型をもつ,
!
属性の変数 又は 静的データメンバ(
#
参照)
―
汎整数型 又は 列挙型をもつ非型のテンプレート仮引数
―
!J
式
浮動小数点リテラル(
)が現れるのは,それらが汎整数型 又は 列挙型にキャストされる場合だけとする。汎
整数型 又は 列挙型への型変換だけが使用できる。特に,
!J
式の中を除き,関数,クラスオブジェクト,ポインタ
)#
又は 参照を使ってはならず,代入演算子,増加演算子,減少演算子,関数呼出し 又は コンマ演算子を使ってはなら
ない。
他の式が《定数式》とみなされるのは,局所的でない静的オブジェクトの初期化(
(
)の場合だけとする。その
場合の《定数式》は,評価した結果が次のいずれかでなければならない。
―
空ポインタ値(
参照)
―
空メンバポインタ値(
参照)
―
算術定数式
―
アドレス定数式
―
参照定数式
―
完全オブジェクト型に対するアドレス定数式と汎整数定数式との加算 又は 減算
―
メンバポインタ定数式
算術定数式は,汎整数の《定数式》の要件を満たさなければならない。ただし ,次の二つは許される。
―
浮動小数点リテラルは,汎整数型 又は 列挙型にキャストしなくてもよい。
―
浮動小数点型への変換をしてもよい。
アドレス定数式は,静的記憶域期間をもつオブジェクト,文字列リテラル(
) 又は 関数のいずれかを表す
左辺値へのポインタとする。そのポインタは,明示的に単項演算子
0
を使うか,暗黙にポインタ型の非型のテンプ
レート仮引数を使うか,又は 配列型(
) 若しくは 関数型(
)の式を使うかして作る。添字付け演算子
ST
及
び クラスメンバアクセス演算子(
(
及び
V
),単項演算子の
0
及び
!
,並びに ポインタのキャスト( 動的キャスト
(
#)
)を除く。)は,アドレス定数式を作るのに使用できるが,オブジェクトの値をこれらの演算子を使ってアクセ
スしてはならない。添字付け演算子を使うとき,その演算対象の一つは,汎整数定数式としなければならない。
"
互
換でないクラスオブジェクト(
*
)の部分オブジェクトのアドレスを示す式は,アドレス定数式としない。関数が イ
ンラインであって参照型を返す場合であっても,その関数の呼出しをアドレス定数式に使ってはならない。
参照定数式は,静的記憶期間をもつオブジェクト,非型テンプレートの参照型の仮引数 又は 関数を指す左辺値と
する。添字付け演算子
ST
,クラスメンバアクセス演算子(
(
及び
V
),単項演算子の
0
及び
!
,並びに 参照キャス
ト[ユーザ定義変換関数(
)を呼び出す場合 及び 動的キャスト(
#)
)を除く。]は,参照定数式を作るの
に使用できるが,あるオブジェクトの値をこれらの演算子を使ってアクセスしてはならない。添字付け演算子を使う
場合,その演算対象の一つは,汎整数定数式としなければならない。
"
互換でないクラスオブジェクト(
*
)の基底
クラス 又は メンバを指す左辺値式は,参照定数式としない(
)
参照)
。関数呼出しは,その関数が インラインで
あって参照型を返す場合であっても,それを参照定数式に使ってはならない。
メンバ先ポインタ定数式は,修飾付き識別子の演算対象(
#
)に単項演算子
0
を作用させて作る。この場合,そ
の演算対象の前にメンバへのポインタのキャスト(
#*
)を置いてもよい。
(
文
特に規定しない限り,文は,順に実行される。文の種類は,次のとおりとする。
文
3
ラベル付き文
式文
複合文
選択文
繰返し文
飛越し文
宣言文
監視ブロック
(
ラベル付き文
文には,ラベルを付けることができる。
ラベル付き文
3
識別子
3
文
定数式
3
文
3
文
識別子のラベルは,その識別子を宣言する。識別子のラベルは,
の目標としてだけに使う。ラベルの有効範囲
は,それが出現した関数の中とする。ラベルを関数内で再宣言してはならない。ラベルは,その定義の前にある
)(
文で使ってもよい。ラベルは,それ自身の名前空間をもち,他の識別子との干渉はない。
!
ラベル 及び
3
ラベルは,
!<
文の中にしか使ってはならない。
(
式文
式文の形式は,次のとおりとする。
式文
3
式
&
《式》を評価し ,その結果を捨てる。
《式文》の《式》には,左辺値から右辺値への標準変換(
),配列からポイン
タへの標準変換(
) 及び 関数からポインタへの標準変換(
)を適用しない。すべての式文の副作用は,その
次の文の実行開始前に完了する。
《式》のない《式文》を,空文と呼ぶ。
参考
文のほとんどは,式文( 通常は,代入 又は 関数呼出し )となる。空文は,複合文の終了を示す
の直
前にラベルを置くのに役立ち,
<
文(
(#
)のような繰返し文に空の本体を置くのにも役立つ。
(
複合文(ブロック) 単一の文が想定されている場所に複数の文を書けるようにするために,複合文(いわゆる
:
ブロック
;
と同じ 。)がある。文列の文は,特に規定しない限り,その現れた順に実行する。
複合文
3
文列
文列
3
文
文列
文
《複合文》は,局所的有効範囲を定める(
参照)
。
参考
文の一種に,宣言がある(
()
参照)
。
(
選択文
選択文は,いくつかの制御の流れのうち,いずれか一つを選択する。
選択文
3
条件
文
条件
文
文
条件
文
条件
3
式
型指定子列
宣言子
%
代入式
(
では,副文という用語を用いて,構文規則の中に現れる単一の文 又は 複数の文を表す。
《選択文》の中の副文(
文の
!
形式における二つの文の場合,それぞれの副文)は,暗黙に局所的有効範囲を定める(
参照)。選択文
中の副文が単一の文であって複合文ではない場合,元の副文を,単一の文から成る文列を波括弧でくくってできる複
合文に書き変えたとして扱う。
例
&
この例は,次のように書き換えることができる。
Q
&
R
したがって,
文の後では,
は,もはや有効でない。
《条件》に対する規則は,
《選択文》だけでなく,
文 及び
<
文にも適用される(
(#
参照)
。
《条件》の中の
《宣言子》には,関数 又は 配列を指定してはならない。
《型指定子列》には,
を含めてはならず,新たなク
ラス 又は 列挙体を宣言してはならない。
《条件》の中の一種の宣言によって導入した名前(《条件》の中の《型指定子列》 又は 《宣言子》によって導入し
た名前)の有効範囲は,それを宣言した位置から,その条件が制御する副文の終了の位置までとする。そういう名前
が,その条件が制御している副文の中の最外側ブロックで再宣言された場合,その名前を再宣言した宣言は,不適格
とする。
例
%
Q
&
''
不適格,
の再宣言
R
))
Q
&
''
不適格,
の再宣言
R
!<
文ではない文において 《条件》が初期化をもつ宣言となっている場合,その値は,宣言された変数の値を
暗黙に
%
型に変換した値とする。その変換が不適格な場合,そのプログラムは不適格とする。
!<
文において,
《条件》が初期化をもつ宣言となっている場合,その値は,宣言された変数が汎整数型 又は 列挙体型のときには,そ
の変数の値とし ,そうでないときには,汎整数 又は 列挙体に暗黙に変換された変数の値とする。
《条件》が《式》の
場合には,その値は,その《式》の値とするが,
!<
文を除く文においては,
%
型に暗黙に変換した値とする。
その変換が不適格な場合,そのプログラムは不適格とする。
《条件》の値のことを,あいまいな使い方でない場所で
は,単に
:
条件
;
という。
《条件》が,構文上 《式》とも 局所的名前の宣言とも解釈できる場合,宣言と解釈する。
(
"
文
条件(
(
)が
の場合,第
の副文が実行される。
《選択文》が
!
部をもち,
《条件》が
の場合,第
の副文が実行される。
文が第
の形式(
を含む形式)であって,第
の副文も
文とした場合,
その内側の
文には,
部を付けなければならない。
(
+
&
文
!<
文は,
《条件》の値に応じて,複数の文の中から一つを選んでそこに制御を移す。
《条件》の型は,汎整数型,列挙体型 又は 単一の変換関数によって汎整数型 若しくは 列挙型になるクラス型(
)
のいずれかでなければならない。
《条件》がクラス型の場合,その変換関数を呼び出して変換する。
(
では,その
変換結果を元の条件の代りとして使う。汎整数昇格を,実行する。
!<
文中のすべての文は,次の形式の
!
ラ
ベルを一つ以上もつことができる。
定数式
3
ここで 《定数式》は,汎整数の《定数式》でなければならない。汎整数の《定数式》
(
#*
)は,
!<
文の《条件》
の昇格後の型に暗黙に変換する。同じ
!<
文内では,どの二つの
!
定数をとっても,その値が
!<
文の《条
件》の昇格後の型に変換したときに同じであってはならない。
一つの
!<
文の中には,次の形式のラベルは,高々一つでなければならない。
3
複数の
!<
文を,入れ子にしてもよい。その場合,
!
ラベル 又は
3
ラベルは,それを囲む最小の
!<
文に結び付く。
!<
文の実行では,その《条件》を評価し,それぞれの
!
定数の値と比較する。ある
!
定数の値が《条件》
の値と同じ 場合,その一致した
!
ラベルが付いた文に制御を移す。ど の
!
定数も《条件》と一致しない場合,
3
ラベルがあるときには,
3
ラベルの付いた文に制御を移し ,
3
ラベルがないときには,
!<
文
中のどの文も実行せずに
!<
文の実行を終える。
!
ラベル 及び
3
ラベル自体は,制御の流れを変えない。制御の流れは,それらのラベルをまたいで続いて
いく。
!<
文からの飛出しについては,
((
の
%I
文に規定する。
参考
通常,
!<
文を構成する副文は,複合文となっており,
!
ラベル 及び
3
ラベルは,その副
文( 複合文)中の最上位の文に現れるが,これは必要条件ではない。宣言を,
!<
文の副文内に書いて
もよい。
(#
繰返し文
繰返し文は,ループ実行を指定する。
繰返し文
3
条件
文
文
式
&
初期化文
条件
&
式
文
初期化文
3
式文
単純宣言
参考 《
初期化文》は,セミコロンで終了する。
《繰返し文》中の副文は,局所的有効範囲(
)を暗黙に定める。その範囲は,そのループ実行の各回ごとに入っ
てから出るまでの範囲とする。
注
すなわち,
は,最も近い
のない
%
と結び付く。
)
《繰返し文》の副文が単一の文であって複合文でない場合,元の単一の文から成る文列を波括弧でくくってできる
複合文に書き換えたとして扱う。
例
VV
%
.
&
この例は,次のように書き換えたものと同じになる。
VV
%
.
Q
&
R
したがって,
は,
<
文の後では有効でない。
参考 《繰返し文》の中の《条件》に対する要件は,
(
に規定している。
(#
+&
文
<
文では,
《条件》の値(
(
)が
!
になるまで,その副文を繰り返して実行する。その検査
は,副文の実行前に毎回行う。
<
文の《条件》が《宣言》である場合,宣言された変数の有効範囲は,その宣言地点から
<
文の終わりま
でとする。
%
文
この形式の
<
文は,次と同じとする。
3
Q
''
条件の有効範囲の始まり
%
&
Q
文
&
R
R
''
条件の有効範囲の終わり
《条件》の中で作られたオブジェクトは,ループの繰返しごとに解体する。
例
6
Q
&
6
3
Q
R
X6
Q
R
Q
[%
.&
R
R&
%
L&
6
%
Q
''(((
%
.&
R
この
<
ループでは,コンストラクタ 及び デストラクタがそれぞれ
回ずつ呼び出される。
回目
では《条件》が成功し ,
回目では 《条件》が失敗する。
(#
文
3
文の中の《式》は,暗黙に
に変換する。それができない場合,そのプログラムは不適格とする。
3
文は,
《式》が
!
になるまで,副文を繰り返し実行する。その検査は,副文の実行の後で毎回行う。
(#
"
文
文の形式は,次のとおりとする。
初期化文
条件
&
式
文
この
文の形式は,次の形式と同じとする。
Q
初期化文
条件
Q
文
式
&
R
R
ただし ,次の違いがある。
―
《
初期化文》内で宣言された名前は 《条件》で宣言された名前と同じ宣言領域にある。
)*
― ( 別の繰返し文によって囲まれてはいない)
《文》の中の
(
((
)は,
《式》を実行して《条件》
の再評価にただちに制御を移す。
参考 したがって,第
の文は,ループの初期化を指定し,
《条件》
(
(
)は,各繰返しの実行前に行われる検
査を指定する。
《条件》が
になると,ループから抜け出る。
《式》は,各繰返しの実行後に行われる
増加を指定することが多い。
《条件》 及び 《式》の,いずれか一方 又は 両方を省略してもよい。
《条件》がない場合,対応する
<
文表記
を
としたものに等価とする。
《
初期化文》が宣言である場合,宣言された名前の有効範囲は 《
文》の最後までとする。
例
%
M+&
SL.T&
%
.&
L.&
))
ST
%
&
%
&
''
は,
M+
となる。
((
飛越し文
飛越し文は,無条件に制御を移す。
飛越し文
3
&
&
式
&
識別子
&
ある有効範囲からの飛出しの時点(ただし ,有効範囲は終わっている。)では,その有効範囲内で宣言されて構築
された自動記憶域期間(
)
)をもつすべてのオブジェクト( 名前付きオブジェクト 又は 一時変数)に対応するデ
ストラクタ(
)を,それらの宣言の逆順に呼び出す。ループの外への制御の移動,ブロックの外への制御の移動
又は そのブロック内で自動記憶域期間をもつ初期化変数の宣言地点の前に戻る移動においては,制御が移動した時点
では有効範囲にあるが,移動先では有効範囲にはない自動記憶域期間をもつ変数を解体する(ブロックの中への制御
の移動については,
()
で規定する。)
。
参考 ただし,プログラムは,
( 例えば(
?
又は
%
の呼出し(
)によって,
)自動記憶域期間をも
つクラスオブジェクトを解体せずに終了することもある。
((
%.
文
%I
文は,
《繰返し文》 又は
!<
文の中にしか現れてはならず,それを最小に取り囲む《繰返
し文》 又は
!<
文を終了させる。その終了させた文に続く文( 存在すれば )に,制御を移す。
((
文
文は,
《繰返し文》の中にしか現れてはならず,そのループを最小に取り囲む《繰返し
文》のループ 継続処理の部分,すなわちループの末端部に制御を移す。より正確にいえば ,次のそれぞれの文につい
て,
文が別の《繰返し文》の中に入っていない場合,
と同等とする。
Q
Q
&
&
Q
Q
Q
Q
''
(((
''
(((
''(((
R
R
R
3
&
3
&
3
&
R
R
&
R
((
文
関数は,
文によって呼出し元に戻る。
《式》のない
文は,値を返さない関数にだけ使うことができる。すなわち,
0
3
型を返す関数,コンストラ
クタ(
),デストラクタ(
)のいずれかでだけ使うことができる。
0
3
でない型の《式》をもつ
文
は,値を返す関数でだけ使うことができ,その《式》の値が関数の呼出し元に渡される。その《式》は,それが現れ
る関数の返却値の型に,暗黙に変換される。
文は,一時的オブジェクト(
)の構築 及び コピーを伴うこ
とがある。関数の終点からはずれ出てしまうことは,値なしの
文がある場合と同等とする。それが,値を返す
関数で発生した場合の挙動は,末定とする。
型
:
;
の《式》をもつ
文は,返却値の型が
の関数においてだけ使うことができる。
《式》の
評価は,関数が呼出し元に戻る直前に行う。
((
文
文は,その《識別子》のラベルが付いた文に,無条件で制御を移す。その《識別子》は,その
時点の関数の中に存在するラベル(
(
)でなければならない。
()
宣言文
一つの宣言文は,一つ以上の新しい識別子をブロック内に導入する。形式は,次のとおりとする。
宣言文
3
ブロック宣言
ある宣言によってブロックに導入された識別子が,その外側のブロックですでに宣言されている場合,外側の宣言は,
内側ブロックの残りの部分では隠ぺいされ,内側ブロックの終了後に再びその効力を現わす。
自動記憶域期間(
)
)をもつ変数は,その変数の《宣言文》を実行するたびに初期化する。ブロック内で宣言さ
れた自動記憶域期間をもつ変数は,そのブロックから出るときに解体する(
((
参照)
。
ブロックの中に飛び込むことは可能であるが,初期化をもつ《宣言》を迂回して飛び込むことはできない。自動記
憶域期間をもつある局所変数が有効範囲にない場所から,その有効範囲になっている場所への飛越し
があるプロ
グラムは,その変数が
"
互換型(
*
)であって《初期化子》
(
#
)をもたずに宣言されている場合を除き,不適格
とする。
例
Q
''(((
&
''
不適格
3
の有効範囲内への飛越し
''(((
3
5
%
L&
''(((
3
&
''
この飛越しは,
B>
。この飛越しが,
のデストラクタを
''
呼び出すことになり,再びラベル
の直後で構築される。
R
静的記憶域期間(
)
)をもつすべての局所オブジェクトは,そのゼロ初期化(
#
)を,その他のすべての初期
化が起きる前に実行する。静的記憶域期間をもつ
"
互換型(
*
)の局所オブジェクトの定数式による初期化は,初
めてそのブロックに入る前に行う。処理系は,名前空間有効範囲(
(
)内の静的記憶域期間をもつオブジェクトを
静的に初期化することが許されているが,それと同じ条件で,静的記憶域期間をもつ他の局所オブジェクトを早期に
初期化してよい。そうしない場合,そのようなオブジェクトの初期化は,その宣言に初めて制御が渡った時点で行わ
れる。そのようなオブジェクトは,初期化が完了した時点で,初期化されたことになる。初期化が例外を送出して抜
け出てしまった場合,初期化は未完了とし ,その宣言に再度制御が渡った時点で再試行する。オブジェクトを初期化
している間に,制御がその宣言に( 再帰的に )再度渡った場合の挙動は,未定義とする。
例
Q
%
+!&
''
再帰的呼出しであり,動作は未定義。
)L&
R
静的記憶域期間をもつ局所オブジェクトのデストラクタは,そのオブジェクトが構築された場合にだけ実行する。
参考
静的記憶域期間をもつ局所オブジェクトが解体される順序については,
(
に規定する。
(
あいまい性の解決 《式文》 及び 《宣言》を含む文法には,あいまい性がある。左端の部分式に関数形の明示
的型変換(
#
)をもつ《式文》は,最初の《宣言子》が
で始まる《宣言》と区別できないことがある。この場
合のその《文》は,
《宣言》とする。
参考 あいまい性を解決するには,それが《式文》なのか《宣言》なのかを決めるために《文》の全体を調べ
ることが必要となるかもしれない。それによって,多くのあいまい性が解決される。
例
を《単純型指定子》
(
)#
)とする。
V
%
,&
''
これは式文
))&
''
これは式文
/&
''
これは式文
!&
''
これは宣言
S/T&
''
これは宣言
%
Q
L
+
R&
''
これは宣言
!*&
''
これは宣言
注
'"
文の《条件》から
"
ラベルへの制御の移動も,この意味からいって,飛越しと考える。
この最後の例では,
は,
へのポインタであり,それを
*
で初期化している。もちろ
ん,この例は,意味規則からは不適格となるが,そのことは,構文規則の解析には影響しない。
次の例は,すべて《宣言》となる。
例
Q
''(((
3
&
&
,
&
R&
&
''
宣言
!
&
''
宣言
%
,&
''
宣言
,
,
%*&
''
宣言
&
,
+&
''
宣言
あいまい性の解決は,純粋に構文規則上のこととする。すなわち,ある文の中にある名前の意味は,それが《型名》
であってもなくても,一般的にいって,あいまい性の解決には使えないし ,あいまい性の解決によって変わらない。
クラステンプレートは,修飾付き名前が《型名》であるか否かを決めるために,必要に応じて具現化される。あいま
い性の解決は,文法解析処理
1!
に先行し ,あいまい性が解決されて宣言とされた文が,不適格な宣言となる
こともある。文法解析処理中に,テンプレート仮引数の名前の結合が,試行の文法解析のときの結合と異なってきた
場合,そのプログラムは,不適格とする。診断は,不要とする。
参考 これは,その名前がその宣言のはじめのほうで宣言されている場合にだけ発生し うる。
例
L
Q
L
Q
L&
R
%
Q
&
R
L
Q
R
R&
+
Q
+
Q
R
R&
!!+
&
Q
''
あいまい性の解決からは,これは宣言であると文法解析される。
L
%
*
+M
''
+
は,
L
型の変数として宣言される。
!!+
&
''
しかし ,この宣言の最後の部分では
''
文法解析不可能となる。それは,
+
が
''
型名であることに依存するからである。
R
)
宣言
宣言は,名前をど う解釈すべきかを指定する。宣言の形式は,次のとおりとする。
宣言列
3
宣言
宣言列
宣言
宣言
3
ブロック宣言
関数定義
テンプレート宣言
明示的具現化
明示的特殊化
結合指定
名前空間定義
ブロック宣言
3
単純宣言
!
定義
名前空間別名定義
!
宣言
!
指令
単純宣言
3
宣言指定子列
初期化宣言子並び
&
参考 《
!
定義》は
)
で規定し,
《結合指定》は
)#
で規定する。
《関数定義》は
で規定し,
《テンプレー
ト宣言》は
で規定する。
《名前空間定義》は
)
で規定し 《
!
宣言》は
)
で,
《
!
指令》
は
)
で規定する。
《単純宣言》は 《宣言指定子列》 及び 《初期化宣言子並び》の二つの部分に分かれる。
《宣言指定子列》を構成する
《宣言指定子》については
)
で規定し 《初期化宣言子並び》を構成する《宣言子》については
で規定する。
《宣言》は,ある有効範囲(
)の中に現れる。有効範囲の規則は,
で規定する。関数を宣言している宣言,
又は クラス,テンプレート 若しくは 関数を定義している宣言は,その中に
重以上に入れ子になった有効範囲をも
つ。これらの入れ子になった有効範囲は,更にその中に宣言を入れ子にすることができる。この
)
において,
を
宣言 又は 宣言の部分構成要素とし ,
を構成要素として,次の書き方をしたときは,いずれも,その宣言の直接の
構成要素
だけを意味し ,入れ子になった内側の宣言の構成要素は意味しない。
―
の
―
の中の
―
に含まれる
《単純宣言》において,省略可能な《初期化宣言子並び》が実際に省略できるのは,クラス(
*
)又は 列挙体(
)
)
を宣言する場合だけ,すなわち,
《宣言指定子列》に 《クラス指定子》,
《クラスキー》
(
*
)付き《詳述型指定子》 又
は 《列挙体指定子》のいずれか一つが含まれる場合だけとする。これらの場合,及び 《クラス指定子》 又は 《列挙
体指定子》が《宣言指定子列》に存在する場合,その指定子の中の《識別子》は,その《宣言》によって宣言される
名前( 構文規則に従って,
《クラス名》《列挙体名》 又は 《列挙子》のいずれか )の一つとなる。こうした場合,無
名のビットフィールド(
*(
)を宣言するときを除いて,その《宣言指定子列》は,プログラムに一つ以上の名前を新
たに導入するか,以前の宣言で導入した名前を再度宣言し直すかのいずれかでなければならない。
例
Q
R&
''
不適格
Q
R&
''
不適格
《初期化宣言子並び》中の《初期化宣言子》は,それぞれ 《宣言子識別子》を一つだけもつ。この《宣言子識別子》
が,その《初期化宣言子》によって宣言される名前となり,したがって,その《宣言》によって宣言される名前の一
つともなる。
《宣言指定子列》中の《型指定子》
(
)#
)と,
《初期化宣言子》中の再帰的な《宣言子》の構造とによっ
て,一つの型(
)が指定される。この型が 《初期化宣言子》の宣言する名前に結び付けられる。
《宣言指定子列》に
1
3
指定子がある場合,その宣言は,型定義宣言と呼ぶ。その《初期化宣言子》の名前は,
それぞれ《型定義名》として宣言され,それに結び付けられる型の同義語になる(
)
参照)
。
《宣言指定子列》に
1
3
指定子がない場合,その宣言を,その名前に結び付けられる型が関数型(
#
)のとき関数宣言と呼び,そ
うでないときオブジェクト宣言と呼ぶ。
関数宣言は,宣言一般には現れえない構文要素を書き加えて初めて関数定義となる。しかし,オブジェクト宣言は,
それ自身で定義ともなる。ただし ,次の二つの条件の両方を満たす場合を除く。
―
?
指定子を含んでいる
―
初期化子(
)をもたない
定義を行うと,適切な量の記憶域が割り付けられ,適切な初期化(
#
)が行われる。
《宣言指定子列》を省略してもよいのは,コンストラクタ,デストラクタ 及び 型変換の関数宣言だけとする。
)
指定子 《宣言》の中で使える指定子は,次のとおりとする。
宣言指定子
3
記憶域種別指定子
型指定子
注
言語の
暗黙の
の規則は,
では許されていない。
関数指定子
宣言指定子列
3
宣言指定子列
宣言指定子
《宣言指定子》の最長の列が 《宣言》の《宣言指定子列》とみなされる。それが型名一つだけのこともある。この
列は,自己矛盾していてはならない。
( 自己矛盾していないことの定義は,
)
〜
)#
による。)
例
!
C&
C&
''
エラー
3
名前がない。
ここで,宣言
C
は,型
C
の静的変数の名前が指定されていないので,不適格となる。
C
とい
う変数を得たければ (
,
以外の)
《型指定子》を書いて,その《型定義名》
C
が( 再)宣
言される名前であって 《宣言指定子》の列の一部ではないことを示しておかなければならない。もう一つ
の例を,次に示す。
C&
''
!
となり,
''
!
にはならない。
C&
''
これは,
となる。
参考
,,
及び
は,特に指定しなければ,
を指定したことになるので,それら
の指定子の直後に現れる《型名》は,宣言 又は 再宣言される名前として扱われる。
例
C&
''
となる。
C&
''
となる。
)
記憶域種別指定子
記憶域種別指定子は,次のとおりとする。
記憶域種別指定子
3
《記憶域種別指定子》は,一つの《宣言指定子列》の中に高々一回しか現れてはならない。
《記憶域種別指定子》が《宣
言指定子列》に現れる場合,その《宣言指定子列》の中に
1
3
指定子があってはならず,その宣言の《初期化宣言
子並び》が空であってはならない。ただし ,大域的な無名の共用体で,
として宣言されるものは除く(
*#
参
照)
。
《記憶域種別指定子》は,それぞれの《初期化宣言子》で宣言される名前に適用され,その他の指定子によって
宣言される名前には適用されない。
《記憶域種別指定子》は,明示的特殊化(
)
) 又は 明示的具現化(
)
)
の指令の中に指定してはならない。
指定子 又は
!
指定子は,ブロック(
(
) 又は 関数仮引数(
)内で宣言されるオブジェクトの名前
にだけ適用することができる。これらは,名前付きオブジェクトが自動記憶域期間(
)
)をもつことを指定する。
ブロック有効範囲で《記憶域種別指定子》を伴わずに宣言されるオブジェクト,又は 関数仮引数として宣言されるオ
ブジェクトの記憶域期間は,自動記憶域期間とする。
参考 したがって,
指定子は,ほとんど すべての場合に冗長となり,あまり使われない。
には,
《宣
言文》を《式文》から明確に区別するために使うという使い方がある(
(
参照)
。
!
指定子は,
指定子と同じ 意味をもつ。ただし ,指定したオブジェクトの使用頻度が高い可能性がある
という情報を,処理系に与える。
参考
処理系は,この情報を無視してもよい。そのオブジェクトのアドレスを使っているプログラムについて
は,多くの処理系がこの情報を無視している。
!
指定子は,オブジェクト名,関数名 及び 無名の共用体(
*#
)にだけ適用することができる。ブロック中に
の関数宣言があってはならないし ,関数の仮引数に
を指定してはならない。オブジェクトの宣言にお
ける
!
指定子は,そのオブジェクトが静的記憶域期間(
)
)をもつことを宣言する。
!
指定子は,クラス
メンバの宣言に使うこともできる。その効果は
*
で規定する。
!
指定子付きで宣言された名前の結合について
は,
#
で規定する。
?
指定子は,オブジェクト 又は 関数の名前にだけ適用できる。
?
指定子は,クラスメンバ 又は 関数仮引
数の宣言に使うことはできない。
?
指定子付きで宣言された名前の結合については,
#
で規定する。
ある名前空間有効範囲の中で《記憶域種別指定子》を伴わずに宣言した名前は,それに先行する宣言によって内部
結合をもっている場合,及び
と宣言されている場合を除き,外部結合をもつ。
と宣言され ,明示的に
と宣言されていないオブジェクトは,内部結合をもつ。
一つの実体に対する一連の宣言が導く結合は,一致していなければならない。すなわち,ある有効範囲において,
同じオブジェクト名を宣言している宣言ど うし ,又は 一つの関数の同じ多重定義を宣言している宣言ど うしは,同じ
結合を導かなければならない。しかし ,多重定義される関数の集合の中の個々の関数が異なる結合をもっていても差
し支えない。
例
!
&
''
は,内部結合
!
''
は,やはり内部結合
Q
'!(((!'
R
!
&
''
は,外部結合
!
''
エラー
3
結合の不一致
Q
'!(((!'
R
&
&
''
外部結合
&
&
''
外部結合
&
&
''
外部結合
&
&
''
内部結合
&
''
は,内部結合
&
''
エラー
3
二つの定義
&
''
は,内部結合
&
''
は,やはり内部結合
&
''
は,外部結合
&
''
エラー
3
結合の不一致
&
''
は,外部結合
&
''
エラー
3
結合の不一致
宣言だけがあって定義がないクラスの名前は,
?
宣言の中で使うことができる。そのような宣言は,完全クラ
ス型を要求しない範囲でだけ,使うことができる。
例
F&
F
&
F
&
F&
Q
&
''
エラー
3
F
が不完全なため
&
''
エラー
3
F
が不完全なため
R
%
指定子は,クラスデータメンバ(
*
)に対してだけ適用でき,
又は
として宣言された名前に
は適用できず,参照メンバにも適用できない。
例
5
Q
!
&
''
B>
!
&
''
不適格
R&
#
クラスのデータメンバに対する
%
指定子は,それを含むクラスオブジェクトに適用された
!
指定子の効
果を取り消し,そのデータメンバの変更を可能にする(
)#
参照)
。ただし,そのオブジェクトの残りの部分の定
値性は変わらない。
)
関数指定子
関数指定子は,関数宣言にだけ使うことができる。
関数指定子
3
関数宣言(
#
,
*
及び
参照)は,
指定子付きの場合,インライン関数の宣言とする。
指定子
は,処理系に対し,通常の関数呼出し機構を使わず,関数本体を呼出し位置にインライン置換をするのが望ましいこ
とを指示する。処理系は,必ずしも呼出し時点でのインライン置換を行わなくてもよいが,インライン置換しない場
合であっても,
)
で規定するインライン関数のそれ以外の規則には従わなければならない。
クラス定義の中で定義される関数は,インライン関数とする。
指定子は,ブロック有効範囲をもつ関数宣言
に現れてはならない。
インライン関数は,それを使用する翻訳単位ごとに定義しなければならず,すべてが完全に同じ定義でなければな
らない(
参照)
。
参考
翻訳単位中で,インライン関数を定義する前に,そのインライン関数の呼出しを書いてもよい。
ある翻訳単位中で
として宣言した関数が外部結合をもつ場合,その関数が現れるすべての翻訳単位において
と宣言しなければならない。診断は,不要とする。外部結合をもつインライン関数中の静的な局所変数は,常
に同じオブジェクトを参照する。外部結合をもつインライン関数中の文字列リテラルは,異なる翻訳単位であっても
同じオブジェクトとする。
0
指定子は,クラス宣言中のメンバ指定の中に現れる非静的クラスメンバ関数の宣言にしか使ってはならない
(
参照)
。
?1
指定子は,クラス宣言中のコンストラクタの宣言にしか使ってはならない(
参照)
。
)
"
指定子
1 3
指定子をもつ《宣言》は 《識別子》を宣言し ,後で基本型(
*
) 又は 複合型
(
*
)を名指すことができるようにする。
1
3
指定子は,関数定義(
)に使ってはならず,
《宣言指定子列》
の中で《型指定子》以外の指定子と組み合わせて使ってはならない。
型定義名
3
識別子
1
3
指定子によって宣言された名前は 《型定義名》となる。その宣言の有効範囲内で 《型定義名》は,構文規則
上ではキーワード と同等とし ,
での規定に従って,その識別子に結び付いた型を名指す。したがって 《型定義名》
は,一つの型の別名になる。
《型定義名》は,クラス宣言(
*
) 又は 列挙体宣言とは異なり,新たな型を作り出し
はしない。
例
@<?8F
!>?<7>FC&
この宣言の後に次の構文が来た場合,すべて正当な宣言となる。
@<?8F
&
>?<7>FC
&
の型は
になり,
の型は
:
へのポインタ
;
になる。
クラスではない有効範囲の中で,
1
3
指定子を使って,その有効範囲内で宣言された別の型の名前を再定義し
てもよく,その結果としてかつて参照していた型を再参照するようになっても差し支えない。
例
Q'!
(((
!'R
&
<&
<&
<
<&
有効範囲の中で,
1
3
指定子を使ってその有効範囲内で宣言された他の型の名前を再定義し ,別の型を参照す
るようにしてはならない。
例
Q
'!
(((
!'
R&
&
''
エラー
3
再定義
注
キーワード
は,関数の結合に影響を与えない。
(
同様に,有効範囲の中で,クラス 又は 列挙体を宣言するのに,そのクラス 又は 列挙体とは別の型を参照するように
その有効範囲で宣言されている《型定義名》と同じ名前を使ってはならない。
例
&
Q
'!
(((
!'
R&
''
エラー
3
再定義
クラスを名指す《型定義名》は,
《クラス名》
(
*
)となる。
《詳述型指定子》
(
)#
)の中 又は クラス宣言の《ク
ラス先頭語》の中で 《クラスキー》に引き続いて《型定義名》が使用されている場合,又は コンストラクタ(
)
又は デストラクタ(
)を宣言する《宣言子》の中で《型定義名》が《識別子》として使用されている場合,その
プログラムは不適格とする。
例
F
Q
F&
XF&
R&
F
&
F
%
&
''
B>
!
&
''
エラー
型定義の宣言が無名のクラス( 又は 列挙体)を定義する場合,その宣言によってそのクラス型( 又は 列挙型)に
なることを宣言される最初の《型定義名》は,結合目的(
#
参照)の場合にだけ,そのクラス型( 又は 列挙型)を
表すのに使うことができる。
例
Q
R
!
F&
''
F
は,結合目的のクラス名になる。
《クラス名》
( 又は 《列挙体名》)が必要なところに,この最初の《型定義名》を使っている場合,そのプログラムは
不適格とする。
例
Q
F&
''
エラー
3
F
は,通常のメンバ関数であってコンストラクタで
''
ないから,返却値型が必要である。
R
F&
)
"
指定子
3
指定子は,クラスメンバへのアクセスを指定するために使う(
参照)
。
)#
型指定子
型指定子の構文規則は,次のとおりとする。
型指定子
3
単純型指定子
クラス指定子
列挙体指定子
詳述型指定子
0
修飾子
一般規則として 《宣言》の《宣言指定子列》全体の中には,高々一つの《型指定子》しか許されない。この規則に対
する例外は,次のとおりとする。
―
及び
は,任意の《型指定子》と組み合わせることができる。しかし,型定義(
)
) 又
は テンプレートの型実引数(
)を使って導入される場合(これらの場合,冗長な
0
修飾子は,無視
される。)を除き,冗長な 《
0
修飾子》は,禁止されている。
―
又は
は,
,
,
又は
のいずれかと組み合わせることができる。
―
又は
は,
と組み合わせることができる。
―
は,
と組み合わせることができる。
コンストラクタ,デストラクタ 及び 変換関数を宣言する場合を除き,
《宣言》内には 《
0
修飾子》とは異なる少な
くとも一つの《型指定子》を必要とする。
参考 《クラス指定子》 及び 《列挙体指定子》については,それぞれ
*
及び
)
で規定する。その他の《型
指定子》については,
)#
〜
)#
で規定する。
注
《型指定子》のない《宣言指定子列》,又は 《
"#
修飾子》だけを指定している《型指定子》をもつ《宣言指定子列》に対する特別な規
定はない。
言語の
暗黙の
の規則は,
では許されていない。
)
)#
'
修飾子
0
修飾子には,
及び
がある。
《
0
修飾子》が《宣言指定子列》にある場合,そ
の宣言の《初期化宣言子並び》は,空であってはならない。
参考
*
に,オブジェクト型 及び 関数型に
0
修飾子が与える影響を規定している。
と明示宣言されていない場合,又は 外部結合をもつことを先に宣言していない場合,名前空間有効範囲の
中で宣言された
修飾の付いた型をもつオブジェクトは,内部結合をもつ。
が付かなくて
修飾
の付いた汎整数型 又は 列挙型の変数は,汎整数定数式で初期化されている場合,汎整数定数式の中で使ってもよい
(
#*
参照)
。
参考
#
で規定するように,
修飾付き型をもつオブジェクト 又は 部分オブジェクトの定義では,初期
化子を指定するか,省略時初期化の対象にするかしなければならない。
0
修飾付き型へのポインタ 又は 参照は,
0
修飾付きオブジェクトを実際に指しているか参照しているかする必
要はないが,そうしているとして扱われる。
修飾付きのアクセスパスを使って,オブジェクトを変更してはな
らない。この禁止は,参照されるオブジェクトが定値オブジェクトであるか否か,他のアクセスパスから変更できる
か否かに依らない,
参考
0
修飾子は,型の体系に組み込まれているので,キャスト(
#
)を使わない限り無効にはできない。
(
)
)と宣言したクラスメンバは,変更可能とする。これに当てはまらない定値オブジェクトをその生
存期間(
)中に変更しようとした場合,その結果の挙動は未定義とする。
例
%
*&
''
修飾( 要求ど おり初期化している。)
%
M&
''
不適格
3
を変更しようとした。
%
+&
''
修飾なし 。
!
&
''
へのポインタ
%
0&
''
B>3
修飾付きアクセスパスが,修飾なしの
''
オブジェクトを指している。
!
%
M&
''
不適格
3
へのポインタで
''
変更しようとした。
!
&
%
P!
&
''
!
から
!
への変換キャストが必要。
!
%
M&
''
定義される
3
は,
をポイントしており,
''
これは,定値オブジェクトではない。
!
%
*&
''
初期化される。
!
%
P!
&
''
キャストが必要。
!
%
M&
''
未定義
3
定値オブジェクトの変更である。
別の例を次に示す。
例
5
Q
3
&
&
R&
J
Q
3
5
&
J
&
R&
J
&
(())&
''
適格
3
メンバは変更できる。
(())&
''
不適格
3
修飾のメンバは変更できない。
J!
%
PJ!0
&
''
をキャストして定値でなくする。
CV(
%
OO&
''
適格
3
メンバはキャストできる。
V(
%
OO&
''
未定義
3
定値メンバを変更しようとしている。
修飾付き型と定義されたオブジェクトを,
修飾なし型の左辺値を使って参照しようとした場合,
そのプログラムの挙動は,未定義とする。
参考
の指定は,その属性のオブジェクトの値が処理系で検出不可能な手段で変更されうるので,そ
ういうオブジェクトに対する過度の最適化処理を避けるようにというヒントを,処理系に与える。詳細な
意味規則は,
*
に規定してある。一般に,
"##
における
の意味は,
"
での意味と同じになる
ように意図している。
)#
単純型指定子
単純型指定子の構文規則は,次のとおりとする。
単純型指定子
3
33
入れ子名前指定子
型名
33
入れ子名前指定子
テンプレート識別子
P
型名
3
クラス名
列挙体名