JIS X 3010:2003 プログラム言語C | ページ 3

                                                                                              7
X 3010 : 2003 (ISO/IEC 9899 : 1999)
ばならない。さらに,この改行文字の直前に(接合を行う前の時点で)逆斜線文字があってはなら
ない。
(3) ソースファイルを,前処理字句(6)及び空白類文字(注釈を含む。)の並びに分割する。ソースファイ
ルは,前処理字句の途中又は注釈の途中で終了してはならない。各注釈を,一つの空白文字に置き
換える。改行文字を保持する。改行文字を除く空白類文字の並びを保持するか一つの空白文字に置
き換えるかは,処理系定義とする。
(4) 前処理指令を実行し,マクロ呼出しを展開する。さらに,Pragma単項演算子式を実行する。字句
連結(6.10.3.3参照)の結果として生成される文字の並びが国際文字名の構文規則に一致する場合,
その動作は未定義とする。#include前処理指令に指定された名前をもつヘッダ又はソースファイ
ルに対して,フェーズ(1)からフェーズ(4)までの処理を再帰的に行い,すべての前処理指令を
削除する。
(5) 文字定数及び文字列リテラル中のソース文字集合の各要素及び各逆斜線表記を,それぞれに対応す
る実行文字集合の要素に変換する。対応する要素が存在しない場合,ナル(ワイド)文字以外の処
理系定義の要素に変換する(7)。
(6) 隣接する文字列リテラル字句同士を連結する。
(7) 字句を分離している空白類文字は,もはや意味をもたない。各前処理字句を字句に変換する。その
結果,生成された字句の列を構文的及び意味的に解析し,翻訳単位として翻訳する。
(8) すべての外部オブジェクト参照及び外部関数参照を解決する。その翻訳単位中に定義されていない
関数及びオブジェクトへの外部参照を解決するため,ライブラリの構成要素を連係する。これらす
べての翻訳出力をまとめて,実行環境上での実行に必要な情報を含む一つのプログラムイメージを
作る。
前方参照 3文字表記(5.2.1.1),外部定義(6.9),国際文字名(6.4.3),字句要素(6.4),前処理指令(6.10)
5.1.1.3 診断メッセージ 前処理翻訳単位又は翻訳単位が何らかの構文規則違反又は制約違反を含む場
合(たとえ,その動作が未定義の動作又は処理系定義の動作として明示的に規定されていても),規格合致
処理系は,その前処理翻訳単位又は翻訳単位に対して,少なくとも一つの(処理系定義の方法で識別され
る)診断メッセージを出力しなければならない。その他の状況においては,診断メッセージを出力しなく
てもよい(8)。
例 処理系は,次に示す翻訳単位に対して診断メッセージを出力しなければならない。
char i;
int i;
その理由は,この規格での記述が,ある構文要素に対する動作を,制約違反かつ結果として未定
───────────────────────────────────────────────
(6) ソースファイルの文字を前処理字句に分ける処理は,文脈に依存する(6.4で規定する。)。例えば,
#include前処理指令の中では<の扱いが他の場合と異なる。
(7) 処理系は,対応する要素がないソース文字集合の要素のすべてを,実行文字集合の同じ要素に変換す
る必要はない。
(8) 処理系は,各違反の性質及び可能な限り,違反箇所を明らかにしたほうがよいことを意図している。
もちろん,正しいプログラムを正しく翻訳している限り,処理系が任意の個数の診断メッセージを出
力することは自由である。処理系は正しくないプログラムを最後まで翻訳し続けてもよい。

――――― [JIS X 3010 pdf 11] ―――――

8
X 3010 : 2003 (ISO/IEC 9899 : 1999)
義の動作になると規定している場合は,制約違反に対する診断メッセージを出力しなければなら
ないからである。
5.1.2 実行環境 フリースタンディング(freestanding)実行環境及びホスト(hosted)実行環境の2種類
の実行環境を定義する。いずれの場合も,実行環境が指定されたCの関数を呼び出すときの処理を,プロ
グラム開始処理(program startup)という。静的記憶域期間をもつすべてのオブジェクトをプログラム開始
処理以前に初期化(initialize)(それらの初期値に設定)しなければならない。初期化の方法及び時期につ
いて,これ以外は,未規定とする。プログラム終了処理(program termination)は,実行環境に制御を戻す。
前方参照 オブジェクトの記憶域期間(6.2.4),初期化(6.7.8)
5.1.2.1 フリースタンディング環境 フリースタンディング環境では,オペレーティングシステムのいか
なる支援もなしにCプログラムの実行を行う。プログラム開始時に呼び出される関数の名前及び型は,処
理系定義とする。フリースタンディング環境でプログラムが利用できるライブラリ機能は,4.で要求する
最低限必要なライブラリ機能を除いて,処理系定義とする。
フリースタンディング環境におけるプログラム終了処理の効果は,処理系定義とする。
5.1.2.2 ホスト環境 ホスト環境を提供する必要はないが,提供する場合,5.1.2.2.15.1.2.2.3の規定に合
致しなければならない。
5.1.2.2.1 プログラム開始処理 プログラム開始処理において呼び出される関数の名前は,mainとする。
処理系は,この関数に対して関数原型を宣言しない。この関数は,次の4種類の方法のいずれかで定義し
なければならない。
− 返却値の型intをもち仮引数をもたない関数
int main(void) [{ }]
− 二つの仮引数をもつ関数(仮引数は,これらが宣言された関数に対して局所的であるため,どのよう
な名前を使用してもよいが,ここではargc及びargvとする。)
int main(int argc, char * argv[]) [{ }]
− 上に掲げた二つの方法のいずれかと等価な方法(9)
− 上に掲げた三つの方法のいずれでもない処理系定義の方法
二つの仮引数を定義する場合,関数mainの仮引数は,次の制約に従わなければならない。
− argcの値は,非負でなければならない。
− argv[argc]は,空ポインタでなければならない。
− argcの値が正の場合,argv[0]からargv[argc-1]までの配列要素は,文字列へのポインタでなけ
ればならない。これらの文字列には,プログラム開始処理に先立ち,ホスト環境が処理系定義の値を
与える。これは,ホスト環境中のどこかでプログラム開始処理に先立って決定された情報をプログラ
ムに与えることを目的とする。ホスト環境が大文字と小文字のいずれか一方しか扱えない場合,処理
系がmainに渡す文字列は,小文字にしなければならない。
− argcの値が正の場合,argv[0]が指す文字列は,プログラム名(program name)を表す。ホスト環
境からプログラム名を得ることができない場合,argv[0][0]は,ナル文字でなければならない。argc
の値が1より大きい場合,argv[1]からargv[argc-1]までが指す文字列は,プログラム仮引数
───────────────────────────────────────────────
(9) したがって,intは,intとして定義された型定義名で置き換えることができるし,argvの型は,
char ** argvと書くこともできる。

――――― [JIS X 3010 pdf 12] ―――――

                                                                                              9
X 3010 : 2003 (ISO/IEC 9899 : 1999)
(program parameter)を表す。
− 仮引数argc,argv及びargv配列が指す文字列は,プログラムによって変更可能でなければならな
い。さらに,プログラム開始処理からプログラム終了処理までの間,最後に格納された値を保持しな
ければならない。
5.1.2.2.2 プログラムの実行 ホスト環境では,プログラムは,ライブラリの箇条(7.)で規定するすべ
ての関数,マクロ,型定義及びオブジェクトを使用してよい。
5.1.2.2.3 プログラム終了処理 main関数の返却値の型がintと適合する場合,main関数の最初の呼出
しからの復帰は,main関数が返す値を実引数としてもつexit関数の呼出しと等価とする(10)。main関
数を終了する}]に到達した場合,main関数は,値0を返す。main関数の返却値の型がintと適合しない
場合,ホスト環境に戻される終了状態は,未規定とする。
前方参照 exit関数(7.20.4.3),用語の定義(7.1.1)
5.1.2.3 プログラムの実行 この規格における意味規則の規定では,最適化の問題を無視して抽象計算機
の動作として記述する。
ボラタイルオブジェクトへのアクセス,オブジェクトの変更,ファイルの変更,又はこれらのいずれか
の操作を行う関数の呼出しは,すべて副作用(side effect)と呼び(11),実行環境の状態に変化を生じる。式
の評価は,副作用を引き起こしてもよい。副作用完了点(sequence point)と呼ばれる実行順序における特
定の点において,それ以前の評価に伴う副作用は,すべて完了していなければならず,それ以降の評価に
伴う副作用が既に発生していてはならない。(副作用完了点の要約を附属書Cに示す。)
抽象計算機では,すべての式は意味規則で規定するとおりに評価する。実際の処理系では,値が使用さ
れないこと,及び(関数の呼出し又はボラタイルオブジェクトのアクセスによって起こる副作用を含め)
副作用が必要とされないことが保証できる式は,評価しなくてよい。
シグナルの受理によって抽象計算機が処理を中断する場合,その直前の副作用完了点でのオブジェクト
の値だけが信頼できる。直前の副作用完了点と次の副作用完了点との間で変更される可能性があるオブジ
ェクトは,正しい値を受け取り終わっているとは限らない。
規格合致処理系は,少なくとも次の要求を満たさなければならない。
− 副作用完了点において,ボラタイルオブジェクトは,それまでのアクセスがすべて完了していること
及び後続のアクセスが行われていないこと,という意味において安定している。
− プログラム終了の時点で,ファイルに書き込まれたすべてのデータは,プログラムの抽象意味規則に
従った実行が生成する結果と一致する。
───────────────────────────────────────────────
(10) 6.2.4に従い,main関数の最初の呼出しから復帰する場合,main関数で宣言された自動記憶域期
間をもつオブジェクトの生存期間は,終了するが,exit関数の呼出しの場合,その生存期間は,
終了しないかもしれない。
(11) 2進浮動小数点算術に対するIEC 60559規格は,利用者がアクセス可能なある種の状態フラグ及び
制御モードを要求する。浮動小数点の演算は,暗黙に状態フラグをセットし,モードは,浮動小数
点の演算結果の値に影響する。こうした浮動小数点の状態をサポートする処理系は,状態の変化を
副作用として認識しなければならない(詳細は,附属書F参照)。浮動小数点環境ライブラリ
<fenv.h>は,この副作用が問題となる場合は,それを処理系に示し,副作用が問題とならない場
合は,処理系を自由にしておくためのプログラム上の手段を提供する。

――――― [JIS X 3010 pdf 13] ―――――

10
X 3010 : 2003 (ISO/IEC 9899 : 1999)
− 対話型装置に対する入出力動作は,7.19.3で規定するとおりに行う。この要求は,入力要求メッセー
ジが実際にプログラムの入力待ち以前に現れることを確実にするため,バッファリングされない出力
又は行バッファリングされた出力ができる限り早く現れることを意図する。
どのようなものが対話型装置であるかは,処理系定義とする。
抽象意味規則と実際の意味規則とのより厳密な対応付けは,各処理系において定義してよい。
例1. 処理系は,抽象意味規則と実際の意味規則とを1対1に対応させてもよい。このような処理系
では,任意の副作用完了点における実際のオブジェクトの値は,抽象意味規則で規定する値と
一致する。その場合,キーワードvolatileは冗長となる。
別の実現例として,処理系は,それぞれの翻訳単位内で各種最適化処理を施してもよい。こ
の場合,翻訳単位の境界を越える関数呼出しが行われる場合だけは,実際の意味規則と抽象意
味規則とが一致することになる。このような処理系では,呼び出した関数と呼び出された関数
とが異なる翻訳単位に属する場合,各関数に入る時点及び関数からの戻りの時点において,す
べての外部結合オブジェクトの値及びそれらの中からポインタを介してアクセスできるすべて
のオブジェクトの値は,抽象意味規則での値と一致する。さらに,このような関数に入った時
点において,呼び出された関数のすべての仮引数の値及びそれらの中からポインタを介してア
クセスできるすべてのオブジェクトの値は,抽象意味規則での値と一致する。この形態の処理
系では,signal関数によって起動される割込み処理ルーチンが参照するオブジェクトには,
明示的なvolatile記憶域の指定が必要であり,そのほかにも処理系定義の制約が必要であり
うる。
例2. 次のプログラム片を実行する場合,
char c1, c2;

c1 = c1 + c2;
“整数拡張”の規則に従って,抽象計算機はまずそれぞれの変数の値をint型の大きさに拡張
し,次に二つのintの加算を行い,結果の切捨てを行う。実際の実行では,同一の結果を得る
ことだけが必要であり,オーバフローを起こさずに,二つのcharの加算を実行できるのであ
れば,又はオーバフローが起こっても,例外にならずに,正しい結果を生成できるのであれば,
拡張を省くことができる。
例3. 同様に,次のプログラム片では,
float f1, f2;
double d;

f1 = f2 * d;
処理系が(例えば,dを型doubleをもつ定数2.0に置き換えた場合のように)倍精度演算で
実行した場合と同じ結果になることを確認できるのならば,乗算を単精度演算で実行してもよ
い。
例4. ビット数が多いレジスタを採用している処理系は,意味規則を正しく守ることに留意しなけれ
ばならない。値は,それがレジスタに格納されて表現されるのか,又はメモリに格納されて表
現されるのか,ということとは独立である。例えば,データが暗黙にレジスタからメモリに退
避されることによってその値が変わることは,許されない。さらに,記憶域の種類ごとに決ま

――――― [JIS X 3010 pdf 14] ―――――

                                                                                             11
X 3010 : 2003 (ISO/IEC 9899 : 1999)
る精度にデータを丸めるためには,明示的にその記憶域へデータを格納し,再びそれを読み出
すことが必要である。特に,キャスト及び代入では,指定された変換を実際に実行する必要が
ある。次のプログラム片では,
double d1, d2;
float f;
d1 = f = 式;
d2 = (float) 式;
d1及びd2に代入される値は,いったんfloatに変換されたものでなければならない。
例5. 浮動小数点型の式に対する再構成は,しばしば精度と範囲の制約によって制限される。処理系
は,たとえオーバフロー及びアンダフローが発生しない場合でも,丸め誤差のために,加算若
しくは乗算に対する数学的結合法則,又は数学的分配法則を一般に適用することはできない。
さらに,処理系は,一般的に,式の再構成の目的で10進定数を置き換えることはできない。次
のプログラム片では,実数に対する数学の諸規則の適用による式の再構成は,必ずしも正しい
とは限らない(附属書F.8参照)。
double x, y, z;

x = (x * y) * z; // x *= y * z; と等価ではない。
z = (x - y) + y ; // z = x; と等価ではない。
z = x + x * y; // z = x * (1.0 + y); と等価ではない。
y = x / 5.0; // y = x * 0.2; と等価ではない。
例6. 式のグループ分けを次のプログラム例で示す。
int a, b;

a = a + 32760 + b + 5;
この式文は,演算子の結合と優先順位に関する規則によって,
a = (((a + 32760) + b) + 5);
と同一の動作をする。したがって,加算(a + 32760)の結果が,bに加えられ,その結果が5
に加えられ,その結果がaに代入される値となる。オーバフローが明示的なトラップを発生さ
せ,intで表現できる範囲が[ 32768,+32767]の計算機では,処理系は,この式を次のように書
き換えることはできない。
a = ((a + b) + 32765);
理由は,仮にaとbの値がそれぞれ 32754と 15であった場合,加算a + bは,トラップを
発生することになるが,元の式では発生しないからである。さらに,
a = ((a + 32765) + b);
又は
a = (a + (b + 32765));
にも書き換えられない。理由は,aとbの値がそれぞれ4と 8又は 17と12かもしれないか
らである。しかし,オーバフローが何らかの値を生成させ,正のオーバフロー及び負のオーバ
フローが打ち消し合う計算機では,同じ結果が得られるので,処理系は上で述べた方法のいず
れにも書き換えることができる。

――――― [JIS X 3010 pdf 15] ―――――

次のページ PDF 16

JIS X 3010:2003の引用国際規格 ISO 一覧

  • ISO/IEC 9899:1999(IDT)

JIS X 3010:2003の国際規格 ICS 分類一覧

JIS X 3010:2003の関連規格と引用規格一覧