C Language
実装定義の振る舞い
サーチ…
備考
概要
C標準は、言語構文、標準ライブラリによって提供される関数、および適合するCプロセッサ(大まかに言えばコンパイラ)と適合するCプログラムの動作を記述する。ビヘイビアに関しては、大部分の標準がプログラムやプロセッサの特定の動作を指定しています。一方、一部の操作には、明示的または暗黙的な未定義の動作があります。そのような操作は、その操作については何も頼ることができないため、常に避けるべきです。その間には、さまざまな実装定義の振る舞いがあります。これらの動作は、Cプロセッサ、ランタイム、および標準ライブラリ(総称して実装 )によって異なる場合がありますが、いずれの実装でも一貫性と信頼性があり、適合する実装ではこれらの各領域での動作を記録します。
プログラムが実装定義の振る舞いに依存することは時には妥当です。たとえば、プログラムが特定のオペレーティング環境に固有のものであれば、その環境の共通プロセッサに一般的なインプリメンテーション定義の動作に依存することは問題になりにくいでしょう。あるいは、条件付きコンパイル指示を使用して、使用中の実装に適した実装定義の振る舞いを選択することもできます。どのような場合でも、どの操作に実装定義の振る舞いがあるのかを知ることが重要です。その振る舞いを回避するか、使用するかどうか、どのように使用するかについて情報に基づいた決定を下すことが重要です。
これらの発言のバランスは、C2011標準で規定されている実装定義動作と特性のリストであり、標準への参照となります。それらの多くは標準の用語を使用しています 。他の人たちは、ソースコードをプログラムに変換する8段階や、ホストされた実装と自立して実装されている実装の違いなど、標準の文脈にもっと一般的に頼っています。特に驚くべきことや注目すべきものが太字で表示されています。記述されたすべての動作が以前のC標準でサポートされているわけではありませんが、一般的に言えば、それらをサポートする標準のすべてのバージョンで実装定義の動作があります。
プログラムとプロセッサ
一般
ソース翻訳
物理ソースファイルのマルチバイト文字がソースキャラクタセット( 5.1.1.2/1 )にマッピングされる方法。
翻訳フェーズ3( 5.1.1.2/1 )の間に空白以外の空白でない空白のシーケンスが単一の空白で置き換えられるかどうかは、
対応する文字がない場合( 5.1.1.2/1 )、文字列定数の文字リテラルおよび文字が変換フェーズ5で変換される実行セット文字。
動作環境
フリースタンディング実装( 5.1.2.1/1 )で起動時に呼び出される関数の名前と型。
指定された最小セット( 5.1.2.1/1 )を超えて自立的な実装で利用可能なライブラリ機能。
フリースタンディング環境( 5.1.2.1/2 )におけるプログラム終了の影響。
ホストされた環境では、
int main(int argc, char *arg[])
およびint main(void)
( 5.1.2.2.1 / 1 )以外のmain()
関数で許可されたシグニチャ。ホストされた実装が
main()
( 5.1.2.2.1 / 2 )の第2引数が指す文字列を定義する方法。セクション5.1.2.3 (プログラム実行)と7.21.3 (ファイル)( 5.1.2.3/7 )の目的のための「対話型デバイス」を構成するもの
最適化実装( 5.1.2.3 / 10 )で割り込みハンドラルーチンが参照するオブジェクトの制限。
フリースタンディングの実装では、複数の実行スレッドがサポートされているかどうか( 5.1.2.4/1 )。
実行文字セット( 5.2.1 / 1 )のメンバーの値。
定義されたアルファベットのエスケープシーケンス( 5.2.2 / 3 )に対応する
char
値。整数および浮動小数点数の制限と特性 ( 5.2.4.2/1 )。
浮動小数点演算の精度と、標準ライブラリの内部浮動小数点表現から文字列表現への変換( 5.2.4.2.2 / 6 )。
デフォルトの浮動小数点丸めモード( 5.2.4.2.2 / 8 )をエンコードするマクロ
FLT_ROUNDS
の値。丸め動作は、サポートされている
FLT_ROUNDS
値が3以上または-1未満( 5.2.4.2.2 / 8 )であることを特徴とします。浮動小数点評価動作( 5.2.4.2.2 / 9 )を特徴付けるマクロ
FLT_EVAL_METHOD
の値。サポートされている
FLT_EVAL_METHOD
値が-1より小さい( 5.2.4.2.2 / 9 )ことを特徴とする動作。マクロの値
FLT_HAS_SUBNORM
、DBL_HAS_SUBNORM
、およびLDBL_HAS_SUBNORM
は、標準浮動小数点フォーマットが非正規化数( 5.2.4.2.2 / 10 )をサポートするかどうかをLDBL_HAS_SUBNORM
、
タイプ
オブジェクトが関連付けられているスレッド以外のスレッドからスレッド記憶期間を持つオブジェクトに(間接的に)アクセスしようとした結果( 6.2.4 / 4 )
基本実行セット外の文字が割り当てられている
char
の値( 6.2.5 / 3 )。サポートされている拡張符号付き整数型(存在する場合)( 6.2.5 / 4 )、それらを識別するための拡張キーワード。
char
がsigned char
またはunsigned char
( 6.2.5 / 15 ) と同じ表現と動作をするかどうか 。char
がそれぞれ符号なしまたは符号付きの場合は、0
またはSCHAR_MIN
をCHAR_MIN
問合せできます。オブジェクトの表現におけるバイトの数、順序、およびエンコーディング 。ただし、標準で明示的に指定されている場合を除く( 6.2.6.1/2 )。
整数表現の3つの認識された形式のどれが与えられた状況に適用されるか、および整数オブジェクトの特定のビットパターンがトラップ表現 ( 6.2.6.2/2 )であるかどうか 。
各タイプの整列要件( 6.2.8 / 1 )。
任意の拡張されたアライメントがサポートされているかどうか( 6.2.8 / 3 )。
サポートされている拡張アラインメントのセット( 6.2.8 / 4 )。
整数変換は、互いに拡張された符号付き整数型( 6.3.1.1/1 )を基準にしてランク付けされます。
符号なし整数 ( 6.3.1.3/3 )に範囲外の値を割り当てる効果 。
範囲内だが表現できない値が浮動小数点オブジェクトに割り当てられている場合、オブジェクトに格納されている表現可能な値は、最も近い2つの表現可能な値( 6.3.1.4/2 ; 6.3.1.5/1 ; 6.4.4.2 / 3 )。
値
0
( 6.3.2.3/5 )の整数定数式を除いて、整数をポインタ型に変換した結果 。
ソースフォーム
ヘッダ名トークンが認識される
#pragma
ディレクティブ内の場所( 6.4 / 4 )。マルチバイト文字、アンダースコア以外の文字、アクセントのないラテン文字、ユニバーサルキャラクタ名、および識別子( 6.4.2.1/1 )に現れることがある小数点を含む文字。
識別子の有効文字数 ( 6.4.2.1/5 )。
いくつかの例外を除いて、整数文字定数のソース文字が実行セット文字( 6.4.4.4/2 ; 6.4.4.4/10 )にマップされる方法。
ワイド文字定数の値を計算するために使用される現在のロケール、および多くのそのような定数( 6.4.4.4/11 )の変換の他の側面。
異なる接頭辞のワイド文字列リテラルトークンを連結することができるかどうか、もしそうであれば、結果として生じるマルチバイト文字シーケンス( 6.4.5 / 5 )の処理は、
変換フェーズ7でワイド文字列リテラルをマルチバイト文字シーケンスに変換するために使用されるロケールと、結果が実行文字セット( 6.4.5 / 6 )で表現できない場合の値。
ヘッダ名がファイル名( 6.4.7 / 2 )にマッピングされる方法。
評価
FP_CONTRACT
が使用されていないときに浮動小数点式が収縮するかどうか( 6.5 / 8 )sizeof
演算子と_Alignof
演算子の結果の値 ( 6.5.3.4/5 )。ポインタ減算の結果の型のサイズ( 6.5.6 / 9 )。
符号付き整数を負の値 ( 6.5.7 / 5 ) で右シフトした結果 。
実行時の動作
register
キーワードの有効範囲( 6.7.1 / 6 )。int
として宣言されたビットフィールドの型がunsigned int
と同じ型かsigned int
( 6.7.2 / 5 )であるかどうか。任意の修飾された
_Bool
、signed int
、およびunsigned int
以外の、ビットフィールドの種類ビットフィールドが原子タイプ( 6.7.2.1/5 )を持つかどうか。実装がどのようにビットフィールドの記憶域をレイアウトするかについての側面( 6.7.2.1 / 11 )。
構造体と共用体の非ビットフィールドメンバの配置( 6.7.2.1/14 )。
各列挙型( 6.7.2.2/4 )の基礎となる型。
volatile
-qualifed型( 6.7.3 / 7 )のオブジェクトへの「アクセス」を構成するものinline
関数宣言の有効性( 6.7.4 / 6 )。
プリプロセッサ
文字定数が整数値に変換されるかどうかは、通常の式と同じようにプリプロセッサの条件と同じか、1文字の定数が負の値( 6.10.1 / 4 )を持つかどうかです。
場所は、
#include
指令( 6.10.2 / 2-3 )で指定されたファイルを検索します。ヘッダー名がマルチトークン
#include
ディレクティブ( 6.10.2 / 4 )のトークンから形成される方法。#include
ネスティングの制限( 6.10.2 / 6 )。かどうか
\
文字が前に挿入された\
プリプロセッサの結果にユニバーサル文字名を導入#
演算子( 6.10.3.2/2 )。STDC
( 6.10.6 / 1 )以外のプラグマの#pragma
preprocessingディレクティブの動作。変換日時がない場合は、
__DATE__
__TIME__
マクロと__TIME__
マクロの値がそれぞれ使用可能です( 6.10.8.1/1 )。マクロ
__STDC_ISO_10646__
が定義されていない場合は、wchar_t
使用される内部文字エンコーディング( 6.10.8.2/1 )。マクロ
__STDC_UTF_32__
が定義されていない場合にchar32_t
使用される内部文字エンコーディング( 6.10.8.2/1 )。
標準ライブラリ
一般
- アサーションが失敗したときに出力されるメッセージの形式( 7.2.1.1/2 )。
浮動小数点環境関数
標準で定義されているものを超える追加の浮動小数点例外( 7.6 / 6 )。
標準で定義されている以外の浮動小数点丸めモード( 7.6 / 8 )。
標準によって定義されたものを超える追加の浮動小数点環境( 7.6 / 10 )。
浮動小数点環境アクセススイッチ( 7.6.1 / 2 )のデフォルト値。
fegetexceptflag()
( 7.6.2.2/1 )によって記録された浮動小数点ステータスフラグの表現。feraiseexcept()
関数が、 "オーバーフロー"または "アンダーフロー"浮動小数点例外( 7.6.2.3/2 )を発生させるたびに、「不正確な」浮動小数点例外をさらに発生させるかどうか。
ロケール関連の関数
-
setlocale()
( 7.11.1.1/3 )でサポートされる"C"
以外のロケール文字列。
数学関数
で表されるタイプ
float_t
とdouble_t
FLT_EVAL_METHOD
マクロとは異なる値を有する0
、1
、及び2
( 7.12 / 2 )。標準で定義されている浮動小数点数を超える浮動小数点数の分類( 7.12 / 6 )。
math.h
関数が返す値は、ドメインエラー( 7.12.1 / 2 )の場合に発生します。極エラー( 7.12.1 / 3 )のイベントで
math.h
関数が返す値。結果がアンダーフローしたときの
math.h
関数の戻り値、errno
がERANGE
設定さERANGE
ているかどうか、およびこれらの状況( 7.12.1 / 6 )で浮動小数点例外が発生するかどうかの側面。FP収縮スイッチのデフォルト値( 7.12.2 / 2 )。
fmod()
関数が0を返すか、2番目の引数が0( 7.12.10.1/3 )のときにドメインエラーを発生させるかどうか。remainder()
関数が0を返すか、2番目の引数が0( 7.12.10.2/3 )のときにドメインエラーを発生させるかどうか。remquo()
関数( 7.12.10.3 / 2 )によって計算された商モジュラスの有効ビット数。remquo()
関数が0を返すか、2番目の引数が0( 7.12.10.3/3 )のときにドメインエラーを発生させるかどうか。
信号
サポートされているシグナルの完全なセット、そのセマンティクス、およびデフォルト処理( 7.14 / 4 )。
シグナルが生成され、そのシグナルに関連付けられたカスタムハンドラが存在する場合、ハンドラ( 7.14.1.1/3 )の実行中にシグナルがブロックされている場合は、それがブロックされます。
SIGFPE
、SIGILL
、およびSIGSEGV
以外のSIGFPE
は、カスタムシグナルハンドラから戻ったときの動作を未定義にします( 7.14.1.1/3 )。
雑
- マクロ
NULL
展開する特定のNULLポインター定数( 7.19 / 3 )。
ファイル処理関数
テキストストリームの最後の行に終端改行( 7.21.2 / 2 )が必要かどうか。
バイナリストリーム( 7.21.2 / 3 )に自動的に付加されるヌル文字の数。
追加モード( 7.21.3 / 1 )で開いたファイルの初期位置。
テキストストリームへの書き込みによってストリームが切り捨てられるかどうか( 7.21.3 / 2 )
ストリームバッファリング( 7.21.3 / 3 )のサポート
長さがゼロのファイルが実際に存在するかどうか( 7.21.3 / 4 )。
有効なファイル名を作成するための規則( 7.21.3 / 8 )。
同じファイルを同時に複数回開くことができるかどうか( 7.21.3 / 8 )。
マルチバイト文字( 7.21.3 / 10 )のエンコーディングの性質と選択。
ターゲットファイルが開いているときの
remove()
関数の動作( 7.21.4.1/2 )。ターゲットファイルがすでに存在する場合の
rename()
関数の動作( 7.21.4.2/2 )。プログラムが異常終了した場合に、
tmpfile()
関数によって作成されたtmpfile()
が削除されるかどうか( 7.21.4.3/2 )。どの状況下で
freopen()
( 7.21.5.4/3 )によってどのモードが変更できるのか
I / O機能
無限または無数のFP値の許容表現のどれがprintf() - ファミリ関数( 7.21.6.1/8 )によって生成されるか。
ポインターが
printf()
family関数( 7.21.6.1/8 )によってフォーマットされる方法。-
文字が[
フィールド( 7.21.6.2/12 )のスキャンリストの内部位置に表示されたときのscanf()
-
family関数の動作。scanf()
family関数のほとんどの側面はp
フィールドを渡します( 7.21.6.2/12 )。失敗時に
fgetpos()
によって設定されたerrno
値( 7.21.9.1/2 )。失敗時に
fsetpos()
によって設定されたerrno
値( 7.21.9.3/2 )。失敗時に
ftell()
によって設定されたerrno
値( 7.21.9.4/3 )。strtod()
の意味は、NaNフォーマット( 7.22.1.3p4 )のいくつかのサポートされている側面の機能です。結果がアンダーフローしたときに
strtod()
family関数がerrno
をERANGE
にerrno
するかどうか( 7.22.1.3 / 10 )。
メモリ割り当て関数
- 要求されたバイト数が0( 7.22.3 / 1 )の場合のメモリ割り当て関数の動作。
システム環境機能
abort()
関数が呼び出されたときにクリーンアップがあれば実行され、どの状態がホストOSに返されるか( 7.22.4.1/2 )。exit()
が呼び出されると、どのようなステータスがホスト環境に返されますか( 7.22.4.4/5 )。_Exit()
が呼び出されたときにオープンストリームの処理とホスト環境に返されるステータス( 7.22.4.5/2 )。getenv()
と環境を変更するためのメソッド( 7.22.4.6/2 )でアクセス可能な一連の環境名。system()
関数の戻り値( 7.22.4.8/3 )。
日時関数
現地時間帯と夏時間( 7.27.1 / 1 )。
clock_t
型とtime_t
型( 7.27.1 / 4 )で表現可能な時間の範囲と精度。clock()
関数( 7.27.2.1/3 )によって返された時間の参照として機能する時代の始まり。timespec_get()
関数によって戻された時間の基準となるエポックの始まり(タイムベースがTIME_UTC
場合、TIME_UTC
/ 3 )。"C"ロケール( 7.27.3.5/7 )の
%Z
変換指定子に対するstrftime()
置き換え。
ワイド文字入出力機能
無限または無数のFP値の許容表現のどれが
wprintf()
family関数( 7.29.2.1/8 )によって生成されるか。ポインターが
wprintf()
family関数( 7.29.2.1/8 )によってフォーマットされる方法。wscanf()
-
familyの動作は、-
文字が[
フィールド( 7.29.2.2/12 )のスキャンリストの内部位置に表示されるときに機能します。wscanf()
family関数のほとんどの機能は、p
フィールドを渡します( 7.29.2.2/12 )。NaNフォーマット( 7.29.4.1.1 / 4 )のいくつかのサポートされている側面の
wstrtod()
ファミリ関数に対する意味。結果がアンダーフローしたときに
wstrtod()
family関数がerrno
をERANGE
にerrno
するかどうか( 7.29.4.1.1 / 10 )。
負の整数の右シフト
int signed_integer = -1;
// The right shift operation exhibits implementation-defined behavior:
int result = signed_integer >> 1;
範囲外の値を整数に代入する
// Supposing SCHAR_MAX, the maximum value that can be represented by a signed char, is
// 127, the behavior of this assignment is implementation-defined:
signed char integer;
integer = 128;
0バイトの割り当て
// The allocation functions have implementation-defined behavior when the requested size
// of the allocation is zero.
void *p = malloc(0);
符号付き整数の表現
各符号付き整数型は、3つの形式のいずれかで表現できます。どちらが使用されるかは実装定義されています。与えられた符号付き整数型のint
型の実装は、実行時にその型の値-1
の表現の下位2ビットから次のように決定することができます。
enum { sign_magnitude = 1, ones_compl = 2, twos_compl = 3, };
#define SIGN_REP(T) ((T)-1 & (T)3)
switch (SIGN_REP(long)) {
case sign_magnitude: { /* do something */ break; }
case ones_compl: { /* do otherwise */ break; }
case twos_compl: { /* do yet else */ break; }
case 0: { _Static_assert(SIGN_REP(long), "bogus sign representation"); }
}
より狭い型の表現にも同じパターンが当てはまりますが、 &
のオペランドは結果が計算される前に「通常の算術変換」の対象となるため、この手法ではテストできません。