X 3010:2003 (ISO/IEC 9899:1999)
(1)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
まえがき
この規格は,工業標準化法第14条によって準用する第12条第1項の規定に基づき,社団法人情報処理
学会情報規格調査会(IPSJ)/財団法人日本規格協会(JSA)から,工業標準原案を具して日本工業規格を改正
すべきとの申出があり,日本工業標準調査会の審議を経て,経済産業大臣が改正した日本工業規格である。
これによって,JIS X 3010:1996は改正され,この規格に置き換えられる。
改正に当たっては,日本工業規格と国際規格との対比,国際規格に一致した日本工業規格の作成及び日
本工業規格を基礎にした国際規格原案の提案を容易にするために,ISO/IEC 9899:1999,Programming
languages―C及びISO/IEC 9899 Technical Corrigendum 1:2001を基礎として用いた。
JIS X 3010には,次に示す附属書がある。
附属書A(参考)言語の構文の要約
附属書B(参考)ライブラリの要約
附属書C(参考)副作用完了点
附属書D(規定)国際文字名
附属書E(参考)処理系限界
附属書F(規定)IEC 60559浮動小数点算術
附属書G(参考)IEC 60559に適合する複素数計算
附属書H(参考)言語共通算術
附属書I(参考)共通の警告
附属書J(参考)可搬性
附属書1(参考)ISO/IEC 9899:1999(Programming languages―C)及び
ISO/IEC 9899 Technical Corrigendum 1:2001
X 3010:2003 (ISO/IEC 9899:1999)
(2)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
目 次
ページ
序文 ··································································································································· 1
1. 適用範囲 ························································································································ 1
2. 引用規格 ························································································································ 2
3. 用語及び記号の定義 ········································································································· 2
3.1 アクセス(access) ········································································································· 2
3.2 境界調整(alignment) ···································································································· 2
3.3 実引数[argument,actual argument,actual parameter(廃止予定)] ······································ 3
3.4 動作(behavior) ··········································································································· 3
3.5 ビット(bit) ················································································································ 3
3.6 バイト(byte) ·············································································································· 3
3.7 文字(character) ·········································································································· 3
3.8 制約(constraint) ········································································································· 4
3.9 正しい丸めの結果(correctly rounded result) ······································································ 4
3.10 診断メッセージ(diagnostic message) ·············································································· 4
3.11 前方参照(forward reference) ························································································ 4
3.12 処理系(implementation) ······························································································ 4
3.13 処理系限界(implementation limit) ················································································· 4
3.14 オブジェクト(object) ································································································· 4
3.15 仮引数[parameter,formal parameter,formal argument(廃止予定)] ·································· 4
3.16 推奨実装仕様(recommended practice) ············································································ 4
3.17 値(value) ················································································································· 4
3.18
x
····························································································································· 5
3.19
x
····························································································································· 5
4. 規格合致性 ····················································································································· 5
5. 環境 ······························································································································ 6
5.1 概念モデル ··················································································································· 6
5.2 環境考慮事項 ··············································································································· 12
6. 言語 ····························································································································· 21
6.1 記法 ··························································································································· 21
6.2 概念 ··························································································································· 21
6.3 型変換 ························································································································ 31
6.4 字句要素 ····················································································································· 35
6.5 式 ······························································································································ 48
6.6 定数式 ························································································································ 70
6.7 宣言 ··························································································································· 71
X 3010:2003 (ISO/IEC 9899:1999) 目次
(3)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ページ
6.8 文及びブロック ··········································································································· 100
6.9 外部定義 ···················································································································· 107
6.10 前処理指令 ················································································································ 111
6.11 今後の言語の方針 ······································································································· 124
7. ライブラリ ··················································································································· 124
7.1 概説 ·························································································································· 124
7.2 診断機能<assert.h> ·································································································· 128
7.3 複素数計算<complex.h> ······························································································ 129
7.4 文字操作<ctype.h> ···································································································· 136
7.5 エラー<errno.h> ······································································································· 138
7.6 浮動小数点環境<fenv.h> ····························································································· 139
7.7 浮動小数点型の特性<float.h> ····················································································· 146
7.8 整数型の書式変換<inttypes.h> ··················································································· 146
7.9 代替つづり<iso646.h> ······························································································· 149
7.10 整数型の大きさ<limits.h> ························································································ 149
7.11 文化圏固有操作<locale.h> ························································································ 149
7.12 数学<math.h>··········································································································· 155
7.13 非局所分岐<setjmp.h> ······························································································ 175
7.14 シグナル操作<signal.h> ··························································································· 177
7.15 可変個数の実引数<stdarg.h> ····················································································· 179
7.16 論理型及び論理値<stdbool.h> ··················································································· 182
7.17 共通の定義<stddef.h> ······························································································ 183
7.18 整数型<stdint.h> ···································································································· 183
7.19 入出力<stdio.h> ······································································································ 188
7.20 一般ユーティリティ<stdlib.h> ·················································································· 220
7.21 文字列操作<string.h> ······························································································ 232
7.22 型総称数学関数<tgmath.h> ························································································ 238
7.23 日付及び時間<time.h> ······························································································· 241
7.24 多バイト文字及びワイド文字拡張ユーティリティ<wchar.h> ············································· 247
7.25 ワイド文字種分類及びワイド文字大文字小文字変換ユーティリティ<wctype.h> ··················· 278
7.26 今後のライブラリの方針 ······························································································ 283
附属書A(参考) 言語の構文の要約 ···················································································· 285
附属書B(参考) ライブラリの要約····················································································· 285
附属書C(参考) 副作用完了点 ·························································································· 285
附属書D(規定) 国際文字名 ····························································································· 285
附属書E(参考) 処理系限界 ····························································································· 285
附属書F(規定) IEC 60559浮動小数点算術 ········································································· 285
附属書G(参考) IEC 60559に適合する複素数計算 ································································ 285
附属書H(参考) 言語共通算術 ·························································································· 285
X 3010:2003 (ISO/IEC 9899:1999) 目次
(4)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ページ
附属書I(参考) 共通の警告 ······························································································ 285
附属書J(参考) 可搬性 ···································································································· 285
附属書1(参考) ISO/IEC 9899:1999(Programming languages―C)及びISO/IEC 9899 Technical
Corrigendum 1:2001 ············································································································ 286
参考文献 ··························································································································· 287
索引 ································································································································· 289
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
日本工業規格 JIS
X 3010:2003
(ISO/IEC 9899:1999)
プログラム言語C
Programming languages−C
序文 この規格は,1999年に第2版として発行されたISO/IEC 9899:1999,(Programming languages―C)
及びTechnical Corrigendum 1 (2001)について,技術的内容を変更することなく日本工業規格として採用する
ために作成されたものであり,ISO/IEC 9899:1999の本体については,原国際規格の同項目を全文翻訳し,
ISO/IEC 9899:1999の附属書については,それぞれ原国際規格の同項目の内容を引用するものとした。た
だし,技術に関する正誤表(Technical Corrigendum)については,編集し,一体とした。
なお,この規格での点線の下線を施してある“参考”は,原国際規格にない事項である。
新しい装置及び拡張文字集合を導入するために,新しい機能をこの規格に追加する可能性がある。言語
の箇条及びライブラリの箇条では,処理系作成者及びプログラマに対し,正しい使用法だが将来の追加機
能と相いれない可能性がある使用法について警告している。
廃止予定の機能がある。これはこの規格の将来の改正で,削除されるかもしれないことを意味する。こ
れらは広く普及している使用法であるため残されている。しかし,今後の処理系又はプログラムではこれ
らの使用は推奨できない[“今後の言語の方針”(6.11)又は“今後のライブラリの方針”(7.26)参照]。
この規格は,大きく次の四つに分かれる。
― 諸前提事項(1.〜4.)
― Cプログラムの翻訳環境及び実行環境(5.)
― 言語の構文規則,制限及び意味規則(6.)
― ライブラリの機能(7.)
例は,記述された構文の有効な形式を例証するためにある。脚注は,その箇条又は他で述べられている
規則から導かれることを強調するためにある。参照は,他の関連する箇条を参照するためにある。推奨す
る実装は,処理系作成者に対して勧告又は指針を与えるためにある。附属書は,付加情報を提供し,この
規格に含まれる情報を要約する。参考文献は,この規格を作成する過程で参照した文献を示す。
言語の箇条(6.)は,“The C Reference Manual”に基づいている。
ライブラリの箇条(7.)は,1984 /usr/group Standardに基づいている。
1. 適用範囲 この規格は,Cプログラム言語で書いたプログラムの形式を規定し,そのプログラムの解
釈を規定する(1)。この規格は,次の事項を規定する。
− Cプログラムの表現方法
− C言語の構文規則と制約
───────────────────────────────────────────────
(1) この規格は,多様なデータ処理システム間でのCプログラムの可搬性を促進するために制定された。
この規格は,処理系の作成者及びプログラマによる使用を想定している。
2
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− Cプログラムを解釈するための意味規則
− Cプログラムが処理する入力データの表現方法
− Cプログラムが生成する出力データの表現方法
− C言語の規格合致処理系がCプログラムに課す制約及び限界
この規格は,次の事項を規定しない。
− データ処理システムで使用するために,Cプログラムを変換する機構
− データ処理システムで使用するために,Cプログラムを呼び出す機構
− Cプログラムで使用するために,入力データを変換する機構
− Cプログラムが出力データを生成した後に,そのデータを変換する機構
− 特定のデータ処理システム又は特定の処理系において,許容範囲を超えるプログラムの大きさ又は複
雑さ及びそのデータの大きさ又は複雑さ
− 規格合致処理系を支援するためにデータ処理システムが備えるべき最小限の要求条件
備考 この規格の対応国際規格を,次に示す。
なお,対応の程度を表す記号は,ISO/IEC Guide 21に基づき,IDT(一致している),MOD
(修正している),NEQ(同等でない)とする。
ISO/IEC 9899:1999,Programming languages―C (IDT)
2. 引用規格 次に掲げる規格は,この規格に引用されることによって,この規格の規定の一部を構成す
る。これらの引用規格のうちで,発効年又は発行年を付記してあるものは,記載の年の版だけがこの規格
の規定を構成するものであって,その後の改正版・追補は適用しない。発効年又は発行年を付記していな
い引用規格は,その最新版(追補を含む。)を適用する。
JIS X 0001:1994 情報処理用語―基本用語
備考 ISO/IEC 2382-1:1993,Information technology―Vocabulary―Part 1: Fundamental termsが,この
規格と一致している。
JIS X 0201 7ビット及び8ビットの情報交換用符号化文字集合
備考 ISO/IEC 646,Information technology―ISO 7-bit coded character set for information interchangeか
らの引用事項は,この規格の該当事項と同等である。
JIS X 0301 日付及び時刻の表記
備考 ISO 8601,Data elements and interchange formats―Information interchange―Representation of
dates and timesが,この規格と一致している。
ISO 31-11:1992,Quantities and units―Part 11:Mathematical signs and symbols for use in the physical sciences
and technology
ISO 4217,Codes for the representation of currencies and funds
ISO/IEC 10646 (all parts),Information technology―Universal Multiple-Octet Coded Character Set (UCS)
参考 ISO/IEC 10646-1:1993は,JIS X 0221:1995 国際符号化文字集合(UCS)―第1部:体系及
び基本多言語面と一致している。
IEC 60559:1989,Binary floating-point arithmetic for microprocessor systems(この規格の番号は,以前IEC
559:1989であった。)
3
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
3. 用語及び記号の定義 この規格で用いる主な用語の定義は,次による。その他の用語は,その用語を
太字で示した場所,又は構文規則の左側に出現した場所で定義したとみなす。この規格で明示的に定義す
る用語は,この規格以外で定義される類似の用語を暗黙に参照すると考えてはならない。この規格で定義
しない用語は,JIS X 0001に従って解釈する。この規格で定義しない数学記号は,ISO 31-11に従って解釈
する。
3.1
アクセス(access) <実行時の動作>オブジェクトの値を読み取る,又は変更すること。
参考1. これらの二つの動作のうちのいずれか一方だけを意味する場合は,“読み取る”又は“変更す
る”という用語を使う。
2. “変更する”は,格納する新しい値が,格納前の値と同じである場合も含む。
3. 評価されない式は,オブジェクトをアクセスしない。
3.2
境界調整(alignment) 特定の型のオブジェクトを特定のバイトアドレスの倍数のアドレスをもつ
記憶域境界に割り付ける要求。
3.3
実引数[argument,actual argument,actual parameter(廃止予定)] 関数呼出し式において,括
弧で囲まれコンマで区切られた並びの中の式,又は関数形式マクロの呼出しにおいて,括弧で囲まれコン
マで区切られた並びの中の前処理字句の列。
3.4
動作(behavior) 外から見る様子又は動作。
3.4.1
処理系定義の動作(implementation-defined behavior) 未規定の動作のうち,各処理系が選択し
た動作を文書化するもの。
例 処理系定義の動作の例としては,符号付き整数を右シフトした場合の最上位ビットの伝ぱ(播)
法がある。
3.4.2
文化圏固有動作(locale-specific behavior) 国家,文化及び言語の地域規約に依存する動作であり,
各処理系がその動作を文書化するもの。
例 文化圏固有動作の例としては,islower関数が26種類のラテン小文字以外の文字に対し,真を
返すかどうかがある。
3.4.3
未定義の動作(undefined behavior) 可搬性がない若しくは正しくないプログラム構成要素を使
用したときの動作,又は正しくないデータを使用したときの動作であり,この規格が何ら要求を課さない
もの。
参考 未定義の動作に対して,その状況を無視して予測不可能な結果を返してもよい。翻訳時又はプ
ログラム実行時に,文書化された,環境に特有な方法で処理してもよい(診断メッセージの発
行を伴っても伴わなくてもよい。)。さらに(診断メッセージを出力し)翻訳又は実行を中断し
てもよい。
例 未定義の動作の例としては,整数演算のオーバフローに対する動作がある。
3.4.4
未規定の動作(unspecified behavior) この規格が,二つ以上の可能性を提供し,個々の場合にど
の可能性を選択するかに関して何ら要求を課さない動作。
例 未規定の動作の例としては,関数の実引数の評価順序がある。
3.5
ビット(bit) 2種類の値のうちの一方を値としてもつオブジェクトを保持するために十分な大き
さをもつ実行環境でのデータ記憶域の単位。
参考1. オブジェクトの個々のビットのアドレスを表現できる必要はない。
2. ビットがもちうる2種類の値のうちの一方を値0という。ビットの値を値0以外にすること
を,この規格では,“ビットをセットする”という。
4
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
3.6
バイト(byte) 実行環境の基本文字集合の任意の要素を保持するために十分な大きさをもつアド
レス付け可能なデータ記憶域の単位。
参考1. オブジェクトの個々のバイトのアドレスは,一意に表現できる。
2. バイトは連続するビットの列から成る。1バイト中のビットの個数は,処理系定義である。
最も重みの小さいビットを最下位ビット(low-order bit)と呼び,最も重みの大きいビットを
最上位ビット(high-order bit)と呼ぶ。
3.7
文字(character) <抽象的意味>データを構成する,制御する,又は表現するために使用する基
本要素から成る集合の要素。
3.7.1
文字(character),1バイト文字(single-byte character) <プログラム言語Cでの意味>1バイ
トに納まるビット表現。
3.7.2
多バイト文字(multibyte character) ソース環境又は実行環境の拡張文字集合の要素を表す1バ
イト以上のバイトの列。
参考 拡張文字集合は,基本文字集合を包含する。
3.7.3
ワイド文字(wide character) 型wchar̲tのオブジェクトに納まり,その時点のロケールでの任
意の文字を表現できるビット表現。
3.8
制約(constraint) 言語要素に関する規定を解釈するに当たっての構文上又は意味上の制限。
3.9
正しい丸めの結果(correctly rounded result) 有効な丸めモードの下で得られる結果の形式の表現
で,無制限の範囲及び精度を仮定して得られる結果に最も近いもの。
3.10 診断メッセージ(diagnostic message) 処理系が出力するメッセージのうち,処理系定義の部分集
合に属するメッセージ。
3.11 前方参照(forward reference) その箇条に関連する付加情報を含むこの規格の前方の箇条への参照。
3.12 処理系(implementation) 特定の翻訳環境中において特定の制御オプションの下で走行し,特定の
実行環境用にプログラムを翻訳し,その実行環境における関数の実行をサポートする特定のソフトウェア
集合。
3.13 処理系限界(implementation limit) 処理系がプログラムに課す制限。
3.14 オブジェクト(object) その内容によって,値を表現することができる実行環境中の記憶域の部分。
参考 オブジェクトを参照する場合,オブジェクトは,特定の型をもっていると解釈してもよい
(6.3.2.1参照)。
3.15 仮引数[parameter,formal parameter,formal argument(廃止予定)] 関数宣言若しくは関数定
義の一部として宣言され,関数に入る時点で値を得るオブジェクト,又は関数形式マクロ定義におけるマ
クロ名の直後の括弧で囲まれコンマで区切られた並びに現れる識別子。
3.16 推奨実装仕様(recommended practice) この規格の趣旨に沿うために強く推奨する規定。しかし,
処理系によっては非現実的な場合もある。
3.17 値(value) オブジェクトが特定の型をもっていると解釈する場合のオブジェクトの内容の厳密な
意味。
3.17.1 処理系定義の値(implementation-defined value) 未規定の値のうち,各処理系が選択した値を文
書化するもの。
3.17.2 不定の値(indeterminate value) 未規定の値又はトラップ表現。
3.17.3 未規定の値(unspecified value) 適切な型の正しい値であり,この規格が,個々の場合にどの値
を選択するかに対して何ら要求を課さないもの。
5
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
参考 未規定の値は,トラップ表現となることはない。
3.18
x
xの切上げ,すなわち,x以上の最小の整数。
例 2.4 は,3。 −2.4 は,−2。
3.19
x
xの切下げ,すなわち,x以下の最大の整数。
例 2.4 は,2。 −2.4 は,−3。
4. 規格合致性 この規格では,“…(し)なければならない”という表現は,処理系又はプログラムに対
する要求を表す。さらに,“…(し)てはならない”という表現は,禁止を表す。
この規格の制約以外の箇所で現れる“…(し)なければならない”又は“…(し)てはならない”とい
う要求をプログラムが守っていない場合,その動作は未定義とする。この規格では,このほかに,用語“未
定義の動作”を使うことによるか又は動作の明示的な定義を与えないことによって未定義の動作を示すこ
ともある。これらの三つの書き方は強調度において何ら変わりはなく,それらはすべて“未定義の動作”
を規定する。
プログラムが未規定の動作を含んでいても,それ以外のあらゆる側面において正しく,かつ正しいデー
タを操作する場合,それは,正しいプログラムとみなし,5.1.2.3に従って動作しなければならない。
#error前処理指令が条件付き取込みによって読み飛ばされるグループの中にない限り,処理系は,
#error前処理指令を含む前処理翻訳単位の翻訳を成功させてはならない。
規格厳密合致プログラム(strictly conforming program)は,この規格で規定する言語機能及びライブラリ
だけを使用しなければならない(2)。さらに,いかなる未規定の動作,未定義の動作又は処理系定義の動作
に依存する出力も生成してはならず,しかもどのような最低限の処理系限界も超えてはならない。
規格合致処理系(conforming implementation)は,ホスト及びフリースタンディングの2種類とする。規
格合致ホスト処理系(conforming hosted implementation)は,任意の規格厳密合致プログラムを受理しなけ
ればならない。規格合致フリースタンディング処理系(conforming freestanding implementation)は,次の二
つの条件を満たす任意の規格厳密合致プログラムを受理しなければならない。
− 複素数型を使っていない。
− ライブラリの箇条(7.)で規定する機能の使用を,標準ヘッダ<float.h>,<iso646.h>,<limits.h>,
<stdarg.h>,<stdbool.h>,<stddef.h>及び<stdint.h>の内容に限定している。
規格合致処理系は,任意の規格厳密合致プログラムの動作を変更しない限り,(ライブラリ関数の追加を含
───────────────────────────────────────────────
(2) 規格厳密合致プログラムは,どの処理系でもサポートしているわけではない機能(附属書Fの中に例
がある。)を使うことができる。ただし,その機能を使うことができるのは,それが適切なマクロを
もつ#ifdef指令とそれに対応する#endif指令とに囲まれている場合に限る。次に示すプログラム
片がその例である。
#ifdef ̲ ̲STDC̲IEC̲559̲ ̲ /* FE̲UPWARD が定義されている */
/* ... */
fesetround(FE̲UPWARD);
/* ... */
#endif
6
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
む)拡張をしてもよい(3)。
規格合致プログラム(conforming program)は,ある規格合致処理系が受理することができるプログラム
とする(4)。
処理系は,すべての処理系定義の特性,すべての文化圏固有の特性及びすべての拡張を定義した文書を
伴わなければならない。
前方参照 エラー指令(6.10.5),可変個数実引数<stdarg.h>(7.15),共通の定義<stddef.h>(7.17),
条件付き取込み(6.10.1),整数型<stdint.h>(7.18),整数型の大きさ<limits.h>(7.10),代替つづり
<iso646.h>(7.9),浮動小数点型の特性<float.h>(7.7),論理型及び値<stdbool.h>(7.16)
5. 環境 処理系は,二つのデータ処理システム環境の中でCソースファイルを翻訳し,Cプログラムを
実行する。この規格では,これらの環境をそれぞれ翻訳環境(translation environment)及び実行環境(execution
environment)と呼ぶ。これらの環境がもつ特性は,構文規則及び意味規則に従って構成された規格合致C
プログラムのその規格合致処理系における実行結果を定義し,制約する。
前方参照 この箇条(5.)では,実際の前方参照の一部だけを示す。
5.1
概念モデル
5.1.1
翻訳環境
5.1.1.1
プログラム構成 一つのCプログラムの全体を同時に翻訳する必要はない。プログラムのテキス
トは,この規格でソースファイル(source file)[又は前処理ファイル(preprocessing file)]と呼ぶ単位で保
持する。一つのソースファイルに,#include前処理指令を通して取り込むすべてのヘッダ及びソースフ
ァイルを加えたものを前処理翻訳単位(preprocessing translation unit)と呼ぶ。前処理完了後の前処理翻訳
単位を翻訳単位(translation unit)と呼ぶ。過去に翻訳した翻訳単位を,個々に又はライブラリ中にまとめ
て保存してもよい。一つのプログラムを構成する各翻訳単位は,(例えば)識別子が外部結合をもつ関数の
呼出し,識別子が外部結合をもつオブジェクトの操作,又はデータファイルの操作によって,互いに連絡
する。複数の翻訳単位を別々に翻訳し,後で結合して一つの実行可能プログラムを作成してもよい。
前方参照 外部定義(6.9),識別子の結合(6.2.2),前処理指令(6.10)
5.1.1.2
翻訳フェーズ 次に示すフェーズによって,翻訳上の構文規則間の優先順位を規定する(5)。
(1) 必要ならば,物理的なソースファイルの多バイト文字を,対応するソース文字集合に,処理系定義
の方法で,写像する(この際,行の終わりを示すものに対して改行文字を導入する。)。3文字表記
を,対応する単一の文字の内部表現に置き換える。
(2) 逆斜線文字(\)の直後に改行文字が現れた場合,それらの2文字を削除する。これによって物理ソ
ース行を接合して論理ソース行を作成する。一つの物理ソース行においてこの接合の対象となるの
は,その行の最後の逆斜線文字だけとする。空でないソースファイルは,改行文字で終了しなけれ
───────────────────────────────────────────────
(3) これは,規格合致処理系がこの規格で明示的に予約する識別子以外の識別子を予約してはならないこ
とを意味する。
(4) 規格厳密合致プログラムは,規格合致処理系間で,最大限の可搬性を意図したプログラムである。規
格合致プログラムは,規格合致処理系における可搬性のない機能に依存してもよい。
(5) 処理系は,実際には,ここに示す幾つかのフェーズを一つにまとめてもよいが,ここに示す別々のフ
ェーズが存在するとみなした場合と同じ規則に従って動作しなければならない。
7
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ばならない。さらに,この改行文字の直前に(接合を行う前の時点で)逆斜線文字があってはなら
ない。
(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) 処理系は,各違反の性質及び可能な限り,違反箇所を明らかにしたほうがよいことを意図している。
もちろん,正しいプログラムを正しく翻訳している限り,処理系が任意の個数の診断メッセージを出
力することは自由である。処理系は正しくないプログラムを最後まで翻訳し続けてもよい。
8
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
義の動作になると規定している場合は,制約違反に対する診断メッセージを出力しなければなら
ないからである。
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.1〜5.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と書くこともできる。
9
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(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>は,この副作用が問題となる場合は,それを処理系に示し,副作用が問題とならない場
合は,処理系を自由にしておくためのプログラム上の手段を提供する。
10
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 対話型装置に対する入出力動作は,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. ビット数が多いレジスタを採用している処理系は,意味規則を正しく守ることに留意しなけれ
ばならない。値は,それがレジスタに格納されて表現されるのか,又はメモリに格納されて表
現されるのか,ということとは独立である。例えば,データが暗黙にレジスタからメモリに退
避されることによってその値が変わることは,許されない。さらに,記憶域の種類ごとに決ま
11
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
る精度にデータを丸めるためには,明示的にその記憶域へデータを格納し,再びそれを読み出
すことが必要である。特に,キャスト及び代入では,指定された変換を実際に実行する必要が
ある。次のプログラム片では,
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かもしれないか
らである。しかし,オーバフローが何らかの値を生成させ,正のオーバフロー及び負のオーバ
フローが打ち消し合う計算機では,同じ結果が得られるので,処理系は上で述べた方法のいず
れにも書き換えることができる。
12
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例7. 式のグループ分けは,その評価を完全に決定するものではない。次のプログラム片
#include <stdio.h>
int sum;
char *p;
/* ... */
sum = sum * 10 - '0' + (*p++ = getchar());
では,式文は次のように書いた場合と同じにグループ分けされる。
sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));
しかし,pの実際の増加は,直前の副作用完了点と次の副作用完了点(セミコロンの位置)の
間の任意の時点で起きてよい。さらに,getcharの呼出しは,その返却値が必要となる以前の
任意の時点に起きてよい。
前方参照 signal関数(7.14),型修飾子(6.7.3),式(6.5),ファイル(7.19.3),文(6.8)
5.2
環境考慮事項
5.2.1
文字集合 ソースファイルでプログラムの記述に用いる文字集合[ソース文字集合(source character
set)],及び実行環境で解釈する文字集合[実行文字集合(execution character set)]の二つの文字集合の定
義,並びにそれらの文字集合に関する文字の大小順序の定義がなければならない。ソース文字集合及び実
行文字集合のそれぞれは,更に,次の二つの集合に分けられる。
− 基本文字集合(basic character set)(その内容は,5.2.1で規定する。)
− (基本文字集合の要素ではない)0個以上の文化圏固有の要素[拡張文字(extended character)]の集
合
これら二つの集合の和を拡張文字集合(extended character set)という。実行文字集合の要素の値は,処理
系定義とする。
文字定数又は文字列リテラルの中では,実行文字集合の要素をソース文字集合の対応する要素,又は逆
斜線(\)に続く一つ以上の文字から成る逆斜線表記(escape sequence)によって表現しなければならない。
すべてのビットが0であるバイトをナル文字(null character)という。ナル文字は,実行基本文字集合中に
存在しなければならない。文字列の終わりを示すためにナル文字を用いる。
ソース基本文字集合及び実行基本文字集合は,少なくとも次に掲げる要素をもっていなければならない。
− 26個のラテンアルファベットの大文字(uppercase letter)
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
− 26個のラテンアルファベットの小文字(lowercase letter)
a b c d e f g h i j k l m
n o p q r s t u v w x y z
− 10個の10進数字(digit)
0 1 2 3 4 5 6 7 8 9
− 29個の図形文字
! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] ^ ̲ { | } ~
− 空白文字
− 水平タブ,垂直タブ,及び書式送りのそれぞれを表す制御文字
13
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ソース基本文字集合の各要素の表現,及び実行基本文字集合の各要素の表現は,1バイトの中に納まらな
ければならない。ソース基本文字集合及び実行基本文字集合の双方において,10進数字に関する上の並び
において,0の右側に並んでいる各文字の値は,一つ左側にある文字の値に比べ1だけ大きくなければな
らない。ソースファイルの中でテキストの各行の終わりを表す何らかの方法が存在しなければならない。
この規格では,行の終わりを示すものを一つの文字(改行文字)とみなして扱う。実行基本文字集合の中
には,警報,後退,復帰及び改行を表す制御文字がなければならない。(識別子,文字定数,文字列リテラ
ル,ヘッダ名,注釈,又は字句に変換されることのない前処理字句の中を除いて,)ソースファイル中にこ
れら以外の文字がある場合,動作は未定義とする。
参考 この規格で規定する基本文字集合の中の二つの要素\と~は,JIS X 0201では,それぞれ¥(円
記号)と̅(オーバライン)に置き換える。
英字(letter)は,上で定義した大文字又は小文字とする。この規格での英字には,他の文字(ラテン以
外のアルファベット)は含まない。
国際文字名は,他の文字を表す方法を提供する。
前方参照 国際文字名(6.4.3),注釈(6.4.9),前処理指令(6.10),文字定数(6.4.4.4),文字列(7.1.1),
文字列リテラル(6.4.5)
5.2.1.1
3文字表記 次に示す左側の三つの文字の並び[3文字表記(trigraph sequence(12))という。]が
ソースファイルの中にある場合,その三つの文字の並びを同じ行の右側の対応する1文字に置き換える。
??=
#
??(
[
??/
\
??)
]
??'
^
??<
{
??!
|
??>
}
??-
~
これら以外の3文字表記は,存在しない。上に掲げた3文字表記の始まりとならない?は,置き換えな
い。
例 次のソース行
printf("Eh???/n");
は,(3文字表記??/の置き換え後),
printf("Eh?\n");
となる。
5.2.1.2
多バイト文字 ソース文字集合は,拡張文字集合の要素を表現するための多バイト文字を含んで
いてもよい。実行文字集合も,多バイト文字を含んでいてもよく,その多バイト文字の表現形式は,ソー
ス文字集合における表現形式と一致していなくてもよい。二つの文字集合は,次の条件を満たさなければ
───────────────────────────────────────────────
(12)
3文字表記は,7ビットUS ASCII符号集合の部分集合であるISO/IEC 646で規定する不変符号集合
に定義がない文字の入力を可能にする。
14
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ならない。
− 基本文字集合が存在しなければならず,各文字は,1バイトとして符号化しなければならない。
− 追加要素が存在するか否か,並びにそれらの意味及び表現は,文化圏固有とする。
− 多バイト文字集合は,シフト状態に依存した表現形式(state-dependent encoding)をもっていてもよい。
この表現形式では,多バイト文字の並びは初期シフト状態(initial shift state)で始まり,その並びの中
に特定の多バイト文字が現れたとき文化圏固有のその他のシフト状態(shift state)に移る。初期シフ
ト状態では,すべての1バイト文字は,通常と同じ解釈をもち,シフト状態を変えない。それ以外の
シフト状態で,多バイト文字の並びの中のバイトの列の解釈をどのように行うかは,その位置でのシ
フト状態に依存する。
− すべてのビットが0のバイトは,シフト状態にかかわらずナル文字として解釈しなければならない。
− すべてのビットが0のバイトは,一つの多バイト文字の2番目以降のバイトに現れてはならない。
ソースファイルに対しては,次の条件が成立しなければならない。
− 識別子,注釈,文字列リテラル,文字定数及びヘッダ名は,初期シフト状態で始まり,初期シフト状
態で終わらなければならない。
− 識別子,注釈,文字列リテラル,文字定数及びヘッダ名は,有効な多バイト文字の並びで構成しなけ
ればならない。
5.2.2
文字表示の意味 fputc関数が出力する次の文字が現れる表示装置上の位置を,現表示位置(active
position)という。表示文字(isprint関数が真となる文字として定義する。)を表示装置に書くというこ
とは,現表示位置にその文字の図形表現を表示し,次に現表示位置をその行の次の位置に進めることを意
図する。書込みの方向は,文化圏固有とする。行の最終位置というものが存在して,現表示位置が行の最
終位置にある場合,表示装置の動作は未規定とする。
実行文字集合中の非図形文字を表す英字逆斜線表記は,次に列挙する表示装置上での動作を生じること
を意図する。
\a 警報(alert)聴覚的又は視覚的な警報を生じる。現表示位置の変更を伴わない。
\b 後退(backspace)現表示位置をその行の上で直前の位置に移動する。現表示位置が行の最初の位置に
ある場合,表示装置の動作は未規定とする。
\f 書式送り(form feed)現表示位置を次の論理ページの始まりにおける最初の位置に移動する。
\n 改行(new line)現表示位置を次の行の最初の位置に移動する。
\r 復帰(carriage return)現表示位置をその行の最初の位置に移動する。
\t 水平タブ(horizontal tab)現表示位置をその行における次の水平タブ位置に移動する。現表示位置が定
められた最後の水平タブ位置にある,又はその位置を過ぎている場合,表示装置の動作は未規定とす
る。
\v 垂直タブ(vertical tab)現表示位置を次の垂直タブ位置における最初の位置に移動する。現表示位置が
定められた最後の垂直タブ位置にある,又はその位置を過ぎている場合,表示装置の動作は未規定と
する。
上に掲げた7個の英字逆斜線表記は,それぞれchar型の単一のオブジェクトに格納することができる
処理系定義の一意の値をもたなければならない。テキストファイルにおける外部表現は,内部表現と一致
する必要はなく,この規格の範囲外とする。
前方参照 fputc関数(7.19.7.3),isprint関数(7.4.1.8)
5.2.3
シグナル及び割込み 関数は,いつシグナルによって中断されてもよいように,シグナル処理ルー
15
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
チンによって呼び出されてもよいように,又はその双方が行われてもよいように実現しなければならない。
これらの場合,関数は,それ以前に起動されていて,まだ終了していない呼出しの(中断から復帰後の)
制御の流れ,関数の返却値又は自動記憶域期間をもつオブジェクトを変えることなしに,実現しなければ
ならない。これらすべてのオブジェクトは関数イメージ(function image)(関数の実行可能な表現を構成
する命令列)とは別に,関数の各呼出しに対応して保持しなければならない。
5.2.4
環境限界 翻訳環境及び実行環境の双方とも,言語翻訳プログラム及びライブラリを制約する。規
格合致処理系における環境限界を5.2.4.1及び5.2.4.2にまとめる。ライブラリにおける限界は,7.で規定す
る。
5.2.4.1
翻訳限界 処理系は,この箇条に示す(各項目の最後の括弧で囲まれた数値で示す)各限界の出
現をそれぞれ少なくとも一つ含むプログラムのうちの少なくとも一つを翻訳及び実行することができなけ
ればならない(13)。
− ブロックの入れ子のレベル数(127)
− 条件付き取込みにおける入れ子のレベル数(63)
− 一つの宣言中の一つの算術型,構造体型,共用体型又は不完全型を修飾するポインタ,配列及び関数
宣言子(の任意の組合せ)の個数(12)
− 一つの完結宣言子における括弧で囲まれた宣言子の入れ子のレベル数(63)
− 一つの完結式における括弧で囲まれた式の入れ子のレベル数(63)
− 内部識別子又はマクロ名において意味がある先頭の文字数[各国際文字名又は各ソース拡張文字は,1
個の文字とみなす。](63)
− 外部識別子において意味がある先頭の文字数[0000FFFF以下の短い識別子を表す各国際文字名は,6
個の文字とみなす。00010000以上の短い識別子を表す各国際文字名は,10個の文字とみなす。各ソー
ス拡張文字は,(もしあれば)対応する国際文字名と同じ個数の文字とみなす(14)。](31)
− 一つの翻訳単位中における外部識別子数(4095)
− 一つのブロックで宣言されるブロック有効範囲をもつ識別子数(511)
− 一つの前処理翻訳単位中で同時に定義されるマクロ識別子数(4095)
− 一つの関数定義における仮引数の個数(127)
− 一つの関数呼出しにおける実引数の個数(127)
− 一つのマクロ定義における仮引数の個数(127)
− 一つのマクロ呼出しにおける実引数の個数(127)
− 一つの論理ソース行における文字数(4095)
− (連結後の)単純文字列リテラル又はワイド文字列リテラル中における文字数(4095)
− (ホスト環境の場合)一つのオブジェクトのバイト数(65535)
− #includeで取り込まれるファイルの入れ子のレベル数(15)
− 一つのswitch文(入れ子になったswitch文を除く)中におけるcaseラベルの個数(1023)
− 一つの構造体又は共用体のメンバ数(1023)
− 一つの列挙体における列挙定数の個数(1023)
───────────────────────────────────────────────
(13)
処理系は,固定的な翻訳限界を課することを,可能な限り避けるのが望ましい。
(14)
“今後の言語の方針”(6.11.3)参照。
16
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 一つのメンバ宣言並びにおける構造体又は共用体定義の入れ子のレベル数(63)
5.2.4.2
数量的限界 処理系は,5.2.4.2で規定するすべての限界(ヘッダ<limits.h>及び<float.h>
の中で定義される。)を文書化しなければならない。これ以外に<stdint.h>でも限界を定めている。
前方参照 整数型<stdint.h>(7.18)
5.2.4.2.1
整数型の大きさ<limits.h> 次に列挙する値は,#if前処理指令の中で使用するために適し
た定数式に置き換えなければならない。さらに,CHAR̲BIT及びMB̲LEN̲MAXに対する値を除き,これ
らの値は,対応する型のオブジェクトだけからなる式が整数拡張に従って変換された場合の型と同じ型を
もつ式に置き換えなければならない。これらの処理系定義の値は,それぞれの項目の右に示してある値と
同じ符号をもち,その値以上の大きさ(絶対値)をもたなければならない。
− ビットフィールドでない最小のオブジェクト(バイト)におけるビット数
CHAR̲BIT
8
− 型signed charのオブジェクトにおける最小値
SCHAR̲MIN
-127
// − (27−1)
− 型signed charのオブジェクトにおける最大値
SCHAR̲MAX
+127
// 27−1
− 型unsigned charのオブジェクトにおける最大値
UCHAR̲MAX
255
// 28−1
− 型charのオブジェクトにおける最小値
CHAR̲MIN
(値は,後で規定する。)
− 型charのオブジェクトにおける最大値
CHAR̲MAX
(値は,後で規定する。)
− サポートするロケールに対する一つの多バイト文字の最大バイト数
MB̲LEN̲MAX
1
− 型short intのオブジェクトにおける最小値
SHRT̲MIN
-32767
// − (215−1)
− 型short intのオブジェクトにおける最大値
SHRT̲MAX
+32767
// 215−1
− 型unsigned short intのオブジェクトにおける最大値
USHRT̲MAX
65535
// 216−1
− 型intのオブジェクトにおける最小値
INT̲MIN
-32767
// − (215−1)
− 型intのオブジェクトにおける最大値
INT̲MAX
+32767
// 215−
− 型unsigned intのオブジェクトにおける最大値
UINT̲MAX
65535
// 216−1
− 型long intのオブジェクトにおける最小値
LONG̲MIN
-2147483647 // − (231−)
− 型long intのオブジェクトにおける最大値
LONG̲MAX
+2147483647 // 231−1
− 型unsigned long intのオブジェクトにおける最大値
17
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ULONG̲MAX
4294967295
// 232−1
− 型long long intのオブジェクトにおける最小値
LLONG̲MIN
-9223372036854775807 // − (263−1)
− 型long long intのオブジェクトにおける最大値
LLONG̲MAX
+9223372036854775807 // 263−1
− 型unsigned long long intのオブジェクトにおける最大値
ULLONG̲MAX
18446744073709551615 // 264−1
型charのオブジェクトの値を式の中で符号付き整数として扱う場合,CHAR̲MINの値は,SCHAR̲MIN
の値と同じでなければならず,CHAR̲MAXの値は,SCHAR̲MAXの値と同じでなければならない。符号無
し整数として扱う場合,CHAR̲MINの値は,0でなければならず,CHAR̲MAXの値は,UCHAR̲MAXの値と
同じでなければならない(15)。値UCHAR̲MAXは,2CHAR̲BIT−1と等しくなければならない。
前方参照 型の表現(6.2.6),条件付き取込み(6.10.1)
5.2.4.2.2
浮動小数点型の特性<float.h> 浮動小数点数の表現に関するモデル及び処理系の浮動小数
点演算についての情報を与える値によって,浮動小数点型の特性を定義する(16)。各浮動小数点型に対する
モデルを定義するために,次のパラメタを使用する。
S 符号(±1)
b 指数表現の基数又は底(1より大きい整数)
e 指数(最小eminから最大emaxまでの整数)
p 精度(bを基数としたときの有効数字部)
fk bより小さい非負の整数(有効数字部の数字)
浮動小数点数(floating-point number)(x)を次のモデルによって定義する。
∑
−
p
k
k
k
e
b
f
sb
x
1
=
=
, emin≦e≦emax
浮動小数点型は,正規化された(normalized)浮動小数点数(x≠0の場合,f1>0)を保持することができ,
更に,他の種類の浮動小数点数[例えば,正規化できないほど小さな(subnormal)浮動小数点数(x≠0,
e=emin,f1=0),及び正規化されていない(unnormalized)浮動小数点数(x≠0,e>emin,f1=0)]及び浮動小
数点数ではない値(例えば,無限大及びNaN)が保持できてもよい。NaNは,非数(Not-a-Number)を意
味する表現形式とする。qNaN(quiet NaN)は,浮動小数点例外を生成することなく,ほとんどすべての
算術演算を通して伝ぱ(播)する。sNaN(signaling NaN)は,算術オペランドとして現れる場合,一般的
に浮動小数点例外を生成する(17)。
浮動小数点演算(+,-,*,/)の正確度,並びに<math.h>及び<complex.h>の中で定義する(浮動
小数点型の結果を返却する)ライブラリ関数の正確度は,処理系定義とする。処理系は,正確度は不明,
と規定してもよい。
───────────────────────────────────────────────
(15)
6.2.5参照。
(16)
この浮動小数点型のモデルは,浮動小数点数の各特性の規定を明確にすることを意図したものであ
り,処理系の浮動小数点演算の実現法がこのとおりであることを要求するものではない。
(17)
IEC 60559:1989が,qNaN及びsNaNを規定している。IEC 60559:1989をサポートしない処理系では,
qNaN及びsNaNは,これらと同じ動作となる表現形式を適用することを意図している。
18
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
<float.h>ヘッダの中で定義するすべての整数値は,FLT̲ROUNDSを除き,#if前処理指令の中で使
用するために適した定数式でなければならない。<float.h>ヘッダの中で定義するすべての浮動小数点数
の値は,定数式でなければならない。DECIMAL̲DIG,FLT̲EVAL̲METHOD,FLT̲RADIX及びFLT̲ROUNDS
を除くすべては,三つの浮動小数点型それぞれに対し別個の名前をもつ。FLT̲EVAL̲METHOD及び
FLT̲ROUNDSを除くすべての値に対し,浮動小数点型のモデルにおける表現が与えられる。
浮動小数点加算の丸めモードは,FLT̲ROUNDSの処理系定義の値によって次のとおり特徴付けられる(18)。
-1
不確定
0
0の方向へ
1
最も近い値へ
2
正の無限大の方向へ
3
負の無限大の方向へ
FLT̲ROUNDSに対するその他の値は,処理系定義の丸め動作を特徴付ける。
浮動小数点型のオペランドをもつ演算の結果の値,通常の算術型変換の結果の値,及び浮動小数点定数
の値は,その型に対する要求よりも大きな範囲と精度をもつ形式で評価してもよい。どのような評価形式
を使うかは,FLT̲EVAL̲METHODの処理系定義の値によって次のとおり特徴付けられる(19)。
-1
不確定
0
すべての演算及び定数を,その型の範囲及び精度のとおりに評価する
1
型float及び型doubleの演算及び定数を,型doubleの範囲及び精度で評
価し,型long doubleの演算及び定数を,型long doubleの範囲及び精
度で評価する
2
すべての演算及び定数を,型long doubleの範囲及び精度で評価する
FLT̲EVAL̲METHODに対するその他の負の値は,処理系定義の動作を特徴付ける。
次に列挙する値は,それぞれの項目の行の右に示してある値と同じ符号,及びその値以上の絶対値をも
つ処理系定義の値を表す定数式で置き換えなければならない。
− 指数表現における基数b
FLT̲RADIX
2
− 浮動小数点数の有効数字部(FLT̲RADIXを基数とする。)のけた数p
FLT̲MANT̲DIG
DBL̲MANT̲DIG
LDBL̲MANT̲DIG
− 次の条件を満たす10進数のけた数n。bを基数とするpmaxけたの数字をもつ(処理系がサポートする
最大の精度をもつ浮動小数点型の)浮動小数点数は,nけたの10進数の浮動小数点数に丸めることが
でき,それを正確に元の値に戻すことができる。nは,次の式で与えられる。
───────────────────────────────────────────────
(18)
FLT̲ROUNDSの値は,<fenv.h>の中の関数fesetroundによる丸めモードの実行時の変更に伴
って変わる。
(19)
評価方法は,実数型だけではなくすべての浮動小数点型の式の評価形式を決定する。例えば,
FLT̲EVAL̲METHODが1の場合,二つのfloat ̲Complexオペランドの積は,double
̲Complex形式で表現し,その実部と虚部は,それぞれdoubleで評価する。
19
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
pmax log10 b
bが10のべき乗の場合
1+pmax log10 b
それ以外の場合
DECIMAL̲DIG
10
− 次の条件を満たす10進数のけた数q。qけたの10進数の浮動小数点数は,bを基数とするpけたの浮
動小数点数に丸めることができ,それを正確に元のqけたの10進数に戻すことができる。qは,次の
式で与えられる。
p log10 b
bが10のべき乗の場合
(p−1) log10 b
それ以外の場合
FLT̲DIG
6
DBL̲DIG
10
LDBL̲DIG
10
− FLT̲RADIXをその値から1減算した値でべき乗したとき,正規化された浮動小数点数となる最小の
負の整数emin
FLT̲MIN̲EXP
DBL̲MIN̲EXP
LDBL̲MIN̲EXP
− 10をその値でべき乗したとき,正規化された浮動小数点数の範囲内の値となる最小の負の整数。次の
式で与えられる。
1
10
min
log
−
e
b
FLT̲MIN̲10̲EXP
-37
DBL̲MIN̲10̲EXP
-37
LDBL̲MIN̲10̲EXP
-37
− FLT̲RADIXをその値から1減算した値でべき乗したとき,表現可能な有限の浮動小数点数となる最
大の整数emax
FLT̲MAX̲EXP
DBL̲MAX̲EXP
LDBL̲MAX̲EXP
− 10をその値でべき乗したとき,表現可能な有限の浮動小数点数の範囲内の値となる最大の整数。次の
式で与えられる。
)
)
1
((
log
max
10
e
pb
b−
−
FLT̲MAX̲10̲EXP
+37
DBL̲MAX̲10̲EXP
+37
LDBL̲MAX̲10̲EXP
+37
次に列挙する値は,それぞれの項目の行の右に示してある値以上の処理系定義の値をもつ定数式で置き
換えなければならない。
− 表現可能な最大の有限浮動小数点数
max
)
1(
e
pb
b−
−
FLT̲MAX
1E+37
DBL̲MAX
1E+37
LDBL̲MAX
1E+37
次に列挙する値は,それぞれの項目の行の右に示してある値以下の処理系定義の(正の)値をもつ定数
20
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
式で置き換えなければならない。
− 与えられた浮動小数点型で表現可能な1より大きい最小の値と1との差b1−p
FLT̲EPSILON
1E-5
DBL̲EPSILON
1E-9
LDBL̲EPSILON
1E-9
− 最小の正規化された正の浮動小数点数
1
min−
e
b
FLT̲MIN
1E-37
DBL̲MIN
1E-37
LDBL̲MIN
1E-37
推奨実装仕様 doubleからDECIMAL̲DIGけたの10進数字へ変換し,続いて逆変換した結果は,元の値
と等しくなることが望ましい。
例1. この規格の最低限の要求に適合する人工的な浮動小数点表現,及び型floatに対するヘッダ
<float.h>内の適切な値を次に示す。
∑
−
6
1
16
16
=
=
k
k
k
e
f
s
x
, −31≦e≦+32
FLT̲RADIX
16
FLT̲MANT̲DIG
6
FLT̲EPSILON
9.53674316E-07F
FLT̲DIG
6
FLT̲MIN̲EXP
-31
FLT̲MIN
2.93873588E-39F
FLT̲MIN̲10̲EXP
-38
FLT̲MAX̲EXP
+32
FLT̲MAX
3.40282347E+38F
FLT̲MAX̲10̲EXP
+38
例2. IEC 60559(20)での単精度正規化数及び倍精度正規化数に対する要求にも適合する浮動小数点表
現,及び型floatと型doubleに対する<float.h>ヘッダ内の適切な値を次に示す。
∑
−
24
1
2
2
=
=
k
k
k
e
f
f
s
x
, −125≦e≦+128
∑
−
53
1
2
2
=
=
k
k
k
e
d
f
s
x
, −1021≦e≦+1024
FLT̲RADIX
2
DECIMAL̲DIG
17
FLT̲MANT̲DIG
24
FLT̲EPSILON
1.19209290E-07F
// 10進定数
FLT̲EPSILON
0X1P-23F
// 16進定数
───────────────────────────────────────────────
(20)
IEC 60559での浮動小数点型のモデルでは,bの0乗からのべき乗の和であるので,指数の限界値は,
ここに示すものより1小さい。
21
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
FLT̲DIG
6
FLT̲MIN̲EXP
-125
FLT̲MIN
1.17549435E-38F
// 10進定数
FLT̲MIN
0X1P-126F
// 16進定数
FLT̲MIN̲10̲EXP
-37
FLT̲MAX̲EXP
+128
FLT̲MAX
3.40282347E+38F
// 10進定数
FLT̲MAX
0X1.fffffeP127F
// 16進定数
FLT̲MAX̲10̲EXP
+38
DBL̲MANT̲DIG
53
DBL̲EPSILON
2.2204460492503131E-16 // 10進定数
DBL̲EPSILON
0X1P-52
// 16進定数
DBL̲DIG
15
DBL̲MIN̲EXP
-1021
DBL̲MIN
2.2250738585072014E-308 // 10進定数
DBL̲MIN
0X1P-1022
// 16進定数
DBL̲MIN̲10̲EXP
-307
DBL̲MAX̲EXP
+1024
DBL̲MAX
1.7976931348623157E+308 // 10進定数
DBL̲MAX
0X1.fffffffffffffP1023 // 16進定数
DBL̲MAX̲10̲EXP
+308
doubleより大きな型をサポートする場合,DECIMAL̲DIGは,17より大きい。例えば,最も
大きな型が,最小幅のIEC 60559(精度が64ビットの)拡張倍精度(double-extended)形式を
使う場合,DECIMAL̲DIGは,21になる。
前方参照 条件付き取込み(6.10.1),数学<math.h>(7.12),複素数計算<complex.h>(7.3),浮動小数
点環境<fenv.h>(7.6)
6. 言語
6.1
記法 6.で用いる構文の記法では,構文要素(非終端記号)は英数字を含む日本語で示し,プログラ
ムにそのまま用いられるリテラル語及び文字集合の要素(終端記号)は英数字及び特殊記号で示す。非終
端記号に続くコロン(:)は,その後に非終端記号の定義があることを示す。幾つかの定義が別々の行に
表示されている場合,又は“次のいずれか”と前置きしている場合,それらのうちの一つを選択すること
を意味する。省略可能な記号は,添字“opt”で示す。したがって,
{ 式opt }
は,波括弧の中に省略可能な式があることを示す。
言語の構文の要約を附属書Aに記す。
6.2
概念
6.2.1
識別子の有効範囲 識別子は,次のいずれか一つを表す。
− オブジェクト
− 関数
22
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 構造体,共用体,又は列挙体のタグ又はメンバ
− 型定義名
− ラベル名
− マクロ名
− マクロ仮引数
同一の識別子であっても,プログラム内の異なる位置では異なる実体を表すことがある。列挙体のメンバ
を列挙定数(enumeration constant)と呼ぶ。プログラム翻訳の意味解析フェーズより前に,ソースファイ
ル中のすべてのマクロ名の出現を,そのマクロ定義を構成する前処理字句列で置き換えるから,以下では
マクロ名とマクロ仮引数を考慮しない。
識別子が指し示すそれぞれの異なる実体について,識別子は,有効範囲(scope)と呼ぶプログラムテキ
ストの範囲にあるときだけ,可視(visible)(すなわち,使用可能)とする。同じ識別子が異なる実体を指
し示すのは,それらが異なる有効範囲をもつときか,又は異なる名前空間に属するときかのいずれかとす
る。有効範囲は,関数,ファイル,ブロック及び関数原型の4種類とする。[関数原型(function prototype)
は,その仮引数の型を宣言する関数の宣言とする。]
ラベル名は,関数有効範囲(function scope)をもつ唯一の種類の識別子とする。ラベル名は,それが現
れる関数のどこでも(goto文の中で)使用でき,(:と文が続く)その構文の出現によって,暗黙に宣言
される。
その他の各識別子は,それらの(宣言子又は型指定子における)宣言の位置によって定められる有効範
囲をもつ。識別子を宣言する宣言子又は型指定子がどのブロック又は仮引数並びよりも外側に現れる場合,
その識別子はファイル有効範囲(file scope)をもち,その範囲は翻訳単位の最後で終了する。識別子を宣
言する宣言子又は型指定子がブロックの中又は関数定義の仮引数宣言並びに現れる場合,その識別子はブ
ロック有効範囲(block scope)をもち,その範囲は対応するブロックの最後で終了する。識別子を宣言す
る宣言子又は型指定子が(関数定義の一部ではない)関数原型の中の仮引数宣言並びに現れる場合,その
識別子は関数原型有効範囲(function prototype scope)をもち,その範囲は関数宣言子の最後で終了する。
識別子が同一の名前空間で二つの異なる実体を指し示す場合,それらの有効範囲は重なることがある。こ
の場合,一方の実体の有効範囲[内側の有効範囲(inner scope)]は,もう一方の実体の有効範囲[外側の
有効範囲(outer scope)]の真部分集合となる。内側の有効範囲の中では,識別子は内側の有効範囲で宣言
された実体を指し示し,外側の有効範囲で宣言された実体は,内側の有効範囲の中では隠される(hidden)
(すなわち,不可視となる。)。
明示的に異なる規定を行わない限り,この規格が“識別子”という用語をある実体(構文の構成要素と
してではなく)を参照するために用いる場合,それは,その識別子が出現した位置においてその宣言が可
視である実体(関連する名前空間に属するもの)を参照しているものとする。
二つの識別子は,有効範囲が同じ位置で終わる場合,そしてその場合に限り,同じ有効範囲(same scope)
をもつという。
構造体,共用体及び列挙体のタグは,そのタグを宣言する型指定子中のタグの出現の直後から始まる有
効範囲をもつ。各々の列挙定数は,列挙子並びの中にその列挙定数を定義する列挙子が出現した直後から
始まる有効範囲をもつ。それ以外のすべての識別子は,その宣言子の完了の直後から始まる有効範囲をも
つ。
前方参照 関数定義(6.9.1),関数呼出し(6.5.2.2),識別子(6.4.2),識別子の名前空間(6.2.3),宣言(6.7),
ソースファイル取込み(6.10.2),文(6.8),マクロ置き換え(6.10.3)
23
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6.2.2
識別子の結合 異なる有効範囲で又は同じ有効範囲で2回以上宣言された識別子は,結合(linkage)
(21)と呼ぶ過程によって,同じオブジェクト又は関数を参照することができる。結合は,外部結合,内部結
合及び無結合の3種類とする。
プログラム全体を構成する翻訳単位及びライブラリの集合の中で,外部結合(external linkage)をもつ一
つの識別子の各々の宣言は,同じオブジェクト又は関数を表す。一つの翻訳単位の中で,内部結合(internal
linkage)をもつ一つの識別子の各々の宣言は,同じオブジェクト又は関数を表す。無結合(no linkage)を
もつ識別子の各々の宣言は,それぞれが別々の実体を表す。
オブジェクト又は関数に対するファイル有効範囲の識別子の宣言が記憶域クラス指定子staticを含む
場合,その識別子は,内部結合をもつ(22)。
識別子が,その識別子の以前の宣言が可視である(23)有効範囲において,記憶域クラス指定子externを
伴って宣言される場合,次のとおりとする。
− 以前の宣言において内部結合又は外部結合が指定されているならば,新しい宣言における識別子は,
以前の宣言と同じ結合をもつ。
− 可視である以前の宣言がない場合,又は以前の宣言が無結合である場合,この識別子は外部結合をも
つ。
関数の識別子の宣言が記憶域クラス指定子をもたない場合,その結合は,記憶域クラス指定子extern
を伴って宣言された場合と同じ規則で決定する。オブジェクトの識別子の宣言がファイル有効範囲をもち,
かつ記憶域クラス指定子をもたない場合,その識別子の結合は,外部結合とする。
オブジェクト又は関数以外を宣言する識別子,関数仮引数を宣言する識別子,及び記憶域クラス指定子
externを伴わないブロック有効範囲のオブジェクトを宣言する識別子は,無結合とする。
翻訳単位の中で同じ識別子が内部結合と外部結合の両方で現れた場合,その動作は未定義とする。
前方参照 外部定義(6.9),式(6.5),宣言(6.7),文(6.8)
6.2.3
識別子の名前空間 翻訳単位中のある位置で特定の識別子の複数の宣言が可視である場合,構文的
な文脈によって異なった実体への参照を区別する。すなわち,識別子を様々に分類するため,次に示す種
類の名前空間(name space)が存在する。
− ラベル名(label name)(ラベルの宣言及び使用の構文によって区別する。)。
− 構造体,共用体及び列挙体のタグ(tag)(先行するキーワードstruct,union又はenum(24)によっ
て区別する。)。
− 構造体又は共用体のメンバ(member)。構造体又は共用体の各々は,そのメンバに対する別個の名前
空間をもつ(.演算子又は->演算子を使ってメンバをアクセスするのに使用される式の型によって区
別する。)。
− その他のすべての識別子(通常の宣言子で宣言されたもの,又は列挙定数として宣言されたもの)。こ
───────────────────────────────────────────────
(21)
異なる識別子の間で結合が行われることはない。
(22)
関数宣言が記憶域クラス指定子staticをもつことができるのは,ファイル有効範囲をもつ宣言の
場合だけである(6.7.1参照)。
(23)
新しい宣言は以前の宣言を隠すことがある(6.2.1参照)。
(24)
タグ名の名前空間を三つとすることも考えられるが,この規格ではただ一つの名前空間が存在する
ことにしている。
24
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
れらを通常の識別子(ordinary identifier)と呼ぶ。
前方参照 goto文(6.8.6.1),構造体指定子及び共用体指定子(6.7.2.1),構造体及び共用体のメンバ(6.5.2.3),
タグ(6.7.2.3),ラベル付き文(6.8.1),列挙型指定子(6.7.2.2)
6.2.4
オブジェクトの記憶域期間 オブジェクトは,その生存期間を決定する記憶域期間(storage
duration)をもつ。記憶域期間は,静的記憶域期間,自動記憶域期間,及び割付け記憶域期間の3種類とす
る。割付け記憶域は7.20.3で規定する。
オブジェクトの生存期間(lifetime)とは,オブジェクトに対して記憶域の確保が保証されている,プロ
グラム実行の一部分をいう。オブジェクトは,生存期間を通じて存在し,一定のアドレス(25)をもち,最後
に格納された値を保持する(26)。オブジェクトを生存期間の外部で参照したときの動作は未定義とする。ポ
インタの値は,そのポインタが指すオブジェクトが生存期間の最後に到達すると,不定になる。
外部結合若しくは内部結合をもつか,又は記憶域クラス指定子staticを使って宣言された識別子のオ
ブジェクトは,静的記憶域期間(static storage duration)をもつ。その生存期間はプログラム実行の全体と
する。その値はプログラム開始処理の前に1回だけ初期化する。
無結合をもち,かつ記憶域クラス指定子staticをもたずに宣言された識別子のオブジェクトは,自動
記憶域期間(automatic storage duration)をもつ。
可変長配列型をもたず,自動記憶域期間をもつオブジェクトの生存期間は,オブジェクトが関連付けら
れているブロックに入る時から,どのような形であれ,そのブロックの実行が終了する時までとする。(内
側のブロックに入ったり,又は関数を呼び出したりした場合,そのブロックの実行は一時停止するが,終
了はしない。)ブロックに再帰的に入るごとに,オブジェクトの新しい実体を生成する。オブジェクトの初
期値は不定とする。オブジェクトの初期化が指定されている場合,ブロックの実行がその宣言に到達する
ごとに,初期化を行う。初期化が指定されていない場合,その宣言に到達するごとに,オブジェクトの値
を不定にする。
可変長配列型をもち,自動記憶域期間をもつオブジェクトの生存期間は,オブジェクトの宣言の時から,
プログラムの実行が宣言の有効範囲から離れる時までとする(27)。有効範囲に再帰的に入るごとに,オブジ
ェクトの新しい実体を生成する。オブジェクトの初期値は不定とする。
前方参照 関数呼出し(6.5.2.2),初期化(6.7.8),宣言子(6.7.5),配列宣言子(6.7.5.2),文(6.8)
6.2.5
型 オブジェクトに格納した値又は関数の返す値の意味は,それをアクセスするのに使われる式の
型(type)によって決定する。(オブジェクトとして宣言された識別子は最も単純な式とし,その型は識別
子の宣言において指定された型とする。)型は,オブジェクト型(object type)(オブジェクトを完全に規定
する型),関数型(function type)(関数を規定する型),及び不完全型(incomplete type)(オブジェクトを
規定する型で,その大きさを確定するのに必要な情報が欠けたもの)に分類する。
型̲Boolとして宣言されたオブジェクトは,値0及び1を格納するのに十分な大きさをもつ。
───────────────────────────────────────────────
(25)
“一定のアドレス”とは,オブジェクトへのポインタの(場合によっては異なる時における)二つ
の生成に関して,二つのポインタを比較して等しいことを意味する。同じプログラムの二つの異な
る実行については,アドレスが異なることもありうる。
(26)
ボラタイルオブジェクトの場合,最後の格納はプログラム中で明示的でないかもしれない。
(27)
宣言を含む最も内側のブロックを離れると,又はそのブロック若しくは更に内側のブロックで,宣
言より前の位置に移動すると,宣言の有効範囲から離れる。
25
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
型charとして宣言されたオブジェクトは,実行基本文字集合の任意の要素を格納するのに十分な大き
さをもつ。実行基本文字集合の任意の要素をchar型のオブジェクトに格納した場合,その値は非負であ
ることを保証する。その他の文字をchar型のオブジェクトに格納した場合,その結果の値は処理系定義
とするが,その型で表現可能な値の範囲に含まれなければならない。
標準符号付き整数型(standard signed integer type)は,signed char,short int,int,long int
及びlong long intの5種類とする。[これらの型及び他の型は幾つかの別の方法で指定してもよい
(6.7.2で規定する。)。]さらに,処理系定義の拡張符号付き整数型(extended signed integer type)(28)を処
理系が提供してもよい。標準符号付き整数型及び拡張符号付き整数型を総称して符号付き整数型(signed
integer type)と呼ぶ(29)。
型signed charとして宣言されたオブジェクトは,“単なる”char型のオブジェクトと同じ大きさの
記憶域を占有する。“単なる”int型のオブジェクトは,実行環境のアーキテクチャによって決まる自然
な(ヘッダ<limits.h>に定義されるINT̲MINからINT̲MAXまでの範囲にある任意の値を格納するのに
十分な)大きさをもつ。
符号付き整数型の各々に対応するが,それとは異なる符号無し整数型が存在する(キーワードunsigned
で示される)。符号無し整数型は,符号付き整数型と(符号情報を含めて)同じ大きさの記憶域を使い,か
つ同じ境界調整要求をもつ。型̲Bool,及び標準符号付き整数型に対応する符号無し整数型は,標準符号
無し整数型(standard unsigned integer type)とする。拡張符号付き整数型に対応する符号無し整数型は,拡
張符号無し整数型(extended unsigned integer type)とする。標準符号無し整数型及び拡張符号無し整数型を
総称して符号無し整数型(unsigned integer type)と呼ぶ(30)。
標準符号付き整数型及び標準符号無し整数型を総称して標準整数型(standard integer type)と呼び,拡張
符号付き整数型及び拡張符号無し整数型を総称して拡張整数型(extended integer type)と呼ぶ。
二つの整数型が,符号の有無に関して同じであり,整数変換の順位(6.3.1.1参照)に関して異なる場合,
整数変換の順位が低い型の値の範囲は,もう一方の型の値の範囲の部分集合とする。
符号付き整数型の負でない値の範囲は,対応する符号無し整数型の範囲の部分集合とし,二つの型にお
いて同じ値の表現は同じとする(31)。符号無しオペランドを含む計算は,決してオーバフローしない。すな
わち,結果を符号無し整数型で表現できないときは,その型で表現しうる最大値より1だけ大きい数を法
とする剰余を結果とする。
実浮動小数点型(real floating type)は,float,double及びlong double(32)の3種類とする。型
floatの値の集合は,型doubleの値の集合の部分集合とする。型doubleの値の集合は,型long
───────────────────────────────────────────────
(28)
処理系定義のキーワードは,どのような目的のためにも予約された識別子の形式(7.1.3で規定す
る。)をもたなければならない。
(29)
したがって,この規格において符号付き整数型に関するすべての記述を,拡張符号付き整数型にも
適用する。
(30)
したがって,この規格において符号無し整数型に関するすべての記述を,拡張符号無し整数型にも
適用する。
(31)
二つの型において,値の表現と境界調整要求が同じであれば,関数の引数として,関数からの返却
値として,又は共用体のメンバとして,両方の値が交換可能であることを意味する。
(32)
“今後の言語の方針”(6.11.1参照)。
26
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
doubleの値の集合の部分集合とする。
複素数型(complex type)は,float ̲Complex,double ̲Complex及びlong double ̲Complex
の3種類とする(33)。実浮動小数点型及び複素数型を総称して浮動小数点型(floating type)と呼ぶ。
それぞれの浮動小数点型に対して,対応する実数型(corresponding real type)が存在し,それは常に実浮
動小数点型とする。実浮動小数点型に対しては,同じ型を対応する実数型とする。複素数型に対しては,
型名からキーワード̲Complexを除いた型を,対応する実数型とする。
それぞれの複素数型は,対応する実数型の(正確に)二つの要素をもつ配列型と同じ表現及び境界調整
要求をもつ。この配列の最初の要素は複素数の実部に等しく,第2の要素は虚部に等しい。
型char,符号付き整数型,符号無し整数型及び浮動小数点型を総称して基本型(basic type)と呼ぶ。
たとえ,処理系が二つ以上の基本型を同じ表現で定義しても,これらは異なった型とする(34)。
三つの型char,signed char及びunsigned charを総称して文字型(character type)と呼ぶ。処理
系は,charを,signed char又はunsigned charのいずれかと同じ値の範囲,同じ表現形式,そし
て同じ動作をするものとして定義しなければならない(35)。
列挙体(enumeration)は,名前付けられた整数定数値から成る。それぞれの列挙体は,異なる列挙型
(enumerated type)を構成する。
型char,符号付き整数型,符号無し整数型,及び列挙型を総称して整数型(integer type)と呼ぶ。整数
型及び実浮動小数点型を総称して実数型(real type)と呼ぶ。
整数型及び浮動小数点型を総称して算術型(arithmetic type)と呼ぶ。それぞれの算術型は,一つの型領
域(type domain)に属する。実数型領域(real type domain)は実数型から成り,複素数型領域(complex type
domain)は複素数型から成る。
void型の値の集合は空とする。それは,完全にすることのできない不完全型とする。
派生型(derived type)は,オブジェクト型,関数型及び不完全型から幾つでも構成することができる。
派生型の種類は,次のとおりとする。
− 配列型(array type)は,要素型(element type)と呼ぶ特定のメンバオブジェクト型をもつ空でないオ
ブジェクトの集合を連続して割り付けたものを表す(36)。配列型は,その要素型及び配列の要素の個数
によって特徴付ける。配列型はその要素型から派生されるといい,要素型がTの場合,配列型は“T
の配列”と呼ぶ。要素型から配列型を構成することを“配列型派生”と呼ぶ。
− 構造体型(structure type)は,メンバオブジェクト(ある状況では,不完全配列)の空でない集合を順
───────────────────────────────────────────────
(33)
虚数型の仕様については,附属書G(参考)で示す。
(34)
処理系においては,基本型又は他の型を示すための別の方法としての新しいキーワードを定義して
よい。これは,すべての基本型は異ならなければならないという要求には違反しない。処理系定義
のキーワードは,どのような目的のためにも予約された識別子の形式(7.1.3で規定する。)をもた
なければならない。
(35)
<limits.h>で定義されるCHAR̲MINは,0又はSCHAR̲MINのいずれかの値をとる。これにより,
signed charとunsigned charのいずれを選択したかを区別することができる。いずれを選択
したとしても,charはsigned charやunsigned charとは異なる型であり,いずれとも適合
しない。
(36)
オブジェクト型は不完全型を含まないので,不完全型の配列は作ることができない。
27
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
に割り付けたものを表す。各メンバは,名前を指定してもよく異なる型をもってもよい。
− 共用体型(union type)は,重なり合って割り付けたメンバオブジェクトの空でない集合を表す。各メ
ンバは,名前を指定してもよく異なる型をもってもよい。
− 関数型(function type)は,指定された返却値の型をもつ関数を表す。関数型は,その返却値の型,並
びにその仮引数の個数及び型によって特徴付ける。関数型は,その返却値の型から派生されるといい,
返却値の型がTの場合,関数型は“Tを返す関数”と呼ぶ。返却値の型から関数型を構成することを
“関数型派生”と呼ぶ。
− ポインタ型(pointer type)は,被参照型(referenced type)と呼ぶ関数型,オブジェクト型又は不完全
型から派生することができる。ポインタ型は,被参照型の実体を参照するための値をもつオブジェク
トを表す。被参照型Tから派生されるポインタ型は,“Tへのポインタ”と呼ぶ。被参照型からポイン
タ型を構成することを“ポインタ型派生”と呼ぶ。
派生型を構成するこれらの方法は,再帰的に適用できる。
算術型及びポインタ型を総称して,スカラ型(scalar type)と呼ぶ。配列型及び構造体型を総称して集成
体型(aggregate type)と呼ぶ(37)。
大きさの分からない配列型は,不完全型とする。その型は,それ以降のその型の識別子の宣言(内部結
合又は外部結合をもつ)で大きさを指定することによって,完全となる。内容の分からない構造体型又は
共用体型(6.7.2.3で規定)は,不完全型とする。その型は,同じ有効範囲のそれ以降の同じ構造体タグ又
は共用体タグの宣言で,内容を定義することによって,その型のすべての宣言に関し完全となる。
配列型,関数型及びポインタ型を総称して派生宣言子型(derived declarator type)と呼ぶ。型Tからの宣
言子型派生(declarator type derivation)とは,型Tに配列型派生,関数型派生又はポインタ型派生を適用し
て,型Tから派生宣言子型を構成することをいう。
型は,その型分類(type category)によって特徴付ける。型分類とは,型が派生型を含む場合,(この箇
条の派生型の構成において規定したとおり)最も外側の派生とし,型が派生型を含まない場合,その型自
身とする。
ここまでに定めた型を,非修飾型(unqualified type)と呼ぶ。各非修飾型は,const,volatile,及び
restrict修飾子の一つ,二つ又は三つの組合せに対応する各種の修飾版(qualified version)をもつ(38)。
一つの型の修飾版と非修飾版は,同じ型分類,同じ表現及び同じ境界調整要求をもつが,異なる型とする
(39)。型修飾子をもつ型から派生したとしても,派生型はその型修飾子によって修飾されない。
voidへのポインタは,文字型へのポインタと同じ表現及び同じ境界調整要求をもたなければならない
(39)。同様に,適合する型へのポインタ同士の場合,修飾版であるか又は非修飾版であるかにかかわらず,
同じ表現及び同じ境界調整要求をもたなければならない。構造体型へのポインタは,すべて同じ表現及び
同じ境界調整要求をもたなければならない。共用体型へのポインタは,すべて同じ表現及び同じ境界調整
要求をもたなければならない。これ以外の型へのポインタは,同じ表現又は同じ境界調整要求をもつ必要
───────────────────────────────────────────────
(37)
集成体型には共用体型が含まれないことに注意する。共用体型のオブジェクトは,どの時点でもた
だ一つのメンバしか含まないからである。
(38)
修飾された配列型及び関数型については,6.7.3参照。
(39)
二つの型において,値の表現と境界調整要求が同じであれば,関数の引数として,関数からの返却
値として,又は共用体のメンバとして,両方の値が交換可能であることを意味する。
28
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
はない。
例1. “float *”として表された型は,“floatへのポインタ”型である。その型分類はポインタ
であり,浮動小数点型ではない。この型のconst修飾版は,“float * const”として表すこ
とができる。これに対して“const float *”と表された型は,修飾型ではなく,それは “const
修飾されたfloatへのポインタ”,すなわち修飾型へのポインタである。
例2. “struct tag (*[5])(float)”として表された型は,“struct tagを返す関数へのポイ
ンタの配列”である。配列は長さ5をもち,関数は,float型の引数を1個もつ。この型の型
分類は,配列である。
前方参照 宣言(6.7),適合型及び合成型(6.2.7)
6.2.6
型の表現
6.2.6.1
一般的規定 すべての型の表現は,6.2.6に規定されているものを除き,未規定とする。
ビットフィールドの場合を除き,オブジェクトは1バイト以上の連続した並びから成る。その並びのバ
イト数,バイトの順序,及び表現方法は,明示的に規定するか,又は処理系定義とする。
符号無しビットフィールド及びunsigned char型のオブジェクトに格納した値は,純粋2進表現を
用いて表現しなければならない(40)。
ビットフィールド以外のオブジェクト(unsigned char型以外の型をもつ)に格納した値は,nをこ
の型のオブジェクトのバイト単位の大きさとして,n×CHAR̲BIT個のビットで表す。この値をunsigned
char [n]型のオブジェクトに(例えば,memcpyを用いて)コピーすることができる。コピーした結果
のバイトの集合を,この値のオブジェクト表現(object representation)と呼ぶ。ビットフィールドに指定し
た大きさをmとすると,ビットフィールドに格納する値は,mビットから成る。そのオブジェクト表現は,
ビットフィールドを保持しているアドレス指定可能な記憶域単位に格納された,ビットフィールドを構成
するm個のビットの集合とする。NaNを除き,同じオブジェクト表現をもつ二つの値の比較の結果は等し
い。ただし,比較の結果が等しい値が,異なるオブジェクト表現をもってもよい。
オブジェクト表現の中には,そのオブジェクト型の値を表現しないものがある。オブジェクトに格納し
た値がオブジェクト型の値を表現せず,文字型ではない左辺値式でそれを読み取る場合,その動作は未定
義とする。文字型ではない左辺値式の副作用(その結果,オブジェクトのすべて又は一部が変更される。)
によって,オブジェクト型の値を表現しないオブジェクト表現が生成される場合,その動作は未定義とす
る(41)。オブジェクト型の値を表現しないオブジェクト表現をトラップ表現(trap representation)と呼ぶ。
値を構造体型又は共用体型のオブジェクトに格納する場合,メンバオブジェクトに含まれる部分も含め,
オブジェクト表現の詰め物バイトに対応するバイトの値は未規定とする(42)。詰め物バイトの値は,そのオ
───────────────────────────────────────────────
(40)
0と1の2進数字を用いる,位置に基づく記数法。この値は,連続したビットについて,1で始まる
2のべき乗をそれぞれ乗じ,合計する。ただし,最上位ビットは別扱いとなりうる。(American
National Dictionary for Information Processing Systemsから引用。)1バイトはCHAR̲BIT個のビットか
ら成り,unsigned char型の値の範囲は0から2CHAR̲BIT−1までである。
(41)
したがって,自動変数は,未定義な動作を起こすことなく,トラップ表現で初期化することが可能
である。この場合,この変数の値は,適切な値が格納されるまでは使用できない。
(42)
したがって,処理系は例えば構造体の代入について,要素を1個ずつ代入する方法を用いてもよい
し,memcpyを用いる方法を用いてもよい。
29
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ブジェクトの値がトラップ表現であるかどうかに影響を与えてはならない。構造体又は共用体オブジェク
トのビットで,ビットフィールドメンバと同じバイトに属するが,そのメンバの一部ではないビットも,
同様に,そのオブジェクトの値がトラップ表現であるかどうかに影響を与えてはならない。
値を共用体型のオブジェクトのメンバに格納すると,このメンバに対応せず,他のメンバに対応するオ
ブジェクト表現のバイトの値は未規定とする。しかし,共用体オブジェクトの値が,それによってトラッ
プ表現となってはならない。
二つ以上のオブジェクト表現をもつ値に演算子を適用する場合,いずれのオブジェクト表現が用いられ
るかが,結果の値に影響を及ぼしてはならない(43)。ある値に対して二つ以上のオブジェクト表現をもつ型
を用いて,その値をオブジェクトに格納する場合,どの表現が用いられるかは未規定とする。しかしトラ
ップ表現が生成されてはならない。
前方参照 左辺値,配列及び関数指示子(6.3.2.1),式(6.5),宣言(6.7)
6.2.6.2
整数型 unsigned char以外の符号無し整数型において,オブジェクト表現のビットは値ビッ
ト及び詰め物ビットの二つのグループに分けられなければならない(詰め物ビットは存在しなくてもよ
い。)。N個の値ビットがある場合,それぞれのビットは1から2N−1までの,異なる2のべきを表現しなけ
ればならない。その結果,この型のオブジェクトは,純粋2進表現を用いて,0から2N−1までの値を表現
できなければならない。この表現方法を,値表現と呼ぶ。詰め物ビットの値はすべて未規定とする(44)。
符号付き整数型において,オブジェクト表現のビットは,値ビット,詰め物ビット,及び符号ビットの
三つのグループに分けられなければならない。詰め物ビットは存在しなくてもよく,符号ビットはちょう
ど一つでなければならない。それぞれの値ビットは,対応する符号無し整数型のオブジェクト表現におけ
る同じビットと同じ値をもたなければならない。(符号付き整数型にM個の値ビットがあり,符号無し整
数型にN個の値ビットがあれば,M≦N。)符号ビットが0であれば,それは結果の値に影響を及ぼしては
ならない。符号ビットが1であれば,値は次に示す方法の一つに従って変更されなければならない。
− 符号ビットが0のときの値を負数化した値[符号と絶対値(sign and magnitude)]
− 符号ビットが値− (2N)をもつとするときの値[2の補数(two's complement)]
− 符号ビットが値− (2N−1)をもつとするときの値[1の補数(one's complement)]
これらのうちいずれが適用されるかは処理系定義とする。同様に,符号ビットが1ですべての値ビットが
0である数(符号と絶対値若しくは2の補数の場合),又は符号ビット及びすべての値ビットが1である値
(1の補数の場合)が,トラップ表現であるか又は通常の値であるかも処理系定義とする。符号と絶対値
───────────────────────────────────────────────
(43)
同じ有効型Tをもつオブジェクトxとyが,T型のオブジェクトとしてアクセスされる場合に同じ
値をもち,他の文脈では異なる値をもつことがありうる。特にT型に対して==演算が定義されてい
るとしても,x == yはmemcmp(&x, &y, sizeof(T)) == 0であることを意味しない。さら
に,x == yはxとyが同じ値をもつことを必ずしも意味しない。T型の値に対する他の演算では
結果が違うかもしれない。
(44)
詰め物ビットの幾つかの組合せが,トラップ表現を生む可能性がある。例として,詰め物ビットの
一つがパリティビットの場合がある。それにもかかわらず,オーバフローのように例外条件の一部
となる場合(符号無し型では起こり得ない)を除き,正しい値を用いる算術演算が,トラップ表現
を生成することはない。詰め物ビットのその他の組合せは,値ビットによって指定された値の代替
的なオブジェクト表現となる。
30
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
の場合,又は1の補数の場合,この表現が通常の値であるならば,これを負の0(negative zero)と呼ぶ。
処理系が負の0をサポートする場合,処理系が負の0を生成するのは次に示す演算の場合に限られなけ
ればならない。
− 負の0を生成するオペランドを伴った,&,|,^,~,<<,及び>>演算子
− 一方のオペランドが負の0で,結果が0となる,+,-,*,/,及び%演算子
− 上に掲げた二つの場合に基づく複合代入演算子
これらの場合に実際に負の0を生成するか,又は通常の0を生成するかは未規定とする。また,負の0が,
オブジェクトに格納されるときに通常の0になるかどうかも未規定とする。
処理系が負の0をサポートしない場合,負の0を生成するオペランドを伴った&,|,^,~,<<,及び
>>演算の結果は未定義とする。
詰め物ビットの値は未規定とする(45)。符号ビットが0である符号付き整数型の正しい(例外でない)オ
ブジェクト表現は,対応する符号無し整数型の正しいオブジェクト表現で,これと同じ値を表現しなけれ
ばならない。
整数型の精度(precision)とは,値を表現するのに用いられるビット(符号ビットと詰め物ビットは含
めない。)の数とする。整数型の幅(width)も同じとするが,符号ビットは含める。符号無し整数型では
これら二つは等しいが,符号付き整数型では幅は精度より1大きい。
6.2.7
適合型及び合成型 二つの型が同じ場合,二つの型は適合する(compatible)とする。これ以外に
二つの型が適合する場合を定める規則は,型指定子については6.7.2で,型修飾子については6.7.3で,宣
言子については6.7.5で規定する(46)。さらに,別々の翻訳単位で宣言された二つの構造体型,共用体型又
は列挙型は,それらのタグ及びメンバが次に示す要求を満たす場合に,適合する。
− 一方がタグ付きで宣言されている場合,もう一方も同じタグ付きで宣言されていなければならない。
− 両方が完全型であれば,次に示す要求が新たに満たされなければならない。すなわち,両方のメンバ
の間に1対1の対応がつき,対応するメンバ同士が適合する型をもち,更に対応するメンバの一方が
名前付きで宣言されているならば,もう一方も同じ名前付きで宣言されていなければならない。
− 二つの構造体については,対応するメンバは同じ順序で宣言されていなければならない。
− 二つの構造体又は共用体については,対応するビットフィールドは同じ幅をもたなければならない。
− 二つの列挙体については,対応するメンバは同じ値をもたなければならない。
同じオブジェクト又は関数を参照するすべての宣言は,適合する型をもたなければならない。そうでなけ
れば,その動作は未定義とする。
合成型(composite type)は,適合する二つの型から構成することができる。合成型は,二つの型の両方
に適合し,かつ次の条件を満たす型とする。
− 一方の型が既知の固定長をもつ配列の場合,合成型は,その大きさの配列とする。そうでなく,一方
の型が可変長の配列の場合,合成型はその型とする。
───────────────────────────────────────────────
(45)
詰め物ビットの幾つかの組合せが,トラップ表現を生む可能性がある。例として,詰め物ビットの
一つがパリティビットの場合がある。それにもかかわらず,オーバフローのように例外条件の一部
となる場合を除き,正しい値を用いる算術演算が,トラップ表現を生成することはない。詰め物ビ
ットのその他の組合せは,値ビットによって指定された値の代替的なオブジェクト表現となる。
(46)
二つの型が適合するためには,完全に同じである必要はない。
31
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 一方の型だけが仮引数型並びをもつ関数型(関数原型)の場合,合成型は,その仮引数型並びをもつ
関数原型とする。
− 両方の型が仮引数型並びをもつ関数型の場合,合成仮引数型並びにおける各仮引数の型は,対応する
仮引数の型の合成型とする。
これらの規則は,二つの型が派生される元の型に再帰的に適用する。
内部結合又は外部結合をもつ識別子が,ある有効範囲の中で宣言され,その識別子の以前の宣言が可視
であり(47),以前の宣言が内部結合又は外部結合を指定している場合,現在の宣言での識別子の型は合成型
となる。
例 次の二つのファイル有効範囲をもつ宣言が与えられた場合,
int f(int (*)(), double (*)[3]);
int f(int (*)(char *), double (*)[]);
得られる関数の合成型は,
int f(int (*)(char *), double (*)[3]);
である。
6.3
型変換 幾つかの演算子は,オペランドの値をある型から他の型へ自動的に型変換する。6.3は,こ
の暗黙の型変換(implicit conversion)の結果及びキャスト演算[明示的な型変換(explicit conversion)]の
結果に対する要求を規定する。通常の演算子によって行われるほとんどの型変換は,6.3.1.8にまとめる。
各演算子における型変換については,必要に応じて6.5に補足する。
適合する型へのオペランドの値の型変換は,値又は表現の変更を引き起こさない。
前方参照 キャスト演算子(6.5.4)
6.3.1
算術オペランド
6.3.1.1
論理型,文字型及び整数型 すべての整数型は,次のとおり定義される整数変換の順位(integer
conversion rank)をもつ。
− 二つの符号付き整数型は,同じ表現をもつ場合であっても,同じ順位をもってはならない。
− 符号付き整数型は,より小さい精度の符号付き整数型より高い順位をもたなければならない。
− long long int型はlong int型より高い順位をもたなければならない。long int型はint型
より高い順位をもたなければならない。int型はshort int型より高い順位をもたなければならな
い。short int型はsigned char型より高い順位をもたなければならない。
− ある符号無し整数型に対し,対応する符号付き整数型があれば,両方の型は同じ順位をもたなければ
ならない。
− 標準整数型は,同じ幅の拡張整数型より高い順位をもたなければならない。
− char型は,signed char型及びunsigned char型と同じ順位をもたなければならない。
− ̲Bool型は,その他のすべての標準整数型より低い順位をもたなければならない。
− すべての列挙型は,それぞれと適合する整数型と同じ順位をもたなければならない(6.7.2.2参照)。
− 精度の等しい拡張符号付き整数型同士の順位は処理系定義とするが,整数変換の順位を定める他の規
則に従わなければならない。
− 任意の整数型T1,T2,及びT3について,T1がT2より高い順位をもち,かつT2がT3より高い順
───────────────────────────────────────────────
(47)
新しい宣言は以前の宣言を隠すことがある(6.2.1参照)。
32
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
位をもつならば,T1はT3より高い順位をもたなければならない。
int型又はunsigned int型を使用してよい式の中ではどこでも,次に示すものを使用することがで
きる。
− 整数変換の順位がint型及びunsigned int型より低い整数型をもつオブジェクト又は式
− ̲Bool型,int型,signed int型,又はunsigned int型のビットフィールド
これらのものの元の型のすべての値をint型で表現可能な場合,その値をint型に変換する。そうでな
い場合,unsigned int型に変換する。これらの処理を,整数拡張(integer promotion)と呼ぶ(48)。これ
ら以外の型が整数拡張によって変わることはない。
整数拡張は,符号を含めてその値を変えない。“単なる”char型を符号付きとして扱うか否かは,処理
系定義とする(6.2.5参照)。
前方参照 構造体指定子及び共用体指定子(6.7.2.1),列挙型指定子(6.7.2.2)
6.3.1.2
論理型 任意のスカラ値を̲Bool型に変換する場合,その値が0に等しい場合は結果は0とし,
それ以外の場合は1とする。
6.3.1.3
符号付き整数型及び符号無し整数型 整数型の値を̲Bool型以外の他の整数型に変換する場合,
その値が新しい型で表現可能なとき,値は変化しない。
新しい型で表現できない場合,新しい型が符号無し整数型であれば,新しい型で表現しうる最大の数に
1加えた数を加えること又は減じることを,新しい型の範囲に入るまで繰り返すことによって得られる値
に変換する(49)。
そうでない場合,すなわち,新しい型が符号付き整数型であって,値がその型で表現できない場合は,
結果が処理系定義の値となるか,又は処理系定義のシグナルを生成するかのいずれかとする。
6.3.1.4
実浮動小数点型及び整数型 実浮動小数点型の有限の値を̲Bool型以外の整数型に型変換する
場合,小数部を捨てる(すなわち,値を0方向に切り捨てる。)。整数部の値が整数型で表現できない場合,
その動作は未定義とする(50)。
整数型の値を実浮動小数点型に型変換する場合,変換する値が新しい型で正確に表現できるとき,その
値は変わらない。変換する値が表現しうる値の範囲内にあるが正確に表現できないならば,その値より大
きく最も近い表現可能な値,又はその値より小さく最も近い表現可能な値のいずれかを処理系定義の方法
で選ぶ。変換する値が表現しうる値の範囲外にある場合,その動作は未定義とする。
6.3.1.5
実浮動小数点型 floatをdouble若しくはlong doubleに拡張する場合,又はdoubleを
long doubleに拡張する場合,その値は変化しない。
doubleをfloatに変換する場合,long doubleをdouble若しくはfloatに変換する場合,又
───────────────────────────────────────────────
(48)
整数拡張は,通常の算術型変換の一部として,実引数を表す式に,単項の+,-,及び~演算子のオ
ペランドに,又はシフト演算子の両オペランドにだけ適用される。それぞれについて記述している
箇条の規定に従って適用する。
(49)
この規則は数学的な値に関する計算についての規則であり,式の与えられた型の値についての規則
ではない。
(50)
実浮動小数点型の値を符号無し整数型に型変換する場合,整数型の値を符号無し整数型に型変換す
るときに行われる剰余操作が行われるとは限らない。したがって,可搬な実浮動小数点値の範囲は,
(−1,Utype̲MAX+1)である。
33
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
は,意味上の型(6.3.1.8参照)が要求するより高い精度及び広い範囲で表現された値をその意味上の型に
明示的に変換する場合,変換する値がその新しい型で正確に表現できるならば,その値は変わらない。変
換する値が,表現しうる値の範囲内にあるが正確に表現できない場合,その結果は,その値より大きく最
も近い表現可能な値,又はその値より小さく最も近い表現可能な値のいずれかを処理系定義の方法で選ぶ。
変換する値が表現しうる値の範囲外にある場合,その動作は未定義とする。
6.3.1.6
複素数型 複素数型の値を他の複素数型に変換する場合,実部と虚部の両方に,対応する実数型
の変換規則を適用する。
6.3.1.7
実数型及び複素数型 実数型の値を複素数型に変換する場合,複素数型の結果の実部は対応する
実数型への変換規則により決定し,複素数型の結果の虚部は正の0又は符号無しの0とする。
複素数型の値を実数型に変換する場合,複素数型の値の虚部を捨て,実部の値を,対応する実数型の変
換規則に基づいて変換する。
6.3.1.8
通常の算術型変換 算術型のオペランドをもつ多くの演算子は,同じ方法でオペランドの型変換
を行い,結果の型を決める。型変換は,オペランドと結果の共通の実数型(common real type)を決めるた
めに行う。与えられたオペランドに対し,それぞれのオペランドは,型領域を変えることなく,共通の実
数型を対応する実数型とする型に変換する。この規格で明示的に異なる規定を行わない限り,結果の対応
する実数型も,この共通の実数型とし,その型領域は,オペランドの型領域が一致していればその型領域
とし,一致していなければ複素数型とする。これを通常の算術型変換(usual arithmetic conversion)と呼ぶ。
通常の算術型変換の規則は,次による。
まず,一方のオペランドの対応する実数型がlong doubleならば,他方のオペランドを,型領域を
変えることなく,変換後の型に対応する実数型がlong doubleとなるように型変換する。
そうでない場合,一方のオペランドの対応する実数型がdoubleならば,他方のオペランドを,型領
域を変えることなく,変換後の型に対応する実数型がdoubleとなるように型変換する(51)。
そうでない場合,一方のオペランドの対応する実数型がfloatならば,他方のオペランドを,型領域
を変えることなく,変換後の型に対応する実数型がfloatとなるように型変換する。
そうでない場合,整数拡張を両オペランドに対して行い,拡張後のオペランドに次の規則を適用する。
− 両方のオペランドが同じ型をもつ場合,更なる型変換は行わない。
− そうでない場合,両方のオペランドが符号付き整数型をもつ,又は両方のオペランドが符号無し整
数型をもつならば,整数変換順位の低い方の型を,高い方の型に変換する。
− そうでない場合,符号無し整数型をもつオペランドが,他方のオペランドの整数変換順位より高い
又は等しい順位をもつならば,符号付き整数型をもつオペランドを,符号無し整数型をもつオペラ
ンドの型に変換する。
− そうでない場合,符号付き整数型をもつオペランドの型が,符号無し整数型をもつオペランドの型
のすべての値を表現できるならば,符号無し整数型をもつオペランドを,符号付き整数型をもつオ
ペランドの型に変換する。
− そうでない場合,両方のオペランドを,符号付き整数型をもつオペランドの型に対応する符号無し
整数型に変換する。
───────────────────────────────────────────────
(51)
例えば,double ̲Complex型とfloat型を加える場合,float型オペランドをdouble型に変
換しさえすればよい(結果はdouble ̲Complex型になる。)。
34
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
浮動小数点型のオペランドの値及び式の結果の値を,型が要求する精度や範囲を超えて表現してもよい。
ただし,それによって型が変わることはない(52)。
6.3.2
他のオペランド
6.3.2.1
左辺値,配列及び関数指示子 左辺値(lvalue)は,オブジェクト型,又はvoid以外の不完全型
をもつ式とする(53)。左辺値が評価されたときにオブジェクトを指し示していなければ,動作は未定義とす
る。オブジェクトがもつ型に言及する場合,その型とは,オブジェクトを指し示すために用いる左辺値に
よって指定される型とする。変更可能な左辺値(modifiable lvalue)とは,配列型をもたず,不完全型をも
たず, const修飾型をもたない左辺値とし,それが構造体又は共用体の場合,const修飾型のメンバ(再帰
的に包含されているすべての集成体又は共用体の任意のメンバ又は要素を含めて)をもたないものとする。
左辺値がsizeof演算子,単項&演算子,++演算子若しくは--演算子のオペランド,又は,演算子若し
くは代入演算子の左側のオペランドである場合を除いて,配列型以外の左辺値は,指し示されたオブジェ
クトが格納する値に変換する(そして,それはもはや左辺値ではない。)。左辺値が修飾型をもつ場合,そ
の値は左辺値の型の非修飾版をもつ。そうでない場合,その値は左辺値の型をもつ。左辺値が不完全型を
もち,配列型以外の型をもつ場合,その動作は未定義とする。
左辺値がsizeof演算子のオペランド,単項&演算子のオペランド,又は文字配列を初期化するのに使
われる文字列リテラルである場合を除いて,型“〜型の配列”をもつ式は,型“〜型へのポインタ”の式
に型変換する。それは配列オブジェクトの先頭の要素を指し,左辺値ではない。配列オブジェクトがレジ
スタ記憶域クラスをもつ場合,その動作は未定義とする。
関数指示子(function designator)は,関数型をもつ式とする。関数指示子がsizeof演算子(54)又は単項
&演算子のオペランドである場合を除いて,型“〜型を返す関数”をもつ関数指示子は,型“〜型を返す
関数へのポインタ”をもつ式に変換する。
前方参照 sizeof演算子(6.5.3.4),アドレス及び間接演算子(6.5.3.2),共通の定義<stddef.h>(7.17),
構造体及び共用体のメンバ(6.5.2.3),後置増分及び後置減分演算子(6.5.2.4),初期化(6.7.8),前置増分
及び前置減分演算子(6.5.3.1),代入演算子(6.5.16)
6.3.2.2
void ボイド式(void expression)(型voidをもつ式)の(存在しない)値は,いかなる方法で
も使ってはならない。ボイド式には,暗黙の型変換も明示的な型変換(voidへの型変換を除く。)も適用
してはならない。他の型の式をボイド式として評価する場合,その値又は指示子は捨てる。(ボイド式は,
副作用のために評価する。)
───────────────────────────────────────────────
(52)
この場合でもキャストと代入演算子は,型変換を行うことを要求される(6.3.1.4及び6.3.1.5で規定
する。)。
(53)
“左辺値”という名前は,代入式E1=E2から由来している。すなわち,代入式の左のオペランド
E1は,(変更可能な)左辺値となる必要がある。左辺値は,オブジェクトの位置を示す値を表現す
るものと考えたほうがよいかもしれない。時として“右辺値”と呼ばれるものは,この規格におい
ては“式の値”として記述する。
左辺値の最も明確な例は,オブジェクトの識別子である。もう一つの例としては,Eがオブジェ
クトへのポインタである単項式ならば,*EはEが指すオブジェクトを指し示す左辺値である。
(54)
この型変換が起こらないから,sizeof演算子のオペランドは,関数指示子のまま残り,6.5.3.4の
制約に違反することになる。
35
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6.3.2.3
ポインタ voidへのポインタは,任意の不完全型若しくはオブジェクト型へのポインタに,又
はポインタから,型変換してもよい。任意の不完全型又はオブジェクト型へのポインタを,voidへのポ
インタに型変換して再び戻した場合,結果は元のポインタと比較して等しくなければならない。
任意の型修飾子qに対して非q修飾型へのポインタは,その型のq修飾版へのポインタに型変換しても
よい。元のポインタと変換されたポインタに格納された値は,比較して等しくなければならない。
値0をもつ整数定数式又はその定数式を型void *にキャストした式を,空ポインタ定数(null pointer
constant)(55)と呼ぶ。空ポインタ定数をポインタ型に型変換した場合,その結果のポインタを空ポインタ
(null pointer)と呼び,いかなるオブジェクト又は関数へのポインタと比較しても等しくないことを保証
する。
空ポインタを他のポインタ型に型変換すると,その型の空ポインタを生成する。二つの空ポインタは比
較して等しくなければならない。
整数は任意のポインタ型に型変換できる。これまでに規定されている場合を除き,結果は処理系定義と
し,正しく境界調整されていないかもしれず,被参照型の実体を指していないかもしれず,トラップ表現
であるかもしれない(56)。
任意のポインタ型は整数型に型変換できる。これまでに規定されている場合を除き,結果は処理系定義
とする。結果が整数型で表現できなければ,その動作は未定義とする。結果は何らかの整数型の値の範囲
に含まれているとは限らない。
オブジェクト型又は不完全型へのポインタは,他のオブジェクト型又は不完全型へのポインタに型変換
できる。その結果のポインタが,被参照型に関して正しく境界調整されていなければ(57),その動作は未定
義とする。そうでない場合,再び型変換で元の型に戻すならば,その結果は元のポインタと比較して等し
くなければならない。オブジェクトへのポインタを文字型へのポインタに型変換する場合,その結果はオ
ブジェクトの最も低位のアドレスを指す。その結果をオブジェクトの大きさまで連続して増分すると,そ
のオブジェクトの残りのバイトへのポインタを順次生成できる。
ある型の関数へのポインタを,別の型の関数へのポインタに型変換することができる。さらに再び型変
換で元の型に戻すことができるが,その結果は元のポインタと比較して等しくなければならない。型変換
されたポインタを関数呼出しに用い,関数の型がポインタが指すものの型と適合しない場合,その動作は
未定義とする。
前方参照 オブジェクトを指すポインタを保持可能な整数型(7.18.1.4),キャスト演算子(6.5.4),単純代
入(6.5.16.1),等価演算子(6.5.9)
6.4
字句要素
構文規則
───────────────────────────────────────────────
(55)
空ポインタ定数としてマクロNULLが<stddef.h>(及び他のヘッダ)で定義されている(7.17参
照)。
(56)
ポインタを整数に変換する関数,又は整数をポインタに変換する関数は,実行環境におけるアドレ
ス構造に関して一貫した動作をするように作られている。
(57)
一般には,“境界を正しく調整する”という概念は推移的である。すなわち,型Aのポインタが型B
のポインタとして境界を正しく調整され,それが型Cのポインタとしても境界を正しく調整されて
いるならば,型Aのポインタは型Cのポインタとして境界を正しく調整されている。
36
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
字句:
キーワード
識別子
定数
文字列リテラル
区切り子
前処理字句:
ヘッダ名
識別子
前処理数
文字定数
文字列リテラル
区切り子
上の分類のいずれにも当てはまらない非空白類文字
制約 字句に変換される各前処理字句は,キーワード,識別子,定数,文字列リテラル又は区切り子の字
句としての形式をもたなければならない。
意味規則 字句(token)は,翻訳フェーズ(7)及び(8)において言語の最小の字句的な単位とする。字
句の分類は,キーワード,識別子,定数,文字列リテラル及び区切り子とする。前処理字句は,翻訳フェ
ーズ(3)から(6)までにおいて言語の最小の字句的な単位とする。前処理字句の分類は,ヘッダ名,識
別子,前処理数,文字定数,文字列リテラル,区切り子,及び字句的に他の前処理字句の分類に一致しな
い単一の非空白類文字とする(58)。文字'又は文字"がその最後の分類に入る場合,その動作は未定義とす
る。前処理字句は,間に空白類(white space)を入れて分離することができる。空白類とは,注釈(6.4.9
で規定する。),空白類文字(white-space character)(空白,水平タブ,改行,垂直タブ及び書式送り),又
はその両方のこととする。翻訳フェーズ(4)のある状況下では空白類(又はそれが存在しないこと)は前
処理字句を区切る以外の役割を果たす(6.10で規定する。)。 空白類が前処理字句の中に現れてよいのは,
ヘッダ名の一部又は文字定数若しくは文字列リテラルの引用符と引用符の間だけとする。
入力ストリームをある文字まで前処理字句に解析し終わったとき,次の前処理字句は,前処理字句を構
成することのできる最も長い文字の並びとする。この規則には一つの例外がある。すなわち,ヘッダ名前
処理字句は,#include前処理指令の中だけで認識し,この指令の中では,ヘッダ名としても文字列リテ
ラルとしても解釈できる文字の並びは,ヘッダ名として認識する。
例1. プログラム片1Exは,(正しい浮動小数点定数字句でも整数定数字句でもない)一つの前処理
数字句として解釈する。これは,たとえ(例えば,Exが+1としてマクロ定義されていて)二
つの前処理字句1及びExに分ければ正しい式として解釈できる場合でも,同じである。同様
に,Eがマクロ名であろうとなかろうと,プログラム片1E1は前処理数(正しい浮動小数点定
数字句)として解釈する。
───────────────────────────────────────────────
(58)
追加の分類であるプレースマーカは,翻訳フェーズ(4)の内部で使用される(6.10.3.3参照)。プレ
ースマーカは,ソースファイルに出現することはない。
37
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
例2. プログラム片x+++++yは,x ++ ++ + yとして解釈する。これは増分演算子の制約に違反
するが,正しい式になりうる解釈x ++ + ++ yは採らない。
前方参照 後置増分及び後置減分演算子(6.5.2.4),式(6.5),前置増分及び前置減分演算子(6.5.3.1),注
釈(6.4.9),浮動小数点定数(6.4.4.2),ヘッダ名(6.4.7),前処理指令(6.10),前処理数(6.4.8),マクロ
置き換え(6.10.3),文字定数(6.4.4.4),文字列リテラル(6.4.5)
6.4.1
キーワード
構文規則
キーワード:次のいずれか
auto
enum
restrict unsigned
break
extern
return
void
case
float
short
volatile
char
for
signed
while
const
goto
sizeof
̲Bool
continue if
static
̲Complex
default inline
struct
̲Imaginary
do
int
switch
double
long
typedef
else
register union
意味規則 上に掲げた字句(大文字小文字の違いには意味がある。)は,キーワードとして用いるために[翻
訳フェーズ(7)及び(8)で]予約しており,その他の目的に使用してはならない。
6.4.2
識別子
6.4.2.1
一般的規定
構文規則
識別子:
識別子用非数字
識別子 識別子用非数字
識別子 数字
識別子用非数字:
非数字
国際文字名
その他の処理系定義の文字
非数字:次のいずれか
̲ a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
数字:次のいずれか
0 1 2 3 4 5 6 7 8 9
38
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
意味規則 識別子は,非数字文字(下線̲,小文字及び大文字のラテン英字,並びにその他の文字を含む)
及び数字の列とする。識別子は,一つ又はそれ以上の実体を指し示す(6.2.1参照)。英小文字と英大文字
は,区別する。識別子の最大の長さに,特別の制限はない。
識別子の中のそれぞれの国際文字名が指定する文字は,そのISO/IEC 10646での表現形式が附属書Dに
示す範囲の一つに分類されるものでなければならない(59)。先頭の文字は,数字を表す国際文字名であって
はならない。処理系は,ソース基本文字集合の一部でない多バイト文字が識別子の中に現れることを許し
てもよい。使用してよい多バイト文字及びその文字と国際文字名との対応は,処理系定義とする。
前処理字句を翻訳フェーズ(7)で字句に変換するとき,前処理字句をキーワードにも識別子にも変換で
きるならば,キーワードに変換する。
処理系限界 処理系は,意味がある先頭の文字の個数を制限してもよい(5.2.4.1参照)。外部名(external
name)(外部結合をもつ識別子)は,内部名(internal name)(マクロ名又は外部結合をもたない識別子)
より制限を強くしてもよい。識別子の意味がある文字の個数は,処理系定義とする。
意味がある文字が異なる識別子は,異なる識別子とする。二つの識別子が意味のない文字でだけ異なる
場合,その動作は未定義とする。
前方参照 国際文字名(6.4.3),マクロ置き換え(6.10.3)
6.4.2.2
あらかじめ定義された識別子
意味規則 識別子̲ ̲func̲ ̲は,翻訳プログラムによって,それぞれの関数定義の左波括弧の直後に,次
の宣言が現れた場合と同じ規則で暗黙に宣言される。
static const char ̲ ̲func̲ ̲ [] = "関数名";
関数名は,字句的に囲んでいる関数の名前とする(60)。
この名前は,暗黙の宣言をソース文字集合で書き,そして次に翻訳フェーズ(5)で示したとおり実行文
字集合に変換した場合と同じ規則で符号化する。
例 次のプログラム片を考える。
#include <stdio.h>
void myfunc(void)
{
printf("%s\n", ̲ ̲func̲ ̲);
/* ... */
}
関数が呼び出されるたびに,次の名前を標準出力ストリームに表示する。
myfunc
前方参照 関数定義(6.9.1)
───────────────────────────────────────────────
(59)
リンカが拡張文字を受け付けることができないシステムでは,有効な外部識別子を形成するために,
国際文字名の表現形式を使用してもよい。例えば,他の目的では使われていない文字又は文字の並
びを,国際文字名の\uを符号化するために使用してもよい。拡張文字は,長い外部識別子を生成し
てもよい。
(60)
名前̲ ̲func̲ ̲は,どのような目的のためにも処理系によって予約されている(7.1.3)ため,名前
̲ ̲func̲ ̲を使用して他の識別子を宣言する場合,その動作は未定義になる。
39
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6.4.3
国際文字名
構文規則
国際文字名:
\u 16進4数字
\U 16進4数字 16進4数字
16進4数字:
16進数字 16進数字 16進数字 16進数字
制約 国際文字名は,次に示す短い識別子をもつ文字を指定してはならない(61)。
− 00A0未満[0024($),0040(@)及び0060(̀)を除く。]
− D800〜DFFF
補足説明 国際文字名は,基本文字集合の中にない文字を表すために識別子,文字定数及び文字列リテラ
ルの中で使用してもよい。
意味規則 国際文字名\Unnnnnnnnは,8けたの短い識別子(ISO/IEC 10646で規定)がnnnnnnnnである文
字を表す(62)。同様に,国際文字名\unnnnは,4けたの短い識別子がnnnnである文字を表す(この文字の
8けたの短い識別子は,0000nnnnである。)。
6.4.4
定数
構文規則
定数:
整数定数
浮動小数点定数
列挙定数
文字定数
制約 定数の値は,その型で表現可能な値の範囲の中になければならない。
意味規則 各定数は型をもつ。その型は定数の形式及び値から決まる。型の定め方は,後に詳述する。
6.4.4.1
整数定数
構文規則
整数定数:
10進定数 整数接尾語opt
8進定数 整数接尾語opt
16進定数 整数接尾語opt
10進定数:
非0数字
10進定数 数字
8進定数:
───────────────────────────────────────────────
(61)
許されない文字は,基本文字集合の文字,並びに制御文字,文字DELETE,及びS領域(UTF-16
で使用するために予約されている。)のためにISO/IEC 10646で予約した符号位置である。
(62)
文字のための短い識別子は,ISO/IEC 10646-1/AMD9:1997で最初に規定された。
40
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
0
8進定数 8進数字
16進定数:
16進接頭語 16進数字
16進定数 16進数字
16進接頭語: 次のいずれか
0x 0X
非0数字: 次のいずれか
1 2 3 4 5 6 7 8 9
8進数字: 次のいずれか
0 1 2 3 4 5 6 7
16進数字: 次のいずれか
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
整数接尾語:
U接尾語 L接尾語opt
U接尾語 LL接尾語
L接尾語 U接尾語opt
LL接尾語 U接尾語opt
U接尾語: 次のいずれか
u U
L接尾語: 次のいずれか
l L
LL接尾語: 次のいずれか
ll LL
補足説明 整数定数は,数字で始まり,ピリオドも指数部ももたない。その定数の基数を指定する接頭語,
及び型を指定する接尾語をもってもよい。
10進定数は,0以外の数字から始まる10進数字列から成る。8進定数は,0で始まる0から7までの数
字だけの列から成る。16進定数は,接頭語0x又は0Xをもち,その後ろに10進数字及び10から15まで
の値をそれぞれもつa(又はA)からf(又はF)までの英字の列から成る。
意味規則 10進定数は基数10,8進定数は基数8,16進定数は基数16で値を計算する。字句的に先頭の
数字が最も重みが大きい。
整数定数の型は,次の表の対応する並びの中で,その値を表現できる最初の型とする。
41
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
接尾語
10進定数
8進定数又は16進定数
なし
int
long int
long long int
int
unsigned int
long int
unsigned long int
long long int
unsigned long long int
u又はU
unsigned int
unsigned long int
unsigned long long int
unsigned int
unsigned long int
unsigned long long int
l又はL
long int
long long int
long int
unsigned long int
long long int
unsigned long long int
u又はU及びl又はLの両方
unsigned long int
unsigned long long int
unsigned long int
unsigned long long int
ll又はLL
long long int
long long int
unsigned long long int
u又はU及びll又はLLの両方
unsigned long long int
unsigned long long int
整数定数がその並びの中のどの型でも表現できず,かつ拡張整数型がその値を表現できるとき,それは,
拡張整数型をもってもよい。該当する並びの中のすべての型が符号付きである場合,拡張整数型は符号付
きとする。その並びの中のすべての型が符号無しである場合,拡張整数型は符号無しとする。その並びが
符号付きと符号無しの両方の型を含む場合,拡張整数型は符号付きでも符号無しでもよい。
6.4.4.2
浮動小数点定数
構文規則
浮動小数点定数:
10進浮動小数点定数
16進浮動小数点定数
10進浮動小数点定数:
小数点定数 指数部opt 浮動小数点接尾語opt
数字列 指数部 浮動小数点接尾語opt
16進浮動小数点定数:
16進接頭語 16進小数点定数 2進指数部 浮動小数点接尾語opt
16進接頭語 16進数字列 2進指数部 浮動小数点接尾語opt
小数点定数:
数字列opt . 数字列
数字列 .
指数部:
e 符号opt 数字列
E 符号opt 数字列
符号: 次のいずれか
+ -
数字列:
42
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
数字
数字列 数字
16進小数点定数:
16進数字列opt . 16進数字列
16進数字列 .
2進指数部:
p 符号opt 数字列
P 符号opt 数字列
16進数字列:
16進数字
16進数字列 16進数字
浮動小数点接尾語: 次のいずれか
f l F L
補足説明 浮動小数点定数は有効数字部(significand part)をもち,その後ろに指数部(exponent part)及
びその型を指定する接尾語が続いてもよい。有効数字部は,整数部を表す数字列,その後ろに続くピリオ
ド(.),更にその後ろに続く数字列(小数部を表す)から成る。指数部は,e, E, p又はPの後ろに省
略可能な符号が付いた数字列から成る指数が続く。整数部又は小数部のいずれかがなければならない。10
進浮動小数点定数の場合,ピリオド又は指数部のいずれかがなければならない。
意味規則 有効数字部は,(10進又は16進の)有理数として解釈する。指数部の数字列は,10進整数とし
て解釈する。10進浮動小数点定数の場合,指数は有効数字部に乗じる10のべき乗を示す。16進浮動小数
点定数の場合,指数は有効数字部に乗じる2のべき乗を示す。10進浮動小数点定数の場合,又はFLT̲RADIX
が2のべき乗でないときの16進浮動小数点定数の場合,その結果は,最も近い表現可能な値とするか,又
は,最も近い表現可能な値のすぐ隣(大きい値若しくは小さい値)で表現可能な値とするか,いずれかを
処理系定義の方法で選ぶ。FLT̲RADIXが2のべき乗であるときの16進浮動小数点定数の場合,その結果
は,正確に丸めた値とする。
接尾語のない浮動小数点定数は,型doubleをもつ。英字f又はFを接尾語としてもつ場合,型float
をもつ。l又はLを接尾語としてもつ場合,型long doubleをもつ。
浮動小数点定数は,翻訳時と同じ規則に従って,内部形式に変換する。浮動小数点定数の変換は,実行
時に例外条件又は浮動小数点例外を生成してはならない。
推奨実装仕様 処理系は,16進定数が評価形式で正確に表現できない場合,診断メッセージを出力するこ
とが望ましい。処理系は,それからプログラムの翻訳を続けることが望ましい。
浮動小数点定数の翻訳時変換は,次の条件を満たすライブラリ関数(例えば,strtodなど)での文字
列の実行時変換と一致することが望ましい(63)。
− 入力が両方の変換に適している。
− 同じ結果形式をもつ。
───────────────────────────────────────────────
(63)
ライブラリ関数の規定は,浮動小数点定数に要求されるよりも,更に正確な型変換を推奨する
(7.20.1.3参照)。
43
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 既定の実行時丸めを行う。
6.4.4.3
【列挙定数】
構文規則
列挙定数:
識別子
意味規則 列挙定数として宣言された識別子は,型intをもつ。
前方参照 列挙型指定子(6.7.2.2)
6.4.4.4
文字定数
構文規則
文字定数:
' c文字列 '
L' c文字列 '
c文字列:
c文字
c文字列 c文字
c文字:
一重引用符',逆斜線\及び改行文字を除くソース文字集合中の任意の要素
逆斜線表記
逆斜線表記:
単純逆斜線表記
8進逆斜線表記
16進逆斜線表記
国際文字名
単純逆斜線表記: 次のいずれか
\' \" \? \\
\a \b \f \n \r \t \v
8進逆斜線表記:
\ 8進数字
\ 8進数字 8進数字
\ 8進数字 8進数字 8進数字
16進逆斜線表記:
\x 16進数字
16進逆斜線表記 16進数字
補足説明 単純文字定数は,一重引用符で囲まれた一つ以上の多バイト文字の並びとする(例えば'x')。
ワイド文字定数は,英字Lという接頭語が付いていることを除いて単純文字定数と同一とする。後に詳述
する幾つかの例外を除いて,列の要素はソース文字集合の任意の要素とする。それらは実行文字集合の要
素に処理系定義の方法で対応付ける。
一重引用符',二重引用符",疑問符?,逆斜線\及び任意の整数値は,次の逆斜線表記によって表現可能
44
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
とする。
一重引用符 '
\'
二重引用符 "
\"
疑問符 ?
\?
逆斜線 \
\\
8進整数
\8進数字の列
16進整数
\x16進数字の列
二重引用符"及び疑問符?は,それ自身ででも逆斜線表記\",\?ででも表現可能とするが,一重引用符'
及び逆斜線\はそれぞれ逆斜線表記\'及び逆斜線表記\\で表現しなければならない。
8進逆斜線表記の中の逆斜線に続く8進数字の列は,単純文字定数に対する単一の文字,又はワイド文
字定数に対する単一のワイド文字を構成する役割を果たす。8進整数の数値が,その文字又はワイド文字
の値を規定する。
16進逆斜線表記の中の逆斜線及び英字xに続く16進数字の列は,単純文字定数に対する単一の文字,
又はワイド文字定数に対する単一のワイド文字を構成する役割を果たす。16進整数の数値が,その文字又
はワイド文字の値を規定する。
8進逆斜線表記又は16進逆斜線表記は,逆斜線表記を構成できる最も長い文字の並びとする。
さらに,基本文字集合にない文字は,国際文字名によって表現可能とする。そして,特定の非図形文字
は,逆斜線\及びそれに続く英小文字で構成する逆斜線表記\a,\b,\f,\n,\r,\t及び\vによって表
現可能とする(64)。
制約 8進逆斜線表記又は16進逆斜線表記の値は,単純文字定数に対してはunsigned char型,ワイ
ド文字定数に対してはwchar̲t型に対応する符号無し整数型で表現可能な値の範囲内になければならな
い。
意味規則 単純文字定数は,型intをもつ。1バイトの実行文字に対応する単一の文字を含む単純文字定
数の値は,対応付けた文字の表現を整数として解釈した数値とする。2文字以上を含む(例えば'ab')又
は1バイトの実行文字で表現できない文字若しくは逆斜線表記を含む単純文字定数の値は,処理系定義と
する。単純文字定数が単一の文字又は逆斜線表記を含む場合,その値はその単一の文字又は逆斜線表記の
値をもつchar型のオブジェクトをint型に変換したときの結果の値とする。
ワイド文字定数は,型wchar̲t(ヘッダ<stddef.h>の中で定義される整数型)をもつ。実行拡張文字
集合の一つの文字に対応する単一の多バイト文字を含むワイド文字定数の値は,その多バイト文字に対応
するワイド文字とする。その対応は,処理系定義のその時点のロケールにおけるmbtowc関数によって定
義する。2文字以上の多バイト文字を含む又は実行拡張文字集合で表現できない多バイト文字若しくは逆
斜線表記を含むワイド文字定数の値は,処理系定義とする。
例1. 普通,ナル文字を表すために表現'\0'を使う。
例2. 整数に対し2の補数表現を用い,型charをもつオブジェクトに対して8ビットを用いる処理
系を考える。型charがsigned charと同じ範囲の値をもつ処理系では,単純文字定数
'\xFF'は値−1をもつ。型charがunsigned charと同じ範囲の値をもつ場合,文字定数
───────────────────────────────────────────────
(64)
これらの文字の意味は,5.2.2で規定している。他の文字が逆斜線の後に続く場合,その結果は字句
ではなく,診断メッセージの出力を必要とする。“今後の言語の方針”(6.11.4)参照。
45
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
'\xFF'は値+255をもつ。
例3. たとえ,型charをもつオブジェクトに対して8ビットを用いる場合でも,16進逆斜線表記は
非16進文字によってだけ終了するので,表現'\x123'はただ1文字を含む単純文字定数を示
す。値が'\x12'及び値'3'である二つの文字を含む単純文字定数を指定するためには,8進逆
斜線表記は三つの8進数字の後で終了するので,表現'\0223'を用いればよい。(この二つの
文字から成る単純文字定数の値は,処理系定義である。)
例4. たとえ,型wchar̲tをもつオブジェクトに対して12ビット以上を用いる場合でも,表現
L'\1234'は,値0123と値'4'の組合せから得られる処理系定義の値を指定する。
前方参照 mbtowc関数(7.20.7.2),共通の定義<stddef.h>(7.17)
6.4.5
文字列リテラル
構文規則
文字列リテラル:
" s文字列opt "
L" s文字列opt "
s文字列:
s文字
s文字列 s文字
s文字:
二重引用符",逆斜線\及び改行文字を除くソース文字集合中の任意の要素
逆斜線表記
補足説明 単純文字列リテラル(character string literal)は,二重引用符で囲まれた0個以上の多バイト文
字の並びとする(例えば"xyz"。)。ワイド文字列リテラル(wide string literal)は,文字Lという接頭語を
もつことを除いて,単純文字列リテラルと同一とする。
文字列リテラル中では,一重引用符'はそれ自身ででも逆斜線表記\'ででも表現可能とするが,二重引
用符は逆斜線表記\"で表現しなければならない。このことを除けば,単純文字列リテラル又はワイド文字
列リテラル中の各要素に対して,その要素が単純文字定数又はワイド文字定数の中にあるとみなした場合
と同じ規則に従った考え方を適用する。
意味規則 翻訳フェーズ(6)において,隣り合う単純文字列リテラル字句又はワイド文字列リテラル字句
で指定される多バイト文字の並びは,連結して一つの多バイト文字の並びになる。字句のいずれかがワイ
ド文字列リテラルである場合,結果として生じる多バイト文字の並びは,ワイド文字列リテラルとして扱
う。それ以外の場合,それは単純文字列リテラルとして扱う。
翻訳フェーズ(7)において,文字列リテラル又はその並びから得られる多バイト文字の並びの最後に値
0のバイト又はコードを付加する(65)。結果の多バイト文字の並びは,静的記憶域期間をもち,かつその並
びを含むのにちょうど十分な長さの配列を初期化するのに用いる。単純文字列リテラルの場合,配列の要
素は型charをもち,多バイト文字の並びの個々のバイトで初期化する。ワイド文字列リテラルの場合,
───────────────────────────────────────────────
(65)
一つの単純文字列リテラルが,一つの文字列(7.1.1参照)になるとは限らない。なぜなら,ナル文
字を\0逆斜線表記によってリテラルに埋め込んでもよいからである。
46
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
配列の要素は型wchar̲tをもち,多バイト文字の並びに対応するワイド文字の並びで初期化する。その
対応は,処理系定義のその時点のロケールにおけるmbstowcs関数によって定義する。実行文字集合で表
現できない多バイト文字又は逆斜線表記を含む文字列リテラルの値は,処理系定義とする。
それらの要素が適切な値をもっている場合,これらの配列同士が別個であるかどうかは未規定とする。
プログラムがこれらの配列を変更しようとした場合,その動作は未定義とする。
例 隣り合った単純文字列リテラルの組
"\x12" "3"
は,隣り合う文字列リテラルの連結の前に逆斜線表記が実行文字集合の一つの要素に変換される
ので,値が'\x12'と値'3'の二つの文字を含む一つの単純文字列リテラルを作る。
前方参照 mbstowcs関数(7.20.8.1),共通の定義<stddef.h>(7.17)
6.4.6
区切り子
構文規則
区切り子: 次のいずれか
[ ] ( ) { } . ->
++ -- & * + - ~ !
/ % << >> < > <= >= == != ^ | && ||
? : ; ...
= *= /= %= += -= <<= >>= &= ^= |=
, # ##
<: :> <% %> %: %:%:
意味規則 区切り子は,独立した構文的及び意味的な機能をもつ記号とする。文脈によっては,行うべき
操作(値又は関数指示子を生成する,副作用を引き起こす,又はそれらの組合せ)を指定することもある。
この場合,それを演算子(operator)と呼ぶ(文脈によっては,これ以外の演算子が存在することもある。)。
オペランド(operand)は,演算子が作用する実体とする。
言語のすべての局面において,次の六つの字句は(66),
<: :> <% %> %: %:%:
つづりが違うことだけを除いて(67),次の六つの字句とそれぞれ同じ動作をする。
[ ] { } # ##
前方参照 式(6.5),宣言(6.7),文(6.8),前処理指令(6.10)
6.4.7
ヘッダ名
構文規則
ヘッダ名:
< h文字列 >
" q文字列 "
───────────────────────────────────────────────
(66)
これらの字句を,“2文字表記”と呼ぶ。
(67)
したがって,[及び<:は,“文字列化”(6.10.3.2参照)されるとき異なった動作をするが, そうでな
ければ, 自由に置き換えることができる。
47
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
h文字列:
h文字
h文字列 h文字
h文字:
改行文字及び>を除くソース文字集合中の任意の要素
q文字列:
q文字
q文字列 q文字
q文字:
改行文字及び"を除くソース文字集合中の任意の要素
意味規則 ヘッダ名の両方の形式中の文字列は,処理系定義の方法によってヘッダ又は外部ソースファイ
ルの名前に対応付ける(6.10.2で規定)。
文字',\,",//又は/*が区切り記号<と>の間の文字列中に現れた場合,その動作は未定義とする。同
様に,文字',\,//又は/*が二つの区切り記号"の間の文字列中に現れた場合,その動作は未定義とする
(68)。ヘッダ名前処理字句は,#include前処理指令の中でだけ認識される。
例 次の文字の並び
0x3<1/a.h>1e2
#include <1/a.h>
#define const.member@$
は,次のような前処理字句列を形成する(各前処理字句を{及び}によって区切って示す。)。
{0x3}{<}{1}{/}{a}{.}{h}{>}{1e2}
{#}{include} {<1/a.h>}
{#}{define} {const}{.}{member}{@}{$}
前方参照 ソースファイル取込み(6.10.2)
6.4.8
前処理数
構文規則
前処理数:
数字
. 数字
前処理数 数字
前処理数 識別子用非数字
前処理数 e符号
前処理数 E符号
前処理数 p符号
前処理数 P符号
前処理数 .
───────────────────────────────────────────────
(68)
このように,逆斜線表記に似た文字の並びは,未定義の動作の原因となる。
48
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
補足説明 前処理数は,省略可能な先行するピリオド(.)をもつ数字で始まる。その後ろに正しい識別
子用文字及び文字の並びe+,e-,E+,E-,p+,p-,P+又はP-が続いてもよい。
前処理数字句は,字句的にすべての浮動小数点定数字句及び整数定数字句を含む。
意味規則 前処理数は,型も値ももたない。型と値は,[翻訳フェーズ(7)で]浮動小数点定数字句又は
整数定数字句に変換された結果として決まる。
6.4.9
注釈 文字定数,文字列リテラル又は注釈の中を除いて,文字の並び/*は注釈の始まりを示す。
注釈の内容は,多バイト文字を識別すること及び注釈を終了させる文字の並び*/を捜すことだけのために
調べる(69)。
文字定数,文字列リテラル又は注釈の中を除いて,文字の並び//は注釈の始まりを示す。この形式の注
釈は,次の改行文字までのすべての多バイト文字を含むが,改行文字自身は含まない。注釈の内容は,多
バイト文字を識別すること及び注釈を終了させる改行文字を捜すことだけのために調べる。
例
"a//b"
// 4文字の文字列リテラル
#include "//e"
// 未定義の動作
// */
// 構文エラーではなく,注釈
f = g/**//h;
// f = g / h;と等しい
//\
i();
// 2行にまたがる注釈の部分
/\
/ j();
// 2行にまたがる注釈の部分
#define glue(x,y) x##y
glue(/,/) k();
// 注釈ではなく,構文エラー
/*//*/ l();
// l();と等しい
m = n//**/o
+ p;
// m = n + p;と等しい
6.5
式 式(expression)は,演算子及びオペランドの列とする。式は,値の計算を指定するか,オブジ
ェクト若しくは関数を指し示すか,副作用を引き起こすか,又はそれらの組合せを行う。
直前の副作用完了点から次の副作用完了点までの間に,式の評価によって一つのオブジェクトに格納さ
れた値を変更する回数は,高々1回でなければならない。さらに,変更前の値の読取りは,格納される値
を決定するためだけに行われなければならない(70)。
───────────────────────────────────────────────
(69)
したがって,注釈/* ... */の入れ子はない。
(70)
この段落の規定によると,
i = i + 1;
a[i] = i;
は許されるが,
i = ++i + 1;
a[i++] = i;
は,未定義の式文である。
49
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
演算子とオペランドのグループ分けを6.5.1〜6.5.17の構文規則で示す(71)。(関数呼出しの(),&&,||,?:
及びコンマ演算子に対して)後で規定する場合を除いて,部分式の評価順序及び副作用が生じる順序は未
規定とする。
幾つかの演算子[総称してビット単位の演算子(bitwise operator)と呼ぶ単項演算子~並びに2項演算子
<<,>>,&,^及び|]は,整数型のオペランドを必要とする。これらの演算子は,整数の内部表現に依存
した値を返すので,符号付き整数型に対して処理系定義又は未定義の側面をもつ。
式の評価中に例外条件(exceptional condition)が発生した場合(すなわち,結果が数学的に定義できな
いか,又は結果の型で表現可能な値の範囲にない場合),その動作は未定義とする。
格納された値にアクセスするときのオブジェクトの有効型(effective type)は,(もしあれば)そのオブ
ジェクトの宣言された型とする(72)。宣言された型をもたないオブジェクトへ,文字型以外の型をもつ左辺
値を通じて値を格納した場合,左辺値の型をそのアクセス及び格納された値を変更しないそれ以降のアク
セスでのオブジェクトの有効型とする。宣言された型をもたないオブジェクトに,memcpy関数若しくは
memmove関数を用いて値をコピーするか,又は文字型の配列として値をコピーした場合,そのアクセス及
び値を変更しないそれ以降のアクセスでのオブジェクトの有効型は,値のコピー元となったオブジェクト
の有効型があれば,その型とする。宣言された型をもたないオブジェクトに対するその他のすべてのアク
セスでは,そのアクセスでの左辺値の型を有効型とする。
オブジェクトに格納された値に対するアクセスは,次のうちのいずれか一つの型をもつ左辺値によらな
ければならない(73)。
− オブジェクトの有効型と適合する型
− オブジェクトの有効型と適合する型の修飾版
− オブジェクトの有効型に対応する符号付き型又は符号無し型
− オブジェクトの有効型の修飾版に対応する符号付き型又は符号無し型
− メンバの中に上に列挙した型の一つを含む集成体型又は共用体型(再帰的に包含されている部分集成
体又は含まれる共用体のメンバを含む。)
− 文字型
浮動小数点型の式は短縮(contract)してもよい。すなわち,ハードウェアによる不可分な操作として評
───────────────────────────────────────────────
(71)
構文は,式の評価における演算子の優先順位を指定する。それは6.5の箇条の順序と同じであり,
最初の箇条が最も高い優先順位をもつ。したがって,例えば2項+演算子(6.5.6)のオペランドと
して許される式は,6.5.1〜6.5.6で定義された式である。例外は,オペランドとしてキャスト式(6.5.4)
をもってよい単項演算子(6.5.3)及び次に示す対の演算子で囲まれたオペランドである。すなわち,
グループ分けの括弧()(6.5.1),添字付けの角括弧[](6.5.2.1),関数呼出しの括弧()(6.5.2.2)及
び条件演算子?:(6.5.15)。
各箇条の中では,演算子は同じ優先順位をもつ。左結合であるか右結合であるかは,各箇条で述
べる式の構文によって示す。
(72)
割付けオブジェクトは宣言された型をもたない。
(73)
この列挙は,オブジェクトに別名を付けてもよい状況と,付けてはならない状況を規定するための
ものである。
50
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
価して,ソースコードの記述及び式の評価方法どおりなら生じるはずの丸め誤差を省いてもよい(74)。
<math.h>のFP̲CONTRACTプラグマは,式の短縮を禁止する方法を提供する。FP̲CONTRACTプラグマ
がない場合,式が短縮されるかどうか,及びそれをどのように短縮するかは処理系定義とする(75)。
前方参照 FP̲CONTRACTプラグマ(7.12.2),コピー関数(7.21.2)
6.5.1
一次式
構文規則
一次式:
識別子
定数
文字列リテラル
( 式 )
意味規則 識別子がオブジェクト(この場合,識別子は左辺値となる。),又は関数(この場合,関数指示
子となる。)を指し示すと宣言されている場合,識別子は一次式とする(76)。
定数は,一次式とする。その型は,その形式と値によって決まる(6.4.4で規定する。)。
文字列リテラルは,一次式とする。それは,6.4.5の規則で決まる型をもつ左辺値とする。
括弧で囲まれた式は,一次式とする。その型及び値は,括弧の中の式のそれらと同じとする。括弧の中
の式が左辺値,関数指示子又はボイド式である場合,それは,それぞれ左辺値,関数指示子又はボイド式
とする。
前方参照 宣言(6.7)
6.5.2
後置演算子
構文規則
後置式:
一次式
後置式 [ 式 ]
後置式 ( 実引数式並びopt )
後置式 . 識別子
後置式 -> 識別子
後置式 ++
後置式 --
( 型名 ) { 初期化子並び }
( 型名 ) { 初期化子並び , }
───────────────────────────────────────────────
(74)
短縮式では浮動小数点例外の発生を省略してもよい。
(75)
これは複数のCの演算子を結合させた高速な計算機命令の使用を許可することを明確に意図してい
る。式の短縮は,予測可能性を損なうおそれがあり,計算結果の正確さを低下させるおそれすらあ
る。したがって,短縮式を処理系が使用するに当たっては,仕様をよく定義し,明確に文書化する
必要がある。
(76)
したがって,宣言されていない識別子は構文規則違反である。
51
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
実引数式並び:
代入式
実引数式並び , 代入式
6.5.2.1
配列の添字付け
制約 式の一方は,型“オブジェクト型〜型へのポインタ”をもたなければならない。もう一方の式は,
整数型をもたなければならない。結果は,型“〜型”をもつ。
意味規則 角括弧[]に囲まれた式を後ろに伴う後置式は,配列オブジェクトの要素の添字による指定とす
る。添字演算子[]は,E1[E2]が(*((E1)+(E2)))と等価であると定義する。2項+演算子に適用する型
変換の規則によって,E1が配列オブジェクト(又は,配列オブジェクトの先頭要素へのポインタ)であり,
E2が整数である場合,E1[E2]はE1のE2番目(0から数える。)の要素を指し示す。
連続した添字演算子は,多次元配列の要素を指し示す。Eが次元i×j×...×kをもつn次元配列(n≧2)
である場合,E(左辺値以外として用いた場合。)は,次元j×...×kをもつ(n−1)次元配列へのポインタ
に型変換する。単項*演算子をこのポインタに明示的に適用するか,又は暗黙に添字付けの結果として適
用する場合,その結果は,指されている(n−1)次元配列となり,それ自身を左辺値以外として用いる場
合,ポインタに型変換する。このことから,配列は,行優先の順序(最後の添字が最も速く変わる。)で格
納する。
例 次の宣言で定義された配列オブジェクトを考える。
int x[3][5];
ここでxは,intの3×5の配列である。より正確には,xは三つの要素オブジェクトの配列であ
り,その各要素は,五つのintの配列である。式x[i]は(*((x)+(i)))と等価であり,xをま
ず五つのintの配列の最初の一つへのポインタに型変換する。次にiを,xの型に対応するよう
に調整する。このことは,概念的にはポインタが指すオブジェクト,すなわち五つのintオブジ
ェクトの配列の大きさをiに乗じることを伴っている。これらの結果を加えて,間接演算を適用
することによって,五つのintの配列を生じる。式x[i][j]中で用いられると,その配列は先
頭のintへのポインタに型変換され,その結果,x[i][j]はintを生じる。
前方参照 アドレス及び間接演算子(6.5.3.2),加減演算子(6.5.6),配列宣言子(6.7.5.2)
6.5.2.2
関数呼出し
制約 呼び出される関数を表す式(77)は,voidを返す関数へのポインタ型,又は配列型以外のオブジェク
ト型を返す関数へのポインタ型をもたなければならない。
呼び出される関数を表す式が関数原型を含む型をもつ場合,実引数の個数は,仮引数の個数と一致しな
ければならない。各実引数は,対応する仮引数の型の非修飾版をもつオブジェクトにその値を代入するこ
とのできる型をもたなければならない。
意味規則 コンマで区切られた式の並び(空であってもよい。)を囲む括弧()を後ろに伴う後置式は,関
数呼出しとする。後置式は呼び出される関数を表す。式の並びは,関数への実引数を指定する。
実引数は,任意のオブジェクト型の式でよい。関数呼出しの準備の段階で,実引数を評価し,各実引数
───────────────────────────────────────────────
(77)
たいてい,これは関数指示子である識別子を型変換した結果である。
52
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
の値を対応する仮引数に代入する(78)。
呼び出される関数を表す式が,オブジェクト型を返す関数へのポインタ型をもつ場合,関数呼出し式は
そのオブジェクト型と同じ型をもち,その値は6.8.6.4で規定するとおりに決まる。そうでない場合,関数
呼出しは型voidをもつ。関数呼出しの結果を変更しようとした場合,又は次の副作用完了点の後にアク
セスしようとした場合,その動作は未定義とする。
呼び出される関数を表す式が,関数原型を含まない型をもつ場合,各実引数に対して整数拡張を行い,
型floatをもつ実引数は型doubleに拡張する。この操作を既定の実引数拡張(default argument promotion)
と呼ぶ。実引数の個数と仮引数の個数が等しくない場合,その動作は未定義とする。関数原型を含む型で
関数を定義し,かつ,関数原型が省略記号(, ...)で終わっている場合,又は拡張後の実引数の型が,
仮引数の型と適合しない場合,その動作は未定義とする。関数原型を含まない型で関数を定義し,かつ拡
張後の実引数の型が,拡張後の仮引数の型と適合しない場合,その動作は未定義とする。ただし,次の場
合は除く。
− 拡張された型の一方が符号付き整数型で,他方が対応する符号無し整数型であり,かつ値がいずれの
型でも表現可能な場合。
− いずれの型も文字型又はvoidの修飾版又は非修飾版へのポインタである場合。
呼び出される関数を表す式が関数原型を含む型をもつ場合,実引数は代入と同じ規則で,対応する仮引
数の型に暗黙に変換する。このとき各仮引数の型は,宣言した型の非修飾版とする。関数原型宣言子にお
ける省略記号表記は,最後に宣言されている仮引数の直後から実引数の型変換を止める。残りの実引数に
対しては,既定の実引数拡張を行う。
これら以外の型変換は,暗黙には行わない。特に,実引数の個数及び型を関数原型宣言子を含まない関
数定義中の仮引数の個数及び型と比較することはない。
呼び出される関数を表す式によって指される式の型が関数が定義された型と適合しない場合,その動作
は,未定義とする。
関数指示子,実引数及び実引数内の部分式の評価順序は未規定とするが,実際に呼出しが行われる前に
副作用完了点がある。
直接にも,他の関数の連鎖を通じて間接的にも,再帰関数呼出しが許される。
例 次の関数呼出しにおいて
(*pf[f1()]) (f2(), f3() + f4())
関数f1,f2,f3及びf4は,任意の順序で呼んでもよい。すべての副作用は,pf[f1()]が指
す関数が呼ばれる前に完了していなければならない。
前方参照 return文(6.8.6.4),関数宣言子(関数原型を含む)(6.7.5.3),関数定義(6.9.1),単純代入
(6.5.16.1)
6.5.2.3
構造体及び共用体のメンバ
制約 .演算子の最初のオペランドは,構造体型又は共用体型の修飾版又は非修飾版をもたなければなら
───────────────────────────────────────────────
(78)
関数は,その仮引数の値を変更してもよいが,これらの変更が実引数の値に影響を与えることはで
きない。一方,オブジェクトへのポインタを渡すことは可能であり,関数はそれによって指される
オブジェクトの値を変更してもよい。配列型又は関数型をもつと宣言された仮引数は,ポインタ型
をもつように型調整される(6.9.1で規定する。)。
53
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ず,2番目のオペランドは,その型のメンバの名前でなければならない。
->演算子の最初のオペランドは,型“構造体の修飾版若しくは非修飾版へのポインタ”,又は型“共用
体の修飾版若しくは非修飾版へのポインタ”をもたなければならず,2番目のオペランドは,指される型
のメンバの名前でなければならない。
意味規則 .演算子及び識別子を後ろに伴う後置式は,構造体又は共用体オブジェクトの一つのメンバを
指し示す。その値は,指定されたメンバの値とする。最初の式が左辺値の場合,その式は,左辺値とする。
最初の式が修飾型をもつ場合,結果の型は,指定されたメンバの型に同じ修飾を加えた型とする。
->演算子及び識別子を後ろに伴う後置式は,構造体又は共用体オブジェクトの一つのメンバを指し示す。
その値は,最初の式が指すオブジェクトの指定されたメンバの値とする。その式は左辺値とする(79)。最初
の式の型が修飾型へのポインタである場合,結果の型は,指定されたメンバの型に同じ修飾を加えた型と
する。
共用体の使用を簡単にするため,次の保証をする。すなわち,共用体が同一の先頭のメンバの並びをも
つ幾つかの構造体を含み,共用体オブジェクトがそれらの構造体のいずれか一つを保持している場合,そ
の共用体の完全型の宣言が可視である場所ならばどこでも,いずれの構造体の同一の先頭のメンバの並び
の部分を参照してもよい。先頭から一つ以上のメンバの並びに対して,対応するメンバが適合する型(か
つ,ビットフィールドに対しては,同じ幅)をもつ場合,二つの構造体は,同一の先頭のメンバの並び
(common initial sequence)をもつという。
例1. fが構造体又は共用体を返す関数で,xがその構造体又は共用体のメンバである場合,f().x
は正しい後置式である。しかし,左辺値ではない。
例2. 次のプログラム例では,
struct s { int i; const int ci; };
struct s s;
const struct s cs;
volatile struct s vs;
各々のメンバは次の型をもつ。
s.i
int
s.ci
const int
cs.i
const int
cs.ci const int
vs.i
volatile int
vs.ci volatile const int
例3. 次の例は,正しいプログラム片である。
union {
struct {
int alltypes;
} n;
───────────────────────────────────────────────
(79)
&Eが正しいポインタ式(ここで,&は“〜のアドレス”演算子であり,そのオペランドへのポイン
タを生成する。)の場合,式(&E)->MOSは,E.MOSと同じである。
54
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
struct {
int type;
int intnode;
} ni;
struct {
int type;
double doublenode;
} nf;
} u;
u.nf.type = 1;
u.nf.doublenode = 3.14;
/* ... */
if (u.n.alltypes == 1)
if (sin(u.nf.doublenode) == 0.0)
/* ... */
次の例は正しくないプログラム片である(共用体型が関数fの中で可視ではないから。)。
struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 * p1, struct t2 * p2)
{
if (p1->m < 0)
p2->m = -p2->m;
return p1->m;
}
int g()
{
union {
struct t1 s1;
struct t2 s2;
} u;
/* ... */
return f(&u.s1, &u.s2);
}
前方参照 アドレス及び間接演算子(6.5.3.2),構造体指定子及び共用体指定子(6.7.2.1)
6.5.2.4
後置増分及び後置減分演算子
制約 後置増分演算子又は後置減分演算子のオペランドは,実数型又はポインタ型の修飾版又は非修飾版
をもたなければならず,変更可能な左辺値でなければならない。
意味規則 後置++演算子の結果は,そのオペランドの値とする。結果を取り出した後,オペランドの値を
増分する(すなわち,適切な型の値1をそれに加える。)。制約,型,並びにポインタに対する型変換及び
演算の効果については,加減演算子及び複合代入の規定のとおりとする。オペランドに格納されている値
55
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
を更新する副作用は,直前の副作用完了点から次の副作用完了点までの間に起こらなければならない。
後置--演算子は,オペランドの値を減分する(すなわち,適切な型の値1をそれから引く)点を除いて,
後置++演算子と同一とする。
前方参照 加減演算子(6.5.6),複合代入(6.5.16.2)
6.5.2.5
複合リテラル
制約 型名はオブジェクト型又は大きさの分からない配列を指定しなければならないが,可変長配列型を
指定してはならない。
複合リテラルが指定する名前のないオブジェクトに含まれないオブジェクトに,初期化子で値を与えて
はならない。
複合リテラルが関数本体の外に出現した場合,初期化子並びに含まれる式はすべて定数式でなければな
らない。
意味規則 括弧で囲まれた型名とそれに続く波括弧で囲まれた初期化子の並びで構成される後置式を複合
リテラル(compound literal)と呼ぶ。複合リテラルは,初期化子並びで与えられる値をもつ名前のないオ
ブジェクトを与える(80)。
型名が大きさの分からない配列を指定している場合,6.7.8で規定するとおりに初期化子の並びによって
大きさが決まる。さらに,この場合の複合リテラルの型は完全にされた配列型とする。そうでない場合(型
名がオブジェクト型を指定する場合),複合リテラルの型は型名で指定されたものとする。いずれの場合も
結果は左辺値とする。
複合リテラルの値は,初期化子並びで初期化された名前のないオブジェクトの値とする。複合リテラル
が関数本体の外側に出現した場合,オブジェクトは静的記憶域期間をもつ。そうでない場合,それを囲む
ブロックに結び付けられた自動記憶域期間をもつ。
6.7.8で規定する初期化子並びのすべての意味規則及び制約を複合リテラルにも適用する(81)。
文字列リテラルとconst修飾型の複合リテラルは,同じオブジェクトを指し示してもよい(82)。
例1. ファイル有効範囲での定義
int *p = (int []){2, 4};
は,二つのintをもつ配列の最初の要素を指すようにpを初期化する。最初の要素は値2をも
ち,2番目の要素は値4をもつ。この複合リテラル中の式は定数でなければならない。この複
合リテラルによって生成される名前のないオブジェクトは静的記憶域期間をもつ。
例2. 対照的に次のプログラムでは,
void f(void)
{
int *p;
/* ... */
───────────────────────────────────────────────
(80)
これはキャスト式とは異なる。例えば,キャストはスカラ型かvoid型への変換しか指示できない。
また,キャスト式の結果は左辺値とはなり得ない。
(81)
例えば,明示的な初期化子をもたない部分オブジェクトは0に初期化される。
(82)
このことは,文字列リテラルとconst修飾型の複合リテラルが同じか重なり合った記憶域をもつよ
うな実装を許している。
56
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
p = (int [2]){*p};
/* ... */
}
pには二つのintをもつ配列の最初の要素のアドレスが代入される。最初の要素はpが直前に
指していた値をもち,2番目の要素は値0をもつ。この複合リテラル中の式は,定数である必
要はない。この複合リテラルによって生成される名前のないオブジェクトは自動記憶域期間を
もつ。
例3. 指示付きの初期化子を複合リテラルと組み合わせることができる。複合リテラルを用いて生成
された構造体オブジェクトは,メンバの順番に依存することなく,関数に渡すことができる。
drawline((struct point){.x=1, .y=1},
(struct point){.x=3, .y=4});
又はdrawlineが構造体pointへのポインタを期待している場合は,次のように書く。
drawline(&(struct point){.x=1, .y=1},
&(struct point){.x=3, .y=4});
例4. 読取り専用の複合リテラルは次のように書くことができる。
(const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6}
例5. 次の三つの式は異なる意味をもつ。
"/tmp/fileXXXXXX"
(char []){"/tmp/fileXXXXXX"}
(const char []){"/tmp/fileXXXXXX"}
最初の式は,常に静的記憶域期間をもち,charの配列という型をもつが,変更可能である必
要はない。後の二つの式は関数本体の内部に出現した場合,自動記憶域期間をもち,最初から
2番目の式は変更可能である。
例6. 文字列リテラルと同様に,const修飾型の複合リテラルは読取り専用記憶域に格納でき,共有す
ることもできる。例えば,
(const char []){"abc"} == "abc"
はリテラルの記憶域が共有されていれば,結果として1となりうる。
例7. 複合リテラルは名前がないので,単一の複合リテラルで循環するオブジェクトを指定すること
はできない。例えば,次に示す名前付けられたオブジェクトendless̲zerosの代わりに,関
数実引数として使うことができる自己参照する複合リテラルをプログラムで書く方法はない。
struct int̲list { int car; struct int̲list *cdr; };
struct int̲list endless̲zeros = {0, &endless̲zeros};
eval(endless̲zeros);
例8. 各複合リテラルは,その有効範囲においてオブジェクトを一つしか生成しない。
struct s { int i; };
int f (void)
{
struct s *p = 0, *q;
int j = 0;
57
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
again:
q = p, p = &((struct s){ j++ });
if (j < 2) goto again;
return p == q && q->i == 1;
}
関数f()は常に値1を返す。
明示的なgoto文及びラベル付き文の代わりに繰返し文が使われた場合,名前のないオブジ
ェクトの生存期間はループ本体だけとなる。ループの次の繰返しの入り口では,pは不定な値
をもち,結果として動作は未定義となる。
前方参照 型名(6.7.6),初期化(6.7.8)
6.5.3
単項演算子
構文規則
単項式:
後置式
++ 単項式
-- 単項式
単項演算子 キャスト式
sizeof 単項式
sizeof ( 型名 )
単項演算子:次のいずれか
& * + - ~ !
6.5.3.1
前置増分及び前置減分演算子
制約 前置増分演算子又は前置減分演算子のオペランドは,実数型又はポインタ型の修飾版又は非修飾版
をもたなければならず,変更可能な左辺値でなければならない。
意味規則 前置++演算子はオペランドの値を増分する。その結果は,増分された後のオペランドの新しい
値とする。式++Eは,(E+=1)と等価とする。制約,型,副作用,並びにポインタに対する型変換及び演
算の効果については,加減演算子及び複合代入の規定のとおりとする。前置--演算子は,オペランドの値
を減分する点を除いて,前置++演算子と同一とする。
前方参照 加減演算子(6.5.6),複合代入(6.5.16.2)
6.5.3.2
アドレス及び間接演算子
制約 単項&演算子のオペランドは,関数指示子,[]演算子若しくは単項*演算子の結果,又は左辺値でな
ければならない。左辺値の場合,ビットフィールドでもなく,register記憶域クラス指定子付きで宣言
されてもいないオブジェクトを指し示さなければならない。
単項*演算子のオペランドは,ポインタ型をもたなければならない。
意味規則 単項&演算子は,そのオペランドのアドレスを返す。オペランドが型“〜型”をもっている場
合,結果は,型“〜型へのポインタ”をもつ。オペランドが,単項*演算子の結果の場合,*演算子も&演
算子も評価せず,両演算子とも取り除いた場合と同じ結果となる。ただし,その場合でも演算子に対する
制約を適用し,結果は左辺値とならない。同様に,オペランドが[]演算子の結果の場合,単項&演算子と,
58
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
[]演算子が暗黙に意味する単項*演算子は評価されず,&演算子を削除し[]演算子を+演算子に変更した場
合と同じ結果となる。これら以外の場合,結果はそのオペランドが指し示すオブジェクト又は関数へのポ
インタとなる。
単項*演算子は,間接参照を表す。オペランドが関数を指している場合,その結果は関数指示子とする。
オペランドがオブジェクトを指している場合,その結果はそのオブジェクトを指し示す左辺値とする。オ
ペランドが型“〜型へのポインタ”をもつ場合,その結果は型“〜型”をもつ。正しくない値がポインタ
に代入されている場合,単項*演算子の動作は,未定義とする(83)。
前方参照 記憶域クラス指定子(6.7.1),構造体指定子及び共用体指定子(6.7.2.1)
6.5.3.3
単項算術演算子
制約 単項+演算子及び単項-演算子のオペランドは,算術型をもたなければならない。~演算子のオペラ
ンドは,整数型をもたなければならない。!演算子のオペランドは,スカラ型をもたなければならない。
意味規則 単項+演算子の結果は,その(拡張された)オペランドの値とする。オペランドに対して整数
拡張を行い,その結果は,拡張された型をもつ。
単項-演算子の結果は,その(拡張された)オペランドの符号を反転した値とする。オペランドに対し
て整数拡張を行い,その結果は,拡張された型をもつ。
~演算子の結果は,その(拡張された)オペランドのビット単位の補数とする(すなわち,結果の各ビ
ットは,拡張されたオペランドの対応するビットがセットされていない場合,そしてその場合に限り,セ
ットされる。)。オペランドに対して整数拡張を行い,その結果は,拡張された型をもつ。拡張された型が
符号無し整数型である場合,~Eはその型で表現可能な最大値からEを減算した値と等価とする。
論理否定演算子!の結果は,そのオペランドの値が0と比較して等しくない場合0とし,等しい場合1
とする。結果の型は,intとする。式!Eは,(0==E)と等価とする。
6.5.3.4
sizeof演算子
制約 sizeof演算子は,関数型若しくは不完全型をもつ式,それらの型の名前を括弧で囲んだもの,又
はビットフィールドメンバを指し示す式に対して適用してはならない。
意味規則 sizeof演算子の結果は,そのオペランドの大きさ(バイト数)とする。オペランドは,式,
又は括弧で囲まれた型の名前のいずれかとする。その大きさは,オペランドの型によって決定する。結果
は,整数とする。オペランドの型が可変長配列型である場合,オペランドを評価する。そうでない場合,
オペランドは評価せず,その結果は,整数定数とする。
型char,unsigned char若しくはsigned char(又はそれらの修飾版)をもつオペランドに適用
した場合の結果は,1とする。配列型をもつオペランドに適用した場合の結果は,その配列中の総バイト
───────────────────────────────────────────────
(83)
&*EはEと等価であり(Eが空ポインタであっても),&(E1[E2])は((E1)+(E2))と等価である。
Eが単項&演算子の正しいオペランドとなる関数指示子又は左辺値の場合,*&EはEに等しい関数
指示子又は左辺値である。*Pが左辺値であり,かつTがオブジェクトポインタ型の名前である場
合,キャストを含む式*(T)Pは,Tが指すものと適合する型をもつ左辺値である。
単項*演算子によるポインタ参照をする場合の正しくない値には,空ポインタ,指されるオブジ
ェクトの型に対して正しく境界調整されていないアドレス,そしてその生存期間が終了してしまっ
ているオブジェクトのアドレスなどがある。
59
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
数とする(84)。構造体型又は共用体型をもつオペランドに適用した場合の結果は,内部及び末尾の詰め物部
分を含めたオブジェクトの総バイト数とする。
結果の値は,処理系定義とする。その型(符号無し整数型)は,ヘッダ<stddef.h>(及び,その他の
ヘッダ)で定義されるsize̲tとする。
例1. sizeof演算子の主な用途は,記憶域割付け及び入出力システムといったルーチンとのやりと
りにある。記憶域割付け関数は,記憶域を割り付けるオブジェクトの大きさ(バイト数)を受
け取り,voidへのポインタを返すであろう。例えば,次のとおりである。
extern void *alloc(size̲t);
double *dp = alloc(sizeof *dp);
alloc関数の実装は,alloc関数の返却値がdoubleを指すポインタに型変換できるように,
適切に境界調整されていることを保証しなければならない。
例2. sizeof演算子のもう一つの用途は,次のようにして配列の要素の個数を求めることである。
sizeof array / sizeof array[0]
例3. この例では,可変長配列型の大きさを計算し,関数から返している。
#include <stddef.h>
size̲t fsize3(int n)
{
char b[n+3];
// 可変長配列
return sizeof b;
// 実行時に決まるsizeof
}
int main()
{
size̲t size;
size = fsize3(10);
// fsize3は13を返す
return 0;
}
前方参照 型名(6.7.6),共通の定義<stddef.h>(7.17),構造体指定子及び共用体指定子(6.7.2.1),宣
言(6.7),配列宣言子(6.7.5.2)
6.5.4
キャスト演算子
構文規則
キャスト式:
単項式
( 型名 ) キャスト式
制約 型名がvoid型を指定する場合を除いて,型名はスカラ型の修飾版又は非修飾版を指定しなければ
───────────────────────────────────────────────
(84)
配列型又は関数型をもつと宣言された仮引数に適用する場合,sizeof演算子は,型調整された(ポ
インタ)型の大きさを与える(6.9.1参照)。
60
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ならず,オペランドは,スカラ型をもたなければならない。
6.5.16.1の制約で許されるものを除いた,ポインタを含む型変換は,明示的なキャストで指定しなければ
ならない。
意味規則 括弧で囲まれた型名に続く式は,式の値を指定された型に型変換する。この構文をキャスト
(cast)と呼ぶ(85)。型変換を指定しないキャストは,式の型又は値に対して何の効果ももたない(86)。
前方参照 型名(6.7.6),関数宣言子(関数原型を含む)(6.7.5.3),単純代入(6.5.16.1),等価演算子(6.5.9)
6.5.5
乗除演算子
構文規則
乗除式:
キャスト式
乗除式 * キャスト式
乗除式 / キャスト式
乗除式 % キャスト式
制約 各オペランドは,算術型をもたなければならない。%演算子のオペランドは,整数型をもたなけれ
ばならない。
意味規則 通常の算術型変換をオペランドに適用する。
2項*演算子の結果は,オペランドの積とする。
/演算子の結果は,第1オペランドを第2オペランドで除した商とし,%演算子の結果は剰余とする。両
演算子とも,第2オペランドの値が0の場合,その動作は未定義とする。
整数同士の除算の場合,/演算子の結果は,代数的な商から小数部を切り捨てた値とする(87)。商a/bが
表現できる場合,式(a/b)*b+a%bは,aに等しくなければならない。
6.5.6
加減演算子
構文規則
加減式:
乗除式
加減式 + 乗除式
加減式 - 乗除式
制約 加算の場合,両オペランドが算術型をもつか,又は一方のオペランドがオブジェクト型へのポイン
タで,もう一方のオペランドの型が整数型でなければならない。(増分は1の加算に等しい。)
減算の場合,次のいずれかの条件を満たさなければならない。
− 両オペランドが算術型をもつ。
− 両オペランドが適合するオブジェクト型の修飾版又は非修飾版へのポインタである。
───────────────────────────────────────────────
(85)
キャストは左辺値を結果として返さない。したがって,修飾型へのキャストは,その型の非修飾版
へのキャストと同じ効果をもつ。
(86)
式の値が,キャストで指定した型が要求する精度や範囲を超えて表現される場合(6.3.1.8参照),式
の型が指定された型と同じであるとしても,キャストは型変換を指定する。
(87)
これは,“0方向への切捨て”とも呼ぶ。
61
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 左オペランドがオブジェクト型へのポインタで,右オペランドの型が整数型である。(減分は1の減算
に等しい。)
意味規則 両オペランドが算術型をもつ場合,通常の算術型変換をそれらに適用する。
2項+演算子の結果は,両オペランドの和とする。
2項-演算子の結果は,第1オペランドから第2オペランドを引いた結果の差とする。
これらの演算子に関しては,配列の要素でないオブジェクトへのポインタは,要素型としてそのオブジ
ェクトの型をもつ長さ1の配列の最初の要素へのポインタと同じ動作をする。
整数型をもつ式をポインタに加算又はポインタから減算する場合,結果は,ポインタオペランドの型を
もつ。ポインタオペランドが配列オブジェクトの要素を指し,配列が十分に大きい場合,その結果は,そ
の配列の要素を指し,演算結果の要素と元の配列要素の添字の差は,整数式の値に等しい。すなわち,式
Pが配列オブジェクトのi番目の要素を指している場合,式(P)+N(N+(P)と等しい)及び(P)-N(Nは値
nをもつと仮定する。)は,それらが存在するのであれば,それぞれ配列オブジェクトのi+n番目及びi−n
番目の要素を指す。さらに,式Pが配列オブジェクトの最後の要素を指す場合,式(P)+1はその配列オブ
ジェクトの最後の要素を一つ越えたところを指し,式Qが配列オブジェクトの最後の要素を一つ越えたと
ころを指す場合,式(Q)-1はその配列オブジェクトの最後の要素を指す。ポインタオペランド及びその結
果の両方が同じ配列オブジェクトの要素,又は配列オブジェクトの最後の要素を一つ越えたところを指し
ている場合,演算によって,オーバフローを生じてはならない。それ以外の場合,動作は未定義とする。
結果が配列オブジェクトの最後の要素を一つ越えたところを指す場合,評価される単項*演算子のオペラ
ンドとしてはならない。
二つのポインタを減算する場合,その両方のポインタは同じ配列オブジェクトの要素か,その配列オブ
ジェクトの最後の要素を一つ越えたところを指していなければならない。その結果は,二つの配列要素の
添字の差とする。結果の大きさは処理系定義とし,その型(符号付き整数型)は,ヘッダ<stddef.h>で
定義されるptrdiff̲tとする。結果がその型のオブジェクトで表現可能でない場合,その動作は未定義
とする。言い換えれば,式PとQが,それぞれ配列オブジェクトのi番目とj番目の要素を指している場
合,式(P)-(Q)は,それが型ptrdiff̲tのオブジェクトに収まるのであれば,値i−jをもつ。さらに,
式Pが配列オブジェクトの要素,又は配列オブジェクトの最後の要素を一つ越えたところを指していて,
式Qが同じ配列オブジェクトの最後の要素を指している場合,式(Q)+1は,配列オブジェクトの要素を指
していないのだが,式((Q)+1)-(P)は,((Q)-(P))+1及び-((P)-((Q)+1))と同じ値をもち,式Pが
配列オブジェクトの最後の要素を一つ越えたところを指している場合,値0をもつ(88)。
例 ポインタ算術は,可変長配列型へのポインタにも定義される。
───────────────────────────────────────────────
(88)
ポインタ算術のもう一つの説明の方法は,最初にポインタを文字へのポインタに変換する方法であ
る。この考え方では,変換されたポインタに加算されるか,又は変換されたポインタから減算され
る整数式は,最初に本来指していたオブジェクトの大きさで乗算される。加減算の結果,得られる
ポインタは元の型へ逆変換される。同様に,ポインタ同士の減算の場合は,文字へのポインタ間の
差の結果を,本来指していたオブジェクトの大きさによって除算する。
この考え方によって,処理系が“最後の要素を一つ越えたところ”に関する要求を満足するには,
一つだけ余分なバイト(それはそのプログラムの他のオブジェクトに重なってもよい。)をオブジェ
クトの直後に与えれば十分である。
62
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
{
int n = 4, m = 3;
int a[n][m];
int (*p)[m] = a;
// p == &a[0]
p += 1;
// p == &a[1]
(*p)[2] = 99;
// a[1][2] == 99
n = p - a;
// n == 1
}
配列aが既知で一定の大きさをもつ配列として宣言され,ポインタpがaと同じ既知で一定の
大きさをもつ配列へのポインタとして宣言され,aを指している場合,結果はこの例と同じにな
る。
前方参照 共通の定義<stddef.h>(7.17),配列宣言子(6.7.5.2)
6.5.7
ビット単位のシフト演算子
構文規則
シフト式:
加減式
シフト式 << 加減式
シフト式 >> 加減式
制約 各オペランドは,整数型をもたなければならない。
意味規則 整数拡張を各オペランドに適用する。結果の型は,左オペランドを拡張した後の型とする。右
オペランドの値が負であるか,又は拡張した左オペランドの幅以上の場合,その動作は,未定義とする。
E1<<E2の結果は,E1をE2ビット分左にシフトした値とする。空いたビットには0を詰める。E1が符
号無し整数型をもつ場合,結果の値は,E1×2E2の,結果の型で表現可能な最大値より1大きい値を法と
する剰余とする。E1が符号付き整数型と非負の値をもち,E1×2E2が結果の型で表現可能である場合,そ
れが結果の値となる。それ以外の場合,その動作は未定義とする。
E1>>E2の結果は,E1をE2ビット分右にシフトした値とする。E1が符号無し整数型をもつ場合,又は
E1が符号付き整数型と非負の値をもつ場合,結果の値は,E1/2E2の商の整数部分とする。E1が符号付き
整数型と負の値をもつ場合,結果の値は処理系定義とする。
6.5.8
関係演算子
構文規則
関係式:
シフト式
関係式 < シフト式
関係式 > シフト式
関係式 <= シフト式
関係式 >= シフト式
制約 次のいずれかの条件を満たさなければならない。
− 両オペランドが実数型をもつ。
− 両オペランドが適合するオブジェクト型の修飾版又は非修飾版へのポインタである。
63
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 両オペランドが適合する不完全型の修飾版又は非修飾版へのポインタである。
意味規則 両オペランドが算術型をもつ場合,通常の算術型変換を適用する。
関係演算子に関しては,配列の要素でないオブジェクトへのポインタは,要素型としてそのオブジェク
トの型をもつ長さ1の配列の最初の要素へのポインタと同じ動作をする。
二つのポインタを比較する場合,その結果は指されているオブジェクトのアドレス空間内の相対位置に
依存する。オブジェクト型又は不完全型への二つのポインタがいずれも同じオブジェクトを指しているか,
いずれも同じ配列オブジェクトの最後の要素を一つ越えたところを指している場合,それらは比較して等
しいとする。指されている両オブジェクトが同一の集成体オブジェクトのメンバの場合,後方で宣言され
た構造体のメンバへのポインタは,その構造体中で前方に宣言されたメンバへのポインタと比較すると大
きく,大きな添字の値をもつ配列の要素へのポインタは,より小さな添字の値をもつ同じ配列の要素への
ポインタと比較すると大きいとする。同じ共用体オブジェクトのメンバへのポインタは,すべて等しいと
する。式Pが配列オブジェクトの要素を指しており,式Qが同じ配列オブジェクトの最後の要素を指して
いる場合,ポインタ式Q+1は,Pと比較してより大きいとする。その他のすべての場合,動作は未定義と
する。
<(小さい),>(大きい),<=(以下)及び>=(以上)の各演算子は,指定された関係が真の場合は1
を,偽の場合は0を返す(89)。その結果は,型intをもつ。
6.5.9
等価演算子
構文規則
等価式:
関係式
等価式 == 関係式
等価式 != 関係式
制約 次のいずれかの条件を満たさなければならない。
− 両オペランドは算術型をもつ。
− 両オペランドとも適合する型の修飾版又は非修飾版へのポインタである。
− 一方のオペランドがオブジェクト型又は不完全型へのポインタで他方がvoidの修飾版又は非修飾版
へのポインタである。
− 一方のオペランドがポインタで他方が空ポインタ定数である。
意味規則 ==(等しい)及び!=(等しくない)演算子は,関係演算子より優先順位が低いことを除いて関
係演算子と同じとする(90)。各演算子は指定された関係が真の場合は1を,偽の場合は0を返す。その結果
は,型intをもつ。どのようなオペランドの組に対しても,いずれか一方の関係が必ず真となる。
両オペランドが算術型をもつ場合,通常の算術型変換を適用する。複素数型の値は,互いの実部及び虚
部がそれぞれ等しい場合,そしてその場合に限り,等しいとする。異なる型領域に属する二つの算術型の
値は,通常の算術型変換によって決定される(複素数型の)結果の型への変換の結果が等しい場合,そし
───────────────────────────────────────────────
(89)
式a<b<cは,通常の数学的な意味のようには解釈されない。構文が示しているように,(a<b)<c
を意味している。言い換えれば,“aがbより小さい場合は1とcを比較し,それ以外の場合は0
とcを比較する”ということである。
(90)
優先順位から,a<b == c<dは,a<b及びc<dが同じ真理値をもつ場合に1となる。
64
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
てその場合に限り,等しいとする。
そうでない場合,少なくとも一つのオペランドはポインタになる。一方のオペランドがポインタで,も
う一方のオペランドが空ポインタ定数の場合,空ポインタ定数をポインタの型へ型変換する。一方のオペ
ランドがオブジェクト型又は不完全型へのポインタで,もう一方がvoidの修飾版又は非修飾版へのポイ
ンタの場合,前者を後者の型へ型変換する。
二つのポインタは,次のいずれかの場合,そしてその場合に限り,等しいとする。
− いずれも空ポインタである。
− いずれも同じオブジェクト又は同じ関数を指すポインタである(一方がオブジェクトを指し,他方が
そのオブジェクトの先頭にある部分オブジェクトを指す場合も含む。)。
− いずれも同じ配列オブジェクトの最後の要素を一つ越えたところを指している。
− 一方が配列オブジェクトの最後の要素を一つ越えたところを指すポインタであり,もう一方がアドレ
ス空間中でその配列オブジェクトの直後に続く異なる配列オブジェクトの先頭を指すポインタである
(91)。
6.5.10 ビット単位のAND演算子
構文規則
AND式:
等価式
AND式 & 等価式
制約 各オペランドの型は,整数型でなければならない。
意味規則 オペランドに対して通常の算術型変換を適用する。
2項&演算子の結果は,オペランドのビット単位の論理積とする(すなわち,型変換されたオペランドの
対応するビットが両者ともセットされている場合,そしてその場合に限り,結果のそのビットをセットす
る。)。
6.5.11 ビット単位の排他OR演算子
構文規則
排他OR式:
AND式
排他OR式 ^ AND式
制約 各オペランドの型は,整数型でなければならない。
意味規則 オペランドに対して通常の算術型変換を適用する。
^演算子の結果は,オペランドのビット単位の排他的論理和とする(すなわち,型変換されたオペラン
ドの対応するビットのいずれか一方だけがセットされている場合,そしてその場合に限り,結果のそのビ
ットをセットする。)。
───────────────────────────────────────────────
(91)
二つのオブジェクトは,大きな配列の隣接した要素である場合,メンバの間に詰め物がない構造体
の隣接したメンバである場合,又は全く関連をもたない場合でも,実装上の選択による配置などに
よって,記憶域で隣接していることがある。それ以前のポインタ演算で配列の境界を越えてアクセ
スするような未定義の動作を行った場合,それに続く比較の効果は未定義とする。
65
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6.5.12 ビット単位のOR演算子
構文規則
OR式:
排他OR式
OR式 | 排他OR式
制約 各オペランドの型は,整数型でなければならない。
意味規則 オペランドに対して通常の算術型変換を適用する。
|演算子の結果は,オペランドのビット単位の論理和とする(すなわち,型変換されたオペランドの対
応するビットの少なくとも一方がセットされている場合,そしてその場合に限り,結果のそのビットをセ
ットする。)。
6.5.13 論理AND演算子
構文規則
論理AND式:
OR式
論理AND式 && OR式
制約 各オペランドの型は,スカラ型でなければならない。
意味規則 &&演算子の結果の値は,両オペランドの値が0と比較してともに等しくない場合は1,それ以
外の場合は0とする。結果の型は,intとする。
ビット単位の2項&演算子と異なり,&&演算子は左から右への評価を保証する。第1オペランドの評価
の直後を副作用完了点とする。第1オペランドの値が0と比較して等しい場合,第2オペランドは評価し
ない。
6.5.14 論理OR演算子
構文規則
論理OR式:
論理AND式
論理OR式 || 論理AND式
制約 各オペランドの型は,スカラ型でなければならない。
意味規則 ||演算子の結果の値は,両オペランドを0と比較していずれか一方でも等しくない場合は1,
それ以外の場合は0とする。結果の型はintとする。
ビット単位の|演算子と異なり,||演算子は左から右への評価を保証する。第1オペランドの評価の直
後を副作用完了点とする。第1オペランドの値が0と比較して等しくない場合,第2オペランドは評価し
ない。
6.5.15 条件演算子
構文規則
条件式:
論理OR式
論理OR式 ? 式 : 条件式
制約 第1オペランドの型は,スカラ型でなければならない。
第2及び第3オペランドの型は,次のいずれかの条件を満たさなければならない。
66
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 両オペランドの型が算術型である。
− 両オペランドの型が同じ構造体型又は共用体型である。
− 両オペランドの型がvoid型である。
− 両オペランドが適合する型の修飾版又は非修飾版へのポインタである。
− 一方のオペランドがポインタであり,かつ他方が空ポインタ定数である。
− 一方のオペランドがオブジェクト型又は不完全型へのポインタであり,かつ他方がvoidの修飾版又
は非修飾版へのポインタである。
意味規則 第1オペランドを評価し,その評価の直後を副作用完了点とする。第1オペランドが0と比較
して等しくない場合だけ,第2オペランドを評価する。第1オペランドが0と比較して等しい場合だけ,
第3オペランドを評価する。第2又は第3オペランド(いずれか評価したほう)の値を結果とする。結果
の型は6.5.15の規定に従って型変換する(92)。条件演算子の結果を変更するか,又は次の副作用完了点の後,
それにアクセスしようとした場合,その動作は,未定義とする。
第2及び第3オペランドの型がともに算術型ならば,通常の算術型変換をこれら二つのオペランドに適
用することによって決まる型を結果の型とする。両オペランドの型がともに構造体型又は共用体型ならば,
結果の型はその型とする。両オペランドの型がともにvoid 型ならば,結果の型はvoid型とする。
第2及び第3オペランドがともにポインタである場合,又は,一方が空ポインタ定数かつ他方がポイン
タである場合,結果の型は両オペランドが指す型のすべての型修飾子で修飾された型へのポインタとする。
さらに,両オペランドが適合する型へのポインタ又は適合する型の異なる修飾版へのポインタである場合,
結果の型は適切に修飾された合成型へのポインタとする。一方のオペランドが空ポインタ定数である場合,
結果の型は他方のオペランドの型とする。これら以外の場合(一方のオペランドがvoid又はvoidの修
飾版へのポインタである場合),結果の型は,適切に修飾されたvoid型へのポインタとする。
例 第2及び第3オペランドがポインタである場合の結果の共通の型は,二つの独立な段階を経て決
まる。例えば,結果の型の適切な型修飾子は,二つのポインタの型が適合するかどうかに依存し
ない。
次の宣言をしたとき,
const void *c̲vp;
void *vp;
const int *c̲ip;
volatile int *v̲ip;
int *ip;
const char *c̲cp;
次に示すものの右端の欄は,第2及び第3オペランドの型が最初の二つの欄(いずれかの順番で)
である場合の条件式の結果となる共通の型である。
c̲vp
c̲ip
const void *
v̲ip
0
volatile int *
c̲ip
v̲ip
const volatile int *
vp
c̲cp
const void *
───────────────────────────────────────────────
(92)
条件式は,左辺値を返さない。
67
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ip
c̲ip
const int *
vp
ip
void *
6.5.16 代入演算子
構文規則
代入式:
条件式
単項式 代入演算子 代入式
代入演算子: 次のいずれか
= *= /= %= += -= <<= >>= &= ^= |=
制約 代入演算子の左オペランドは,変更可能な左辺値でなければならない。
意味規則 代入演算子は,左オペランドで指し示されるオブジェクトに値を格納する。代入式は,代入後
の左オペランドの値をもつが,左辺値ではない。代入式の型は,左オペランドの型とする。ただし,左オ
ペランドの型が修飾型である場合は,左オペランドの型の非修飾版とする。左オペランドに格納されてい
る値を更新する副作用は,直前の副作用完了点から次の副作用完了点までの間に起こらなければならない。
オペランドの評価順序は,未規定とする。代入演算子の結果を変更するか,又は次の副作用完了点の後,
それにアクセスしようとした場合,その動作は未定義とする。
6.5.16.1 単純代入
制約 次のいずれかの条件が成立しなければならない(93)。
− 左オペランドの型が算術型の修飾版又は非修飾版であり,かつ右オペランドの型が算術型である。
− 左オペランドの型が右オペランドの型に適合する構造体型又は共用体型の修飾版又は非修飾版である。
− 両オペランドが適合する型の修飾版又は非修飾版へのポインタであり,かつ左オペランドで指される
型が右オペランドで指される型の型修飾子をすべてもつ。
− 一方のオペランドがオブジェクト型又は不完全型へのポインタであり,かつ他方がvoidの修飾版又
は非修飾版へのポインタである。さらに,左オペランドで指される型が,右オペランドで指される型
の型修飾子をすべてもつ。
− 左オペランドがポインタであり,かつ右オペランドが空ポインタ定数である。
− 左オペランドの型が̲Bool型であり,かつ右オペランドがポインタである。
意味規則 単純代入(simple assignment)(=)は,右オペランドの値を代入式の型に型変換し,左オペラ
ンドで指し示されるオブジェクトに格納されている値をこの値で置き換える。
オブジェクトに格納されている値を,何らかの形でそのオブジェクトの記憶域に重なる他のオブジェク
トを通してアクセスする場合,重なりは完全に一致していなければならない。さらに,二つのオブジェク
トの型は,適合する型の修飾版又は非修飾版でなければならない。そうでない場合,動作は未定義とする。
例1. 次のプログラム片では,
int f(void);
char c;
───────────────────────────────────────────────
(93)
型修飾子に関するこれらの制約の非対称性は,左辺値を“式の値”に変更する型変換(6.3.2.1参照)
の際に,その式の型分類から型修飾子が取り除かれることに起因する。
68
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
/* ... */
if ((c = f()) == -1)
/* ... */
関数から返されたint型の値は,char型に格納されるときに切り捨てられ,それから比較に
先立ってintの幅に型変換されるかもしれない。単なるcharとunsigned charの値の範
囲が同じである(さらに,charがintよりも幅の狭い)処理系では,型変換の結果が負にな
ることはないので,オペランドの比較は決して等しくはならない。可搬性を最大にするために,
変数cはint型として宣言することが望ましい。
例2. 次のプログラム片では,
char c;
int i;
long l;
l = (c = i);
iの値は代入式 c = iの型,すなわちchar型へ型変換される。その後,括弧内で囲まれた式
の値は外側の代入式の型,すなわちlong int型へ型変換される。
例3.
const char **cpp;
char *p;
const char c = 'A';
cpp = &p;
// 制約違反
*cpp = &c;
// 正しい
*p = 0;
// 正しい
最初の代入は安全ではない。なぜなら,その後で正しいコードによってconstオブジェクトc
の値を変更できるからである。
6.5.16.2 複合代入
制約 演算子+=及び-=の場合は,次のいずれかの条件を満たさなければならない。
− 左オペランドがオブジェクト型へのポインタであり,かつ右オペランドの型が整数型である。
− 左オペランドの型が算術型の修飾版又は非修飾版であり,かつ右オペランドの型が算術型である。
その他の演算子の場合,各オペランドの型は,対応する2項演算子に対して許される算術型でなければ
ならない。
意味規則 形式E1 op= E2の複合代入(compound assignment)は,左辺値E1がただ1回だけ評価される
点を除いて,単純代入式E1 = E1 op (E2)と同じとする。
6.5.17 コンマ演算子
構文規則
式:
代入式
式 , 代入式
69
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
意味規則 コンマ演算子は,左オペランドをボイド式として評価する。その評価の直後を副作用完了点と
する。次に右オペランドを評価する。コンマ演算子の結果は,右オペランドの型及び値をもつ(94)。コンマ
演算子の結果を変更するか,又は次の副作用完了点の後でそれにアクセスしようとした場合,その動作は
未定義とする。
例 構文規則で示すとおり,コンマが区切り子である文脈(関数呼出しの実引数並びの中,及び初期
化子並びの中)では,コンマ演算子が現れることはない。一方,このような文脈でも括弧で囲ま
れた式の中,又は条件演算子の第2オペランドの中では使うことができる。関数呼出し
f(a, (t=3, t+2), c)
は,3個の実引数をもち,2番目の実引数の値は5である。
前方参照 初期化(6.7.8)
6.6
定数式
構文規則
定数式:
条件式
補足説明 定数式は,実行時ではなく翻訳時に評価することができる。したがって,定数を使用してよい
ところならばどこでも使用してよい。
制約 定数式は,代入,増分,減分,関数呼出し又はコンマ演算子を含んではならない。ただし,定数式
が評価されない部分式(95)に含まれている場合を除く。
定数式を評価した結果は,その型で表現可能な値の範囲内にある定数でなければならない。
意味規則 評価して定数になる式は,幾つかの文脈で必要となる。浮動小数点型の式を翻訳環境下で評価
する場合,その算術的な精度及び範囲は,式が実行環境下で評価される場合以上でなければならない。
整数定数式(integer constant expression)(96)の型は,整数型でなければならない。整数定数式のオペラン
ドは,整数定数,列挙定数,文字定数,その結果が整数定数であるsizeof式又は浮動小数点定数でなけ
ればならない。この場合の浮動小数点定数は,キャストの直接のオペランドでなければならない。整数定
数式中のキャスト演算子は,sizeof演算子のオペランドの一部である場合を除いて,算術型を整数型に
変換するものでなければならない。
初期化子中の定数式に対しては,更に広い自由度を許す。この場合の定数式の形,又はそれを評価した
結果は,次のいずれかでなければならない。
− 算術定数式
− 空ポインタ定数
− アドレス定数
− オブジェクト型に対するアドレス定数+整数定数式
− オブジェクト型に対するアドレス定数-整数定数式
───────────────────────────────────────────────
(94)
コンマ演算子は,左辺値を返さない。
(95)
sizeof演算子のオペランドは通常評価されない(6.5.3.4)。
(96)
整数定数式を使用しなければならないのは,構造体のビットフィールドメンバの大きさ,列挙定数
の値,配列の大きさ又はcase定数の値を指定する場合である。条件付き取込み前処理指令で使用
される整数定数式に適用されるその他の制約は,6.10.1で規定する。
70
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
算術定数式(arithmetic constant expression)は,算術型をもたなければならない。オペランドとして使え
るのは,整数定数,浮動小数点定数,列挙定数,文字定数及びsizeof式だけとする。算術定数式中のキ
ャスト演算子は,その結果が整数定数であるsizeof演算子のオペランドの一部である場合を除いて,算
術型を算術型に変換するものでなければならない。
アドレス定数(address constant)は,空ポインタ,静的記憶域期間のオブジェクトを指し示す左辺値を
指すポインタ又は関数指示子を指すポインタとする。アドレス定数は,単項&演算子若しくは整数定数の
ポインタ型へのキャストによって明示的に生成されるか,又は配列型若しくは関数型の式の使用によって
暗黙に生成されたものでなければならない。配列添字演算子[],メンバアクセス演算子.及び->,アドレ
ス単項演算子&,間接単項演算子*,並びにポインタへのキャストは,アドレス定数の生成に使用してもよ
いが,これらの演算子を使用することによってオブジェクトの値をアクセスしてはならない。
処理系は,定数式の他の形式を許してもよい。
定数式の評価に対する意味規則は,定数でない式の場合と同じとする(97)。
前方参照 初期化(6.7.8),配列宣言子(6.7.5.2)
6.7
宣言
構文規則
宣言:
宣言指定子列 初期化宣言子並びopt;
宣言指定子列:
記憶域クラス指定子 宣言指定子列opt
型指定子 宣言指定子列opt
型修飾子 宣言指定子列opt
関数指定子 宣言指定子列opt
初期化宣言子並び:
初期化宣言子
初期化宣言子並び , 初期化宣言子
初期化宣言子:
宣言子
宣言子 = 初期化子
制約 宣言では,少なくとも一つの宣言子(関数の仮引数又は構造体若しくは共用体のメンバ以外のもの),
タグ又は列挙体のメンバを宣言しなければならない。
識別子が無結合である場合,その識別子の宣言(宣言子又は型指定子の中の)が同じ有効範囲及び同じ
名前空間の中で,二つ以上あってはならない。ただし,タグの宣言は除く(6.7.2.3参照)。
同じオブジェクト又は同じ関数についての同じ有効範囲の中のすべての宣言は,適合する型を指定しな
ければならない。
───────────────────────────────────────────────
(97)
したがって,次のような初期化では,
static int i = 2 || 1 / 0;
式は値1をもった有効な整数定数式である。
71
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
意味規則 宣言は,幾つかの識別子の解釈及び属性を指定する。識別子の定義(definition)とは,宣言の
うち次のものをいう。
− オブジェクトに対しては,そのオブジェクトの記憶域を確保する宣言
− 関数に対しては,関数本体を含む宣言(98)
− 列挙定数又は型定義名に対しては,その識別子の(唯一の)宣言
宣言指定子列は,結合,記憶域期間及び宣言子が表す実体の型の一部を示す指定子の列から成る。初期
化宣言子並びは,コンマで区切られた宣言子の列とし,各宣言子は,付加的な型情報,初期化子又はそれ
らの両方をもっていてもよい。宣言子は,(もしあれば)宣言する識別子を含む。
オブジェクトの識別子が無結合で宣言されている場合,オブジェクトの型は,その宣言子の終わりまで
に,又は初期化宣言子の終わりまで(その宣言子が初期化子をもつとき)に,完全になっていなければな
らない。(関数原型の場合も含めて)関数の仮引数の場合,完全型でなければならないのは型調整された型
(6.7.5.3参照)とする。
前方参照 初期化(6.7.8),宣言子(6.7.5),列挙型指定子(6.7.2.2)
6.7.1
記憶域クラス指定子
構文規則
記憶域クラス指定子:
typedef
extern
static
auto
register
制約 一つの宣言の宣言指定子列の中で二つ以上の記憶域クラス指定子を与えてはならない(99)。
意味規則 typedef指定子は,構文的な都合だけから“記憶域クラス指定子”と呼ぶ。これについては,
6.7.7で規定する。各種の結合及び記憶域期間の意味については,6.2.2及び6.2.4で規定する。
オブジェクトの識別子が記憶域クラス指定子registerを用いて宣言されている場合,そのオブジェク
トへのアクセスを可能な限り高速にすべきであることを示唆する。この示唆が効果をもつ程度は,処理系
定義とする(100)。
関数の識別子がブロック有効範囲で宣言される場合,extern以外の明示的な記憶域クラス指定子をも
ってはならない。
───────────────────────────────────────────────
(98)
関数定義は異なる構文をもつが,これについては,6.9.1で規定する。
(99)
“今後の言語の方針”(6.11.5)参照。
(100) 処理系は,register宣言を単にauto宣言として扱ってもよい。しかし,アドレス付け可能な記
憶域が実際に使われるかどうかにかかわらず,記憶域クラス指定子 registerを伴って宣言され
たオブジェクトのどの部分のアドレスも,(6.5.3.2で述べる単項&演算子によって)明示的にも又は
(6.3.2.1で述べる配列名のポインタへの変換によって)暗黙にも,計算することはできない。した
がって,記憶域クラス指定子 registerを伴って宣言された配列に適用できる演算子は,sizeof
だけである。
72
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
集成体又は共用体のオブジェクトがtypedef以外の記憶域クラス指定子を用いて宣言されたとき,結
合に関するものを除いて,記憶域クラス指定子による性質をオブジェクトのメンバにも適用する。また再
帰的に集成体又は共用体であるすべてのメンバオブジェクトに適用する。
前方参照 型定義(6.7.7)
6.7.2
型指定子
構文規則
型指定子:
void
char
short
int
long
float
double
signed
unsigned
̲Bool
̲Complex
̲Imaginary
構造体共用体指定子
列挙型指定子
型定義名
制約 それぞれの宣言の宣言指定子列の中で,又はそれぞれの構造体宣言及び型名の型指定子型修飾子並
びの中で,少なくとも一つの型指定子を指定しなければならない。型指定子の並びは,次に示すもののい
ずれか一つでなければならない(1行に二つ以上の組がある場合,コンマで区切ってある。)。型指定子は,
いかなる順序で現れてもよく,更に,他の宣言指定子と混合してもよい。
− void
− char
− signed char
− unsigned char
− short,signed short,short int,signed short int
− unsigned short,unsigned short int
− int,signed,signed int
− unsigned,unsigned int
− long,signed long,long int,signed long int
− unsigned long,unsigned long int
− long long,signed long long,long long int,signed long long int
− unsigned long long,unsigned long long int
− float
73
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− double
− long double
− ̲Bool
− float ̲Complex
− double ̲Complex
− long double ̲Complex
− float ̲Imaginary
− double ̲Imaginary
− long double ̲Imaginary
− 構造体共用体指定子
− 列挙型指定子
− 型定義名
型指定子̲Complex及び̲Imaginaryは,処理系がそれらを提供しない場合は使用してはならない(101)。
意味規則 構造体,共用体及び列挙型の指定子は,6.7.2.1〜6.7.2.3で規定する。型定義名の宣言は,6.7.7
で規定する。他の型の性質は,6.2.5で規定する。
コンマで区切られているそれぞれの組は,同じ型を表す。ただし,ビットフィールドの場合,型指定子
intがsigned intと同じ型を表すか,unsigned intと同じ型を表すかは処理系定義とする。
前方参照 型定義(6.7.7),構造体指定子及び共用体指定子(6.7.2.1),タグ(6.7.2.3),列挙型指定子(6.7.2.2)
6.7.2.1
構造体指定子及び共用体指定子
構文規則
構造体共用体指定子:
構造体共用体 識別子opt { メンバ宣言並び }
構造体共用体 識別子
構造体共用体:
struct
union
メンバ宣言並び:
メンバ宣言
メンバ宣言並び メンバ宣言
メンバ宣言:
型指定子型修飾子並び メンバ宣言子並び ;
型指定子型修飾子並び:
型指定子 型指定子型修飾子並びopt
型修飾子 型指定子型修飾子並びopt
メンバ宣言子並び:
───────────────────────────────────────────────
(101) 処理系は虚数型を提供しなくてもよい。フリースタンディング処理系では複素数型を提供しなくて
もよい。
74
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
メンバ宣言子
メンバ宣言子並び , メンバ宣言子
メンバ宣言子:
宣言子
宣言子opt : 定数式
制約 構造体及び共用体は,不完全型又は関数型のメンバを含んではならない。したがって,構造体及び
共用体は,その型自身のインスタンスを含んではならない(しかし,その型自身へのポインタは含んでも
よい。)。例外的に,二つ以上の名前付きメンバをもつ構造体の最後のメンバは不完全配列型をもってもよ
い。そのような構造体[又はそのような構造体をメンバとしてもつ共用体(再帰的に含む場合でも)]を構
造体メンバ又は配列要素にしてはならない。
ビットフィールドの幅を指定する式は,整数定数式でなければならない。その値は,0以上でなければ
ならず,コロン及び式が省略された場合,指定された型のオブジェクトがもつビット数を超えてはならな
い。値が0の場合,その宣言に宣言子があってはならない。
ビットフィールドの型は,修飾版又は非修飾版の̲Bool,signed int,unsigned int又は他の処理
系定義の型でなければならない。
意味規則 構造体は,メンバの列から成る型とし,メンバの記憶域は,並べられた順に割り付ける(6.2.5
参照)。共用体は,メンバの列から成る型とし,メンバの記憶域は重なり合う。
構造体及び共用体の指定子は,同一の形式をもつ。
構造体共用体指定子の中にメンバ宣言並びがある場合,翻訳単位内での新しい型を宣言する。メンバ宣
言並びは,構造体又は共用体のメンバの宣言の列とする。メンバ宣言並びが名前付きのメンバを含まない
場合,その動作は未定義とする。型は,並びを終了する}までは不完全型とする。
構造体又は共用体のメンバの型は,可変修飾型(102)を除くいかなるオブジェクト型であってもよい。さ
らに,メンバは,ビット数(もしあれば符号ビットも含めて)の指定付きで宣言してもよい。ビット数が
指定されたメンバをビットフィールド(bit field)(103)と呼ぶ。その(ビット数を示す)幅の直前には,コ
ロンを置く。
ビットフィールドは,指定された個数のビットから成る符号付き又は符号無しの整数型として解釈する
(104)。値0又は1を幅1以上の̲Bool型のビットフィールドに設定した場合,ビットフィールドの値は設
定された値と比較して等しくなければならない。
処理系は,ビットフィールドを保持するに十分な大きさの任意のアドレス付け可能な記憶域単位を割り
付けてよい。十分な領域が残っている場合,構造体内のビットフィールドの直後に続く別のビットフィー
ルドは,同じ単位の隣接したビットに詰め込まなければならない。十分な領域が残っていない場合,入り
───────────────────────────────────────────────
(102) 構造体及び共用体は可変修飾型のメンバをもつことができない。なぜなら,6.2.3での定義により
メンバ名は通常の識別子ではないからである。
(103) 単項&(アドレス)演算子は,ビットフィールドオブジェクトに適用できない。したがって,ビッ
トフィールドオブジェクトへのポインタ又は配列は存在しない。
(104) 6.7.2の規定によって,使用された実際の型指定子が,intか又はintとして定義されている型定
義名である場合,ビットフィールドが符号付きか符号無しかは処理系定義である。
75
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
切らなかったビットフィールドを次の単位に入れるか,又は隣接した単位の境界をまたがせるかは,処理
系定義とする。単位内のビットフィールド割付けの順序(上位から下位か又は下位から上位か)は,処理
系定義とする。アドレス付け可能な記憶域単位の境界調整は,未規定とする。
宣言子がなく,コロン及び幅だけをもつビットフィールド宣言は,名前のないビットフィールド(105)を
示す。この特別な場合として,幅が0のビットフィールド構造体メンバは,前のビットフィールド(もし
あれば)が割り付けられていた単位に,それ以上のビットフィールドを詰め込まないことを指定する。
構造体又は共用体オブジェクトのビットフィールド以外の各メンバの境界は,その型に適した処理系定
義の方法で調整する。
構造体オブジェクト内では,非ビットフィールドメンバ及びビットフィールドが置かれる単位は,宣言
された順に増加するアドレスをもつ。構造体オブジェクトへのポインタは,適切に変換すれば,その先頭
メンバ(又はビットフィールドならば,それが置かれた単位)を指す。さらに,その逆も成り立つ。構造
体オブジェクトの中に名前のない詰め物があってもよいが,先頭には名前のない詰め物があってはならな
い。
共用体の大きさは,最大のメンバを保持するのに十分な大きさとする。どんなときでも,高々一つのメ
ンバの値だけが共用体オブジェクトに格納できる。共用体オブジェクトへのポインタは,適切に変換すれ
ば,そのそれぞれのメンバ(又はメンバがビットフィールドならば,それが置かれた単位)を指す。さら
に,その逆も成り立つ。
構造体又は共用体の最後に名前のない詰め物があってもよい。
特別な場合として,二つ以上の名前付きメンバをもつ構造体の最後のメンバは,不完全配列型をもって
もよい。これをフレキシブル配列メンバ(flexible array member)と呼ぶ。二つの例外を除いて,フレキシ
ブル配列メンバは無視される。一つ目は,構造体の大きさは,フレキシブル配列メンバを未規定の長さの
配列に置き換えて,それ以外は元のままとした構造体の最後のメンバのオフセットに等しいとする(106)。
二つ目は,.(又は->)演算子がフレキシブル配列メンバをもつ構造体(又はその構造体へのポインタ)
を左オペランドとしてもち,かつ右オペランドがそのメンバであるとき,その動作は,構造体の大きさが
現在アクセスされているオブジェクトの大きさより大きくならないという条件のもとで,そのメンバが同
じ要素型をもつ最大の大きさの配列で置き換えられた場合と同じとする。このとき,たとえ置き換えられ
た配列のオフセットがそのメンバのオフセットと異なるとしても,そのメンバのオフセットは変更しない。
置き換えられた配列が要素をもたないとき,それはただ一つの要素をもつのと同じ規則で動作する。しか
し,その要素にアクセスした場合,又はその要素を一つ越えたポインタを生成した場合,その動作は未定
義とする。
例 すべての配列メンバが同様に境界を調整されると仮定すると,次の宣言について
struct s { int n; double d[]; };
struct ss { int n; double d[1]; };
次の三つの式は,
───────────────────────────────────────────────
(105) 名前のないビットフィールド構造体メンバは,外部から強制された配置に合わせるための詰め物と
して便利である。
(106) 長さが未規定であるため,処理系は,配列であるメンバの長さに応じてそのメンバの境界調整を異
ならせることができる。
76
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
sizeof (struct s)
offsetof(struct s, d)
offsetof(struct ss, d)
同じ値をもつ。 構造体struct sは,一つのフレキシブル配列メンバdをもつ。
sizeof (double)が8である場合,次のコードが実行されて,
struct s *s1;
struct s *s2;
s1 = malloc(sizeof (struct s) + 64);
s2 = malloc(sizeof (struct s) + 46);
二つのmalloc呼出しが成功したとき,s1とs2で指されるオブジェクトは,識別子が次のよう
に宣言された場合と同じ規則で動作する。
struct { int n; double d[8]; } *s1;
struct { int n; double d[5]; } *s2;
さらに,次の代入は,
s1 = malloc(sizeof (struct s) + 10);
s2 = malloc(sizeof (struct s) + 6);
次の宣言があった場合と同じ規則で動作する。
struct { int n; double d[1]; } *s1, *s2;
このとき,
double *dp;
dp = &(s1->d[0]);
// 正しい
*dp = 42;
// 正しい
dp = &(s2->d[0]);
// 正しい
*dp = 42;
// 未定義の動作
次の代入について
*s1 = *s2;
メンバnだけはコピーされるが,配列の要素はコピーされない。同様に,
struct s t1 = { 0 }; // 正しい
struct s t2 = { 2 }; // 正しい
struct ss tt = { 1, { 4.2 }};// 正しい
struct s t3 = { 1, { 4.2 }}; // 正しくない: 4.2が初期化する対象はない
t1.n = 4; // 正しい
t1.d[0] = 4.2; // 未定義の動作
前方参照 タグ(6.7.2.3)
6.7.2.2
列挙型指定子
構文規則
列挙型指定子:
enum 識別子opt { 列挙子並び }
enum 識別子opt { 列挙子並び , }
77
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
enum 識別子
列挙子並び:
列挙子
列挙子並び , 列挙子
列挙子:
列挙定数
列挙定数 = 定数式
制約 列挙定数の値を定義する式は,int型で表現可能な値をもつ整数定数式でなければならない。
意味規則 列挙子並びの中の識別子は,型intをもつ定数として宣言され,この型の定数が許されるとこ
ろならばどこに現れてもよい(107)。=を含む列挙子は,その定数式の値をもつ列挙定数を定義する。最初の
列挙子に=がない場合,その列挙定数の値は0とする。=がない2番目以降の各列挙子は,直前の列挙定数
の値に1を加えて得られる定数式の値をもつ列挙定数を定義する。(=をもつ列挙子を使用することによっ
て,同じ列挙体の中で複数の列挙定数の値が同じになってもよい。)列挙体の列挙子は,そのメンバともい
う。
それぞれの列挙型は,char,符号付き整数型又は符号無し整数型と適合する型とする。型の選択は,処
理系定義とする(108)。しかし,その型は列挙型のすべてのメンバの値を表現できなければならない。列挙
子の宣言の並びを終了する}までは列挙型は不完全型とする。
例
enum hue { chartreuse, burgundy, claret=20, winedark };
enum hue col, *cp;
col = claret;
cp = &col;
if (*cp != burgundy)
/* ... */
この例はhueを列挙型タグにし,次にその型をもつオブジェクトとしてcol,その型をもつオ
ブジェクトへのポインタとしてcpを宣言している。列挙された値の集合は,{0,1, 20, 21}である。
前方参照 タグ(6.7.2.3)
6.7.2.3
タグ
制約 個々の型は1回だけその内容を定義できる。
列挙子並びをもたない次の形式である型指定子
enum 識別子
は,その型が完全型になった後でだけ指定できる。
意味規則 同じ有効範囲をもち,かつ同じタグを使用する構造体型,共用体型又は列挙型のすべての宣言
───────────────────────────────────────────────
(107) したがって,同じ有効範囲で宣言された列挙定数の識別子は,互いに違っていなければならず,通
常の宣言子で宣言された他の識別子とも違っていなければならない。
(108) 処理系はすべての列挙定数が指定された後で整数型の選択を行うことができる。
78
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
は,同じ型を宣言する。型は,内容を定義する並びを終了する}までは不完全型(109)とし,それ以降は完全
型とする。
異なる有効範囲をもつ又は異なるタグを使用する構造体型,共用体型又は列挙型の二つの宣言は別個の
型を宣言する。タグを含まない構造体型,共用体型又は列挙型のそれぞれの宣言は別個の型を宣言する。
型指定子の形式
構造体共用体 識別子opt { メンバ宣言並び }················································· (1)
又は
enum 識別子 { 列挙子並び } ································································· (2)
若しくは
enum 識別子 { 列挙子並び , } ······························································· (3)
は,構造体型,共用体型又は列挙型を宣言する。その並びは構造体の内容(structure content),共用体の内
容(union content)又は列挙体の内容(enumeration content)を定義する。識別子が指定された場合(110),こ
れに加えて,型指定子は識別子をその型のタグとして宣言する。
宣言の形式
構造体共用体 識別子 ; ············································································· (4)
は,構造体型又は共用体型を指定し,その型のタグとして識別子を宣言する(111)。
型指定子の形式
構造体共用体 識別子
は,上記の[形式(1)〜(4)の]のいずれかの一部でない場合,かつタグとしての識別子の他の宣言
が不可視である場合,不完全構造体型又は不完全共用体型を宣言し,その型のタグとして識別子を宣言す
る(111)。
型指定子の形式
構造体共用体 識別子
又は
enum 識別子
は,上記の[形式(1)〜(4)の]いずれかの一部でない場合,かつタグとしての識別子の宣言が可視
である場合,その宣言と同じ型を指定し,タグの再宣言を行わない。
例1. この機構を使えば,自己参照する構造体の宣言が可能である。
struct tnode {
───────────────────────────────────────────────
(109) 不完全型は,その型のオブジェクトの大きさが必要でないときだけ使用できる。例えば構造体若し
くは共用体に対する指定子として型定義名を宣言するとき,構造体若しくは共用体へのポインタを
指定するとき,又は,構造体若しくは共用体を返す関数を宣言するときには,その型のオブジェク
トの大きさは必要ではない(不完全型については6.2.5を参照)。その関数が呼び出される又は定義
されるときには完全型になっていなければならない。
(110)
識別子がない場合,翻訳単位内で,型は,それが一部となっている宣言によってだけ参照できる。
もちろん,それが型定義名の宣言であれば,後に続く宣言では型定義名をその指定された構造体型,
共用体型又は列挙型をもつオブジェクトの宣言に使用できる。
(111)
enumについては同様のことは指定できない。
79
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
int count;
struct tnode *left, *right;
};
この例は,一つの整数及び同じ型のオブジェクトへの二つのポインタを含む構造体を宣言して
いる。いったん,この宣言が与えられると,次のような宣言ができる。
struct tnode s, *sp;
これは,その型のオブジェクトs及びその型のオブジェクトへのポインタspを宣言している。
このような宣言では,式sp->leftは,spが指すオブジェクトのstruct tnodeへの左の
ポインタを参照し,式s.right->countは,sのstruct tnodeへの右のポインタが指す
オブジェクトのメンバであるcountを指し示している。
同じことをtypedef機構を用いて,次のように書くこともできる。
typedef struct tnode TNODE;
struct tnode {
int count;
TNODE *left, *right;
};
TNODE s, *sp;
例2. 相互参照する構造体の組を宣言するために,タグを前もって宣言して使用する例を説明する。
宣言
struct s1 { struct s2 *s2p; /* ... */ }; // D1
struct s2 { struct s1 *s1p; /* ... */ }; // D2
は,互いに他方を指すポインタを含む構造体の対を指定する。しかし,s2がそれを囲む有効範
囲でタグとして既に宣言されている場合,宣言D1はそれを参照し,D2で宣言されるタグs2
を参照しない。このような文脈の影響を除くために,宣言
struct s2;
をD1の前に挿入する方法がある。これは,内側の有効範囲で新しいタグs2を宣言する。宣言
D2で新しい型の仕様を完全にする。
前方参照 型定義(6.7.7),宣言子(6.7.5),配列宣言子(6.7.5.2)
6.7.3
型修飾子
構文規則
型修飾子:
const
restrict
volatile
制約 オブジェクト型又は不完全型から派生したポインタ型以外の型をrestrict修飾してはならない。
意味規則 修飾型に関連する性質は,左辺値である式に対してだけ意味をもつ(112)。
───────────────────────────────────────────────
(112)
処理系は,volatileでないconstオブジェクトを,読取り専用記憶域に置いてもよい。さらに,処
理系はそのアドレスが使われないならば,そのようなオブジェクトに記憶域を割り付けなくてもよい。
80
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
一つの型指定子型修飾子並びの中に同じ型修飾子が(直接に又は一つ以上のtypedefを介して)複数
回出現しても,その動作は1回だけ出現したときと同じとする。
const修飾型で定義されたオブジェクトを,非const修飾型の左辺値を使って変更しようとした場合,そ
の動作は未定義とする。volatile修飾型で定義されたオブジェクトを非volatile修飾型の左辺値を使って参
照しようとした場合,その動作は未定義とする(113)。
volatile修飾型をもつオブジェクトは,処理系に未知の方法で変更されてもよく,又はその他の未知の副
作用をもっていてもよい。したがって,volatile修飾型をもつオブジェクトを参照するすべての式は,抽象
計算機の規則(5.1.2.3で規定する)に厳密に従って評価しなければならない。さらに,そのオブジェクト
に最後に格納された値は,先に述べた未知の要因によって変更された場合を除いて,すべての副作用完了
点で抽象計算機の規則に従った値と一致しなければならない(114)。volatile修飾型のオブジェクトへのアク
セスをどのように構成するかは,処理系定義とする。
restrict修飾されたポインタを使ってアクセスされるオブジェクトは,そのポインタと特別な結び付きを
もつ。6.7.3.1で定義するこの結び付きがあるため,そのオブジェクトにアクセスするときには必ずそのポ
インタの値を直接的又は間接的に使わなければならならない(115)。(register記憶域クラス指定子と同
様に)restrict修飾子を用いることで最適化を促進することができる。規格合致プログラムを構成する
すべての前処理翻訳単位からrestrict修飾子を削除しても,その意味(すなわち,目に見える動作)は
変わらない。
配列型の指定が型修飾子を含む場合,それは要素の型を修飾するだけで,その配列型を修飾するのでは
ない。関数型の指定が型修飾子を含む場合,その動作は未定義とする(116)。
二つの修飾型が適合するためには,双方が適合する型に同じ修飾を行ったものでなければならない。型
指定子又は型修飾子の並びにおける型修飾子の順序は,指定された型に影響を与えない。
例1. 次のように宣言されたオブジェクトは,ハードウェアによって変更されることがあってもよい
が,代入したり,増分したり又は減分したりすることはできない。
extern const volatile int real̲time̲clock;
例2. 次の宣言及び式は,型修飾子が集成体型を修飾する場合の動作を説明する。
const struct s { int mem; } cs = { 1 };
struct s ncs;
// オブジェクトncsは変更可能
typedef int A[2][3];
───────────────────────────────────────────────
(113)
この規則は,修飾型で定義されたもののような動作をするオブジェクトにも適用する。例えば,(メ
モリ上に割り付けられた入出力アドレスのように)実際にはプログラム内のオブジェクトとして定
義されないものも含む。
(114)
volatile宣言は,メモリ上に割り付けられた入出力ポートに相当するオブジェクト,又は非同期
的な割込み機構によってアクセスされるオブジェクトを記述するのに使用してもよい。そのように
宣言されたオブジェクトに対する操作は,式の評価の規則で許されている場合を除いて,処理系の
最適化によって削除又は順序の変更が行われてはならない。
(115)
例えば,mallocの返却値を単一のポインタに代入する文は,割付けオブジェクトとそのポインタ
とを結び付ける。
(116)
これらのことは,typedefの使用を通して起こりうる。
81
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
const A a = {{4,5,6},{7,8,9}}; // const intの配列の配列
int *pi;
const int *pci;
ncs = cs;
// 正しい
cs = ncs;
// 代入演算子の変更可能な左辺値の制約に違反
pi = &ncs.mem;
// 正しい
pi = &cs.mem;
// 代入演算子の型の制約に違反
pci = &cs.mem;
// 正しい
pi = a[0];
// 正しくない: a[0]は型“const int *”をもつ
6.7.3.1
restrictの形式的定義 Dを通常の識別子の宣言とし,この識別子は,型Tを指すrestrict修飾
されたポインタとしてオブジェクトPを指し示すものとする。
Dがブロックの内側に出現し,かつその記憶域クラスがexternでない場合,そのブロックをBで表す。
Dが関数定義の仮引数宣言並びに出現した場合,結び付けられたブロックをBで表す。それ以外の場合,
main関数(又は,フリースタンディング環境でプログラム開始処理から呼び出される関数)のブロック
をBで表す。
ポインタ式EがオブジェクトPをベースとする(based),と呼ぶのは,Pが指していた配列オブジェク
トをコピーして,(式Eの評価より前のB中のある副作用完了点で)そのコピーを指すようにPを変更す
ると,Eの値が変わる場合とする(117)。この“ベースとする”という関係は,ポインタ型をもつ式だけに対
して定義する。
Lを左辺値とする。&LはBの実行中にPをベースとするものとする。Lを使ってLが指し示すオブジェ
クトXの値をアクセスし,(何らかの手段で)Xが変更される場合,次の条件を適用する。
− Tがconst修飾型であってはならない。
− Xの値にアクセスするために使われる他のすべての左辺値は,Pをベースとするアドレスをもたなけ
ればならない。
− Xを変更するすべてのアクセスはPも変更するとみなす(6.7.3.1では)。
− Pとは異なるrestrictポインタオブジェクトP2がブロックB2に結び付けられており,P2をベースと
するポインタ式Eの値をPに代入する場合,B2の実行がBより前に始まるか,又はB2の実行がその
代入よりも前に完了するかでなければならない。
これらの条件を満たさない場合の動作は,未定義とする。
ここでのBの実行とは,プログラムの実行のうち,Bに結び付けられた自動記憶域期間をもつスカラ型
のオブジェクトの生存期間に相当する部分を意味する。
restrictを使うと,処理系は別名付けがあった場合に起こることを無視してよい。
例1. ファイル有効範囲の次の宣言は,
───────────────────────────────────────────────
(117)
言い換えれば,EはPそのものの値に依存し,Pを介して間接的に参照されるオブジェクトの値に
は依存しない。例えば,識別子pが型(int **restrict)をもつ場合,ポインタ式pとp+1は
pが示すrestrictポインタオブジェクトをベースとする。しかし,ポインタ式*pとp[1]はそうな
らない。
82
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
int * restrict a;
int * restrict b;
extern int c[];
a,b又はcのいずれか一つを使ってオブジェクトにアクセスし,プログラム中のどこかでそ
のオブジェクトを変更する場合,他の二つを使ってそのオブジェクトにアクセスすることがな
いことを明示する。
例2. 次の例での関数仮引数宣言は,
void f(int n, int * restrict p, int * restrict q)
{
while (n-- > 0)
*p++ = *q++;
}
関数の実行中に,一方のポインタ仮引数でアクセスするオブジェクトに他方のポインタ仮引数
ではアクセスしないことを明示する。
restrict修飾子を使うと,処理系はプログラム中での関数fの呼出しを検査せずにfでの
実際の依存関係を解析できる。その代わり,fの呼出しがすべて未定義の動作を引き起こさな
いことを,プログラマが保証しなければならない。例えば,次の関数gでの2番目のfの呼出
しは,d[1]からd[49]までにpとqの両方からアクセスすることになるため,未定義の動作
を引き起こす。
void g(void)
{
extern int d[100];
f(50, d + 50, d);
// 正しい
f(50, d + 1, d);
// 未定義の動作
}
例3. 次の関数仮引数宣言は,
void h(int n, int * restrict p, int * restrict q, int * restrict r)
{
int i;
for (i = 0; i < n; i++)
p[i] = q[i] + r[i];
}
オブジェクトを変更しなければ二つのrestrict修飾されたポインタが同じオブジェクトに別名で
アクセスできることを示す。特にaとbが記憶域の重ならない配列の場合,h(100, a, b, b)
という形式で関数hを呼び出しても,関数h内では配列bが変更されないため定義された動作
となる。
例4. restrictポインタ同士での代入を制限する規定は,関数呼出しと,それと同等な入れ子のブロッ
クとを区別しない。一つの例外を除いて,入れ子のブロックで宣言されたrestrict修飾されたポ
インタの間で定義された動作をもつものは,“外側から内側への”代入だけである。
{
83
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
int * restrict p1;
int * restrict q1;
p1 = q1; // 未定義の動作
{
int * restrict p2 = p1;
// 正しい
int * restrict q2 = q1;
// 正しい
p1 = q2;
// 未定義の動作
p2 = q2;
// 未定義の動作
}
}
この例外とは,restrict修飾されたポインタ(より正確には,ポインタを示す通常の識別子)
が宣言されたブロックの実行が終了した場合,その値をそのブロックの外側で使うことができ
ることである。例えば,次のnew̲vectorはvectorを返却することができる。
typedef struct { int n; float * restrict v; } vector;
vector new̲vector(int n)
{
vector t;
t.n = n;
t.v = malloc(n * sizeof (float));
return t;
}
6.7.4
関数指定子
構文規則
関数指定子:
inline
制約 関数指定子は,識別子の関数としての宣言だけで使用できる。
外部結合をもつ関数のインライン定義が,静的記憶域期間をもつ変更可能なオブジェクトの定義を含ん
でいてはならず,内部結合をもつ識別子への参照も含んでいてはならない。
ホスト環境においては,inline関数指定子をmainの宣言に使ってはならない。
意味規則 inline関数指定子で宣言された関数は,インライン関数(inline function)とする。この関数
指定子は複数回出現してもよいが,1回だけ出現したときと同じ動作とする。関数をインライン関数にす
ることは,その関数の呼出しを可能な限り速くすることを示唆する(118)。この示唆が効果をもつ程度は,
───────────────────────────────────────────────
(118)
例えば,通常の関数呼出し機構に対する代替として,“インライン置換”を使う。インライン置換
は,テキスト上の置き換えではないし,新しい関数を作成することもない。そのため,例えば,そ
の関数本体内で使われるマクロの展開は,関数本体が出現する時点で行い,関数が呼び出される時
点では行わない。そして関数本体の位置で有効範囲にある宣言を識別子が参照する。また,外部定
義以外に行われるインライン定義の個数が幾つであれ,関数は単一のアドレスしかもたない。
84
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
処理系定義とする(119)。
内部結合をもつ任意の関数をインライン関数にすることができる。外部結合をもつ関数については次の
制限を適用する。関数をinline関数指定子で宣言する場合,その関数を同じ翻訳単位内で定義しなけれ
ばならない。一つの翻訳単位内で一つの関数に対するすべてのファイル有効範囲の宣言がexternなしで
inline関数指定子を含む場合,その翻訳単位内での定義をインライン定義(inline definition)という。イ
ンライン定義はその関数に対する外部定義を与えず,他の翻訳単位での外部定義も禁止しない。インライ
ン定義は外部定義の代替を与える。処理系はこの代替を,同じ翻訳単位内でのその関数に対する呼出しの
実現に使用することができる。その関数の呼出しでインライン定義を使うか,外部定義を使うかは未規定
とする(120)。
例 外部結合をもつインライン関数を宣言すると,外部定義か,又はその翻訳単位内だけで利用でき
る定義のいずれかを得ることができる。extern付きのファイル有効範囲の宣言は外部定義を生
成する。次の例は一つの翻訳単位全体を示す。
inline double fahr(double t)
{
return (9.0 * t) / 5.0 + 32.0;
}
inline double cels(double t)
{
return (5.0 * (t - 32.0)) / 9.0;
}
extern double fahr(double);
// 外部定義を生成する
double convert(int is̲fahr, double temp)
{
/* 処理系はインライン置換をしてもよい */
return is̲fahr ? cels(temp) : fahr(temp);
}
fahrはextern付きでも宣言されているためfahrの定義は外部定義となるが,celsの定義
はインライン定義であることに注意する。celsは外部結合をもちcelsへの参照も存在するた
め,他の翻訳単位にcelsの外部定義が存在しなければならない(6.9参照)。インライン定義と
外部定義は異なるものであり,その関数の呼出しを実現するのにいずれを使ってもよい。
前方参照 関数定義(6.9.1)
───────────────────────────────────────────────
(119)
例えば,処理系がインライン置換を一切しなくてもよいし,インライン宣言の有効範囲内の呼出し
だけをインライン置換してもよい。
(120) インライン定義は,それに対応する外部定義とは異なり,他の翻訳単位中の対応するインライン定
義とも異なるため,静的記憶域期間をもつすべての対応するオブジェクトも各定義ごとに異なる。
85
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6.7.5
宣言子
構文規則
宣言子:
ポインタopt 直接宣言子
直接宣言子:
識別子
( 宣言子 )
直接宣言子 [ 型修飾子並びopt 代入式opt ]
直接宣言子 [ static 型修飾子並びopt 代入式 ]
直接宣言子 [ 型修飾子並び static 代入式 ]
直接宣言子 [ 型修飾子並びopt * ]
直接宣言子 ( 仮引数型並び )
直接宣言子 ( 識別子並びopt )
ポインタ:
* 型修飾子並びopt
* 型修飾子並びopt ポインタ
型修飾子並び:
型修飾子
型修飾子並び 型修飾子
仮引数型並び:
仮引数並び
仮引数並び , ...
仮引数並び:
仮引数宣言
仮引数並び , 仮引数宣言
仮引数宣言:
宣言指定子列 宣言子
宣言指定子列 抽象宣言子opt
識別子並び:
識別子
識別子並び , 識別子
意味規則 各宣言子は一つの識別子を宣言する。式の中にその宣言子と同じ形式のオペランドが現れた場
合,そのオペランドは,宣言指定子列が指示する有効範囲,記憶域期間及び型をもつ関数又はオブジェク
トを指し示す。
他の宣言子の一部ではない宣言子を完結宣言子(full declarator)と呼ぶ。完結宣言子の最後は副作用完
了点とする。完結宣言子の中に入れ子になった宣言子の並びが可変長配列型を含む場合,完結宣言子で指
定する型を可変修飾(variably modified)であるという。
6.7.5〜6.7.5.3では次の宣言を考える。
86
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
T D1
ここでTは,型T(例えばint)を指定する宣言指定子列とする。D1は宣言子とし,D1に含まれる識別
子をここではidentと呼ぶ。宣言子の各形式では,識別子identに対して指定する型をこの記法を用いて帰
納的に説明する。
宣言“T D1”においてD1が形式
識別子
をもつ場合,identの型はTとする。
宣言“T D1”においてD1が形式
( D )
をもつ場合,identは宣言“T D”によって指定される型をもつ。すなわち括弧内の宣言子は,括弧なしの
宣言子と同一となるが,複雑な宣言子の結合が括弧によって変更されることがある。
処理系限界 5.2.4.1の規定に従い,処理系は算術型,構造体型,共用体型又は不完全型を直接的に又は一
つ以上のtypedefを介して間接的に修飾するポインタ,配列及び関数の宣言子の個数を制限してもよい。
前方参照 型定義(6.7.7),配列宣言子(6.7.5.2)
6.7.5.1
ポインタ宣言子
意味規則
宣言“T D1”において,D1が形式
* 型修飾子並びopt D
をもつ場合,次のとおりとする。宣言“T D”のidentに対して指定される型が“Tの派生宣言子型並び”
であれば,“T D1”のidentに対して指定される型は“Tへの型修飾子並びをもつポインタの派生宣言子型
並び”とする。identは,並びの中の各型修飾子によって修飾されたポインタとなる。
二つのポインタ型が適合するためには,いずれも同一の修飾がなされていなければならず,かつ両者が
適合する型へのポインタでなければならない。
例 次の二つの宣言は,“不変値への可変ポインタ”と“可変値への不変ポインタ”の違いを示す。
const int *ptr̲to̲constant;
int *const constant̲ptr;
ptr̲to̲constantの指すオブジェクトの内容は,そのポインタを通して変更してはならないが,
ptr̲to̲constant自身は他のオブジェクトを指すよう変更してもよい。同様に,
constant̲ptrによって指されるintの内容は変更してもよいが,constant̲ptr自身は常に
同一の位置を指さなければならない。
不変ポインタconstant̲ptrの宣言は,型“intへのポインタ”の定義を含めることで分か
りやすくできる。
typedef int *int̲ptr;
const int̲ptr constant̲ptr;
は,型“intへのconst修飾したポインタ”をもつオブジェクトとしてconstant̲ptrを宣言す
る。
6.7.5.2
配列宣言子
制約 [及び]の間には,省略可能な型修飾子及びキーワードstaticに加え,式又は*を置くことができ
る。[及び]が(配列の大きさを指定する)式を囲む場合,その式の型は整数型でなければならない。式が
定数式の場合,その値は0より大きくなければならない。要素の型が不完全型又は関数型であってはなら
87
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ない。省略可能な型修飾子及びキーワードstaticは,配列型をもつ関数仮引数の宣言中だけで使用でき
る。そして,一番外側の配列型派生だけで使用できる。
通常の識別子(6.2.3で定義する)のうち,ブロック有効範囲又は関数原型有効範囲をもち無結合である
ものだけが可変修飾型をもつことができる。識別子が静的記憶域期間をもつオブジェクトと宣言される場
合,その型を可変長配列型にすることはできない。
意味規則 宣言“T D1”においてD1が
D [ 型修飾子並びopt 代入式opt ]
D [ static 型修飾子並びopt 代入式 ]
D [ 型修飾子並びopt static 代入式 ]
D [ 型修飾子並びopt * ]
のいずれかの形式をもつ場合,次のとおりとする。宣言“T D”のidentに対して指定される型が“Tの派
生宣言子型並び”であれば,“T D1”のidentに対して指定される型は“Tの配列の派生宣言子型並び”と
する(121)。(省略可能な型修飾子とキーワードstaticについては6.7.5.3を参照。)
大きさの指定がない場合,その配列型は不完全型とする。大きさが式ではなく*で指定された場合,そ
の配列型は大きさの指定がない可変長配列型とする。この型は,完全型とするが,関数原型有効範囲をも
つ宣言の中でだけ使用できる(122)。大きさが整数定数式で要素の型が既知で一定の大きさをもつ場合,そ
の配列型は非可変長配列型とする。そうでない場合,その配列型を可変長配列型とする。
大きさが整数定数式以外の式である場合,次のとおりとする。その宣言が関数原型有効範囲にある場合,
式を*で置き換えた場合と同じ規則で扱う。そうでない場合,式を評価した値は,常に0より大きくなけ
ればならない。可変長配列型の各実体の大きさは,その生存期間の間変わることがない。大きさを示す式
がsizeof演算子のオペランドの一部で,その式の値を変更しても演算子の結果に影響を与えない場合,
その式を評価するかどうかは未規定とする。
二つの配列型が適合するためには,まず,両者が適合する要素型をもたなければならない。さらに,両
者が配列の大きさを指定する整数定数式をもつ場合,それらの値は同じ定数値でなければならない。二つ
の配列型が適合することを必要とする文脈で使われ,両者の大きさ指定子を評価した値が異なる場合,そ
の動作は未定義とする。
例1.
float fa[11], *afp[17];
は,float型の配列とfloat型へのポインタの配列を宣言する。
例2. 次の宣言の違いに注意しなければならない。
extern int *x;
extern int y[];
1番目は,xをint型へのポインタと宣言する。2番目は,yを記憶域がどこかで定義される,
大きさの指定されないintの配列(不完全型)と宣言する。
例3. 次の宣言は,幾つかの可変修飾型に関する適合規則を示す。
extern int n;
───────────────────────────────────────────────
(121) 幾つかの“〜の配列”の指定を連続的に並べることによって,多次元配列を宣言できる。
(122) すなわち,*は定義でない関数宣言(6.7.5.3参照)の中だけで使用することができる。
88
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
extern int m;
void fcompat(void)
{
int a[n][6][m];
int (*p)[4][n+1];
int c[n][n][6][m];
int (*r)[n][n][n+1];
p = a;
// 正しくない: 4 != 6であるため適合していない
r = c;
// 適合するが,n == 6でかつm == n+1の場合だけ
// 動作が定義される
}
例4. 可変修飾(VM)型のすべての宣言は,ブロック有効範囲又は関数原型有効範囲をもたなけれ
ばならない。static又はextern記憶域クラス指定子で宣言される配列オブジェクトは,可
変長配列(VLA)型をもてない。しかし,static記憶域クラス指定子で宣言されるオブジェ
クトがVM型(すなわち,VLA型へのポインタ)をもつこともできる。さらに,VM型で宣言
されるすべての識別子は,通常の識別子でなければならないので,構造体又は共用体のメンバ
にはなれない。
extern int n;
int A[n];
// 正しくない:VLAがファイル有効範囲にある
extern int (*p2)[n];
// 正しくない:VMがファイル有効範囲にある
int B[100];
// 正しい:Bはファイル有効範囲にあるがVMではない
void fvla(int m, int C[m][m]); // 正しい:VLAが関数原型有効範囲にある
void fvla(int m, int C[m][m]) // 正しい:VLAへのautoポインタに型調整される
{
typedef int VLA[m][m]; // 正しい:VLAがブロック有効範囲にある
struct tag {
int (*y)[n]; // 正しくない:yが通常の識別子でない
int z[n];
// 正しくない:zが通常の識別子でない
};
int D[m];
// 正しい:autoのVLA
static int E[m];
// 正しくない:VLAがブロック有効範囲のstatic
extern int F[m];
// 正しくない:Fが結合をもっているのにVLA
int (*s)[m];
// 正しい:VLAへのautoポインタ
extern int (*r)[m];
// 正しくない:rが結合をもっているのにVLAへのポインタ
static int (*q)[m] = &B;
// 正しい:qはVLAへのポインタでブロック有効範囲のstatic
}
前方参照 関数宣言子(6.7.5.3),関数定義(6.9.1),初期化(6.7.8)
89
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
6.7.5.3
関数宣言子(関数原型を含む)
制約 関数宣言子は,関数型又は配列型を返却値の型として指定してはならない。
仮引数宣言に記憶域クラス指定子として,register以外のものを指定してはならない。
関数定義の一部でない関数宣言子における識別子並びは,空でなければならない。
関数定義の一部である関数宣言子の仮引数型並びにある仮引数は,型調整後に不完全型をもってはなら
ない。
意味規則 宣言“T D1”においてD1が形式
D ( 仮引数型並び )
又は
D ( 識別子並びopt )
をもつ場合,次のとおりとする。宣言“T D”のidentに対して指定される型が“Tの派生宣言子型並び”
であれば,“T D1”のidentに対して指定される型は“Tを返す関数の派生宣言子型並び”とする。
仮引数型並びは,関数の仮引数の型を指定する。仮引数の識別子を宣言してもよい。
仮引数を“〜型の配列”とする宣言は,“〜型への修飾されたポインタ”に型調整する。そのときの型修
飾子は,配列型派生の[及び]の間で指定したものとする。配列型派生の[及び]の間にキーワードstatic
がある場合,その関数の呼出しの際に対応する実引数の値は,大きさを指定する式で指定される数以上の
要素をもつ配列の先頭要素を指していなければならない。
仮引数を“〜型を返却する関数”とする宣言は,6.3.2.1の規定に従い,“〜型を返却する関数へのポイン
タ”に型調整する。
並びの最後が省略記号(, ...)の場合,そのコンマ以降の実引数の個数及び型に関する情報はない(123)。
並びの中の唯一の項目がvoid型で名前のない仮引数であるという特別な場合,関数が仮引数をもたな
いことを指定する。
仮引数宣言内では,括弧で囲まれた単一の型定義名は,単一の仮引数をもつ関数を指定する抽象宣言子
と解釈する。宣言子の識別子を囲む冗長な括弧とは解釈しない。
関数宣言子が関数定義の一部ではない場合,仮引数の型は不完全型でもよく,また宣言指定子列に[*]
を使って可変長配列型を指定してもよい。
仮引数宣言の宣言指定子列に記憶域クラス指定子がある場合,その仮引数宣言が関数定義の仮引数型並
びの中にあるのでなければ記憶域クラス指定子を無視する。
識別子並びは,関数の仮引数の識別子だけを宣言する。関数定義の一部である関数宣言子で識別子並び
が空の場合,関数が仮引数をもたないことを指定する。関数定義の一部でない関数宣言子の識別子並びが
空の場合,仮引数の個数及び型の情報がないことを指定する(124)。
二つの関数型が適合するためには,次の条件をすべて満たさなければならない。
− 両方が適合する返却値の型をもつ(125)。
− 両方が仮引数型並びをもつ場合,仮引数の個数及び省略記号の有無に関して一致し,対応する仮引数
───────────────────────────────────────────────
(123) <stdarg.h>ヘッダ(7.15参照)で定義されるマクロを使えば,省略記号に対応する引数へのアク
セスが可能となる。
(124) “今後の言語の方針”(6.11.6参照)。
(125) 両方の関数型が“古い形式”の場合,仮引数の型は比較されない。
90
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
の型が適合する。
− 一方の型が仮引数型並びをもち,他方の型が関数定義の一部でない関数宣言子によって指定され,識
別子並びが空の場合,仮引数型並びは省略記号を含まない。各仮引数の型は,既定の実引数拡張を適
用した結果の型と適合する。
− 一方の型が仮引数型並びをもち,他方の型が関数定義によって指定され,識別子並び(空でもよい)
をもつ場合,両方の仮引数の個数は一致する。さらに関数原型のほうの各仮引数の型は,対応する識
別子の型に既定の実引数拡張を適用した結果の型と適合する。(型の適合及び型の合成を判断すると
き,関数型又は配列型で宣言される各仮引数は型調整後の型をもつものとして扱い,修飾型で宣言さ
れる各仮引数は宣言された型の非修飾版をもつものとして扱う。)
例1. 宣言
int f(void), *fip(), (*pfi)();
は,
− 仮引数をもたずintを返す関数f
− 仮引数の情報をもたずintへのポインタを返す関数fip
− 仮引数の情報をもたずintを返す関数へのポインタpfi
を宣言する。特に後者二つの比較が有用である。*fip()の結合は*(fip())となるので,宣言
は,まず関数fipを呼び出し,次にポインタによる間接を使ってintを得ることを示す。こ
れは式の場合も同様である。宣言子(*pfi)()では,まず関数へのポインタに対する間接演算
が関数指示子を生じる。次にそれが関数の呼出しに用いられ,その関数はintを返す。このこ
とを指示するために,括弧は省略できない。
宣言が関数の外にある場合,これらの識別子はファイル有効範囲及び外部結合をもつ。宣言
が関数の中にある場合,関数の識別子f及びfipは,ブロック有効範囲及び(これらの識別子
に対するファイル有効範囲の可視な宣言が何であるかに依存して)内部結合又は外部結合をも
つ。この場合,ポインタの識別子pfiは,ブロック有効範囲及び無結合をもつ。
例2. 宣言
int (*apfi[3])(int *x, int *y);
は,intを返す関数へのポインタ3個から成る配列apfiを宣言する。これらの関数は,仮引
数としてintへのポインタを2個もつ。識別子x及びyの宣言は,説明のための意味しかもた
ず,apfiの宣言の終わりでその有効範囲は終わる。
例3. 宣言
int (*fpfi(int (*)(long), int))(int, ...);
は,関数fpfiを宣言する。関数fpfiは,intを返す関数へのポインタを返す。fpfiは,二
つの仮引数をもつ。それらの仮引数の一つはintを返す関数(long int型の仮引数を1個
もつ。)へのポインタ,もう一つはintである。fpfiが返すポインタが指す関数は,一つの
int型の仮引数をもち,更に0個以上の任意の型の付加的な実引数を受け取る。
例4. 次の関数原型は可変修飾型の仮引数をもつ。
void addscalar(int n, int m,
double a[n][n*m+300], double x);
int main()
91
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
{
double b[4][308];
addscalar(4, 2, b, 2.17);
return 0;
}
void addscalar(int n, int m,
double a[n][n*m+300], double x)
{
for (int i = 0; i < n; i++)
for (int j = 0, k = n*m+300; j < k; j++)
// aはn*m+300個の要素をもつVLAへのポインタ
a[i][j] += x;
}
例5. 次はすべて適合する関数原型を宣言する。
double maximum(int n, int m, double a[n][m]);
double maximum(int n, int m, double a[*][*]);
double maximum(int n, int m, double a[ ][*]);
double maximum(int n, int m, double a[ ][m]);
次も同様である。
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);
(最後の宣言は,fを呼び出すときには,aに対応する実引数が,5個のdoubleから成る配
列要素を3個以上もつ配列の先頭を指す空でないポインタでなければならないことも指定して
いることに注意しなければならない。他の宣言は,そのような指定をしない。)
前方参照 型名(6.7.6),関数定義(6.9.1)
6.7.6
型名
構文規則
型名:
型指定子型修飾子並び 抽象宣言子opt
抽象宣言子:
ポインタ
ポインタopt 直接抽象宣言子
直接抽象宣言子:
( 抽象宣言子 )
直接抽象宣言子opt [ 代入式opt ]
直接抽象宣言子opt [ * ]
92
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
直接抽象宣言子opt ( 仮引数型並びopt )
意味規則 幾つかの文脈では,型を指定することが必要となる。型の指定は,型名(type name)を使って
行う。型名は,構文的にはその型の関数又はオブジェクトの宣言から識別子を取り去った形に相当する(126)。
例 プログラム片
(a)
int
(b)
int *
(c)
int *[3]
(d)
int (*)[3]
(e)
int (*)[*]
(f)
int *()
(g)
int (*)(void)
(h)
int (*const [])(unsigned int, ...)
は,それぞれ次の型を指定する。
(a) int
(b) intへのポインタ
(c) intへのポインタ3個から成る配列
(d) 3個のintから成る配列へのポインタ
(e) 個数が指定されないintの可変長配列へのポインタ
(f) 仮引数に関する情報をもたずintへのポインタを返す関数
(g) 仮引数をもたずintを返す関数へのポインタ
(h) 関数への不変ポインタの,個数が未指定の配列。各関数はunsigned int型の一つの仮引
数及び個数が未指定の他の仮引数をもち,intを返す。
6.7.7
型定義
構文規則
型定義名:
識別子
制約 可変修飾型を指定する型定義名は,ブロック有効範囲をもたなければならない。
意味規則 記憶域クラス指定子がtypedefの宣言では,各宣言子は識別子を型定義名として定義する。
型定義名は,その識別子に対して指定した型を表す(6.7.5で規定する。)。可変長配列宣言子で使われる配
列の大きさを示す式は,型定義名の宣言に到達するたびに評価する。typedef宣言は,新しい型を導入す
るのではなく,指定した型の同義語だけを導入する。すなわち,次の宣言
typedef T type̲ident;
type̲ident D;
において,type̲identを,宣言指定子列T(この型をTとする。)によって指定した型をもつ型定義名
として定義する。Dの中の識別子は,型“Tの派生宣言子型並び”をもつ。ここで,派生宣言子型並びは,
Dの宣言子で指定したものとする。型定義名は,通常の宣言子で宣言した他の識別子と同じ名前空間を共
───────────────────────────────────────────────
(126) 構文が示すとおり,型名の中の空の括弧は,仮引数に関する情報をもたない関数として解釈する。
省略された識別子のまわりの冗長な括弧とは解釈しない。
93
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
有する。
例1.
typedef int MILES, KLICKSP();
typedef struct { double hi, lo; } range;
の後では,プログラム片
MILES distance;
extern KLICKSP *metricp;
range x;
range z, *zp;
は,すべて正しい宣言である。distanceの型はint,metricpの型は“仮引数に関する情
報をもたずintを返す関数へのポインタ”,x及びzの型は前に宣言した構造体,zpは同じ構
造体へのポインタである。オブジェクトdistanceは,任意のintオブジェクトと適合する
型をもつ。
例2. 宣言
typedef struct s1 { int x; } t1, *tp1;
typedef struct s2 { int x; } t2, *tp2;
の後では,型t1とtp1の指す型とは適合する。型t1は,型struct s1と適合する。しか
し,型struct s2,型t2,tp2の指す型及び型intとは適合しない。
例3. 次の,分かりにくいプログラム片
typedef signed int t;
typedef int plain;
struct tag {
unsigned t:4;
const t:5;
plain r:5;
};
では,型定義名tを型signed intとして,型定義名plainを型intとしてそれぞれ宣言 し,
更に三つのビットフィールドメンバをもつ構造体を宣言している。ビットフィールドメンバは
それぞれ,
− 名前がtで,[0,15]の範囲の値をとるもの
− 名前がなく(もしアクセスできたとすれば)[−15,+15]又は[−16,+15]の範囲の値をとるconst
修飾されたもの(範囲の選択は処理系定義)
− 名前がrで,[0,31],[−15,+15]又は[−16,+15]の範囲の値をとるもの(範囲の選択は処理系
定義)
となる。1番目と2番目の違いは,1番目のビットフィールド宣言ではunsignedが型指定子
である(このためtは構造体メンバの名前となる。)のに対し,2番目のビットフィールド宣言
ではconstが型修飾子である(これは型定義名としてこの場所で依然として可視なtを修飾
する。)ことである。この宣言の後で,内側の有効範囲で
t f(t (t));
long t;
94
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
とした場合,関数fを型“名前のない仮引数を一つもち,signed intを返す関数”として
宣言する。fの仮引数は,名前のないsigned int型の仮引数を一つもち,signed intを
返す関数へのポインタ型である。識別子tは型long intをもつ。
例4. 一方,型定義名は,プログラムを読みやすくするために使用できる。次の三つのsignal関数
の宣言は,完全に同じ型を指定している。ここで1番目の例は,型定義名を使用せずに型を指
定している。
typedef void fv(int), (*pfv)(int);
void (*signal(int, void (*)(int)))(int);
fv *signal(int, fv *);
pfv signal(int, pfv);
例5. 型定義名が可変長配列型を表す場合,型定義名が使われるたびではなく,その定義の時に配列
長を固定する。
void copyt(int n)
{
typedef int B[n];
// Bはn個のint,nはここで評価される
n += 1;
B a;
// aはn(+=1適用前のn)個のint
int b[n];
// aとbは異なる大きさ
for (int i = 1; i < n; i++)
a[i-1] = b[i];
}
6.7.8
初期化
構文規則
初期化子:
代入式
{ 初期化子並び }
{ 初期化子並び , }
初期化子並び:
指示opt 初期化子
初期化子並び , 指示opt 初期化子
指示:
要素指示子並び =
要素指示子並び:
要素指示子
要素指示子並び 要素指示子
要素指示子:
[ 定数式 ]
. 識別子
制約 初期化する実体に含まれないオブジェクトに初期化子で値を格納してはならない。
95
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
初期化する実体の型は,大きさの分からない配列型であるか,又は可変長配列型以外のオブジェクト型
でなければならない。
静的記憶域期間をもつオブジェクトの初期化子の中のすべての式は定数式又は文字列リテラルでなけれ
ばならない。
識別子の宣言がブロック有効範囲をもち,かつ識別子が外部結合又は内部結合をもつ場合,その宣言に
その識別子に対する初期化子があってはならない。
要素指示子が
[ 定数式 ]
という形式の場合,現オブジェクト(この箇条で定義する。)は配列型をもち,式は整数定数式でなければ
ならない。配列の大きさが分からない場合,式の値は任意の非負数であってよい。
要素指示子が
. 識別子
という形式の場合,現オブジェクト(この箇条で定義する。)は構造体型又は共用体型をもち,識別子はそ
の型のメンバ名でなければならない。
意味規則 初期化子は,オブジェクトに格納する初期値を指定する。
この規格で明示的に異なる規定を行わない限り,この箇条では構造体型又は共用体型のオブジェクトの
名前のないメンバを初期化の対象とはしない。構造体オブジェクトの名前のないメンバは,初期化後であ
っても不定の値をもつ。
自動記憶域期間をもつオブジェクトを明示的に初期化しない場合,その値は不定とする。静的記憶域期
間をもつオブジェクトを明示的に初期化しない場合,次の規定に従う。
a) そのオブジェクトの型がポインタ型の場合,空ポインタに初期化する。
b) そのオブジェクトの型が算術型の場合,(正又は符号無しの)0に初期化する。
c) そのオブジェクトが集成体の場合,各メンバにa)〜d)の規定を(再帰的に)適用し初期化する。
d) そのオブジェクトが共用体の場合,最初の名前付きメンバにa)〜d)の規定を(再帰的に)適用し初
期化する。
スカラオブジェクトに対する初期化子は,単一の式でなければならない。それを波括弧で囲んでもよい。
そのオブジェクトの初期値は(型変換後の)その式の値とする。型の制限及び型変換は,単純代入と同じ
とする。このとき,宣言した型の非修飾版を,スカラオブジェクトの型とみなす。
この箇条のこれ以降では,集成体型又は共用体型のオブジェクトの初期化子を扱う。
自動記憶域期間をもつ構造体オブジェクト又は共用体オブジェクトに対する初期化子は,この箇条で規
定する初期化子並び,又は適合する構造体型若しくは共用体型の単一の式のいずれかでなければならない。
後者の場合,名前のないメンバも含めて,その式の値を,そのオブジェクトの初期値とする。
文字型の配列は,単純文字列リテラルで初期化してもよい。それを波括弧で囲んでもよい。単純文字列
リテラルの文字(空きがある場合又は配列の大きさが分からない場合,終端ナル文字も含めて。)がその配
列の要素を前から順に初期化する。
wchar̲t型と適合する要素型の配列は,ワイド文字列リテラルで初期化してもよい。それを波括弧で囲
んでもよい。ワイド文字列リテラルのワイド文字(空きがある場合又は配列の大きさが分からない場合,
終端ナルワイド文字も含めて。)がその配列の要素を前から順に初期化する。
これら以外の場合,集成体型又は共用体型をもつオブジェクトに対する初期化子は,要素又は名前付き
メンバに対する初期化子並びを波括弧で囲んだものでなければならない。
96
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
波括弧で囲まれたそれぞれの初期化子並びに結び付くオブジェクトを,現オブジェクト(current object)
という。指示がない場合,現オブジェクト中の部分オブジェクトを,現オブジェクトの型に従う順序で初
期化する。すなわち,配列要素は添字の昇順で初期化し,構造体メンバは宣言の順で初期化し,共用体で
は最初の名前付きメンバを初期化する(127)。一方,指示が存在する場合,それに続く初期化子を使って要
素指示子が示す部分オブジェクトを初期化する。そして要素指示子で示される部分オブジェクトの次の部
分オブジェクトから順に初期化を続ける(128)。
各要素指示子並びは,それを囲む最も近い波括弧の対に結び付けられた現オブジェクトに対する記述で
メンバを指定する。要素指示子並びの各項目は(順に)現オブジェクトの特定のメンバを指定し,次の要
素指示子があれば現オブジェクトをそのメンバに変更する(129)。一つの要素指示子並びを処理した後の現
オブジェクトは,続く初期化子で初期化される部分オブジェクトとする。
初期化は,初期化子並びの順に行う。特定の部分オブジェクトに対する初期化子が,同じ部分オブジェ
クト(129a)に対する以前の初期化子を書き換えることもある。明示的に初期化されないすべての部分オブジ
ェクトについては,静的記憶域期間をもつオブジェクトと同じ規則で暗黙に初期化する。
集成体又は共用体が集成体又は共用体の要素又はメンバを含む場合,これらの規則をその部分集成体又
は含まれる共用体に再帰的に適用する。部分集成体又は含まれる共用体の初期化子が左波括弧で始まる場
合,その波括弧と対応する右波括弧で囲まれた初期化子は,その部分集成体又は含まれる共用体の要素又
はメンバを初期化する。そうでない場合,部分集成体の要素若しくはメンバ又は含まれる共用体の最初の
メンバに見合うに十分なだけ並びから初期化子が取られる。残りの初期化子は,その部分集成体又は含ま
れる共用体の外側の集成体の次の要素又はメンバの初期化のために残す。
集成体型の要素又はメンバの個数より波括弧で囲まれた並びにある初期化子が少ない場合,又は大きさ
が既知の配列の要素数よりその配列を初期化するための文字列リテラル中の文字数が少ない場合,その集
成体型の残りを,静的記憶域期間をもつオブジェクトと同じ規則で暗黙に初期化する。
大きさの分からない配列を初期化する場合,明示的な初期化子をもつ要素の添字の最大値でその大きさ
を決定する。初期化子並びの終了時点で,その配列はもはや不完全型をもたない。
初期化子並びの式中で副作用の発生する順序は,未規定とする(130)。
例1. <complex.h>が#includeされているとき,宣言
int i = 3.5;
complex c = 5 + 3 * I;
───────────────────────────────────────────────
(127) 部分集成体又は含まれる共用体に対する初期化子並びが左波括弧で始まらない場合,それらの部分
オブジェクトを通常の方法で初期化するが,部分集成体又は含まれる共用体が現オブジェクトにな
ることはない。現オブジェクトは,波括弧で囲まれた初期化子並びにだけ結び付く。
(128) 共用体の一つのメンバが初期化された後の次のオブジェクトは,共用体の次のメンバではない。共
用体を含むオブジェクト内の次の部分オブジェクトが次のオブジェクトとなる。
(129) すなわち,波括弧の対に結び付けられた集成体又は共用体の直接の部分オブジェクトを指定するた
めだけに要素指示子を使うことができる。さらに,個々の要素指示子並びは独立である。
(129a) 部分オブジェクトに対する初期化子が書き換えられて,その部分オブジェクトの初期化に使われな
い場合,その初期化子は全く評価しなくてもよい。
(130) 特に,評価の順序が部分オブジェクトを初期化する順序と同じである必要はない。
97
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
は,iを定義し値3で初期化する。さらに,cを定義し値5.0+i3.0で初期化する。
例2. 宣言
int x[] = { 1, 3, 5 };
では,大きさが未指定であり,かつ初期化子が三つあるため,xを三つの要素をもつ1次元配
列のオブジェクトとして定義し,初期化する。
例3. 宣言
int y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};
は,完全に波括弧で囲まれた初期化をもつ定義である。1,3及び5は,yの第1行(配列オブ
ジェクトy[0])すなわちy[0][0],y[0][1]及びy[0][2]を初期化する。同様に,次の2
行は,y[1]及びy[2]を初期化する。初期化子の個数が要素数より少ないので,y[3]の各要素
の初期値は0となる。
int y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
によっても完全に同じ結果を得る。y[0]の初期化子は,左波括弧で始まらないため並びの中か
ら三つの要素を使う。同様にy[1]及びy[2]に次の三つずつを引き続いて使う。
例4. 宣言
int z[4][3] = {
{ 1 }, { 2 }, { 3 }, { 4 }
};
は,zの第1列を指定されたように初期化し,残りを0で初期化する。
例5. 宣言
struct { int a[3], b; } w[] = { { 1 }, 2 };
は,波括弧による囲み方が不統一な初期化をもつ定義である。これは,二つの構造体型の要素
をもつ配列を定義する。w[0].a[0]は1,w[1].a[0]は2となり,他の要素はすべて0とな
る。
例6. 宣言
short q[4][3][2] = {
{ 1 },
{ 2, 3 },
{ 4, 5, 6 }
};
は,不完全だが波括弧による囲み方が統一された初期化を含む。これは,3次元配列オブジェ
クトを定義する。q[0][0][0]は1,q[1][0][0]は2,q[1][0][1]は3となり,更に4,5
及び6はq[2][0][0],q[2][0][1]及びq[2][1][0]をそれぞれ初期化する。残りはすべて
0となる。q[0][0]の初期化子は左波括弧で始まらないので,現在の並びの中から六つまでの
98
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
要素を使うことができる。この場合は初期化子が一つだけなので,残りの五つの要素を0で初
期化する。同様にq[1][0]及びq[2][0]の初期化子は左波括弧で始まらないので,各々六つ
までの要素をそれぞれの2次元部分集成体を初期化するために使う。いずれかの並びの中に六
つを超える要素があった場合,診断メッセージが出力されるであろう。同様の初期化は,
short q[4][3][2] = {
1, 0, 0, 0, 0, 0,
2, 3, 0, 0, 0, 0,
4, 5, 6
};
又は完全に波括弧で囲まれた形式
short q[4][3][2] = {
{
{ 1 },
},
{
{ 2, 3 },
},
{
{ 4, 5 },
{ 6 },
}
};
によっても達成できる。
一般に,完全な括弧付けをした形式,又は最低限の括弧を使った形式が混乱を生じにくい。
例7. 配列型を完全にする初期化の形式の一つは,型定義名を含む。宣言
typedef int A[];
// OK − ブロック有効範囲をもつ宣言
が与えられた場合,宣言
A a = { 1, 2 }, b = { 3, 4, 5 };
は,不完全型の規則によって,
int a[] = { 1, 2 }, b[] = { 3, 4, 5 };
と同一となる。
例8. 宣言
char s[] = "abc", t[3] = "abc";
は,要素を単純文字列リテラルで初期化された“単なる”char型の配列オブジェクトs及びt
を定義する。この宣言は,
char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
と同一となる。配列の内容は,変更できる。一方,宣言
char *p = "abc";
は,pを“charへのポインタ”型として定義し,要素が単純文字列リテラルで初期化され,長
99
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
さが4の“charの配列”型オブジェクトを指すように初期化する。pを用いてその配列の内容
を変更しようとした場合,その動作は未定義である。
例9. 要素指示子を使うことにより,配列を列挙体の要素に対応するように初期化することができる。
enum { member̲one, member̲two };
const char *nm[] = {
[member̲two] = "member two",
[member̲one] = "member one",
};
例10. 構造体メンバの順序に依存せずにメンバを0以外の値に初期化することができる。
div̲t answer = { .quot = 2, .rem = -1 };
例11. 単純な初期化子が誤解されそうな場合,要素指示子を使って明示的な初期化をすることができ
る。
struct { int a[3], b; } w[] =
{ [0].a = {1}, [1].a[0] = 2 };
例12. 要素指示子を一つだけ使うことで,配列の両端に初期値を与えることができる。
int a[MAX] = {
1, 3, 5, 7, 9, [MAX-5] = 8, 6, 4, 2, 0
};
この例においてMAXが10より大きい場合,配列中央に幾つかの値0の要素が存在すること
になる。MAXが10よりも小さい場合,先頭の5個の初期化子で与えられた値の幾つかを後半
の5個の初期化子が書き換える。
例13. 共用体の任意のメンバを初期化することができる。
union { /* ... */ } u = { .any̲member = 42 };
前方参照 共通の定義<stddef.h>(7.17)
6.8
文及びブロック
構文規則
文:
ラベル付き文
複合文
式文
選択文
繰返し文
分岐文
意味規則 文(statement)は,実行すべき動作を規定する。別に規定する場合を除き,文は順番に実行す
る。
ブロック(block)は,幾つかの宣言及び文を一つの構文的な単位にまとめることを可能にする。自動記
憶域期間をもつオブジェクトの初期化子,及びブロック有効範囲をもつ通常の識別子の可変長配列宣言子
は,文の場合と同じく実行中に宣言に到達するたびにこれを評価し,値をそのオブジェクトに格納する(初
期化子をもたないオブジェクトに不定の値を格納することを含む。)。一つの宣言の中の評価と格納の順序
100
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
は,宣言子が現れる順とする。
完結式(full expression)は,他の式の部分にも宣言子の部分にもなっていない式とする。初期化子,式
文の中の式,選択文(if文又はswitch文)の制御式,while文又はdo文の制御式,for文の(省略
可能な)各式,及びreturn文の(省略可能な)式は完結式となる。完結式の終わりは,副作用完了点と
する。
前方参照 return文(6.8.6.4),繰返し文(6.8.5),式文及び空文(6.8.3),選択文(6.8.4)
6.8.1
ラベル付き文
構文規則
ラベル付き文:
識別子
:
文
case 定数式
:
文
default
:
文
制約 caseラベル又はdefaultラベルは,switch文の中以外の場所に現れてはならない。これらのラ
ベルに対するその他の制約は,6.8.4.2で規定する。
ラベル名は,関数の中で一意でなければならない。
意味規則 任意の文の前に,一つの識別子をラベル名として宣言する接頭語があってもよい。ラベル自体
は,制御の流れを変更しない。制御の流れは,ラベルに妨げられることなく続く。
前方参照 goto文(6.8.6.1),switch文(6.8.4.2)
6.8.2
複合文
構文規則
複合文:
{ ブロック構成要素並びopt }
ブロック構成要素並び:
ブロック構成要素
ブロック構成要素並び ブロック構成要素
ブロック構成要素:
宣言
文
意味規則 複合文(compound statement)はブロックとする。
6.8.3
式文及び空文
構文規則
式文:
式opt ;
意味規則 式文の中の式は,その副作用(131)を発生させることを目的に,ボイド式として評価する。
空文(null statement)(セミコロンだけの文)は,何の動作も行わない。
例1. 関数呼出しを副作用だけを目的とする式文として評価する場合,式をキャストでボイド式に型
───────────────────────────────────────────────
(131) 代入や副作用をもつ関数呼出しなど。
101
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
変換することによって,その値を捨て去ることを明示できる。
int p(int);
/* ... */
(void)p(0);
例2. プログラム片
char *s;
/* ... */
while(*s++ != '\0')
;
では,繰返し文に空のループ本体を与えるために,空文を使用している。
例3. 複合文を閉じる}の直前にラベルを置くために,空文を使用することもできる。
while(loop1) {
/* ... */
while(loop2) {
/* ... */
if (want̲out)
goto end̲loop1;
/* ... */
}
/* ... */
end̲loop1: ;
}
前方参照 繰返し文(6.8.5)
6.8.4
選択文
構文規則
選択文:
if ( 式 ) 文
if ( 式 ) 文 else 文
switch ( 式 ) 文
意味規則 選択文は,制御式の値に応じて幾つかの文の中から一つを選択する。
選択文はブロックとする。そのブロックの有効範囲は,それを囲むブロックの有効範囲の真部分集合と
する。各副文もブロックとする。そのブロックの有効範囲は,選択文の有効範囲の真部分集合とする。
6.8.4.1
if文
制約 if文の制御式は,スカラ型をもたなければならない。
意味規則 両形式とも,式の値が0と比較して等しくない場合,最初の副文を実行する。else形式の場
合,式の値が0と比較して等しいならば,2番目の副文を実行する。ラベルを通して最初の副文に制御が
到達した場合,2番目の副文は実行しない。
elseは,構文規則で許されるifのうち,そのelseの前で最も近い位置にあるifと結び付く。
6.8.4.2
switch文
102
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
制約 switch文の制御式は,整数型をもたなければならない。
可変修飾型をもつ識別子の有効範囲の中にそのswitch文に対応するcaseラベル又はdefaultラベ
ルがある場合,switch文全体がその識別子の有効範囲の中になければならない(132)。
各caseラベルの式は,整数定数式でなければならず,同一のswitch文の中で二つのcaseラベルの
定数式が型変換後に同じ値をもっていてはならない。switch文の中には,高々一つのdefaultラベル
があってもよい(ただし,内側のswitch文には,defaultラベル又は外側のswitch文のcase定数
式と重複する値のcase定数式があってもよい。)。
意味規則 switch文は,制御式の値,スイッチ本体(switch body)と呼ばれる文の中のdefaultラベル
の有無及びcaseラベルの値に依存して,スイッチ本体,スイッチ本体の中の文又はスイッチ本体の次の
文に制御を移す。caseラベル又はdefaultラベルは,それを囲んでいる最も内側のswitch文の中だけ
で有効とする。
制御式に対して整数拡張を行う。各caseラベルの定数式を制御式の拡張後の型に型変換する。型変換
した値が拡張した制御式の値と一致する場合,制御はその一致したcaseラベルの直後の文に移る。型変
換したcase定数式のいずれとも一致しない場合,defaultラベルがあれば制御はそのラベル付き文に移
る。defaultラベルがなければ,スイッチ本体のいずれの部分も実行しない。
処理系限界 処理系は,switch文におけるcaseラベルの個数を制限してもよい(5.2.4.1参照)。
例 次の作為的なプログラム片
switch (expr)
{
int i = 4;
f(i);
case 0:
i = 17;
/* default部へ抜ける */
default:
printf("%d\n", i);
}
において,識別子がiのオブジェクトは,(そのブロック内で)自動記憶域期間をもって存在す
るが,初期化されることはない。したがって,制御式が0以外の値をもつ場合,関数printfの
呼出しは不定の値にアクセスすることになる。同様に関数fの呼出しには,制御が到達しない。
6.8.5
繰返し文
構文規則
繰返し文:
while ( 式 ) 文
do 文 while ( 式 ) ;
───────────────────────────────────────────────
(132) つまり,その識別子の宣言は,switch文より前にあるか,又はその宣言を含むブロックにある
switchに関連する最後のcaseラベル若しくはdefaultラベルより後にあるかのいずれかであ
る。
103
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
for ( 式opt ; 式opt ; 式opt ) 文
for (宣言 式opt ; 式opt ) 文
制約 繰返し文の制御式は,スカラ型をもたなければならない。
for文の宣言部分で宣言できるのは,自動記憶域期間をもつオブジェクトだけとする(register記憶
域クラス指定子があってもよい。)。
意味規則 繰返し文は,ループ本体(loop body)と呼ばれる文を,制御式が0と比較して等しくなるまで
の間,繰り返して実行する。
繰返し文はブロックとする。そのブロックの有効範囲は,それを囲むブロックの有効範囲の真部分集合
とする。ループ本体もブロックとする。そのブロックの有効範囲は,繰返し文の有効範囲の真部分集合と
する。
6.8.5.1
while文 制御式の評価は,ループ本体の各実行の前に行う。
6.8.5.2
do文 制御式の評価は,ループ本体の各実行の後に行う。
6.8.5.3
for文 文
for ( 節1 ; 式2 ; 式3 ) 文
の動作は次のとおりとする。式2は制御式とし,ループ本体の各実行の前に評価する。式3はループ本体
の各実行の後にボイド式として評価する。節1が宣言である場合,そこで宣言する変数の有効範囲は宣言
の残り及び他の二つの式を含むループ全体とする。その宣言に到達するのは,制御式の最初の評価の前と
する。節1が式である場合,それは制御式の最初の評価の前にボイド式として評価する(133)。
節1も式3も省略してよい。式2を省略した場合,0でない定数によって置き換える。
6.8.6
分岐文
構文規則
分岐文:
goto 識別子 ;
continue ;
break ;
return 式opt ;
意味規則 分岐文は,別の場所への無条件分岐を引き起こす。
6.8.6.1
goto文
制約 goto文の識別子は,そのgoto文を含む関数内のどこかに位置するラベルを指定しなければなら
ない。goto文は,可変修飾型をもつ識別子の有効範囲の外側からその識別子の有効範囲の内側へ分岐し
てはならない。
意味規則 goto文は,そのgoto文を含む関数内の指定されたラベルが付けられた文への無条件分岐を
引き起こす。
例1. 複雑な文の集まりの途中に分岐することが便利な場合がある。次の三つの仮定が成立する場合
───────────────────────────────────────────────
(133) すなわち,節1はループの初期化を指定し,ループの中で使用する一つ以上の変数を宣言してもよ
い。制御式である式2は,各繰返しの前に評価し,その式が0と比較して等しくなるまでループの
実行を継続することを指定する。式3は各繰返しの後に実行される演算(増加など)を指定する。
104
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
の書き方の例を示す。
1. 共通の初期化コードは,実行中の関数で可視なオブジェクトだけにアクセスする。
2. 共通の初期化コードは,重複して記述するには大きすぎる。
3. 次に行うべき演算を決定するコードは,(例えば,continue文によって到達できるように
するために)ループの先頭にある。
/* ... */
goto first̲time;
for(;;) {
// 次の演算の決定
/* ... */
if (再初期化が必要) {
// 再初期化だけのコード
/* ... */
first̲time:
// 共通の初期化コード
/* ... */
continue;
}
// その他の演算の処理
/* ... */
}
例2. goto文は可変修飾型をもつオブジェクトの宣言を飛び越してはならない。しかし,有効範囲
の中の飛び越しは許される。
goto lab3;
// 正しくない:VLAの有効範囲に入る
{
double a[n];
a[j] = 4.4;
lab3:
a[j] = 3.3
goto lab4;
// 正しい:VLAの有効範囲内
a[j] = 5.5
lab4:
a[j] = 6.6;
}
goto lab4;
// 正しくない:VLAの有効範囲に入る
6.8.6.2
continue文
制約 continue文は,ループ本体の中に又はループ本体としてだけ現れなければならない。
意味規則 continue文は,それを囲む最も内側の繰返し文のループ継続部,すなわちループ本体の終わ
りへの分岐を引き起こす。より正確には,次の3種類の繰返し文
while (/* ... */ ) {
105
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
/* ... */
continue;
/* ... */
contin: ;
}
do {
/* ... */
continue;
/* ... */
contin: ;
} while (/* ... */);
for (/* ... */) {
/* ... */
continue;
/* ... */
contin: ;
}
の中でcontinue文はgoto contin;(134)と等価とする。ただし,continue文が内側の繰返し文の中
にある場合(その場合,それはその繰返し文の中で解釈する。)を除く。
6.8.6.3
break文
制約 break文は,スイッチ本体若しくはループ本体の中に,又はスイッチ本体若しくはループ本体とし
てだけ,現れなければならない。
意味規則 break文は,それを囲む最も内側のswitch文又は繰返し文の実行を終了させる。
6.8.6.4
return文
制約 式をもつreturn文は,void型を返す関数の中に現れてはならない。式をもたないreturn文は,
void型を返す関数の中にだけ現れなければならない。
意味規則 return文は,実行中の関数の実行を終了し,制御をその呼出し元に返す。一つの関数は,任
意の個数のreturn文をもってもよい。
式をもつreturn文を実行すると,その式の値を関数呼出し式の値として呼出し元に返す。式がreturn
文を囲む関数の返却値の型と異なる型をもつ場合,その値は,その関数の返却値の型をもつオブジェクト
への代入と同じ規則で型変換する(135)。
例
struct s { double i; } f(void);
───────────────────────────────────────────────
(134) ラベルcontin:の後は空文である。
(135) return文は,代入でない。6.5.16.1のオブジェクトの記憶域の重なりに関する制約は,関数から
の戻りの場合には適用しない。
106
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
union {
struct {
int f1;
struct s f2;
} u1;
struct {
struct s f3;
int f4;
} u2;
} g;
struct s f(void)
{
return g.u1.f2;
}
/* ... */
g.u2.f3 = f();
ここで,未定義の動作はないが,仮に(値を取得する関数呼出しを使わないで)代入が直接行わ
れるならば,未定義の動作が発生する。
6.9
外部定義
構文規則
翻訳単位:
外部宣言
翻訳単位 外部宣言
外部宣言:
関数定義
宣言
制約 記憶域クラス指定子auto及びregisterが,外部宣言の宣言指定子列の中に現れてはならない。
内部結合で宣言した識別子に対する外部定義が,一つの翻訳単位の中に二つ以上あってはならない。さ
らに,内部結合で宣言した識別子を式(結果が整数定数であるsizeof演算子のオペランドである場合を
除く。)の中で使用する場合,同じ翻訳単位の中にその識別子に対する外部定義がちょうど一つなくてはな
らない。
意味規則 前処理後のプログラムテキストの単位を翻訳単位と呼ぶ(5.1.1.1参照)。翻訳単位は一つ以上の
外部宣言から成る。外部宣言は,どの関数から見ても外側に現れる(したがって,ファイル有効範囲をも
つ。)ので,“外部”という。その識別子を名前とするオブジェクト又は関数のための記憶域の確保を伴う
宣言を定義という(6.7参照)。
(インライン定義以外の)関数の定義又はオブジェクトの定義ともなる外部宣言を外部定義(external
definition)という。外部結合で宣言した識別子を式(結果が整数定数であるsizeof演算子のオペランド
107
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
である場合を除く。)の中で使用している場合,プログラム全体のどこかにその識別子に対する外部定義が
ちょうど一つなければならない。使用していない場合,一つ以下でなければならない(136)。
6.9.1
関数定義
構文規則
関数定義:
宣言指定子列 宣言子 宣言並びopt 複合文
宣言並び:
宣言
宣言並び 宣言
制約 関数定義で宣言する識別子(その関数の名前)の型が関数型であることは,その関数定義の宣言子
の部分で指定しなければならない(137)。
関数の返却値の型は,配列型以外のオブジェクト型又はvoid型でなければならない。
宣言指定子列の中に記憶域クラス指定子がある場合,それはextern又はstaticのいずれかでなけれ
ばならない。
宣言子が仮引数型並びを含む場合,それぞれの仮引数の宣言は識別子を含まなければならない。ただし,
仮引数型並びがvoid型の仮引数一つだけから成る特別な場合を除く。この場合は,識別子があってはな
らず,更に宣言子の後ろに宣言並びが続いてはならない。
宣言子が識別子並びを含む場合,宣言並びの中の各宣言は,少なくとも一つの宣言子をもたなければな
らず,それらの宣言子は,識別子並びに含まれる識別子の宣言でなければならない。そして,識別子並び
の中のすべての識別子を宣言しなければならない。型定義名として宣言された識別子を仮引数として再宣
言してはならない。宣言並びの中の宣言は,register以外の記憶域クラス指定子及び初期化を含んでは
ならない。
意味規則 関数定義の宣言子は,定義される関数の名前及びその仮引数の識別子を指定する。宣言子が仮
引数型並びを含む場合,その仮引数型並びがすべての仮引数の型も指定する。この場合は,同じ翻訳単位
のこれ以降の部分で同じ関数を呼び出すための関数原型としても働く。宣言子が識別子並びを含む場合
───────────────────────────────────────────────
(136) すなわち,外部結合で宣言した識別子を式の中で使用しない場合,その外部定義は必要ではない。
(137) これは,関数定義の型をtypedefから受け継ぐことはできないことを意味する。
typedef int F(void);
// 型Fは“仮引数をもたず,intを返す関数”
F f, g;
// fとgはいずれもFと適合する型をもつ
F f { /* ... */ }
// 誤:構文エラー/制約違反
F g() { /* ... */ }
// 誤:gが関数を返すことになる
int f(void) { /* ... */ }
// 正:fはFと適合する型をもつ
int g() { /* ... */ }
// 正:gはFと適合する型をもつ
F *e(void) { /* ... */ }
// eは関数へのポインタを返す
F *((e))(void) { /* ... */ }
// 同上,括弧は無関係
int (*fp)(void);
// fpは型Fの関数を指す
F *Fp;
// Fpは型Fの関数を指す
108
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
(138),仮引数の型はその後ろに続く宣言並びで宣言しなければならない。いずれの場合でも,各仮引数の
型は,仮引数型並びに対する6.7.5.3の規定に従って型調整する。型調整した結果の型はオブジェクト型で
なければならない。
可変個数の実引数を受け付ける関数を,省略記号表記で終わる仮引数型並びを使わずに定義した場合,
その動作は未定義とする。
各仮引数は,自動記憶域期間をもつ。その識別子は左辺値とし,関数本体を構成する複合文の先頭で宣
言されたとみなす(このため,関数本体では更に内側のブロックの中以外では再宣言できない。)。仮引数
のための記憶域の配置は,未規定とする。
関数の入り口で,可変修飾された各仮引数の大きさを指定する式を評価し,各実引数式の値を代入の場
合と同じ方法で,対応する仮引数の型に変換する(実引数としての配列式及び関数指示子は呼出しの前に
ポインタに変換済みである。)。
すべての仮引数への代入の後,関数定義の本体を構成する複合文を実行する。
関数を終了させる}に到達し,かつ関数呼出しの値を呼出し元が使う場合,その動作は未定義とする。
例1.
extern int max(int a, int b)
{
return a > b ? a : b;
}
この例の中で,externは記憶域クラス指定子,intは型指定子である。max(int a, int b)
は関数宣言子であり,
{ return a > b ? a : b; }
は関数本体である。この関数定義と類似の次の例では,仮引数の宣言に識別子並びの形式を使
用している。
extern int max(a, b)
int a, b;
{
return a > b ? a : b ;
}
ここで,int a, b;は仮引数に対する宣言並びとなる。これら二つの定義の違いは,最初の形
式が関数の呼出し時に強制的に実引数の型変換を行う関数原型の宣言として働くのに対し,2
番目の形式ではそのような動作は行わないという点である。
例2. ある関数を別の関数に渡す場合,次のように書ける。
int f(void);
/* ... */
g(f);
このとき,gの定義は
void g(int (*funcp)(void))
───────────────────────────────────────────────
(138) “今後の言語の方針”(6.11.7)参照。
109
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
{
/* ... */
(*funcp)(); /* 又はfuncp() ... */
}
又は
void g(int func(void))
{
/* ... */
func(); /* 又は(*func)() ... */
}
とすればよい。
6.9.2
外部オブジェクト定義
意味規則 オブジェクトの識別子の宣言がファイル有効範囲及び初期化子をもつ場合,その宣言を識別子
の外部定義という。
ファイル有効範囲のオブジェクトの識別子を,初期化子を使わず,かつ,記憶域クラス指定子なしか又
は記憶域クラス指定子staticで宣言する場合,そのオブジェクトの識別子の宣言を仮定義(tentative
definition)という。翻訳単位が,ある識別子に対する仮定義を一つ以上含み,かつその識別子に対する外
部定義を含まない場合,その翻訳単位に,翻訳単位の終わりの時点での合成型,及び0に等しい初期化子
をもったその識別子のファイル有効範囲の宣言がある場合と同じ規則で動作する。
オブジェクトに対する識別子の宣言が仮定義であり,内部結合をもつ場合,その宣言の型は不完全型で
あってはならない。
例1.
int i1 = 1;
// 定義,外部結合
static int i2 = 2;
// 定義,内部結合
extern int i3 = 3;
// 定義,外部結合
int i4;
// 仮定義,外部結合
static int i5;
// 仮定義,内部結合
int i1;
// 正しい仮定義,前の定義を参照する
int i2;
// 前に内部結合をもつ定義があるため,
// 結合の不一致が生じ,6.2.2によって
// 動作は未定義となる
int i3;
// 正しい仮定義,前の定義を参照する
int i4;
// 正しい仮定義,前の定義を参照する
int i5;
// 前に内部結合をもつ定義があるため,
// 結合の不一致が生じ,6.2.2によって
// 動作は未定義となる
extern int i1;
// 外部結合をもつ前の定義を参照する
extern int i2;
// 内部結合をもつ前の定義を参照する
110
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
extern int i3;
// 外部結合をもつ前の定義を参照する
extern int i4;
// 外部結合をもつ前の定義を参照する
extern int i5;
// 内部結合をもつ前の定義を参照する
例2. 翻訳単位が
int i[];
を含み,その翻訳単位の最後で,配列iが依然として不完全型をもつ場合,配列iは暗黙の初
期化子によって一つの要素をもつようにされる。その要素にはプログラム開始時に0がセット
される。
6.10 前処理指令
構文規則
前処理ファイル:
グループopt
グループ:
グループ構成要素
グループ グループ構成要素
グループ構成要素:
if節
制御行
テキスト行
# 未定義指令
if節:
ifグループ elifグループ列opt elseグループopt endif行
ifグループ:
# if
定数式 改行 グループopt
# ifdef
識別子 改行 グループopt
# ifndef
識別子 改行 グループopt
elifグループ列:
elifグループ
elifグループ列 elifグループ
elifグループ:
# elif
定数式 改行 グループopt
elseグループ:
# else
改行 グループopt
endif行:
# endif
改行
制御行:
# include
前処理字句列 改行
# define
識別子 置換要素並び 改行
111
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
# define
識別子 左括弧 識別子並びopt ) 置換要素並び 改行
# define
識別子 左括弧 ...) 置換要素並び 改行
# define
識別子 左括弧 識別子並び , ...) 置換要素並び 改行
# undef
識別子 改行
# line
前処理字句列 改行
# error
前処理字句列opt 改行
# pragma
前処理字句列opt 改行
#
改行
テキスト行:
前処理字句列opt 改行
未定義指令:
前処理字句列 改行
左括弧:
空白類が直前にない(文字
置換要素並び:
前処理字句列opt
前処理字句列:
前処理字句
前処理字句列 前処理字句
改行:
改行文字
補足説明 前処理指令は,[翻訳フェーズ(4)の最初で]次の二つの条件のいずれかを満たす#前処理字
句で始まり,それに続く最初の改行文字で終わる一連の前処理字句とする(139)。
− ソースファイル中の最初の文字である(改行文字を含まない空白類の後であってもよい。)。
− 少なくとも一つの改行文字を含む空白類の後に続く。改行文字は前処理指令を終わらせる(前処理指
令がなかったとしたら関数形式マクロの呼出しとなる場合においても,改行文字はその前処理指令を
終わらせる。)。
参考 関数形式マクロの呼出しの中の改行文字の扱いについては,6.10.3参照。
テキスト行は,#前処理字句で始まってはならない。未定義指令は構文規則にある指令の名前で始まっ
てはならない。
読み飛ばされるグループ(6.10.1)の中では,指令の構文規則を緩和して,指令の名前とそれに続く改行
文字の間に任意の前処理字句の並びを置くことを可能とする。
制約 前処理指令の中(先頭の#前処理字句の直後から,最後の改行文字の直前まで)の前処理字句の間
に現れてよい空白類文字は,空白と水平タブだけとする[翻訳フェーズ(3)において注釈,又はその他の
───────────────────────────────────────────────
(139) このため,一般に前処理指令を“行”と呼ぶ。これらの“行”には,これ以外の構文的意味はない。
前処理中の特定の場合(例えば,6.10.3.2の#文字列リテラル作成演算子を参照)を除いて,すべて
の空白類は等価だからである。
112
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
空白類文字を置き換えた空白を含む。]。
意味規則 処理系は,ソースファイルの一部分を条件によって処理したり読み飛ばしたり,他のソースフ
ァイルを組み込んだり,マクロを置き換えたりすることができる。これらの処理は,概念的にはその翻訳
単位の翻訳の前に行うので,前処理(preprocessing)と呼ぶ。
前処理指令の中の前処理字句は,この規格で異なる規定を行わない限り,マクロ展開の対象とはならな
い。
例
#define EMPTY
EMPTY #include <file.h>
2行目の前処理字句の並びは,前処理指令ではない。これは,翻訳フェーズ(4)の最初で#で始
まらないからである(EMPTYが置き換えられた後なら#で始まるのだが。)。
6.10.1 条件付き取込み
制約 条件付き取込みを制御する式は,整数定数式でなければならない。ただし,キャストを含んではな
らず,識別子(キーワードと字句的に等しい識別子を含む。)は次の意味規則に従って解釈する(140)。さら
に,次の形式の単項演算子式を含んでもよい。
defined 識別子
又は
defined ( 識別子 )
これらの単項演算子式の評価の結果は,識別子をその時点でマクロ名として定義している場合(すなわち,
あらかじめ定義されているか,又は#define前処理指令の対象になっていて,しかもその後にその同じ識
別子を対象とした#undef前処理指令がない場合)1と評価し,そうでない場合0と評価する。
意味規則 次の形式の前処理指令
# if
定数式 改行 グループopt
# elif 定数式 改行 グループopt
は,制御定数式を評価した結果が0以外かどうかを検査する。
評価に先立って,制御定数式となる前処理字句列の中のマクロ呼出しを,普通のテキストと同様に
(defined単項演算子のオペランドとなるマクロ名を除いて)置き換える。この置き換えによって字句
definedが生成される場合,又はdefined単項演算子のマクロ置き換え前の使用法が,制約の中で規定
した二つの形式のいずれにも一致しない場合,その動作は未定義とする。マクロ展開及びdefined単項
演算子によるすべてのマクロ置き換えの実行後,残っているすべての識別子を前処理数0で置き換えてか
ら,各前処理字句を字句に変換する。変換後の字句は制御定数式を構成する。この式は,6.6の規定に従っ
て評価する。ただし,すべての符号付き整数型及びすべての符号無し整数型がそれぞれヘッダ<stdint.h>
で定義する型intmax̲t及びuintmax̲tと同じ表現をもつとの仮定の下で動作することを除く。これは
文字定数の解釈を含み,その解釈は逆斜線表記から実行文字集合の要素への変換を伴ってもよい。文字定
数に対応する数値が,(#if又は#elif指令の中以外の)式の中に同一の文字定数が現れたとき得られる
───────────────────────────────────────────────
(140) 制御定数式は,翻訳フェーズ(4)において評価するので,識別子にはマクロ名であるか否かの区
別しかない。すなわち,キーワード,列挙定数などはまだ存在しない。
113
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
値と一致しているか否かは,処理系定義とする(141)。さらに,単一文字から成る文字定数が負の値をもっ
てもよいか否かは,処理系定義とする。
次の形式の前処理指令
# ifdef 識別子 改行 グループopt
# ifndef 識別子 改行 グループopt
は,識別子をその時点でマクロ名として定義しているか否かを検査する。これらの前処理指令は,それぞ
れ“#if defined 識別子”及び“#if !defined 識別子”と等価とする。
各指令の条件は,順番に検査する。その条件の評価結果が偽(0)であった場合,それが制御するグルー
プを読み飛ばす。このとき,そのグループ内の前処理指令は,指令の種類を決める名前までを処理して,
if節の入れ子のレベルを追跡するためにだけ用いる。前処理指令のそれ以降の前処理字句及びグループ内
の他の前処理字句は,すべて無視する。条件が真(0以外)と評価された最初のグループだけを処理する。
どの条件も偽の場合,#else指令があるときは,#elseで制御されるグループを処理し,#else指令が
ないときは,#endifまでのすべてのグループを読み飛ばす(142)。
前方参照 最大幅整数型(7.18.1.5),ソースファイル取込み(6.10.2),マクロ置き換え(6.10.3)
6.10.2 ソースファイル取込み
制約 #include指令は,処理系で処理可能なヘッダ又はソースファイルを識別しなければならない。
意味規則 次の形式の前処理指令
# include <h文字列> 改行
は,処理系定義の場所を順に探索して,<区切り記号と>区切り記号の間で指定した文字列で一意に決まる
ヘッダを見つけ,そのヘッダの内容全体でこの指令を置き換える。どのようにして探索の場所を指定する
か,またどのようにしてヘッダを識別するかは,処理系定義とする。
次の形式の前処理指令
# include "q文字列" 改行
は,二つの"区切り記号の間で指定した文字列で一意に決まるソースファイルの内容全体で,この指令を
置き換える。指定したソースファイルの探索手順は処理系定義とする。この探索をサポートしていない場
合,又は探索が失敗した場合,同じ文字列(もしあれば>文字を含めて)を含む次の指令に読み替えたの
と同じ規則で再処理する。
# include <h文字列> 改行
次の(上の二つの形式のいずれとも一致しない)形式の前処理指令
# include 前処理字句列 改行
も許す。この指令の中の,includeの後ろにある前処理字句列は,通常のテキストと同様に処理する(そ
の時点でマクロ名として定義している各識別子は,その識別子の置換要素並びの前処理字句列に置き換え
───────────────────────────────────────────────
(141) すなわち,次の#if指令とif文の中の定数式が,この二つの文脈の中で同じ値として評価される
という保証はない。
#if 'z'-'a' == 25
if ('z'-'a' == 25)
(142) 構文で示したように,#else指令又は#endif指令の改行文字の前に前処理字句を続けてはならな
い。しかし,注釈は前処理指令の中を含めてソースファイルのどこに現れてもよい。
114
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
る。)。すべての置き換えを行った後の指令は,この箇条で規定する二つの形式のうちのいずれかと一致し
なければならない(143)。前処理字句<と>,又は二つの"文字の対に囲まれた前処理字句列を,一つのヘッダ
名の前処理字句に解釈する方法は,処理系定義とする。
処理系は,一つ以上の英字又は数字(5.2.1で定義する)の列の後ろにピリオド(.)及び一つの英字が
続く形式に対して,一意の対応付けを提供しなければならない。最初の文字は,英字でなければならない。
処理系は,アルファベットの大文字と小文字の区別を無視してもよく,対応付けはピリオドの前8文字に
対してだけ有効であると限定してもよい。
#include前処理指令は,入れ子になっていてもよい。すなわち,処理系定義の入れ子の制限(5.2.4.1
参照)の範囲内で,他のファイルの#include前処理指令によって取り込まれたソースファイルの中に現
れてもよい。
例1. #include前処理指令として,最も一般的な用法を次に示す。
#include <stdio.h>
#include "myprog.h"
例2. 次の例は,マクロ置き換えする#include指令を示している。
#if VERSION == 1
#define INCFILE "vers1.h"
#elif VERSION == 2
#define INCFILE "vers2.h" // 以下同様
#else
#define INCFILE "versN.h"
#endif
#include INCFILE
前方参照 マクロ置き換え(6.10.3)
6.10.3 マクロ置き換え
制約 二つの置換要素並びは,その前処理字句列の個数,順序,つづり及び空白類による区切り方が同じ
場合,そしてその場合に限り,同一の並びとみなす。ただし,空白類による区切りは,いずれも同じもの
とみなす。
オブジェクト形式マクロとしてその時点で定義されている識別子は,次の条件を満たす場合に限り,他
の#define前処理指令によって再定義してもよい。
− 2番目の定義がオブジェクト形式マクロ定義である。
− 二つの置換要素並びが同一である。
関数形式マクロとしてその時点で定義されている識別子は,次の条件を満たす場合に限り,他の#define
前処理指令によって再定義してもよい。
− 仮引数の個数とつづりが最初の定義と同一な関数形式マクロの定義である。
− 二つの置換要素並びが同一である。
オブジェクト形式マクロの定義では,識別子と置換要素並びの間に空白類がなければならない。
───────────────────────────────────────────────
(143) 隣接した文字列リテラルが,連結して一つの文字列リテラルになることはない(5.1.1.2の翻訳フェ
ーズ参照)。したがって,展開の結果二つの文字列リテラルが現れると正しくない指令行となる。
115
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
マクロ定義の中の識別子並びが省略記号で終わっていない場合は,関数形式マクロの呼出しにおける実
引数(前処理字句0個から成る実引数を含める)の個数は,マクロ定義内の仮引数の個数と一致しなけれ
ばならない。逆に,識別子並びが省略記号で終わる場合は,マクロ呼出しにおける実引数の個数は,マク
ロ定義内の仮引数(... を除く)の個数より多くなければならない。いずれの場合も,呼出しの終了を示
す)前処理字句がなければならない。
識別子̲ ̲VA̲ARGS̲ ̲は,仮引数に省略記号表記を用いる関数形式マクロにおける置換要素並びの中だ
けに現れなければならない。
関数形式マクロにおける仮引数識別子は,その有効範囲内で同じものを二つ以上宣言してはならない。
意味規則 defineの直後に記述してある識別子を,マクロ名(macro name)という。マクロ名に対する
名前空間が一つだけ存在する。いずれのマクロ形式においても,置換要素並びの前処理字句列の前又は後
に続く一つ以上の空白類文字を,置換要素並びの一部とはみなさない。
字句的に前処理指令の始まりとして許される位置に,#前処理字句に続いて識別子が現れた場合,その
識別子はマクロ置き換えの対象とはならない。
次の形式の前処理指令
# define 識別子 置換要素並び 改行
は,オブジェクト形式マクロ(object-like macro)を定義する。それ以降,そのマクロ名(144)の出現を,こ
の指令の残りを構成する置換要素並びの前処理字句列で置き換える。
次の形式の前処理指令
# define 識別子 左括弧 識別子並びopt ) 置換要素並び 改行
# define 識別子 左括弧 ... ) 置換要素並び 改行
# define 識別子 左括弧 識別子並び , ... ) 置換要素並び 改行
は,関数呼出しと同様の構文の,実引数をもつ関数形式マクロ(function-like macro)を定義する。仮引数
は,省略可能な識別子並びで指定する。仮引数の有効範囲は,識別子並びの中の宣言から,#define前処
理指令の終わりの改行文字までとする。これ以降,この関数形式マクロ名の次の前処理字句として(が現
れたときは,マクロ名からこの(前処理字句に対応する)前処理字句までの前処理字句列を,この定義内の
置換要素並びで置き換える(マクロ呼出し)。この際,間に左右対となる括弧前処理字句があっても,これ
らを無視する。関数形式マクロの呼出しを構成する前処理字句列の中では,改行は普通の空白類文字とみ
なす。
最も外側の括弧によって囲まれた前処理字句の列は,関数形式マクロの実引数の並びを形成する。並び
の中の個々の実引数は,コンマ前処理字句によって区切る。ただし,内側に対をなす括弧がある場合,そ
の中のコンマ前処理字句は,実引数を区切るものではない。実引数の並びの中に,ほかの場合であれば前
処理指令として働く前処理字句列がある場合,その動作は未定義とする。
マクロ定義の中の識別子並びに...が存在する場合,それらを区切るコンマ前処理字句も含め,それ以
後の実引数をまとめて単一の構成要素に結合する。これを可変個数の実引数(variable argument)という。
このように結合した場合の実引数の個数は,マクロ定義の中の(...を除く)仮引数の個数より一つ多い
───────────────────────────────────────────────
(144) マクロ置き換えのときには,すべての文字定数と文字列リテラルは前処理字句であり,識別子のよ
うな部分列を含みうる文字の並びではないので(5.1.1.2翻訳フェーズ参照),マクロ名や仮引数を
探すためにこれらの中を走査することはない。
116
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
個数とする。
6.10.3.1 実引数置換 関数形式マクロの実引数を識別した後,実引数置換を行う。実引数の中に含まれる
すべてのマクロの展開後,置換要素並びの中の仮引数を対応する実引数で置き換える。ただし,次の仮引
数は除く(6.10.3.2及び6.10.3.3参照)。
− #前処理字句又は##前処理字句が前にある仮引数
− ##前処理字句が後に続く仮引数
実引数置換の前に,実引数の前処理字句列を完全にマクロ置き換えする。このとき,実引数ごとに,その
前処理字句列が,現在の前処理ファイルの残りとなっているものとみなして処理する。つまり,他の前処
理字句列が存在しないかのように扱われる。
置換要素並びの中に現れる識別子̲ ̲VA̲ARGS̲ ̲は,それが一つの仮引数であるかのように扱わなけれ
ばならない。それを,可変個数の実引数が形成する前処理字句列で置き換える。
6.10.3.2 #演算子
制約 関数形式マクロの置換要素並びの中にある各#前処理字句の次の前処理字句は,仮引数でなければ
ならない。
意味規則 置換要素並びの中で,仮引数の直前に#前処理字句がある場合,対応する実引数の前処理字句
列のつづりを含んだ一つの単純文字列リテラル前処理字句によって,#前処理字句と仮引数を置き換える。
実引数の前処理字句の間にある各空白類は,その単純文字列リテラルの中で一つの空白文字になる。実引
数の最初の前処理字句の前の空白類と,最後の前処理字句の後ろの空白類は,削除する。これらを除けば,
実引数の各前処理字句の元のつづりが,そのまま単純文字列リテラルの中で保持される。ただし,文字列
リテラルと文字定数のつづりを正しく生成するため,次の特別な処理を行う。
− 文字定数又は文字列リテラルの(区切りのための"文字も含めた)"文字及び\文字の前に,\文字を挿
入する処理
− 国際文字名の最初の\文字の前に\文字を挿入する処理。ただし,この処理を行うか否かは処理系定義
とする。
置き換えの結果が正しい単純文字列リテラルでない場合,その動作は未定義とする。空の実引数に対応す
る単純文字列リテラルは""とする。#演算子及び##演算子の評価順序は,未規定とする。
6.10.3.3 ##演算子
制約 ##前処理字句は,マクロ定義のいずれの形式においても,置換要素並びの先頭又は終わりに現れて
はならない。
意味規則 関数形式マクロの置換要素並びの中で,仮引数の直前又は直後に##前処理字句がある場合,そ
の仮引数を対応する実引数の前処理字句列で置き換える。ただし,実引数が前処理字句0個である場合,
仮引数をプレースマーカ(placemarker)前処理字句で置き換える(145)。
オブジェクト形式マクロ及び関数形式マクロのいずれの呼出しにおいても,更に置き換えるべきマクロ
名があるかどうかを調べるためにその置換要素並びを再検査する前に,置換要素並びの##前処理字句(実
引数の中の##前処理字句を除く)を削除し,その直前にある前処理字句をその直後の前処理字句と連結す
る。プレースマーカ前処理字句は特別に扱う。すなわち,二つのプレースマーカ前処理字句を連結すると,
───────────────────────────────────────────────
(145) プレースマーカ前処理字句は,翻訳フェーズ(4)内部でだけ一時的に存在するため,構文規則の
中には現れない。
117
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
一つのプレースマーカ前処理字句となる。プレースマーカ前処理字句と,プレースマーカでない前処理字
句を連結すると,そのプレースマーカでない前処理字句となる。その結果が正しい前処理字句にならない
場合,その動作は未定義とする。その結果の字句はその後のマクロ置き換えの対象となる。##演算子の評
価順序は,未規定とする。
例 次に示すプログラム片では,
#define hash̲hash # ## #
#define mkstr(a) # a
#define in̲between(a) mkstr(a)
#define join(c, d) in̲between(c hash̲hash d)
char p[] = join(x, y); // char p[] = "x ## y"; と等価
展開によって,段階的に次に示す結果が生成される。
join(x, y)
in̲between(x hash̲hash y)
in̲between(x ## y)
mkstr(x ## y)
"x ## y"
すなわち,hash̲hashを展開して,二つのシャープ記号から成る新しい字句を生成する。しか
し,この新しい字句は##演算子ではない。
6.10.3.4 再走査と再置き換え 置換要素並び中のすべての仮引数を置き換え,更に#演算子及び##演算子
の処理を行った後,すべてのプレースマーカ前処理字句を削除する。その後,更に置き換えるべきマクロ
名があるかどうかを調べるために,ソースファイル上のその後のすべての前処理字句とともにその結果の
前処理字句を再走査する。
現在置き換え中のマクロの名前を,(ソースファイルの残りの前処理字句列は含まない)置換要素並びの
この走査中に検出した場合,置き換えは行わない。さらに,入れ子になった置き換えで現在置き換え中の
マクロの名前を検出した場合も,置き換えは行わない。これらの置き換えられなかったマクロ名の前処理
字句列は,たとえ,他の場合であれば置き換えが起きる文脈上で(再)検査しても,もはや置き換えの対
象とはならない。
完全にマクロ置き換えした結果の前処理字句列は,前処理指令の形をしていたとしても,前処理指令と
して処理することはない。ただし,その結果の中のすべてのプラグマ単項演算子式については,6.10.9の
規定に従って処理する。
6.10.3.5 マクロ定義の有効範囲 マクロ定義は,(ブロック構造とは独立に)対応する#undef指令を検出
するまで,又は(#undef指令がなければ)前処理翻訳単位の最後まで有効とする。マクロ定義は翻訳フ
ェーズ(4)の後は意味をもたない。
次の形式の前処理指令
#undef 識別子 改行
118
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
は,指定された識別子のマクロ名としての定義を無効にする。指定された識別子がその時点でマクロ名と
して定義されていない場合,この指令を無視する。
例1. マクロ機能の最も単純な使用法は,例えば次のような“定数名”の定義である。
#define TABSIZE 100
int table[TABSIZE];
例2. 次の例では,実引数の中で最大のものを値とする関数形式マクロを定義している。このマクロ
は,
− 適合する型であればどんな型の実引数に対しても動作する。
− 関数呼出しのオーバヘッドのないインラインコードを生成する。
という利点をもち,
− 実引数の一方を(副作用を含め)2回評価する。
− 何度も呼び出される場合に,関数に比べコードを多く生成する。
という欠点をもつ。さらに,アドレスをもたないので,アドレスを得ることもできない。
#define max(a, b) ((a) > (b) ? (a) : (b))
括弧は,実引数と結果の式が正しく演算子と結合されることを保証する。
例3. 再定義と再検査の例を次に示す。
#define x
3
#define f(a)
f(x * (a))
#undef
x
#define x
2
#define g
f
#define z
z[0]
#define h
g(~
#define m(a)
a(w)
#define w
0,1
#define t(a)
a
#define p()
int
#define q(x)
x
#define r(x,y)
x ## y
#define str(x)
# x
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };
上の例は,次の結果になる。
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
119
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };
例4. 単純文字列リテラルの生成及び字句の列の連結の規則の例を次に示す。
#define str(s) # s
#define xstr(s)
str(s)
#define debug(s, t)
printf("x" # s "= %d, x" # t "= %s", \
x ## s, x ## t)
#define INCFILE(n)
vers ## n
#define glue(a, b)
a ## b
#define xglue(a, b)
glue(a, b)
#define HIGHLOW
"hello"
#define LOW
LOW ", world"
debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", '\4') // この注釈はなくなる
== 0) str(: @\n), s);
#include xstr(INCFILE(2).h)
glue(HIGH, LOW);
xglue(HIGH, LOW)
上の例は,次の結果になる。
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n",s);
#include "vers2.h" (マクロ置き換え後,ファイルアクセス前)
"hello";
"hello" ", world"
さらに,単純文字列リテラルの連結を行い,最終的には次の結果になる。
printf("x1= %d, x2= %s", x1, x2);
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n",s);
#include "vers2.h" (マクロ置き換え後,ファイルアクセス前)
"hello";
"hello, world"
マクロ定義における#字句及び##字句の前後の空白は,あってもなくてもよい。
例5. プレースマーカ前処理字句の規則の例を次に示す。
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
t(10,,), t(,11,), t(,,12), t(,,) };
上の例は,次の結果になる。
int j[] = { 123, 45, 67, 89,
10, 11, 12, };
例6. 再定義の規則の例を次に示す。次の再定義は正しい。
120
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#define OBJ̲LIKE (1-1)
#define OBJ̲LIKE /* 空白類 */ (1-1) /* その他 */
#define FUNC̲LIKE(a) ( a )
#define FUNC̲LIKE( a )( /* 空白類に注意 */ \
a /* 一部が別の行
*/ )
しかし次の再定義は正しくない。
#define OBJ̲LIKE (0)
// 字句の並びが違う
#define OBJ̲LIKE (1 - 1) // 空白類が違う
#define FUNC̲LIKE(b) ( a )
// 仮引数の使用法が違う
#define FUNC̲LIKE(b) ( b )
// 仮引数のつづりが違う
例7. 最後に,可変個数の実引数の例を示す。
#define debug(...)
fprintf(stderr, ̲ ̲VA̲ARGS̲ ̲)
#define showlist(...) puts(#̲ ̲VA̲ARGS̲ ̲)
#define report(test, ...) ((test)?puts(#test):\
printf(̲ ̲VA̲ARGS̲ ̲))
debug("Flag");
debug("X = %d\n", x);
showlist(The first, second, and third items.);
report(x>y, "x is %d but y is %d", x, y);
上の例は,次の結果になる。
fprintf(stderr, "Flag" );
fprintf(stderr, "X = %d\n", x );
puts( "The first, second, and third items." );
((x>y)?puts("x>y"):
printf("x is %d but y is %d", x, y));
6.10.4 行制御
制約 #line指令の文字列リテラルは(それが存在する場合),単純文字列リテラルでなければならない。
意味規則 現在のソース行の行番号(line number)は,ソースファイルの翻訳フェーズ(1)(5.1.1.2参照)
の処理において,現在の字句までに読み込んだ改行文字の個数より1だけ大きい。
次の形式の前処理指令
# line 数字列 改行
は,処理系に対し,この指令以後のソース行の列が数字列(10進整数として解釈する。)で指定された行
番号で始まるものとして動作する。数字列は,0を指定してはならず,また2147483647より大きい数も指
定してはならない。
次の形式の前処理指令
# line 数字列 "s文字列opt" 改行
は,同様にみなし行番号を設定し,単純文字列リテラルの内容で,みなしソースファイル名を置き換える。
次の(上の二つの形式のいずれとも一致しない)形式の前処理指令
# line 前処理字句列 改行
121
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
も許す。この指令のlineの後にある前処理字句列は,通常のテキストにある場合と同じように処理する
(その時点でマクロ名として定義されている各識別子は,その前処理字句列の置換要素並びによって置き
換える。)すべての置き換えの結果の指令は,先の二つの形式のいずれかと一致しなければならない。一致
した形式の規則に従って処理する。
6.10.5 エラー指令
意味規則 次の形式の前処理指令
# error 前処理字句列opt 改行
は,処理系に対し,指定された前処理字句の列を含む診断メッセージを出力することを指示する。
6.10.6 プラグマ指令
意味規則 次の形式の前処理指令
# pragma 前処理字句列opt 改行
[ただし,(マクロ置き換えに先だって(146))pragmaの直後の前処理字句がSTDCではない]は,処理系
に対し処理系定義の方法で動作することを指示する。この動作の結果,翻訳に失敗してもよいし,翻訳プ
ログラム若しくは結果のプログラムが規格に合致しない動作をしてもよい。処理系が認識できないプラグ
マ指令は,無視する。
(マクロ置き換えに先だって)pragmaの直後の前処理字句がSTDCである場合,この指令に対してマ
クロ置き換えは行わない。この場合,この指令は次の形式(147)のいずれか一つでなければならない。これ
らの意味はこの規格の別の場所で規定する。
#pragma STDC FP̲CONTRACT 状態切替え指定
#pragma STDC FENV̲ACCESS 状態切替え指定
#pragma STDC CX̲LIMITED̲RANGE 状態切替え指定
状態切替え指定: 次のいずれか
ON OFF DEFAULT
前方参照 CX̲LIMITED̲RANGEプラグマ(7.3.4),FENV̲ACCESSプラグマ(7.6.1),FP̲CONTRACTプ
ラグマ(7.12.2)
6.10.7 空指令
意味規則 次の形式の前処理指令
# 改行
は,何の効果もない。
6.10.8 あらかじめ定義されたマクロ名 次に掲げる七つのマクロ名(148)は,処理系によって定義されてい
───────────────────────────────────────────────
(146) 処理系は,プラグマの中でマクロ置き換えを行う必要はない。しかし,標準のプラグマ(pragma
の直後にSTDCが続くもの)を除き,マクロ置き換えを行うことは許されている。標準でないプラ
グマにおいてマクロ置き換えを行った結果が,標準のプラグマと同じ形式になる場合の動作も,処
理系定義である。それが標準のプラグマであるかのように動作してもよい。しかし,そのように動
作する必要はない。
(147) “今後の言語の方針”(6.11.8)参照。
(148) “今後の言語の方針”(6.11.9)参照。
122
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
なければならない。
̲ ̲DATE̲ ̲
前処理翻訳単位の翻訳の日付("Mmm dd yyyy"の形式をもつ単純文
字列リテラルで,月の名前はasctime関数で生成されるものと同じ
とする。ddの値が10より小さいときは,その最初の文字は空白とす
る。)。翻訳の日付が得られない場合,処理系定義の正しい日付を提供
しなければならない。
̲ ̲FILE̲ ̲
みなしソースファイル名(単純文字列リテラル)(149)。
̲ ̲LINE̲ ̲
現在のソース行の(現在のソースファイルの中での)みなし行番号(整
数定数)(149)。
̲ ̲STDC̲ ̲
整数定数1。規格合致処理系であることを示すことを意図している。
̲ ̲STDC̲HOSTED̲ ̲
処理系が規格合致ホスト処理系の場合,整数定数1。そうでない場合,
整数定数0。
̲ ̲STDC̲VERSION̲ ̲
整数定数199901L(150)。
̲ ̲TIME̲ ̲
前処理翻訳単位の翻訳の時刻(asctime関数で生成される時刻と同
じ"hh:mm:ss"の形式の単純文字列リテラル)。翻訳の時刻が得られ
ない場合,処理系定義の正しい時刻を提供しなければならない。
次に掲げる三つのマクロ名は,処理系がサポートする機能に従って定義される。
̲ ̲STDC̲IEC̲559̲ ̲
附属書F(IEC 60559浮動小数点演算)の規定に合致することを示す
ための整数定数1。
̲ ̲STDC̲IEC̲559̲COMPLEX̲ ̲
附属書G(IEC 60559互換複素数演算)の規定に合致することを示す
ための整数定数1。
̲ ̲STDC̲ISO̲10646̲ ̲
型wchar̲tの値が,ISO/IEC 10646(指定した年と月におけるすべ
ての附属書と技術に関する正誤表を含む)で定義された文字の符号化
表現をもつことを示すための(例えば199712Lのような)yyyymmL
の形式の整数定数。
(̲ ̲LINE̲ ̲及び̲ ̲FILE̲ ̲を除いた)あらかじめ定義されたマクロの値は,翻訳単位を通じて定数
のままとする。
これらのマクロ名及び識別子definedは,#define前処理指令又は#undef前処理指令の対象にして
はならない。あらかじめ定義されたマクロ名を処理系が提供する場合は1文字目が下線,2文字目が英大
文字,又は1文字目,2文字目ともに下線,で始めなければならない。
処理系は,マクロ̲ ̲cplusplusをあらかじめ定義してはならない。さらに,標準ヘッダの中で定義し
てもならない。
前方参照 asctime関数(7.23.3.1),標準ヘッダ(7.1.2)
6.10.9 プラグマ演算子
───────────────────────────────────────────────
(149) みなしソースファイル名とみなし行番号は,#line前処理指令を用いて変更することができる。
(150) このマクロは,JIS X 3010:1993では定義していなかった。JIS X 3010:1996では,199409Lと規定
していた。その意図は,今後も,この規格の改正ごとに増やし続けることにある。ただし,常に型
long intの整数定数とする。
123
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
意味規則 次の形式の単項演算子式
̲Pragma ( 文字列リテラル )
は,次に示す順で処理する。
− 文字列リテラルを文字列解除(destringize)する。
− L接頭語があれば,それを削除
− 先頭と末尾の二重引用符を削除
− 逆斜線表記\"を二重引用符に置き換え
− 逆斜線表記\\を逆斜線一つに置き換え
− 文字列解除の結果の文字の並びを翻訳フェーズ(3)で処理し,前処理字句の列を生成する。
− 生成した前処理字句の列を,プラグマ指令の中の前処理字句列として実行する。
− 単項演算子式に最初にあった四つの前処理字句を削除する。
例 次の形式の指令
#pragma listing on "..\listing.dir"
は,次の形式でも表現できる。
̲Pragma ( "listing on \"..\\listing.dir\"" )
後の形式は,このとおり書いてあった場合でも,次のようにマクロ置き換えの結果として生成さ
れた場合でも,同じように処理する。
#define LISTING(x) PRAGMA(listing on #x)
#define PRAGMA(x) ̲Pragma(#x)
LISTING ( ..\listing.dir )
6.11 今後の言語の方針
6.11.1 浮動小数点型 今後の規格化により,long doubleよりも範囲,精度,又はその両方が大きい型
も含め,浮動小数点型を追加することがある。
6.11.2 識別子の結合 static記憶域クラス指定子を使わずに,ファイル有効範囲で内部結合をもつ識別
子を宣言することは廃止予定事項とする。
6.11.3 外部名 外部名の有意性に対し,255文字未満しか有意としない(各国際文字名又はソース拡張文
字は1文字と考える)制限は,廃止予定事項とする(既存の処理系に配慮して残した。)。
6.11.4 文字逆斜線表記 逆斜線表記としての英小文字は,今後の規格化のために予約済みとする。その他
の文字は,拡張のために使用してもよい。
6.11.5 記憶域クラス指定子 記憶域クラス指定子を宣言中の宣言指定子列の先頭以外の場所に置くこと
は,廃止予定事項とする。
6.11.6 関数宣言子 空の括弧を伴う関数宣言子(関数原型形式の仮引数型並びではない。)の使用は,廃
止予定事項とする。
6.11.7 関数定義 仮引数の識別子並びと宣言並びを別々に与える関数定義(関数原型形式の仮引数の型及
び識別子の宣言ではない。)の使用は,廃止予定事項とする。
6.11.8 プラグマ指令 最初の前処理字句がSTDCであるプラグマは,今後の規格化のために予約済みとす
る。
6.11.9 あらかじめ定義されたマクロ名 ̲ ̲STDC̲ で始まるマクロ名は,今後の規格化のために予約済み
とする。
124
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
7. ライブラリ
7.1
概説
7.1.1
用語の定義 最初のナル文字で終わり,かつそれを含む連続した文字の並びを文字列(string)と
いう。用語多バイト文字列(multibyte string)は,文字列中に含まれる多バイト文字に対して行う特別な処
理を強調するためか,又はワイド文字列との混同を避けるために使う。文字列を指すポインタ(pointer to a
string)は,その文字列の先頭の(最も低いアドレスをもつ)文字を指すポインタとする。文字列の長さ(length
of a string)は,ナル文字に先行するバイト数とし,文字列の値(value of a string)は,それに含まれる文
字の値が順序どおりに並んだ値の列とする。
浮動小数点数を文字の並びに,又は逆に文字の並びを浮動小数点数に変換する関数が,文字の並びの中
で小数部の始まりを表すために使用する文字を,小数点文字(decimal-point character)という(151)。この規
格では,小数点文字をピリオドで表現するが,setlocale関数を使用して変更してもよい。
コード値0のワイド文字をナルワイド文字(null wide character)という。
最初のナルワイド文字で終わり,かつそれを含む連続したワイド文字の並びをワイド文字列(wide string)
という。ワイド文字列を指すポインタ(pointer to a wide string)は,そのワイド文字列の先頭の(最も低い
アドレスをもつ)ワイド文字を指すポインタとする。ワイド文字列の長さ(length of a wide string)は,ナ
ルワイド文字に先行するワイド文字の個数とし,ワイド文字列の値(value of a wide string)は,それに含
まれるワイド文字のコード値が順序どおりに並んだ値の列とする。
多バイト文字列の中にあって,シフト状態を変化させる(可能性のある)連続するバイトの列をシフト
シーケンス(shift sequence)という(5.2.1.2参照)。シフトシーケンスは,対応するワイド文字をもっては
ならない。すなわち,シフトシーケンスは,それに隣接する多バイト文字に附属するものとみなす(152)。
前方参照 setlocale関数(7.11.1.1),文字操作(7.4)
7.1.2
標準ヘッダ 各ライブラリ関数は,ヘッダ(header)(153)において宣言する。関数の宣言には,関
数原型を含む型を用いる。ヘッダの内容は,#include前処理指令を使って利用可能となる。ヘッダは,
関連する関数の集合を宣言し,加えてそれらに必要な型や関数の使用を容易にする付加的なマクロ定義も
含む。7.で規定する型の宣言は,この規格で明示的に異なる規定を行わない限り,型修飾子を含んではな
らない。
次に示すヘッダを,標準ヘッダとする。
<assert.h>
<inttypes.h> <signal.h>
<stdlib.h>
<complex.h>
<iso646.h>
<stdarg.h>
<string.h>
<ctype.h>
<limits.h>
<stdbool.h>
<tgmath.h>
───────────────────────────────────────────────
(151) 小数点文字を使用する関数は,数値変換関数(7.20.1,7.24.4.1)及び書式付き入出力関数(7.19.6,
7.24.2)である。
(152) シフト状態に依存した表現形式では,MB̲CUR̲MAX及びMB̲LEN̲MAXの値は,完全な多バイト文
字の最大バイト数に少なくとも一つの隣接するシフトシーケンスの最大長を加えた値以上でなけ
ればならない。二つ以上のシフトシーケンスを含めるかどうかは,処理系が選択する。
(153) ヘッダは必ずしもソースファイルでなくてもよい。さらに,ヘッダ名における<及び>で囲まれた
列が必ずしも正しいソースファイル名である必要はない。
125
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
<errno.h>
<locale.h>
<stddef.h>
<time.h>
<fenv.h>
<math.h>
<stdint.h>
<wchar.h>
<float.h>
<setjmp.h>
<stdio.h>
<wctype.h>
処理系の一部として提供するもの以外に,この箇条で規定する標準ヘッダの<及び>で囲まれた列のいず
れかと同じ名前のファイルが,取り込まれるソースファイルを探索する標準の位置のいずれかにある場合,
その動作は未定義とする。
標準ヘッダはどのような順序で取り込んでもよい。各ヘッダは与えられた有効範囲内で2回以上取り込
んでもよいが,その効果は,<assert.h>の取込みの効果がNDEBUGの定義に依存すること(7.2参照)
を除いて,1回だけ取り込んだ場合と同じとする。ヘッダを使用する場合,ヘッダは外部宣言又は外部定
義の外側で取り込まなければならない。さらに,最初の取込みは,そのヘッダが宣言する関数若しくはオ
ブジェクト,又はヘッダが定義する型若しくはマクロに対する最初の参照よりも前に行わなければならな
い。しかし,同じ識別子を二つ以上のヘッダで宣言又は定義している場合,二つ目及びそれ以降の関連す
るヘッダは,その識別子に対する最初の参照の後に取り込んでもよい。プログラムは,取込みの前の時点
で定義されているキーワードと字句的に同一な名前のマクロをもってはならない。
7.で規定するオブジェクト形式マクロの定義は,必要ならば括弧によって完全に保護されるコードに展
開されなければならない。それによって,任意の式の中で,そのオブジェクト形式マクロが単一の識別子
である場合と同じグループ分けをされる。
ライブラリ関数の宣言は,外部結合をもたなければならない。
標準ヘッダの内容の要約を附属書Bに記す。
前方参照 診断機能(7.2)
7.1.3
予約済み識別子 各ヘッダは,関連する箇条で規定するすべての識別子を宣言又は定義する。関連
する今後のライブラリの方針の箇条で規定する識別子を,宣言又は定義してもよい。いかなる使用に対し
ても予約済みの識別子又はファイル有効範囲の識別子としての使用に対して予約済みの識別子を,宣言又
は定義してもよい。
− 下線に続き大文字1字又は下線に続きもう一つの下線で始まるすべての識別子は,いかなる使用に対
しても常に予約済みとする。
− 一つの下線で始まるすべての識別子は,通常の名前空間及びタグ名前空間の双方におけるファイル有
効範囲をもつ識別子としての使用に対して,常に予約済みとする。
− 7.(今後のライブラリの方針を含む。)で規定する各マクロ名は,それに関連するヘッダのいずれかを
取り込んだ場合,この規格で明示的に異なる規定を行わない限り(7.1.4参照),規定された使用法に
対して予約済みとする。
− 7.(今後のライブラリの方針を含む。)で規定する外部結合をもつすべての識別子は,外部結合をもつ
識別子としての使用に対して常に予約済みとする(154)。
− 7.(今後のライブラリの方針を含む。)で規定するファイル有効範囲をもつ各識別子は,それに関連す
るヘッダのいずれかを取り込んだ場合,マクロ名としての使用に対して,及び,同じ名前空間におい
てファイル有効範囲をもつ識別子としての使用に対して予約済みとする。
───────────────────────────────────────────────
(154) 外部結合をもつ予約済み識別子には,errno,math̲errhandling,setjmp及びva̲endなど
がある。
126
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
これ以外に予約済み識別子はない。プログラムが識別子を宣言又は定義し,その文脈においてその識別
子が予約済みである場合(7.1.4で許されたもの以外),又は予約済みの識別子をマクロ名として定義する
場合,その動作は未定義とする。
プログラムが,下線に続き大文字1字又は下線に続きもう一つの下線で始まる識別子のマクロ定義を
(#undefによって)無効にした場合,その動作は未定義とする。
7.1.4
ライブラリ関数の使用法 明示的に異なる規定を行わない限り,次に規定する各規則を適用する。
− 関数の実引数が,正しくない値(関数の定義域外の値,プログラムのアドレス空間外を指すポインタ,
空ポインタ,対応する仮引数がconst修飾されていない場合に変更不可な記憶域を指すポインタなど),
又は可変個数の実引数をもつ関数が期待しない型(既定の実引数拡張の後)をもつ場合,その動作は
未定義とする。
− ある関数の実引数が配列であるとされている場合,その関数に実際に渡されるポインタは,すべての
アドレス計算及びオブジェクトへのアクセスが実際に有効となる値をもたなければならない(ポイン
タが配列の最初の要素を指す場合は有効となる。)。
− あるヘッダ内で宣言する関数は,同じヘッダ内で定義する関数形式マクロとして追加して実装しても
よい。ヘッダを取り込むことによってあるライブラリ関数を明示的に宣言する場合,その宣言が,そ
のヘッダ内で定義された関数形式マクロに影響されないことを保証するために,次に示す二つの方法
のうちの一つを使うことができる。
− 関数のマクロ定義を局所的に無効にするためには,(その名前の後ろに関数形式マクロの展開を
指示する左括弧が続かなくなるので)括弧で関数名を囲めばよい。同じ構文上の理由で,あるラ
イブラリ関数がマクロとしても定義されている場合でも,その関数のアドレスをとってもよい
(155)。
− #undefを使用してマクロ定義を無効にすれば,実際の関数への参照が保証される。
− マクロとして実装されたライブラリ関数の呼出しでも,その実引数がそれぞれただ1回だけ評価され,
かつ必要ならば括弧によって完全に保護されたコードに展開されなければならない(156)。したがって,
実引数にどのような式を書いても,一般に問題はない。同様に,7.1.4以降の箇条で規定する関数形式
マクロは,適合する返却値の型をもつ関数を呼び出すことができる式であれば,いかなる式からでも
───────────────────────────────────────────────
(155) これは処理系があるライブラリ関数をマクロで提供した場合でも,実際の関数を提供しなければな
らないことを意味する。
(156) このようなマクロは,対応する関数呼出しがもっている副作用完了点をもたないこともありうる。
127
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
呼び出してよい(157)。
− 整数定数式に展開するマクロとして掲げたすべてのオブジェクト形式マクロは,#if前処理指令で使
用するためにも適していなければならない。
ヘッダ中で定義するいかなる型も参照することなくライブラリ関数を宣言できる場合,関連するヘッダ
を取り込まずにその関数を宣言してそれを使用してもよい。
ライブラリ関数が復帰する直前には,副作用完了点が存在する。
標準ライブラリの中の関数は,再入可能であることを保証しない。さらに,静的記憶域期間をもつオブ
ジェクトを変更してもよい(158)。
例 関数atoiは,次のいずれの方法で使用してもよい。
− 関連するヘッダを取り込んで使用する(マクロ展開になる可能性がある。)。
#include <stdlib.h>
const char *str;
/* ... */
i = atoi(str);
− 関連するヘッダを取り込んで使用する(本来の関数への参照になることが保証される。)。
#include <stdlib.h>
#undef atoi
const char *str;
/* ... */
i = atoi(str);
又は,
#include <stdlib.h>
const char *str;
/* ... */
i = (atoi)(str);
───────────────────────────────────────────────
(157) 下線で始まる外部識別子及びマクロ名は予約済みであるので,処理系は下線で始まる外部識別子及
びマクロ名に特別な意味を与えてもよい。例えば,識別子̲BUILTIN̲absを, abs関数のインラ
インコードの生成を指示するために用いるようにしてもよい。その場合,コンパイラのコード生成
部がこの識別子を受け付ける処理系では,ヘッダに,
#define abs(x) ̲BUILTIN̲abs(x)
と記述することができる。
例えば,absというライブラリ関数に対して,処理系のヘッダがabsのマクロを提供している
としても,組込み関数で実装しているとしても,それが本来の関数となることを保証したいユーザ
は,
#undef abs
と書くとよい。その関数原型は,マクロ定義の前で宣言されるため,マクロ定義によって隠されて
いるが,これによって元の関数原型のほうが有効となる。
(158) したがって,シグナル処理ルーチンは,一般に,標準ライブラリ関数を呼ぶことができない。
128
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
− 明示的に宣言して使用する。
extern int atoi(const char *);
const char *str;
/* ... */
i = atoi(str);
7.2
診断機能<assert.h> ヘッダ<assert.h>は,assertマクロを定義し,マクロ
NDEBUG
を参照する。<assert.h>ではNDEBUGを定義しない。ソースファイル中に<assert.h>を取り込む時点
で,NDEBUGがマクロ名として定義されている場合,assertマクロは単に,
#define assert(ignore) ((void)0)
と定義する。assertマクロは,<assert.h>が取り込まれるごとに,その時点のNDEBUGの状態に従っ
て再定義される。
assertマクロは,実際の関数としてではなくマクロとして実装しなければならない。実際の関数にア
クセスするためにマクロ定義を無効にした場合,その動作は未定義とする。
7.2.1
プログラム診断機能
7.2.1.1
assertマクロ
形式
#include <assert.h>
void assert(スカラ型 expression);
機能 assertマクロは,プログラム中に診断機能を付け加える。assertマクロは,ボイド式に展開す
る。assertマクロを実行するとき, expression(スカラ型をもたなければならない。)が偽(すなわ
ち,0と等しい。)である場合,assertマクロは,偽の値をもたらした特定の呼出しに関する情報(情報
の中には,実引数のテキスト,ソースファイル名,ソース行番号及びそのassertマクロの呼出しを字句
的に囲んでいる関数の名前を含む。後の三つはそれぞれマクロ̲ ̲FILE̲ ̲及び̲ ̲LINE̲ ̲の値,並びに
識別子̲ ̲func̲ ̲の値とする。)を処理系定義の書式で標準エラーストリームに書き込む(159)。さらに,そ
の後でabort関数を呼び出す。
返却値 assertマクロは,値を返さない。
前方参照 abort関数(7.20.4.1)
7.3
複素数計算<complex.h>
7.3.1
複素数計算の概説 ヘッダ<complex.h>は,複素数計算をサポートする幾つかのマクロを定義し,
幾つかの関数を宣言する(160)。7.3の各形式は,代表関数及びそれ以外の関数から成る関数群を規定する。
代表関数は,1個以上のdouble complexの仮引数,及びdouble又はdouble complexの返却値を
もつ。関数群の中の代表関数以外の関数は,代表関数の名前の最後にfを付けた名前の関数(float
complexの仮引数,及びfloat又はfloat complexの返却値をもつ。),及び代表関数の名前の最後に
lを付けた名前の関数(long double complexの仮引数,及びlong double又はlong double
───────────────────────────────────────────────
(159) 出力するメッセージは,例えば,次のような形式になる。
Assertion failed : 実引数のテキスト, function 関数名, file ファイル名, line 行番号
(160) “今後のライブラリの方針”(7.26.1)参照。
129
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
complexの返却値をもつ。)から成る。
マクロ
complex
は,̲Complexに展開し,マクロ
̲Complex̲I
は,虚数単位の値をもつ型const float ̲Complexの定数式に展開する(161)。
マクロ
imaginary
及びマクロ
̲Imaginary̲I
は,処理系が虚数型をサポートする場合,そしてその場合に限り,定義する(162)。それらを定義する場合,
imaginaryは,̲Imaginaryに展開し,̲Imaginary̲Iは,虚数単位の値をもつ型const float
̲Imaginaryの定数式に展開する。
マクロ
I
は,̲Imaginary̲I又は̲Complex̲Iに展開する。̲Imaginary̲Iが定義されていない場合,Iは
̲Complex̲Iに展開しなければならない。
7.1.3の規定にかかわらず,プログラムは,マクロcomplex,imaginary,及びIを無効にしてもよく,
更に再定義してもよい。
前方参照 IEC 60559に適合する複素数計算(附属書G)
7.3.2
複素数計算の規約 値は,度ではなく,ラジアンで解釈する。処理系は,errnoを設定してもよ
いが,必ずしも設定する必要はない。
7.3.3
分岐切断線 7.3で規定する幾つかの関数は,それをまたぐと関数が不連続となる分岐切断線をも
つ。符号付き0をもつ処理系(すべてのIEC 60559の実装を含んでいる。)では(その処理系は,附属書G
の規定に従う。),切断線を境とする片側と別の片側とを0の符号で区別する。これによって,切断線を境
とするいずれの側から切断線に接近しても,その関数は,連続になる(内部表現形式上の制限は別として。)。
例えば,平方根関数は,負の実軸に沿って分岐切断線をもっており,切断線の上側,すなわち虚部が+0を
もつ側は,正の虚軸に写像し,切断線の下側,すなわち虚部が−0をもつ側は,負の虚軸に写像する。
符号付き0をサポートしない処理系は(附属書F参照),分岐切断線を境とする両側を区別することが
できない。符号付き0をサポートしない処理系は,切断線の有限な終点のまわりを反時計方向から切断線
に近づくと関数が連続となるように切断線を写像しなければならない。(7.3で規定する関数に対する分岐
切断線は,ちょうど1個の有限な終点しかもたない。)例えば,平方根関数は,負の実軸に沿っている切断
線の有限な終点のまわりを反時計方向に進むと,切断線に上側から近づくので,切断線は,正の虚軸に写
像する。
7.3.4
CX̲LIMITED̲RANGEプラグマ
形式
───────────────────────────────────────────────
(161) 虚数単位は,i2=−1となる数iである。
(162) 虚数型の仕様は,附属書G(参考)にある。
130
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#include <complex.h>
#pragma STDC CX̲LIMITED̲RANGE 状態切替え指定
機能 複素数の乗算,除算,及び絶対値に対する通常の数学公式は,無限大の扱い,並びに不必要なオー
バフロー及びアンダフローのために,問題が多い。CX̲LIMITED̲RANGEプラグマは,(状態が“オン”の
場合)通常の数学公式が適用可能であることを処理系に知らせる目的で使用できる(163)。このプラグマは,
外部宣言の外側か,又は複合文の中のすべての明示的な宣言及び文の前で,用いることができる。外部宣
言の外側で用いる場合,このプラグマは,それが出現した時点から,他のCX̲LIMITED̲RANGEプラグマ
が出現するまで,又は翻訳単位の終わりまで,有効とする。複合文の内側で用いる場合,このプラグマは,
それが出現した時点から他のCX̲LIMITED̲RANGEプラグマが出現するまで(入れ子になった複合文も含
む。),又はその複合文の最後まで有効とする。複合文の終わりでは,このプラグマに対する状態は,その
複合文に入る直前の状態に戻る。このプラグマをこれら以外の文脈で使った場合,その動作は未定義とす
る。このプラグマに対する既定の状態は,“オフ”とする。
7.3.5
複素数三角関数
7.3.5.1
cacos関数群
形式
#include <complex.h>
double complex cacos(double complex z);
float complex cacosf(float complex z);
long double complex cacosl(long double complex z);
機能 cacos関数群は,zの複素数逆余弦を計算する。cacos関数群は,区間[−1,+1]の外側に,実軸に沿
って分岐切断線をもつ。
返却値 cacos関数群は,虚軸方向には数学的に無限の区間,実軸方向には区間[0,+π]を値域とする複素
数逆余弦値を返す。
7.3.5.2
casin関数群
形式
#include <complex.h>
double complex casin(double complex z);
float complex casinf(float complex z);
long double complex casinl(long double complex z);
機能 casin関数群は,zの複素数逆正弦を計算する。casin関数群は,区間[−1,+1]の外側に,実軸に沿
って分岐切断線をもつ。
返却値 casin関数群は,虚軸方向には数学的に無限の区間,実軸方向には区間[−π/2,+π/2]を値域とす
───────────────────────────────────────────────
(163) このプラグマの目的は,プログラマが次の公式が安全だと判定できる場合,それを処理系に知らせ
ることである。
(x+iy)×(u+iv) = (xu−yv) + i(yu+xv)
(x+iy) / (u+iv) = [(xu+yv) + i(yu−xv)] / (u2+v2)
| x+iy | =
2
2
y
x+
131
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
る複素数逆正弦値を返す。
7.3.5.3
catan関数群
形式
#include <complex.h>
double complex catan(double complex z);
float complex catanf(float complex z);
long double complex catanl(long double complex z);
機能 catan関数群は,zの複素数逆正接を計算する。catan関数群は,区間[−i,+i]の外側に,虚軸に沿
って分岐切断線をもつ。
返却値 catan関数群は,虚軸方向には数学的に無限の区間,実軸方向には区間[−π/2,+π/2]を値域とす
る複素数逆正接値を返す。
7.3.5.4
ccos関数群
形式
#include <complex.h>
double complex ccos(double complex z);
float complex ccosf(float complex z);
long double complex ccosl(long double complex z);
機能 ccos関数群は,zの複素数余弦を計算する。
返却値 ccos関数群は,複素数余弦値を返す。
7.3.5.5
csin関数群
形式
#include <complex.h>
double complex csin(double complex z);
float complex csinf(float complex z);
long double complex csinl(long double complex z);
機能 csin関数群は,zの複素数正弦を計算する。
返却値 csin関数群は,複素数正弦値を返す。
7.3.5.6
ctan関数群
形式
#include <complex.h>
double complex ctan(double complex z);
float complex ctanf(float complex z);
long double complex ctanl(long double complex z);
機能 ctan関数群は,zの複素数正接を計算する。
返却値 ctan関数群は,複素数正接値を返す。
7.3.6
複素数双曲線関数
7.3.6.1
cacosh関数群
形式
#include <complex.h>
double complex cacosh(double complex z);
132
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
float complex cacoshf(float complex z);
long double complex cacoshl(long double complex z);
機能 cacosh関数群は,zの複素数逆双曲線余弦を計算する。cacosh関数群は,値が1未満の範囲で,
実軸に沿って分岐切断線をもつ。
返却値 cacosh関数群は,実軸方向には非負である半区間,虚軸方向には区間[−iπ,+iπ]を値域とする複
素数逆双曲線余弦値を返す。
7.3.6.2
casinh関数群
形式
#include <complex.h>
double complex casinh(double complex z);
float complex casinhf(float complex z);
long double complex casinhl(long double complex z);
機能 casinh関数群は,zの複素数逆双曲線正弦を計算する。casinh関数群は,区間[−i,+i]の外側に,
虚軸に沿って分岐切断線をもつ。
返却値 casinh関数群は,実軸方向には数学的に無限の区間,虚軸方向には区間[−iπ/2,+iπ/2]を値域と
する複素数逆双曲線正弦値を返す。
7.3.6.3
catanh関数群
形式
#include <complex.h>
double complex catanh(double complex z);
float complex catanhf(float complex z);
long double complex catanhl(long double complex z);
機能 catanh関数群は,zの複素数逆双曲線正接を計算する。catanh関数群は,区間[−1,+1]の外側に,
実軸に沿って分岐切断線をもつ。
返却値 catanh関数群は,実軸方向には数学的に無限の区間,虚軸方向には区間[−iπ/2,+iπ/2]を値域と
する複素数逆双曲線正接値を返す。
7.3.6.4
ccosh関数群
形式
#include <complex.h>
double complex ccosh(double complex z);
float complex ccoshf(float complex z);
long double complex ccoshl(long double complex z);
機能 ccosh関数群は,zの複素数双曲線余弦を計算する。
返却値 ccosh関数群は,複素数双曲線余弦値を返す。
7.3.6.5
csinh関数群
形式
#include <complex.h>
double complex csinh(double complex z);
float complex csinhf(float complex z);
long double complex csinhl(long double complex z);
133
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
機能 csinh関数群は,zの複素数双曲線正弦を計算する。
返却値 csinh関数群は,複素数双曲線正弦値を返す。
7.3.6.6
ctanh関数群
形式
#include <complex.h>
double complex ctanh(double complex z);
float complex ctanhf(float complex z);
long double complex ctanhl(long double complex z);
機能 ctanh関数群は,zの複素数双曲線正接を計算する。
返却値 ctanh関数群は,複素数双曲線正接値を返す。
7.3.7
複素数指数関数及び複素数対数関数
7.3.7.1
cexp関数群
形式
#include <complex.h>
double complex cexp(double complex z);
float complex cexpf(float complex z);
long double complex cexpl(long double complex z);
機能 cexp関数群は,自然対数の底eのz乗(指数は複素数)を計算する。
返却値 cexp関数群は,eを基数とする複素数指数関数値を返す。
7.3.7.2
clog関数群
形式
#include <complex.h>
double complex clog(double complex z);
float complex clogf(float complex z);
long double complex clogl(long double complex z);
機能 clog関数群は,zの複素数自然対数(eを底とする)を計算する。clog関数群は,負の実軸に沿
って分岐切断線をもつ。
返却値 clog関数群は,実軸方向には数学的に無限の区間,虚軸方向には区間[−iπ,+iπ]を値域とする複
素数自然対数値を返す。
7.3.8
複素数べき乗関数及び複素数絶対値関数
7.3.8.1
cabs関数群
形式
#include <complex.h>
double cabs(double complex z);
float cabsf(float complex z);
long double cabsl(long double complex z);
機能 cabs関数群は,zの複素数絶対値[規数(norm),モジュラス(modulus),又は大きさ(magnitude)
ともいう。]を計算する。
返却値 cabs関数群は,複素数絶対値を返す。
7.3.8.2
cpow関数群
134
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
形式
#include <complex.h>
double complex cpow(double complex x, double complex y);
float complex cpowf(float complex x, float complex y);
long double complex cpowl(long double complex x, long double complex y);
機能 cpow関数群は,複素数べき乗関数xyを計算する。cpow関数群は,負の実軸に沿って,第1仮引
数に対する分岐切断線をもつ。
返却値 cpow関数群は,複素数べき乗関数値を返す。
7.3.8.3
csqrt関数群
形式
#include <complex.h>
double complex csqrt(double complex z);
float complex csqrtf(float complex z);
long double complex csqrtl(long double complex z);
機能 csqrt関数群は,zの複素数平方根を計算する。csqrt関数群は,負の実軸に沿って分岐切断線を
もつ。
返却値 csqrt関数群は,右半平面(虚軸を含む。)を値域とする複素数平方根値を返す。
7.3.9
複素数操作関数
7.3.9.1
carg関数群
形式
#include <complex.h>
double carg(double complex z);
float cargf(float complex z);
long double cargl(long double complex z);
機能 carg関数群は,zの偏角(argument)[位相角(phase angle)ともいう。]を計算する。carg関数
群は,負の実軸に沿って分岐切断線をもつ。
返却値 carg関数群は,区間[−π,+π]を値域とする偏角の値を返す。
7.3.9.2
cimag関数群
形式
#include <complex.h>
double cimag(double complex z);
float cimagf(float complex z);
long double cimagl(long double complex z);
機能 cimag関数群は,zの虚部を計算する(164)。
返却値 cimag関数群は,虚部の値を返す(実数として)。
7.3.9.3
conj関数群
形式
───────────────────────────────────────────────
(164) 複素数型の変数zに対して,z == creal(z) + cimag(z)*Iとなる。
135
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#include <complex.h>
double complex conj(double complex z);
float complex conjf(float complex z);
long double complex conjl(long double complex z);
機能 conj関数群は,zの虚部の符号を反転させて複素共役を計算する。
返却値 conj関数群は,複素共役の値を返す。
7.3.9.4
cproj関数群
形式
#include <complex.h>
double complex cproj(double complex z);
float complex cprojf(float complex z);
long double complex cprojl(long double complex z);
機能 cproj関数群は,リーマン球面上へのzの射影(projection)を計算する。すなわち,zが複素平面
上のすべての無限遠点(たとえ,実部又は虚部の一方が無限大であり,他方がNaNであっても)の場合,
実軸上の正の無限大に射影し,それ以外の場合,z自身に射影する。zの実部又は虚部が無限大である場
合,cproj(z)は,
Infinity + I * copysign(0.0, cimag(z))
と等しい。
返却値 cproj関数群は,リーマン球面上への射影の値を返す。
7.3.9.5
creal関数群
形式
#include <complex.h>
double creal(double complex z);
float crealf(float complex z);
long double creall(long double complex z);
機能 creal関数群は,zの実部を計算する(165)。
返却値 creal関数群は,実部の値を返す。
7.4
文字操作<ctype.h> ヘッダ<ctype.h>は,文字の分類及び文字の変換に有用な幾つかの関数を宣
言する(166)。この中で宣言されるすべての関数は,int型の一つの実引数をもつ。その値はunsigned
charで表現可能であるか,又はマクロEOFの値に等しくなければならない。実引数がその他の値をもつ
場合,その動作は未定義とする。
これらの関数の動作は,その時点のロケールによって影響を受ける。"C"ロケールでない場合に限って
適用される文化圏固有の側面をもつ関数については,それぞれの箇条で規定する。
表示文字(printing character)は,表示装置上で一つの表示位置を占める文字から成る文化圏固有の文字
集合の要素をいう。制御文字(control character)は,表示文字以外の文字から成る文化圏固有の文字集合
───────────────────────────────────────────────
(165) 複素数型の変数zに対して,z == creal(z) + cimag(z)*Iとなる。
(166) “今後のライブラリの方針”(7.26.2)参照。
136
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
の要素をいう(167)。すべての英字及び数字は,表示文字とする。
前方参照 EOF(7.19.1),文化圏固有操作(7.11)
7.4.1
文字種分類関数 この箇条の関数は,実引数cの値がその関数の機能の項で規定するとおりの値で
ある場合,そしてその場合に限り,0以外の値(真)を返す。
7.4.1.1
isalnum関数
形式
#include <ctype.h>
int isalnum(int c);
機能 isalnum関数は,isalpha又はisdigitが真となる文字かどうかを判定する。
7.4.1.2
isalpha関数
形式
#include <ctype.h>
int isalpha(int c);
機能 isalpha関数は,isupper若しくはislowerが真となる文字,又はiscntrl,isdigit,ispunct
若しくはisspaceのいずれも真とならない文化圏固有のアルファベット文字集合の中の文字かどうかを
判定する(168)。"C"ロケールでは,isalphaは,isupper又はislowerが真となる文字に対してだけ真
を返す。
7.4.1.3
isblank関数
形式
#include <ctype.h>
int isblank(int c);
機能 isblank関数は,標準ブランク文字のいずれかの文字,又はisspaceが真となりテキスト中の行
の中の語を区切るために使う文化圏固有の文字集合の中の文字かどうかを判定する。標準ブランク文字は,
空白(' ')及び水平タブ('\t')とする。"C"ロケールでは,isblankは,標準ブランク文字に対して
だけ真を返す。
7.4.1.4
iscntrl関数
形式
#include <ctype.h>
int iscntrl(int c);
機能 iscntrl関数は,制御文字かどうかを判定する。
7.4.1.5
isdigit関数
形式
#include <ctype.h>
───────────────────────────────────────────────
(167) JIS X 0201の7ビット符号化文字集合を使用する処理系では,表示文字は,その値が0x20[文字
SPACE(スペース)]から0x7E(オーバライン)までにある文字である。一方,制御文字は,その
値が,0(NUL)から0x1F(IS1)までにある文字,及び文字0x7F[文字DELETE(抹消)]である。
(168) 関数islower及びisupperは,付加的なこれらの文字のそれぞれに対して,独立に真か偽かを
判定する。したがって,四つの値の組合せのすべてが可能である。
137
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
int isdigit(int c);
機能 isdigit関数は,10進数字(5.2.1で定義)かどうかを判定する。
7.4.1.6
isgraph関数
形式
#include <ctype.h>
int isgraph(int c);
機能 isgraph関数は,空白(' ')を除く表示文字かどうかを判定する。
7.4.1.7
islower関数
形式
#include <ctype.h>
int islower(int c);
機能 islower関数は,小文字,又はiscntrl,isdigit,ispunct若しくはisspaceのいずれも真
とならない文化圏固有の文字集合の中の文字かどうかを判定する。"C"ロケールでは,islowerは,小文
字(5.2.1で定義)に対してだけ真を返す。
7.4.1.8
isprint関数
形式
#include <ctype.h>
int isprint(int c);
機能 isprint関数は,表示文字[空白(' ')を含む。]かどうかを判定する。
7.4.1.9
ispunct関数
形式
#include <ctype.h>
int ispunct(int c);
機能 ispunct関数は,isspace又はisalnumのいずれも真とならない文化圏固有の区切り文字集合
の中の表示文字かどうかを判定する。"C"ロケールでは,ispunctは,isspace又はisalnumのいずれ
も真とならないすべての表示文字に対して真を返す。
7.4.1.10 isspace関数
形式
#include <ctype.h>
int isspace(int c);
機能 isspace関数は,標準空白類文字のいずれかの文字,又はisalnumが偽となる文化圏固有の文字
集合の中の一つの文字かどうかを判定する。標準空白類文字は,空白(' '),書式送り('\f'),改行
('\n'),復帰('\r'),水平タブ('\t')及び垂直タブ('\v')とする。"C"ロケールでは,isspace
は,標準空白類文字に対してだけ真を返す。
7.4.1.11 isupper関数
形式
#include <ctype.h>
int isupper(int c);
機能 isupper関数は,大文字,又はiscntrl,isdigit,ispunct若しくはisspaceのいずれも真
とならない文化圏固有の文字集合の中の文字かどうかを判定する。"C"ロケールでは,isupperは,大文
138
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
字(5.2.1で定義)に対してだけ真を返す。
7.4.1.12 isxdigit関数
形式
#include <ctype.h>
int isxdigit(int c);
機能 isxdigit関数は,16進数字(6.4.4.1で定義)かどうかを判定する。
7.4.2
大文字小文字変換関数
7.4.2.1
tolower関数
形式
#include <ctype.h>
int tolower(int c);
機能 tolower関数は,大文字を対応する小文字に変換する。
返却値 実引数が,isupper関数に対して真となる文字であって,かつislower関数が真となる1個以
上の対応する文字(その時点のロケールの指定に従う。)がある場合,tolower関数はその対応する文字
のいずれか一つを返す(同じロケールに対しては必ず同じ文字。)。そうでない場合,その実引数を変換せ
ずにそのまま返す。
7.4.2.2
toupper関数
形式
#include <ctype.h>
int toupper(int c);
機能 toupper関数は,小文字を対応する大文字に変換する。
返却値 実引数が,islower関数に対して真となる文字であって,かつisupper関数が真となる1個以
上の対応する文字(その時点のロケールの指定に従う。)がある場合,toupper関数はその対応する文字
のいずれか一つを返す(同じロケールに対しては必ず同じ文字。)。そうでない場合,その実引数を変換せ
ずにそのまま返す。
7.5 エラー<errno.h> ヘッダ<errno.h>は,エラー条件の報告に関連する幾つかのマクロを定義する。
定義するマクロは,EDOM,EILSEQ,ERANGE及びerrnoとする。
EDOM
EILSEQ
ERANGE
は,それぞれ区別可能な正の値をもつ型intの整数定数式に展開する。これら三つのマクロは,#if前処
理指令で使用するために適している。
errno
は,型intをもつ変更可能な左辺値(169)に展開する。幾つかのライブラリ関数がその値を正のエラー番号
に設定する。errnoをマクロとするか又は外部結合で宣言された識別子とするかは,未規定とする。実際
のオブジェクトにアクセスするためにマクロ定義を無効にした場合,又はプログラムが名前errnoをもつ
───────────────────────────────────────────────
(169) マクロerrnoは,オブジェクトの識別子である必要はない。それは関数呼出し(例えば,*errno())
によって得られる変更可能な左辺値に展開してもよい。
139
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
識別子を定義した場合,その動作は未定義とする。
プログラム開始時に,errnoの値は0とし,いかなるライブラリ関数も0には設定しない(170)。この規
格の関数の機能の項でerrnoの使用について規定していない場合,エラーのあるなしにかかわらず,ライ
ブラリ関数の呼出しによってerrnoの値を0以外に設定してもよい。
処理系は,Eに続き数字1字又はEに続き大文字1字(171)で始まるマクロ定義を追加してもよい。
7.6
浮動小数点環境<fenv.h> ヘッダ<fenv.h>は,浮動小数点環境(floating-point environment)への
アクセス手段を提供するための二つの型,幾つかのマクロ及び幾つかの関数を宣言する。浮動小数点環境
は,処理系がサポートする何種類かの浮動小数点状態フラグ及び何種類かの浮動小数点制御モードの総称
とする(172)。浮動小数点状態フラグ(floating-point status flag)は,浮動小数点例外(floating-point exception)
(補助的な情報を提供するために例外的な浮動小数点算術の副作用として起きる。)が生成された時に値を
セットする(ただし,決してクリアしない)システム変数とする。浮動小数点制御モード(floating-point
control mode)は,利用者が値を設定してもよいシステム変数とし,その値を設定した後の浮動小数点算術
の動作に影響を与える。
次に掲げる三つのプログラム上の規約は,浮動小数点環境に対してこの規格が意図しているモデルをサ
ポートする(173)。
− 関数呼出しは,その呼出し元の浮動小数点制御モードを変えることはなく,その呼出し元の浮動小数
点状態フラグをクリアすることもなく,また,その呼出し元の浮動小数点状態フラグの状態に依存す
ることもない(これと異なる規約が文書化されていない限りは。)。
− 関数呼出しは,既定の浮動小数点制御モードを要求することを仮定する(要求しないことが文書化さ
れていない限りは。)。
− 関数呼出しは,浮動小数点例外を生成するという可能性があることを仮定する(可能性がないことが
文書化されていない限りは。)。
型
fenv̲t
は,浮動小数点環境全体を表す。
型
fexcept̲t
───────────────────────────────────────────────
(170) したがって,エラー検査のためにerrnoを使用するプログラムは,ライブラリ関数呼出しの前に
errnoの値を0に設定し,その次のライブラリ関数の呼出しの前にその値を検査すべきである。
もちろん,ライブラリ関数は,関数の入口でerrnoの値を保存した後に0に設定し,関数が復帰
する直前までerrnoの値が0のままの場合,元の値に戻すということも可能である。
(171) “今後のライブラリの方針”(7.26.3)参照。
(172) このヘッダは,IEC 60559によって要求される浮動小数点例外の状態を示すフラグ及び丸め方向モ
ード,及びその他の同様な浮動小数点の状態を示す情報をサポートするために設計された。さらに,
すべてのシステムでのコードの可搬性を促進するために設計された。
(173) これらの規約によって,プログラマは,既定の浮動小数点制御モードを安全に仮定することができ
る(又は,それらを意識する必要がなくなる。)。浮動小数点環境へアクセスすることに関しては,
明示的にそれを行っているプログラマ又はプログラムが責任を負う。
140
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
は,浮動小数点状態フラグを集合的に表す(処理系がそのフラグに関連付けている状態すべてを含む。)。
マクロ
FE̲DIVBYZERO
FE̲INEXACT
FE̲INVALID
FE̲OVERFLOW
FE̲UNDERFLOW
のそれぞれは,処理系が7.6.2で規定する関数を使って浮動小数点例外をサポートする場合,そしてその場
合に限り,定義する(173a)。処理系は,上に掲げた五つのマクロ以外に,処理系定義の浮動小数点例外を,
FE̲とそれに続く大文字1字で始まる名前をもつマクロ定義で規定してもよい。定義されたマクロは,整
数定数式に展開する。その値は,これらマクロのあらゆる組合せについて,ビット単位の論理和の結果が
すべて異なる値となる。
マクロ
FE̲ALL̲EXCEPT
は,処理系が定義するすべての浮動小数点例外マクロの単なるビット単位の論理和とする。
マクロ
FE̲DOWNWARD
FE̲TONEAREST
FE̲TOWARDZERO
FE̲UPWARD
のそれぞれは,処理系がfegetround関数によって丸めの方向を取得し,fesetround関数によって丸
めの方向を設定することをサポートする場合,そしてその場合に限り,定義する。処理系は,上に掲げた
四つのマクロ以外に,処理系定義の丸めの方向を,FE̲とそれに続く大文字1字で始まる名前をもつマク
ロ定義で規定してもよい。定義されたマクロは,それぞれ異なる非負の値をもつ整数定数式に展開する(174)。
マクロ
FE̲DFL̲ENV
は,プログラムの既定の浮動小数点環境(プログラム開始処理で設定される。)を表し,型“const修飾さ
れたfenv̲tへのポインタ”をもつ。マクロFE̲DFL̲ENVは,<fenv.h>で規定する浮動小数点環境を管
理する関数の実引数として使用できる。
処理系は,マクロFE̲DFL̲ENV以外に,処理系定義の環境を,FE̲とそれに続く大文字1字で始まる名
前をもち,型“const修飾されたfenv̲tへのポインタ”をもつマクロ定義で規定してもよい。
7.6.1
FENV̲ACCESSプラグマ
形式
───────────────────────────────────────────────
(173a) 7.6.2の関数の少なくとも一つについて,このマクロを適切な実引数として使用した関数呼出しが
成功する状況があれば,処理系は例外をサポートしているとみなされる。7.6.2のすべての関数の
呼出しが常に成功する必要はない。
(174) 丸め方向マクロをFLT̲ROUNDSの値に対応する定数に展開してもよい。しかし,丸め方向マクロ
をそのように展開することは要求されていない。
141
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#include <fenv.h>
#pragma STDC FENV̲ACCESS 状態切替え指定
機能 FENV̲ACCESSプラグマは,プログラムが浮動小数点状態フラグを判定するために浮動小数点環境
にアクセスするかもしれない場合,又は,プログラムが既定状態以外の浮動小数点制御モードの下で走行
するかもしれない場合,処理系にその情報を伝える手段を提供する(175)。このプラグマは,外部宣言の外
側か,又は複合文の中のすべての明示的な宣言及び文の前のいずれかの場所に現れなければならない。外
部宣言の外側に現れる場合,このプラグマは,それが出現した時点から,別のFENV̲ACCESSが出現する
まで,又は翻訳単位の最後まで有効とする。複合文の中に現れる場合,このプラグマは,それが出現した
時点から別のFENV̲ACCESSプラグマが出現するまで(入れ子になった複合文も含む。)又はその複合文
の最後まで有効とする。複合文の最後で,このプラグマに対する状態は,その複合文に入る直前の状態に
戻る。このプラグマをこれら以外の文脈で使った場合,その動作は未定義とする。プログラムの一部が,
浮動小数点状態フラグを判定するか,浮動小数点制御モードを設定するか,又は既定状態以外のモード設
定の下で走行する場合で,かつ,FENV̲ACCESSプラグマに対する状態が“オフ”で翻訳されている場合,
その動作は未定義とする。このプラグマに対する既定の状態(“オン”又は“オフ”)は,処理系定義とす
る。(FENV̲ACCESS“オフ”で翻訳されたプログラムの部分から,FENV̲ACCESS“オン”で翻訳された
プログラムの部分に実行が移る場合,浮動小数点状態フラグの状態は,未規定とし,浮動小数点制御モー
ドは,既定の設定をもつ。)
例
#include <fenv.h>
void f(double x)
{
#pragma STDC FENV̲ACCESS ON
void g(double);
void h(double);
/* ... */
g(x + 1);
h(x + 1);
/* ... */
}
関数gが,最初のx + 1の副作用としてセットされる状態フラグに依存するかもしれない場
合,又は,2番目のx + 1が,関数gの呼出しの副作用として設定される制御モードに依存する
かもしれない場合,そのプログラムの適切な位置に#pragma STDC FENV̲ACCESS ONを置かな
───────────────────────────────────────────────
(175) FENV̲ACCESSプラグマの目的は,フラグの判定及びモードの変更を無効にするかもしれない何ら
かの最適化を可能にすることである(例えば,広域的な共通部分式の削除,コード移動,定数のた
たみ込みなど。)。一般的に,FENV̲ACCESSの状態が“オフ”の場合,翻訳プログラムは,既定の
モードが有効になっており,かつそのフラグは判定されることがない,と仮定することができる。
142
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
ければならない(176)。
7.6.2 浮動小数点例外 7.6.2で規定する関数は,浮動小数点状態フラグへのアクセス手段を提供する(177)。
これらの関数に対するint型の入力実引数は,浮動小数点例外の部分集合を表し,その値は0であるか,
又は1個以上の浮動小数点例外マクロのビット単位の論理和(例えば,FE̲OVERFLOW | FE̲INEXACT)
であってもよい。それ以外の実引数の値に対するこれらの関数の動作は,未定義とする。
7.6.2.1
feclearexcept関数
形式
#include <fenv.h>
int feclearexcept(int excepts);
機能 feclearexcept関数は,実引数が表すサポートされている浮動小数点例外のクリアを試みる。
返却値 feclearexcept関数は,excepts実引数が0の場合,又はすべての指定された例外のクリアに
成功した場合,0を返す。そうでない場合,0以外の値を返す。
7.6.2.2
fegetexceptflag関数
形式
#include <fenv.h>
int fegetexceptflag(fexcept̲t *flagp, int excepts);
機能 fegetexceptflag関数は,実引数exceptsが示す浮動小数点状態フラグの状態に対する処理系
定義の表現の,実引数flagpが指すオブジェクトへの格納を試みる。
返却値 fegetexceptflag関数は,表現の格納に成功した場合,0を返す。そうでない場合,0以外の
値を返す。
7.6.2.3
feraiseexcept関数
形式
#include <fenv.h>
int feraiseexcept(int excepts);
機能 feraiseexcept関数は,その実引数が表すサポートされている浮動小数点例外の生成を試みる
(178)。指定された浮動小数点例外を生成する順序は,未規定とする(F.7.6での規定を除く。)。
feraiseexcept関数が,“オーバフロー”浮動小数点例外又は“アンダフロー”浮動小数点例外を生成
する場合はいつでも,それに加えて“不正確結果”浮動小数点例外を生成するかどうかは,処理系定義と
───────────────────────────────────────────────
(176) この副作用は,時間的な順序どおりに,x + 1の評価を2回行うことを要求する。一方,#pragma
STDC FENV̲ACCESS ONプラグマがない場合,既定の状態が“オフ”であることを仮定すると,
x + 1の評価は1回だけで十分である。
(177) 関数fetestexcept,feraiseexcept,及びfeclearexceptは,セットする又はクリアする
という,フラグに関する基本的な抽象的操作をサポートする。処理系は,より多くの情報をもつ浮
動小数点状態フラグをもっていてもよい(例えば,最初に浮動小数点例外を生成したコードのアド
レス)。関数fegetexceptflag及びfesetexceptflagは,フラグの内容すべてを扱う。
(178) この効果は,算術演算によって生成される浮動小数点例外と似た効果を生じさせることを意図して
いる。したがって,この関数によって生成された浮動小数点例外に対して有効なトラップが働く。
F.7.6の規定も,同じ目的である。
143
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
する。
返却値 feraiseexcept関数は,excepts実引数が0の場合,又はすべての指定された例外の生成に成
功した場合,0を返す。そうでない場合,0以外の値を返す。
7.6.2.4
fesetexceptflag関数
形式
#include <fenv.h>
int fesetexceptflag(const fexcept̲t *flagp, int excepts);
機能 fesetexceptflag関数は,実引数exceptsが示す浮動小数点状態フラグの,flagpが指すオブ
ジェクトに格納されている状態へのセットを試みる。*flagpの値は,それ以前に,fegetexceptflag
の呼出し(その呼出しの第2実引数が,少なくとも,この実引数exceptsが表す浮動小数点例外を表し
ていた。)によって設定されていなければならない。この関数は,浮動小数点例外を生成せず,フラグの状
態のセットだけをする。
返却値 fesetexceptflag関数は,excepts実引数が0の場合,又はすべての指定されたフラグの適
切な状態へのセットに成功した場合,0を返す。そうでない場合,0以外の値を返す。
7.6.2.5
fetestexcept関数
形式
#include <fenv.h>
int fetestexcept(int excepts);
機能 fetestexcept関数は,浮動小数点例外フラグの指定した部分集合の中のいずれがその時点でセッ
トされているかを決定する。excepts実引数は,問い合わせる浮動小数点状態フラグを指定する(179)。
返却値 fetestexcept関数は,exceptsに含まれる浮動小数点例外の中で,その時点でセットされて
いるものに対応する浮動小数点例外マクロのビット単位の論理和の値を返す。
例 “無効演算”浮動小数点例外に対応する浮動小数点状態フラグがセットされるとfを呼び,“オ
ーバフロー”浮動小数点例外に対応する浮動小数点状態フラグがセットされるとgを呼ぶ。
#include <fenv.h>
/* ... */
{
#pragma STDC FENV̲ACCESS ON
int set̲excepts;
feclearexcept(FE̲INVALID | FE̲OVERFLOW);
// 例外が生成されうる
set̲excepts = fetestexcept(FE̲INVALID | FE̲OVERFLOW);
if (set̲excepts & FE̲INVALID) f();
if (set̲excepts & FE̲OVERFLOW) g();
/* ... */
}
7.6.3
丸め fegetround関数及びfesetround関数は,丸め方向モードの制御手段を提供する。
───────────────────────────────────────────────
(179) この機構によって,1回の関数呼出しで複数個の浮動小数点例外を判定することができる。
144
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
7.6.3.1
fegetround関数
形式
#include <fenv.h>
int fegetround(void);
機能 fegetround関数は,その時点の丸め方向を取得する。
返却値 fegetround関数は,その時点の丸め方向を表す丸め方向マクロの値を返す。丸め方向マクロが
存在しないか,又はその時点の丸め方向を決めることができない場合は,負の値を返す。
7.6.3.2
fesetround関数
形式
#include <fenv.h>
int fesetround(int round);
機能 fesetround関数は,実引数roundが表す丸め方向を設定する。実引数が,丸め方向マクロの値
と等しくない場合,丸め方向を変更しない。
返却値 fesetround関数は,要求した丸めモードが設定された場合,そしてその場合に限り,0を返す。
例 丸めモードを保存し,設定し,そして元に戻す。丸め方向の設定が失敗した場合,エラーを報告
し,abort関数を呼び出す。
#include <fenv.h>
#include <assert.h>
void f(int round̲dir)
{
#pragma STDC FENV̲ACCESS ON
int save̲round;
int setround̲ok;
save̲round = fegetround();
setround̲ok = fesetround(round̲dir);
assert(setround̲ok == 0);
/* ... */
fesetround(save̲round);
/* ... */
}
7.6.4
浮動小数点環境 7.6.4で規定する関数は浮動小数点環境,すなわち状態フラグ及び制御モードを
まとめて1個の実体として管理する。
7.6.4.1
fegetenv関数
形式
#include <fenv.h>
int fegetenv(fenv̲t *envp);
機能 fegetenv関数は,その時点の浮動小数点環境の,envpが指すオブジェクトへの格納を試みる。
返却値 fegetenv関数は,環境の格納に成功した場合,0を返す。そうでない場合,0以外の値を返す。
7.6.4.2
feholdexcept関数
145
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
形式
#include <fenv.h>
int feholdexcept(fenv̲t *envp);
機能 feholdexcept関数は,その時点の浮動小数点環境をenvpが指すオブジェクトに保存し,浮動小
数点状態フラグをクリアし,更に,すべての浮動小数点例外について,無停止(non-stop)モード(浮動小
数点例外生成時も実行を継続するモード)に設定する(利用可能な場合に)(180)。
返却値 feholdexcept関数は,無停止浮動小数点例外処理の設定に成功した場合,そしてその場合に限
り,0を返す。
7.6.4.3
fesetenv関数
形式
#include <fenv.h>
int fesetenv(const fenv̲t *envp);
機能 fesetenv関数は,envpが指すオブジェクトが表す浮動小数点環境の設定を試みる。実引数envp
は,fegetenv関数又はfeholdexcept関数の呼出しによって設定されたオブジェクトを指すか,又は
浮動小数点環境マクロに等しくなければならない。fesetenv関数は,単に実引数によって表された浮動
小数点状態フラグの状態を設定するだけで,浮動小数点例外を生成しない。
返却値 fesetenv関数は,環境の設定に成功した場合,0を返す。そうでない場合,0以外の値を返す。
7.6.4.4
feupdateenv関数
形式
#include <fenv.h>
int feupdateenv(const fenv̲t *envp);
機能 feupdateenv関数は,その時点で生成されている浮動小数点例外の自動記憶域への保存を試み,
envpが指すオブジェクトが表す浮動小数点環境の設定を試み,そして保存していた浮動小数点例外の生
成を試みる。実引数envpは,fegetenv関数若しくはfeholdexcept関数の呼出しによって設定され
たオブジェクトを指すか,又は浮動小数点環境マクロに等しくなければならない。
返却値 feupdateenv関数は,すべての動作に成功した場合,0を返す。そうでない場合,0以外の値を
返す。
例 次の例は,見せかけのアンダフロー浮動小数点例外を隠す処理を示している。
#include <fenv.h>
double f(double x)
{
#pragma STDC FENV̲ACCESS ON
double result;
───────────────────────────────────────────────
(180) IEC 60559システムは既定の無停止モードをもち,多くの場合このほかに少なくとも一つの例外処
理モード又は異常停止モードをもつ。システムが既定の無停止モードだけを提供するならば,無停
止モードを設定するということは自明である。このようなシステムでは,feholdexcept関数は
feupdateenv関数とともに,見せかけの浮動小数点例外を隠すプログラムを記述するために用い
ることができる。
146
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
fenv̲t save̲env;
if (feholdexcept(&save̲env))
return /* 環境に問題があった */;
// resultを計算する
if (/* 見せかけのアンダフローかどうかを調べる */)
if (feclearexcept(FE̲UNDERFLOW))
return /* 環境に問題があった */;
if (feupdateenv(&save̲env))
return /* 環境に問題があった */;
return result;
}
7.7
浮動小数点型の特性<float.h> ヘッダ<float.h>は,標準浮動小数点型の種々の限界及びパラメ
タに展開する幾つかのマクロを定義する。
マクロ,マクロの意味,及びマクロの値についての制約(又は制限)は,5.2.4.2.2で規定する。
7.8
整数型の書式変換<inttypes.h> ヘッダ<inttypes.h>は,ヘッダ<stdint.h>を取り込み,ホ
スト処理系によって提供される付加的な機能により,ヘッダ<stdint.h>を拡張する。
ヘッダ<inttypes.h>は,最大幅の整数を操作する関数,及び数値文字列を最大幅の整数に変換する関
数を宣言する。さらに,このヘッダは型
imaxdiv̲t
を宣言する。imaxdiv̲tはimaxdiv関数が返す値の型とし,構造体型とする。ヘッダ<inttypes.h>
は,書式付き入出力関数で使用するために,<stdint.h>で宣言されるそれぞれの型に対応する変換指定
子のマクロを定義する(181)。
前方参照 書式付き入出力関数(7.19.6),書式付きワイド文字入出力関数(7.24.2),整数型<stdint.h>
(7.18)
7.8.1
書式指定子のためのマクロ 次に示すオブジェクト形式マクロ(182)は,単純文字列リテラルに展開
する。この単純文字列リテラルは,変換指定子を含み,場合によっては長さ修飾子によって修飾され,対
応する整数型を変換する場合に,書式付き入出力関数の書式実引数の中で使用するのに適する。これらの
マクロ名の一般的な形式は,PRI(fprintf及びfwprintf関数のための単純文字列リテラル)又はSCN
(fscanf及びfwscanf関数のための単純文字列リテラル)という名前で始まり(183),その後に変換指定
子,更に,7.18.1に規定するのと類似の型名に対応する名前が続く。これらの名前において,Nは7.18.1
の規定と同じく,型の幅を表す。例えばPRIdFAST32は,int̲fast32̲t型の整数の値を表示する書式
文字列で使用することができる。
符号付き整数のためのfprintfマクロは次のとおりとする。
───────────────────────────────────────────────
(181) “今後のライブラリの方針”(7.26.4)参照。
(182) C++処理系は,<inttypes.h>が取り込まれる前に̲ ̲STDC̲FORMAT̲MACROSが定義されている
場合に限って,これらのマクロを定義しなければならない。
(183) fprintf関数とfscanf関数で別々のマクロが規定されている理由は,一般に,たとえ型が同じ
であっても,fprintf関数とfscanf関数で異なる書式指定子が必要な場合があるからである。
147
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
PRIdN PRIdLEASTN PRIdFASTN
PRIdMAX
PRIdPTR
PRIiN PRIiLEASTN PRIiFASTN
PRIiMAX
PRIiPTR
符号無し整数のためのfprintfマクロは次のとおりとする。
PRIoN PRIoLEASTN PRIoFASTN
PRIoMAX
PRIoPTR
PRIuN PRIuLEASTN PRIuFASTN
PRIuMAX
PRIuPTR
PRIxN PRIxLEASTN PRIxFASTN
PRIxMAX
PRIxPTR
PRIXN PRIXLEASTN PRIXFASTN
PRIXMAX
PRIXPTR
符号付き整数のためのfscanfマクロは次のとおりとする。
SCNdN SCNdLEASTN SCNdFASTN
SCNdMAX
SCNdPTR
SCNiN SCNiLEASTN SCNiFASTN
SCNiMAX
SCNiPTR
符号無し整数のためのfscanfマクロは次のとおりとする。
SCNoN SCNoLEASTN SCNoFASTN
SCNoMAX
SCNoPTR
SCNuN SCNuLEASTN SCNuFASTN
SCNuMAX
SCNuPTR
SCNxN SCNxLEASTN SCNxFASTN
SCNxMAX
SCNxPTR
処理系が<stdint.h>で提供しているそれぞれの型に対して,対応するfprintfマクロを定義しなけ
ればならない。また,処理系がその型に対する,fscanf用の適切な長さ修飾子をもっているならば,対
応するfscanfマクロを定義しなければならない。
例
#include <inttypes.h>
#include <wchar.h>
int main(void)
{
uintmax̲t i = UINTMAX̲MAX; // この型は常に存在する
wprintf(L"The largest integer value is %020"
PRIxMAX "\n", i);
return 0;
}
7.8.2
最大幅整数型のための関数
7.8.2.1
imaxabs関数
形式
#include <inttypes.h>
intmax̲t imaxabs(intmax̲t j);
機能 imaxabs関数は,整数jの絶対値を計算する。結果が表現可能でない場合,その動作は未定義と
する(184)。
返却値 imaxabs関数は,絶対値を返す。
7.8.2.2
imaxdiv関数
形式
───────────────────────────────────────────────
(184) 最小の負数の絶対値は,2の補数では表現不可能である。
148
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#include <inttypes.h>
imaxdiv̲t imaxdiv(intmax̲t numer, intmax̲t denom);
機能 imaxdiv関数は,一つの演算でnumer/denom及びnumer%denomを計算する。
返却値 imaxdiv関数は,商と剰余から成るimaxdiv̲t型の構造体を返す。この構造体はquot(商)
及びrem(剰余)という二つのメンバ(順序は任意)を含まなければならない。それぞれのメンバは
intmax̲t型をもつ。結果のいずれかが表現不可能であれば,動作は未定義とする。
7.8.2.3
strtoimax及びstrtoumax関数
形式
#include <inttypes.h>
intmax̲t strtoimax(const char * restrict nptr,
char ** restrict endptr, int base);
uintmax̲t strtoumax(const char * restrict nptr,
char ** restrict endptr, int base);
機能 strtoimax関数及びstrtoumax関数は,文字列の最初の部分をそれぞれintmax̲t型及び
uintmax̲t型の表現に変換するという点を除いて,strtol関数,strtoll関数,strtoul関数,及び
strtoull関数と等価とする。
返却値 strtoimax関数及びstrtoumax関数は,変換が可能ならば,変換した値を返す。変換が不可
能な場合は0を返す。正しい値が表現可能な値の範囲外にある場合は,INTMAX̲MAX,INTMAX̲MIN,又
はUINTMAX̲MAXの値を(返却値の型,及び値の符号があればそれに応じて)返す。そのときマクロERANGE
の値をerrnoに格納する。
前方参照 strtol,strtoll,strtoul及びstrtoull関数(7.20.1.4)
7.8.2.4
wcstoimax及びwcstoumax関数
形式
#include <stddef.h> // wchar̲tのため
#include <inttypes.h>
intmax̲t wcstoimax(const wchar̲t * restrict nptr,
wchar̲t ** restrict endptr, int base);
uintmax̲t wcstoumax(const wchar̲t * restrict nptr,
wchar̲t ** restrict endptr, int base);
機能 wcstoimax関数及びwcstoumax関数は,ワイド文字列の最初の部分をそれぞれintmax̲t型及
びuintmax̲t型の表現に変換するという点を除いて,wcstol関数,wcstoll関数,wcstoul関数及
びwcstoull関数と等価とする。
返却値 wcstoimax関数は,変換が可能ならば,変換した値を返す。変換が不可能な場合は0を返す。
正しい値が表現可能な値の範囲外にある場合は,INTMAX̲MAX,INTMAX̲MIN,又はUINTMAX̲MAXの値
を(返却値の型,及び値の符号があればそれに応じて)返す。そのときマクロERANGEの値をerrnoに
格納する。
前方参照 wcstol,wcstoll,wcstoul及びwcstoull関数(7.24.4.1.2)
7.9
代替つづり<iso646.h> ヘッダ<iso646.h>は,次に示す11個のマクロ(各行の左側)を定義す
る。これらのマクロは,対応するトークン(各行の右側)に展開する。
and
&&
149
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
and̲eq
&=
bitand
&
bitor
|
compl
~
not
!
not̲eq
!=
or
||
or̲eq
|=
xor
^
xor̲eq
^=
7.10 整数型の大きさ<limits.h> ヘッダ<limits.h>は,標準整数型の種々の限界及びパラメタに展
開する幾つかのマクロを定義する。
マクロ,マクロの意味,及びマクロの値についての制約(又は制限)は,5.2.4.2.1で規定する。
7.11 文化圏固有操作<locale.h> ヘッダ<locale.h>は,二つの関数及び一つの型を宣言し,幾つか
のマクロを定義する。
宣言する型は,struct lconvとする。
struct lconv
は,数値の書式に関するメンバを含む。その構造体は,少なくとも次のメンバを含んでいなければならな
い(ただし,順序は任意とする。)。メンバの意味及び通常の値の範囲は,7.11.2.1で規定する。"C"ロケー
ルでは,メンバはそれぞれの注釈に示す値をもたなければならない。
char *decimal̲point;
// "."
char *thousands̲sep;
// ""
char *grouping;
// ""
char *mon̲decimal̲point; // ""
char *mon̲thousands̲sep; // ""
char *mon̲grouping;
// ""
char *positive̲sign;
// ""
char *negative̲sign;
// ""
char *currency̲symbol;
// ""
char frac̲digits;
// CHAR̲MAX
char p̲cs̲precedes;
// CHAR̲MAX
char n̲cs̲precedes;
// CHAR̲MAX
char p̲sep̲by̲space;
// CHAR̲MAX
char n̲sep̲by̲space;
// CHAR̲MAX
char p̲sign̲posn;
// CHAR̲MAX
char n̲sign̲posn;
// CHAR̲MAX
char *int̲curr̲symbol;
// ""
char int̲frac̲digits;
// CHAR̲MAX
char int̲p̲cs̲precedes;
// CHAR̲MAX
char int̲n̲cs̲precedes;
// CHAR̲MAX
150
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
char int̲p̲sep̲by̲space; // CHAR̲MAX
char int̲n̲sep̲by̲space; // CHAR̲MAX
char int̲p̲sign̲posn;
// CHAR̲MAX
char int̲n̲sign̲posn;
// CHAR̲MAX
定義するマクロは,NULL(7.17で規定)とする。さらに,次のマクロも定義する。
LC̲ALL
LC̲COLLATE
LC̲CTYPE
LC̲MONETARY
LC̲NUMERIC
LC̲TIME
これらはsetlocale関数の1番目の実引数として使用するために適した,それぞれ区別可能な値をもつ
整数定数式に展開する(185)。処理系は,LC̲に続き英大文字1字で始まるマクロ定義(186)を追加してもよい。
7.11.1 ロケール制御
7.11.1.1 setlocale関数
形式
#include <locale.h>
char *setlocale(int category, const char *locale);
機能 setlocale関数は,category実引数及びlocale実引数による指定に従って,プログラムのロ
ケールのうちの一部を選択する。setlocale関数は,プログラムのその時点のロケールの全体又は一部
を変更したり,問い合わせたりするために使用してもよい。categoryに対する値LC̲ALLは,プログラ
ムのロケール全体を指定する。categoryのその他の値は,プログラムのロケールの一部だけを指定する。
LC̲COLLATEは,strcoll関数及びstrxfrm関数の動作に影響を与える。LC̲CTYPEは,文字操作関数
の動作(187),多バイト文字関数の動作及びワイド文字関数の動作に影響を与える。LC̲MONETARYは,
localeconv関数が返す金額の書式化に関する情報に影響を与える。LC̲NUMERICは,書式付き入出力関
数及び文字列変換関数のための小数点文字,並びにlocaleconv関数が返す金額以外の書式化に関する情
報に影響を与える。LC̲TIMEは,strftime関数及びwcsftime関数の動作に影響を与える。
localeの値"C"は,Cプログラムの翻訳に必要な最小の環境を規定する。localeの値が""の場合,
その文化圏に固有の環境を規定する。その他の処理系定義の文字列をsetlocale関数の2番目の実引数
として渡してもよい。
プログラム開始時には,
setlocale(LC̲ALL, "C");
と同等のことを実行する。
───────────────────────────────────────────────
(185) ISO/IEC 9945-2は,C言語のためのロケールを指定するために用いることができる,ロケールとチ
ャーマップ書式を規定している。
(186) “今後のライブラリの方針”(7.26.5)参照。
(187) 7.4の関数で,その動作がその時点のロケールの影響を受けないものは,isdigit関数及び
isxdigit関数だけである。
151
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
処理系は,いかなるライブラリ関数もsetlocale関数を呼び出さない場合の動作と同じ動作をしなけ
ればならない。
返却値 localeがある文字列を指すポインタであって,その選択が適切な場合,setlocale関数は,そ
の新しいロケールにおいてその指定したcategoryと結び付けられた文字列を指すポインタを返す。選択
が適切でない場合,setlocale関数は空ポインタを返し,プログラムのロケールを変更しない。
localeが空ポインタの場合,setlocale関数は,プログラムのその時点のロケールにおいて,その
categoryと結び付けられた文字列を指すポインタを返す。この場合,プログラムのロケールは変更しな
い(188)。
setlocale関数は,文字列へのポインタを返す。このポインタが指す文字列の値とそれに結び付けら
れたカテゴリを実引数としてsetlocaleを呼び出すと,プログラムのロケールのその部分を復元する。
このポインタが指す文字列をプログラムで変更してはならないが,引き続くsetlocale関数の呼出しで
書き換わることがある。
前方参照 strcoll関数(7.21.4.3),strftime関数(7.23.3.5),strxfrm関数(7.21.4.5),書式付き入
出力関数(7.19.6),数値変換関数(7.20.1),多バイト文字・ワイド文字変換関数(7.20.7),多バイト文字
列・ワイド文字列変換関数(7.20.8)
7.11.2 数値書式規約の問合せ
7.11.2.1 localeconv関数
形式
#include <locale.h>
struct lconv *localeconv(void);
機能 localeconv関数は,型struct lconvをもつオブジェクトの構成要素に対し,その時点のロケ
ールの規約に従った数量(金額及びそれ以外)の書式化に対する適切な値を設定する。
型char *をもつこの構造体のメンバは文字列を指す。これらのメンバ(decimal̲pointを除く。)は,
その時点のロケールにおいて値が与えられていないか又は値の長さが0であることを示すために,""を指
すことができる。grouping及びmon̲groupingを除き,文字列は,初期シフト状態で開始し,初期シ
フト状態で終了しなければならない。型charをもつメンバは,非負の数であって,いずれもその時点の
ロケールにおいて値が与えられていないことを示すために,CHAR̲MAXとすることができる。メンバとし
て含まれるものを次に示す。
char *decimal̲point
金額以外の数量の書式化に使用する小数点文字。
char *thousands̲sep
書式化された金額以外の数量において,小数点文字の前の数字のグループを区切るための文字。
char *grouping
文字列であって,その要素は書式化された金額以外の数量において数字の各グループのけた数
を示す。
char *mon̲decimal̲point
───────────────────────────────────────────────
(188) 処理系はcategoryがLC̲ALLの値をもつ場合,いろいろな異なるものから構成されるロケール
に応じて,種々のカテゴリの値を文字列中に表現できるように準備しなければならない。
152
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
金額数量を書式化するために使用する小数点文字。
char *mon̲thousands̲sep
書式化された金額数量において,小数点文字の前の数字のグループを区切るための文字。
char *mon̲grouping
文字列であって,その要素は書式化された金額数量において数字の各グループのけた数を示す。
char *positive̲sign
書式化された金額数量が負でない値をもつことを示すために使う文字列。
char *negative̲sign
書式化された金額数量が負の値をもつことを示すために使う文字列。
char *currency̲symbol
その時点のロケールで適用されるその地域の通貨記号。
char frac̲digits
その地域向けに書式化された金額数量において表示される小数部の(小数点の後ろの)けた数。
char p̲cs̲precedes
その地域向けに書式化された負でない金額数量において,currency̲symbolが値に先行する
場合は1,後続する場合は0。
char n̲cs̲precedes
その地域向けに書式化された負の金額数量において,currency̲symbolが値に先行する場合
は1,後続する場合は0。
char p̲sep̲by̲space
その地域向けに書式化された負でない金額数量において,currency̲symbol,符号文字列,
及び値の区切り方を示す値。
char n̲sep̲by̲space
その地域向けに書式化された負の金額数量において,currency̲symbol,符号文字列,及び
値の区切り方を示す値。
char p̲sign̲posn
その地域向けに書式化された負でない金額数量において,positive̲signの位置を示す値。
char n̲sign̲posn
その地域向けに書式化された負の金額数量において,negative̲signの位置を示す値。
char *int̲curr̲symbol
その時点のロケールで適用される国際通貨記号。最初の3文字は,ISO 4217の規定に従って英
字で表した国際通貨記号とする。4番目の(ナル文字の直前の)文字は,国際通貨記号と金額
数量を区切るために使用する文字とする。
char int̲frac̲digits
国際様式で書式化された金額数量において表示される小数部の(小数点の後ろの)けた数。
char int̲p̲cs̲precedes
国際様式で書式化された負でない金額数量において,int̲curr̲symbolが値に先行する場合
は1,後続する場合は0。
char int̲n̲cs̲precedes
国際様式で書式化された負の金額数量において,int̲curr̲symbolが値に先行する場合は1,
153
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
後続する場合は0。
char int̲p̲sep̲by̲space
国際様式で書式化された負でない金額数量において,int̲curr̲symbol,符号文字列,及び
値の区切り方を示す値。
char int̲n̲sep̲by̲space
国際様式で書式化された負の金額数量において,int̲curr̲symbol,符号文字列,及び値の
区切り方を示す値。
char int̲p̲sign̲posn
国際様式で書式化された負でない金額数量において,positive̲signの位置を示す値。
char int̲n̲sign̲posn
国際様式で書式化された負の金額数量において,negative̲signの位置を示す値。
grouping及びmon̲groupingの要素の解釈は,次のとおりとする。
CHAR̲MAX
それ以上のグループ分けを行わない。
0
前の要素を残りの数字に対して繰り返し使用する。
その他
整数値が,その対応するグループを構成する数字の個数を表す。次の要素を調べて,
そのグループの前に来る次のグループの大きさを決定する。
p̲sep̲by̲space,n̲sep̲by̲space,int̲p̲sep̲by̲space,及びint̲n̲sep̲by̲spaceの値
の解釈は,次のとおりとする。
0
通貨記号と値は空白によって区切らない。
1
通貨記号と符号文字列が隣接していれば,一つの空白がそれらと値とを区切る。そうでなけれ
ば一つの空白が通貨記号と値とを区切る。
2
通貨記号と符号文字列が隣接していれば,一つの空白がそれらを区切る。そうでなければ一つ
の空白が符号文字列と値とを区切る。
int̲p̲sep̲by̲space及びint̲n̲sep̲by̲spaceでは,int̲curr̲symbolの4番目の文字を空
白の代わりに使う。
p̲sign̲posn,n̲sign̲posn,int̲p̲sign̲posn,及びint̲n̲sign̲posnの値の解釈は,次の
とおりとする。
0
数量及び通貨記号を括弧で囲む。
1
符号文字列が数量及び通貨記号に先行する。
2
符号文字列が数量及び通貨記号に続く。
3
符号文字列が通貨記号の直前に先行する。
4
符号文字列が通貨記号の直後に続く。
処理系は,いかなるライブラリ関数もlocaleconv関数を呼び出さない場合の動作と同じ動作をしなけ
ればならない。
返却値 localeconv関数は,値の設定されたオブジェクトへのポインタを返す。このポインタが指す構
造体をプログラムで変更してはならないが,引き続くlocaleconv関数の呼出しで書き換わることがある。
さらに,カテゴリとしてLC̲ALL,LC̲MONETARY又はLC̲NUMERICを指定したsetlocale関数の呼出
しで,構造体の内容が書き換わることがある。
例1. 次の表は,金額数量を書式化するために使われる規則の例を四つの国について示している。
154
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
国名
その地域の書式
国際書式
正数
負数
正数
負数
フィンランド
1.234,56 mk
-1.234,56 mk FIM 1.234,56 FIM -1.234,56
イタリア
L.1.234
-L.1.234
ITL 1.234
-ITL 1.234
オランダ
f 1.234,56
f -1.234,56
NLG 1.234,56 NLG -1.234,56
スイス
SFrs.1,234.56 SFrs.1,234.56C CHF 1,234.56 CHF 1,234.56C
これらの四つの国において,localeconv関数が返す構造体の金額に関する各メンバの値を
次に示す。
フィンランド
イタリア
オランダ
スイス
mon̲decimal̲point
","
""
","
"."
mon̲thousands̲sep
"."
"."
"."
","
mon̲grouping
"\3"
"\3"
"\3"
"\3"
positive̲sign
""
""
""
""
negative̲sign
"-"
"-"
"-"
"C"
currency̲symbol
"mk"
"L."
"\u0192"
"SFrs."
frac̲digits
2
0
2
2
p̲cs̲precedes
0
1
1
1
n̲cs̲precedes
0
1
1
1
p̲sep̲by̲space
1
0
1
0
n̲sep̲by̲space
1
0
1
0
p̲sign̲posn
1
1
1
1
n̲sign̲posn
1
1
4
2
int̲curr̲symbol
"FIM "
"ITL "
"NLG "
"CHF "
int̲frac̲digits
2
0
2
2
int̲p̲cs̲precedes
1
1
1
1
int̲n̲cs̲precedes
1
1
1
1
int̲p̲sep̲by̲space
0
0
0
0
int̲n̲sep̲by̲space
0
0
0
0
int̲p̲sign̲posn
1
1
1
1
int̲n̲sign̲posn
4
1
4
2
例2. 次の表は,cs̲precedes,sep̲by̲space,及びsign̲posnメンバが値の書式に及ぼす影
響について示している。
p̲cs̲precedes
p̲sign̲posn
p̲sep̲by̲space
0
1
2
0
0
(1.25$)
(1.25 $)
(1.25$)
1
+1.25$
+1.25 $
+ 1.25$
2
1.25$+
1.25 $+
1.25$ +
3
1.25+$
1.25 +$
1.25+ $
4
1.25$+
1.25 $+
1.25$ +
1
0
($1.25)
($ 1.25)
($1.25)
1
+$1.25
+$ 1.25
+ $1.25
2
$1.25+
$ 1.25+
$1.25 +
3
+$1.25
+$ 1.25
+ $1.25
4
$+1.25
$+ 1.25
$ +1.25
参考 日本での金額数量の書式化の方法の例,及びlocaleconv関数が返す構造体の金額に関する各
メンバの値の例をJIS X 0201を使って示す。
155
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
国名
正数
負数
正数(国際書式)
負数(国際書式)
日本
¥1,234
¥-1,234
JPY 1,234
JPY -1,234
日本
mon̲decimal̲point
""
mon̲thousands̲sep
","
mon̲grouping
"\3"
positive̲sign
""
negative̲sign
"-"
currency̲symbol
"\u00A5"
frac̲digits
0
p̲cs̲precedes
1
n̲cs̲precedes
1
p̲sep̲by̲space
0
n̲sep̲by̲space
0
p̲sign̲posn
1
n̲sign̲posn
4
int̲curr̲symbol
"JPY "
int̲frac̲digits
0
int̲p̲cs̲precedes
1
int̲n̲cs̲precedes
1
int̲p̲sep̲by̲space 0
int̲n̲sep̲by̲space 0
int̲p̲sign̲posn
1
int̲n̲sign̲posn
4
7.12 数学<math.h> ヘッダ<math.h>は,二つの型及び多数の数学関数を宣言し,幾つかのマクロを定
義する。7.12のほとんどの形式は,代表関数及びそれ以外の関数から成る関数群を規定する。代表関数は,
1個以上のdoubleの仮引数をもつか,doubleの返却値をもつか,又はその両方をもつ。関数群の中の
代表関数以外の関数は,代表関数の名前の最後にfを付けた名前の関数(floatの仮引数をもつか,float
の返却値をもつか,又はその両方をもつ。),及び代表関数の名前の最後にlを付けた名前の関数(long
doubleの仮引数をもつか,long doubleの返却値をもつか,又はその両方をもつ。)から成る(189)。整
数算術関数及び文字列変換関数は,7.20で規定する。
型
float̲t
double̲t
は,それぞれ少なくともfloat型及びdouble型と同じ幅をもつ浮動小数点型とする。double̲t型は
少なくともfloat̲t型と同じ幅をもつ。FLT̲EVAL̲METHODが0に等しい場合,float̲t型及び
double̲t型は,それぞれfloat型及びdouble型とする。FLT̲EVAL̲METHODが1に等しい場合,両
方ともdouble型とする。FLT̲EVAL̲METHODが2に等しい場合,両方ともlong double型とする。
───────────────────────────────────────────────
(189) 特に式の評価を大きな型で行う処理系において,<math.h>の関数は,形式の関数原型が示す型よ
りも大きな型で引数を渡したり値を返したりすることもある。
156
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
FLT̲EVAL̲METHODがそれ以外の値の場合,float̲t型及びdouble̲t型は処理系定義とする(190)。
マクロ
HUGE̲VAL
は,float型として表現できるとは限らない正のdouble型の式に展開する。
マクロ
HUGE̲VALF
HUGE̲VALL
は,float型及びlong double型においてHUGE̲VALに対応するマクロとする(191)。
マクロ
INFINITY
は,利用可能な場合は,正の又は符号無しの無限大を表すfloat型の定数式に展開する。そうでなければ,
翻訳時において,オーバフローするfloat型の正の定数に展開する(192)。
マクロ
NAN
は,処理系がfloat型のqNaNをサポートしている場合,そしてその場合に限り,定義される。それは,
qNaNを表すfloat型の定数式に展開する。
マクロ
FP̲INFINITE
FP̲NAN
FP̲NORMAL
FP̲SUBNORMAL
FP̲ZERO
は,数の分類のためのものとする。これらは,浮動小数点数の値の互いに排他的な種類を表す。これらは,
異なる値の整数定数式に展開する。処理系は,FP̲に続き英大文字1字で始まるマクロ定義をもつ,その
他の処理系定義の浮動小数点数の分類を定義してもよい。
マクロ
FP̲FAST̲FMA
は,定義されることもされないこともある。これを定義する場合,fma関数が,double型のオペランド
をもつ1個の乗算と1個の加算と,一般に少なくとも同じ速度で,又はより速く実行されることを表す(193)。
───────────────────────────────────────────────
(190) float̲t型及びdouble̲t型は,少なくともfloat型又はdouble型と同じ幅をもち,処理系
において最も効率的に処理できる型とされている。FLT̲EVAL̲METHODが0,1又は2の場合,
float̲t型は処理系が浮動小数点型の式の評価を行いうる最も狭い型である。
(191) 無限大をサポートしている処理系では,HUGE̲VAL,HUGE̲VALF,及びHUGE̲VALLを正の無限大
とすることができる。
(192) この場合,INFINITYを用いることは6.4.4の制約に反し,診断メッセージが出されることになる。
(193) 典型的な場合,マクロFP̲FAST̲FMAは,fma関数がハードウェアの積和演算命令と直接に結び
付けて実装されている場合,そしてその場合に限り,定義される。ソフトウェアによる処理系では
かなり低速になることもありうる。
157
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
マクロ
FP̲FAST̲FMAF
FP̲FAST̲FMAL
は,float型及びlong double型においてFP̲FAST̲FMAに対応するマクロとする。
マクロ
FP̲ILOGB0
FP̲ILOGBNAN
は,xがそれぞれ0又はNaNの場合にilogb(x)で返される値となる整数定数式に展開する。FP̲ILOGB0
の値はINT̲MIN又は-INT̲MAXのいずれかでなければならない。FP̲ILOGBNANの値はINT̲MAX又は
INT̲MINのいずれかでなければならない。
マクロ
MATH̲ERRNO
MATH̲ERREXCEPT
は,それぞれ整数定数1及び2に展開する。
マクロ
math̲errhandling
は,int型をもち,値がMATH̲ERRNO,MATH̲ERREXCEPT,又は両方のビット単位の論理和のいずれか
の式に展開する。math̲errhandlingの値は,プログラムが実行している間,一定とする。
math̲errhandlingをマクロとするか,又は外部結合をもつ識別子とするかは未規定とする。マクロ定
義を無効にするか,又はプログラムがmath̲errhandlingという名前の識別子を定義する場合,その動
作は未定義とする。math̲errhandling & MATH̲ERREXCEPTという式が0以外の値になりうる場合,
処理系は,<fenv.h>において,マクロFE̲DIVBYZERO,FE̲INVALID,及びFE̲OVERFLOWを定義しな
ければならない。
7.12.1 エラー状態の扱い この規格で異なる規定を行わない限り,<math.h>に含まれる各関数の動作は,
入力実引数のすべての表現可能な値に対して規定される。各関数は,外部的に可視な例外条件を生成させ
ることなく,一つの操作として実行されなければならない。
すべての関数に対し,入力実引数の値が,数学関数が定義される定義域の外側に存在する場合,定義域
エラー(domain error)が発生する。各関数の機能の説明の中で,要求される定義域エラーをすべて規定す
る。処理系は,関数の数学的な定義と矛盾しないエラーを定義域エラーとして追加してもよい(194)。定義
域エラーが発生した場合,関数は処理系定義の値を返す。整数式math̲errhandling & MATH̲ERRNO
が0以外の値の場合,整数式errnoの値はEDOMになる。整数式math̲errhandling &
MATH̲ERREXCEPTが0以外の値の場合,“無効演算”浮動小数点例外を生成する。
同様に,関数の数学的な結果の絶対値が大きすぎるため,指定された型のオブジェクトで表現できない
場合,値域エラー(range error)が発生する。
浮動小数点演算の結果は,数学的な結果の絶対値が有限だが大きすぎ,指定された型のオブジェクトに
おいて,極めて大きい丸めエラーを発生させずには表現することができない場合に,オーバフローを発生
───────────────────────────────────────────────
(194) したがって,無限大をサポートしている処理系は,数学的な定義域が無限大を含んでいない場合,
無限大の実引数を定義域エラーとすることを許す。
158
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
する。浮動小数点演算の結果がオーバフローし既定の丸め動作が有効な場合,又は結果が数学的に無限大
となる場合(例えばlog(0.0)),関数は返却値の型に応じ,関数の正しい値と同じ符号でマクロHUGE̲VAL,
HUGE̲VALF,又はHUGE̲VALLの値を返す。整数式math̲errhandling & MATH̲ERRNOが0以外の値
の場合,整数式errnoの値はERANGEになる。整数式math̲errhandling & MATH̲ERREXCEPTが0
以外の値の場合,結果が数学的に無限大であれば“0除算”浮動小数点例外を生成し,そうでなければ“オ
ーバフロー”浮動小数点例外を生成する。
浮動小数点演算の結果は,数学的な結果の絶対値が小さすぎ,指定された型のオブジェクトにおいて,
極めて大きい丸めエラーを発生させずには表現することができない場合に,アンダフローを発生する(195)。
結果がアンダフローした場合,関数は処理系定義の値を返す。この値の絶対値は高々,指定された型の最
小の正の正規化数とする。整数式math̲errhandling & MATH̲ERRNOが0以外の値の場合,整数式
errnoの値がERANGEとなるかどうかは,処理系定義とする。整数式math̲errhandling &
MATH̲ERREXCEPTが0以外の値の場合,“アンダフロー”浮動小数点例外を生成するかどうかは,処理系
定義とする。
7.12.2 FP̲CONTRACTプラグマ
形式
#include <math.h>
#pragma STDC FP̲CONTRACT 状態切替え指定
機能 FP̲CONTRACTプラグマは,処理系が式(6.5)を短縮することを認める(状態が“オン”の場合)
又は認めない(状態が“オフ”の場合)ために用いる。このプラグマは,外部宣言の外側か,又は複合文
の中のすべての明示的な宣言及び文の前で,用いることができる。外部宣言の外側で用いる場合,このプ
ラグマは,それが出現した時点から,他のFP̲CONTRACTプラグマが出現するまで,又は翻訳単位の終わ
りまで有効とする。複合文の内側で用いる場合,このプラグマは,それが出現した時点から他の
FP̲CONTRACTプラグマが出現するまで(入れ子になった複合文も含む),又はその複合文の最後まで有効
とする。複合文の終わりでは,このプラグマに対する状態は,その複合文に入る直前の状態に戻る。この
プラグマをこれら以外の文脈で使った場合,その動作は未定義とする。このプラグマに対する既定の状態
(“オン”又は“オフ”)は処理系定義とする。
7.12.3 分類用マクロ この箇条の形式において,実浮動小数点型とは引数が実浮動小数点型の式でなけれ
ばならないことを示す。
7.12.3.1 fpclassifyマクロ
形式
#include <math.h>
int fpclassify(実浮動小数点型 x);
機能 fpclassifyマクロは,実引数の値をNaN,無限大,正規化数,非正規化数,0,又はその他の処
理系定義のカテゴリに分類する。最初に,プログラム上の型よりビット数が大きい形式で表現された実引
───────────────────────────────────────────────
(195) ここでは,アンダフローという語は,IEC 60559の段階的アンダフロー及び0切捨てアンダフロー
の両方を含むものとする。
159
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
数は,そのプログラム上の型に変換される。次に実引数の型に基づいて分類される(196)。
返却値 fpclassifyマクロは,実引数の値に応じた分類用マクロの値を返す。
例 マクロfpclassifyは通常の関数を使って次の方法によって実現することができる。
#define fpclassify(x) \
((sizeof (x) == sizeof (float)) ? ̲ ̲fpclassifyf(x) : \
(sizeof (x) == sizeof (double)) ? ̲ ̲fpclassifyd(x) : \
̲ ̲fpclassifyl(x))
7.12.3.2 isfiniteマクロ
形式
#include <math.h>
int isfinite(実浮動小数点型 x);
機能 isfiniteマクロは,実引数が有限の値(0,非正規化数,又は正規化数であって,無限大やNaN
ではない)かどうかを判定する。最初に,プログラム上の型よりもビット数が大きい形式で表現された実
引数は,そのプログラム上の型に変換される。次に実引数の型に基づいて判定する。
返却値 isfiniteマクロは,実引数が有限の値をもつ場合,そしてその場合に限り,0以外の値を返す。
7.12.3.3 isinfマクロ
形式
#include <math.h>
int isinf(実浮動小数点型 x);
機能 isinfマクロは,実引数が無限大(正又は負の)であるかどうかを判定する。最初に,プログラム
上の型よりもビット数が大きい形式で表現された実引数は,そのプログラム上の型に変換される。次に実
引数の型に基づいて判定する。
返却値 isinfマクロは,実引数が無限大の値をもつ場合,そしてその場合に限り,0以外の値を返す。
7.12.3.4 isnanマクロ
形式
#include <math.h>
int isnan(実浮動小数点型 x);
機能 isnanマクロは,実引数の値がNaNかどうかを判定する。最初に,プログラム上の型よりもビッ
ト数が大きい形式で表現された実引数は,そのプログラム上の型に変換される。次に実引数の型に基づい
て判定する(197)。
返却値 isnanマクロは,実引数がNaNの値をもつ場合,そしてその場合に限り,0以外の値を返す。
7.12.3.5 isnormalマクロ
形式
───────────────────────────────────────────────
(196) 式はその型がもつよりも大きな範囲と精度で評価することができるので,分類の基準となる型を知
ることは重要である。例えば,long double型の正規化数が,double型に変換された場合に非
正規化数になり,またfloat型に変換された場合に0になることもある。
(197) マクロisnanについては,処理系がNaNを評価型においてサポートしているが意味的な型では定
義しない場合を除いて,NaNであるかどうかの決定に型は影響しない。
160
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
#include <math.h>
int isnormal(実浮動小数点型 x);
機能 isnormalマクロは,実引数の値が正規化数(0,非正規化数,無限大,NaNのいずれでもない)
かどうかを判定する。最初に,プログラム上の型よりもビット数が大きい形式で表現された実引数は,そ
のプログラム上の型に変換される。次に実引数の型に基づいて判定する。
返却値 isnormalマクロは,実引数が正規化数である場合,そしてその場合に限り,0以外の値を返す。
7.12.3.6 signbitマクロ
形式
#include <math.h>
int signbit(実浮動小数点型 x);
機能 signbitマクロは,実引数の符号が負かどうかを判定する(198)。
返却値 signbitマクロは,実引数の符号が負である場合,そしてその場合に限り,0以外の値を返す。
7.12.4 三角関数
7.12.4.1 acos関数群
形式
#include <math.h>
double acos(double x);
float acosf(float x);
long double acosl(long double x);
機能 acos関数群は,xの逆余弦の主値を計算する。実引数が区間[−1,+1]内にない場合,定義域エラー
が発生する。
返却値 acos関数群は,区間[0,+π]ラジアンの逆余弦値を返す。
7.12.4.2 asin関数群
形式
#include <math.h>
double asin(double x);
float asinf(float x);
long double asinl(long double x);
機能 asin関数群は,xの逆正弦の主値を計算する。実引数が区間[−1,+1]内にない場合,定義域エラー
が発生する。
返却値 asin関数群は,区間[−π/2,+π/2]ラジアンの逆正弦値を返す。
7.12.4.3 atan関数群
形式
#include <math.h>
double atan(double x);
float atanf(float x);
───────────────────────────────────────────────
(198) マクロsignbitは無限大,0,NaNを含めすべての値の符号について結果を返す。0が符号無しの
場合,正として扱う。
161
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
long double atanl(long double x);
機能 atan関数群は,xの逆正接の主値を計算する。
返却値 atan関数群は,区間[−π/2,+π/2]ラジアンの逆正接値を返す。
7.12.4.4 atan2関数群
形式
#include <math.h>
double atan2(double y, double x);
float atan2f(float y, float x);
long double atan2l(long double y, long double x);
機能 atan2関数群は,y/xの逆正接の値を計算する。その際,両方の実引数の符号を用いて返却値の象
限を決定する。両方の実引数が0の場合,定義域エラーが発生することがある。
返却値 atan2関数群は,区間[−π,+π]ラジアンのy/xの逆正接値を返す。
7.12.4.5 cos関数群
形式
#include <math.h>
double cos(double x);
float cosf(float x);
long double cosl(long double x);
機能 cos関数群は,x(ラジアン値)の余弦を計算する。
返却値 cos関数群は,余弦値を返す。
7.12.4.6 sin関数群
形式
#include <math.h>
double sin(double x);
float sinf(float x);
long double sinl(long double x);
機能 sin関数群は,x(ラジアン値)の正弦を計算する。
返却値 sin関数群は,正弦値を返す。
7.12.4.7 tan関数群
形式
#include <math.h>
double tan(double x);
float tanf(float x);
long double tanl(long double x);
機能 tan関数群は,x(ラジアン値)の正接を計算する。
返却値 tan関数群は,正接値を返す。
7.12.5 双曲線関数
7.12.5.1 acosh関数群
形式
#include <math.h>
162
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
double acosh(double x);
float acoshf(float x);
long double acoshl(long double x);
機能 acosh関数群は,xの(非負の)双曲線逆余弦を計算する。実引数が1未満の場合,定義域エラー
が発生する。
返却値 acosh関数群は,区間[0,+∞]の双曲線逆余弦値を返す。
7.12.5.2 asinh関数群
形式
#include <math.h>
double asinh(double x);
float asinhf(float x);
long double asinhl(long double x);
機能 asinh関数群は,xの双曲線逆正弦を計算する。
返却値 asinh関数群は,双曲線逆正弦値を返す。
7.12.5.3 atanh関数群
形式
#include <math.h>
double atanh(double x);
float atanhf(float x);
long double atanhl(long double x);
機能 atanh関数群は,xの双曲線逆正接を計算する。実引数が区間[−1,+1]内にない場合,定義域エラー
が発生する。実引数が−1又は1に等しい場合,値域エラーが発生することがある。
返却値 atanh関数群は,双曲線逆正接値を返す。
7.12.5.4 cosh関数群
形式
#include <math.h>
double cosh(double x);
float coshf(float x);
long double coshl(long double x);
機能 cosh関数群は,xの双曲線余弦を計算する。xの絶対値が大きすぎる場合,値域エラーが発生する。
返却値 cosh関数群は,双曲線余弦値を返す。
7.12.5.5 sinh関数群
形式
#include <math.h>
double sinh(double x);
float sinhf(float x);
long double sinhl(long double x);
機能 sinh関数群は,xの双曲線正弦を計算する。xの絶対値が大きすぎる場合,値域エラーが発生する。
返却値 sinh関数群は,双曲線正弦値を返す。
7.12.5.6 tanh関数群
163
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
形式
#include <math.h>
double tanh(double x);
float tanhf(float x);
long double tanhl(long double x);
機能 tanh関数群は,xの双曲線正接を計算する。
返却値 tanh関数群は,双曲線正接値を返す。
7.12.6 指数関数及び対数関数
7.12.6.1 exp関数群
形式
#include <math.h>
double exp(double x);
float expf(float x);
long double expl(long double x);
機能 exp関数群は,自然対数の底eのx乗を計算する。xの絶対値が大きすぎる場合,値域エラーが発
生する。
返却値 exp関数群は,exの値を返す。
7.12.6.2 exp2関数群
形式
#include <math.h>
double exp2(double x);
float exp2f(float x);
long double exp2l(long double x);
機能 exp2関数群は,2のx乗を計算する。xの絶対値が大きすぎる場合,値域エラーが発生する。
返却値 exp2関数群は,2xの値を返す。
7.12.6.3 expm1関数群
形式
#include <math.h>
double expm1(double x);
float expm1f(float x);
long double expm1l(long double x);
機能 expm1関数群は,自然対数の底eのx乗から1を引いた値を計算する。xが大きすぎる場合,値域
エラーが発生する(199)。
返却値 expm1関数群は,ex−1の値を返す。
7.12.6.4 frexp関数群
形式
#include <math.h>
───────────────────────────────────────────────
(199) xの絶対値が小さい場合,expm1(x)はexp(x) - 1より正確な値を返すと期待してよい。
164
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
double frexp(double value, int *exp);
float frexpf(float value, int *exp);
long double frexpl(long double value, int *exp);
機能 frexp関数群は,浮動小数点数を,正規化した数と2の整数べき乗とに分割する。その整数をexp
が指すint型のオブジェクトに格納する。
返却値 valueが浮動小数点数でない場合,その結果は,未規定とする。それ以外の場合,frexp関数群
は,次の二つの条件を満足する値xを返す。
− xの絶対値が,区間[1/2,1)に含まれる,又は,0に等しい。
− valueがx×2*expに等しい。
valueが0の場合,x及び*expの値は,0とする。
7.12.6.5 ilogb関数群
形式
#include <math.h>
int ilogb(double x);
int ilogbf(float x);
int ilogbl(long double x);
機能 ilogb関数群は,符号付きintの値としてxの指数を抽出する。xが0の場合,値FP̲ILOGB0を
計算結果とする。xが無限大の場合,値INT̲MAXを結果とする。xがNaNの場合,値FP̲ILOGBNANを
計算結果とする。それ以外の場合,対応するlogb関数を呼び出して,その返却値を型intにキャストす
ることと等価とする。xが0の場合,値域エラーが発生することがある。
返却値 ilogb関数群は,xの指数を符号付きintの値として返す。
前方参照 logb関数群(7.12.6.11)
7.12.6.6 ldexp関数群
形式
#include <math.h>
double ldexp(double x, int exp);
float ldexpf(float x, int exp);
long double ldexpl(long double x, int exp);
機能 ldexp関数群は,浮動小数点数と2の整数べき乗を乗算する。値域エラーが発生することがある。
返却値 ldexp関数群は,x×2expの値を返す。
7.12.6.7 log関数群
形式
#include <math.h>
double log(double x);
float logf(float x);
long double logl(long double x);
機能 log関数群は,xのeを底とする(自然)対数を計算する。実引数が負の場合,定義域エラーが発
生する。実引数が0の場合,値域エラーが発生することがある。
返却値 log関数群は,logexの値を返す。
7.12.6.8 log10関数群
165
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
形式
#include <math.h>
double log10(double x);
float log10f(float x);
long double log10l(long double x);
機能 log10関数群は,xの10を底とする(常用)対数を計算する。実引数が負の場合,定義域エラー
が発生する。実引数が0の場合,値域エラーが発生することがある。
返却値 log10関数群は,log10xの値を返す。
7.12.6.9 log1p関数群
形式
#include <math.h>
double log1p(double x);
float log1pf(float x);
long double log1pl(long double x);
機能 log1p関数群は,実引数に1を加えた値のeを底とする(自然)対数を計算する(200)。実引数が−1
より小さい場合,定義域エラーが発生する。実引数が−1の場合,値域エラーが発生することがある。
返却値 log1p関数群は,loge(1+x)の値を返す。
7.12.6.10 log2関数群
形式
#include <math.h>
double log2(double x);
float log2f(float x);
long double log2l(long double x);
機能 log2関数群は,xの2を底とする対数を計算する。実引数が負の場合,定義域エラーが発生する。
実引数が0の場合,値域エラーが発生することがある。
返却値 log2関数群は,log2xの値を返す。
7.12.6.11 logb関数群
形式
#include <math.h>
double logb(double x);
float logbf(float x);
long double logbl(long double x);
機能 logb関数群は,浮動小数点形式における符号付き整数の値としてxの指数を抽出する。xが非正
規化数の場合,正規化されているものとして処理する。したがって,xが有限で正の値ならば,
1≦x×FLT̲RADIX−logb(x)<FLT̲RADIX
の式となる。実引数が0の場合,値域エラーが発生することがある。
返却値 logb関数群は,xの符号付き指数を返す。
───────────────────────────────────────────────
(200) xの絶対値が小さい場合,log1p(x)はlog(1 + x)より正確な値を返すと期待してよい。
166
X 3010:2003 (ISO/IEC 9899:1999)
2019年7月1日の法改正により名称が変わりました。まえがきを除き,本規格中の「日本工業規格」を「日本産業規格」に読み替えてください。
7.12.6.12 modf関数群
形式
#include <math.h>
double modf(double value, double *iptr);
float modff(float value, float *iptr);
long double modfl(long double value, long double *iptr);
機能 modf関数群は,実引数valueを,整数部と小数部とに分割する。整数部及び小数部の符号は,実
引数と同一とする。iptrが指すオブジェクトに(浮動小数点形式の)整数部を格納する。
返却値 modf関数群は,valueの符号付き小数部を返す。
7.12.6.13 scalbn関数群及びscalbln関数群
形式
#include <math.h>
double scalbn(double x, int n);
float scalbnf(float x, int n);
long double scalbnl(long double x, int n);
double scalbln(double x, long int n);
float scalblnf(float x, long int n);
long double scalblnl(long double x, long int n);
機能 scalbn関数群及びscalbln関数群は,効率よくx×FLT̲RADIXnを計算する。通常,実際に
FLT̲RADIXnを計算することはない。値域エラーが発生することがある。
返却値 scalbn関数群及びscalbln関数群は,x×FLT̲RADIXnの値を返す。
7.12.7 べき乗関数及び絶対値関数
7.12.7.1 cbrt関数群
形式
#include <math.h>
double cbrt(double x);
float cbrtf(float x);
long double cbrtl(long double x);
機能 cbrt関数群は,xの実数の立方根を計算する。
返却値 cbrt関数群は,x1/3の値を返す。
7.12.7.2 fabs関数群
形式
#include <math.h>