_Pragma()、FP_CONTRACT、CX_LIMITED_RANGEに関する情報が不足しています。 (2020年11月) |
| C言語の改訂 |
|---|

C99(開発中はC9X 、正式にはISO/IEC 9899:1999)は、Cプログラミング言語オープン標準の過去のバージョンです。[ 1 ]以前のバージョン(C90)を拡張して言語と標準ライブラリの新しい機能が追加され、実装においてIEEE 754-1985浮動小数点演算やコンパイラ技術などの利用可能なコンピュータハードウェアをより有効に活用できるようになります。[ 2 ] 2011年に発行されたCプログラミング言語標準のC11バージョンは、C99を更新したものです。
歴史
1989年にANSIがCプログラミング言語の公式標準を策定し、1990年に国際標準となった後、C言語仕様はしばらくの間比較的静的なままでしたが、C ++は主に独自の標準化活動の中で進化を続けました。1995年には、規範修正第1号によりC言語の新しい標準が作成されましたが、これは1989年標準の一部を修正し、国際文字セットのサポートをより広範囲に追加することのみを目的としていました。この標準は1990年代後半にさらに改訂され、1999年にISO/IEC 9899:1999が発行され、2000年5月にANSI標準として採用されました。この標準バージョンで定義された言語は、一般に「C99」と呼ばれています。国際C標準は、ISO/IEC JTC1/SC22 /WG14ワーキンググループ によって保守されています。
デザイン

C99はC89と大部分で下位互換性があるが、いくつかの点ではより厳密である。[ 3 ]
特に、型指定子のない宣言は、int暗黙的に型指定子が想定されなくなりました。C標準委員会は、暗黙的な型指定子に依存したレガシーコードを黙って処理するよりも、コンパイラが型指定子の不注意な省略を診断する方が価値があると判断しました。int実際には、コンパイラは警告を表示し、その後は型指定子が想定されてintプログラムの変換を続行する傾向があります。
C99ではいくつかの新機能が導入されたが、その多くはすでにいくつかのコンパイラで拡張機能として実装されていた。[ 4 ]
- インライン関数
- 宣言とコードの混在:変数宣言は、ファイル スコープまたは複合ステートメント (ブロック) の開始に制限されなくなりました。
- いくつかの新しいデータ型
long long int( 、オプションの拡張整数型、明示的なブールデータ型(_Bool)、および複素数を表す複素数型(型指定子)を含む)_Complex - 可変長配列(ただし、C11では実装でサポートする必要のない条件付き機能に格下げされた)
- 柔軟な配列メンバー
- BCPL、C++、Javaのように、で始まる1 行コメントのサポート
// - 新しいライブラリ関数、例えば
snprintf - 新しいヘッダー(、、、など)
<stdbool.h><complex.h><tgmath.h><inttypes.h> - 、、または引数などに基づいて数学ライブラリ関数
<tgmath.h>を選択する、 内の型汎用数学 (マクロ) 関数。floatdoublelong double - IEEE 754-1985浮動小数点のオプションサポート
- 指定された初期化子。例えば、フィールド名で構造体を初期化する:
struct Point p = { .x = 1, .y = 2 };[ 5 ] - 複合リテラル。例えば、関数呼び出しの中に構造体を構築することができる。
function((struct x) {1, 2})[ 6 ] - 可変長マクロ(可変数の引数を持つマクロ)のサポート
restrict修飾子により、より積極的なコード最適化が可能になり、以前はFORTRANがANSI Cよりも優れていたコンパイル時の配列アクセスの利点がなくなる[ 7 ]- ユニバーサル文字名。ユーザー変数に標準文字セット以外の文字(4桁
\u0040または8桁の16進数シーケンス)を含めることができます。\U0001f431 staticパラメータ宣言内の配列インデックス内のキーワード[ 8 ] : 例えば、void someFunction(int someArray[static 100]){...}someFunctionが呼び出されるたびに、渡されたポインタが確実にNULLではなく、少なくとも100個の配列を指していることをコンパイラに伝えますint。[ 9 ] [ 10 ]
C99標準の一部は、整数型、ヘッダー、ライブラリ関数など、現在のC++標準に含まれています。可変長配列は、C++の標準テンプレートライブラリに既に同様の機能が含まれているため、これらの標準には含まれていません。
IEEE 754浮動小数点サポート
C99の主要な特徴は数値演算のサポートであり、特に、現代のプロセッサのほとんどに搭載されているIEEE 754-1985(IEC 60559とも呼ばれる)浮動小数点ハードウェアの機能へのアクセスをサポートしている(「附属書F IEC 60559浮動小数点演算」で定義)。IEEE 754ハードウェアを搭載していないプラットフォームでも、ソフトウェアで実装できる。[ 2 ]
IEEE 754 浮動小数点プラットフォームの場合:
floatは IEEE 754単精度として定義され、は倍精度doubleとして定義され、 はIEEE 754拡張精度(例: x86またはx86-64プラットフォーム上のIntel 80 ビット拡張倍精度) として定義されるか、使用可能な場合は何らかの形式の4 倍精度として定義されます。それ以外の場合は倍精度です。long double- 四則演算と平方根は、IEEE 754 の定義に従って正しく丸められます。
FLT_EVAL_METHOD フロート ダブル ロングダブル 0 フロート ダブル ロングダブル 1 ダブル ダブル ロングダブル 2 ロングダブル ロングダブル ロングダブル - 式の評価は、3つの明確に定義された方法のいずれかで実行されるように定義されています。これらの方法は、式内の浮動小数点変数を最初により正確な形式に昇格するかどうかを示します。 は、
FLT_EVAL_METHOD == 2すべての内部中間計算が、利用可能な場合はデフォルトで高精度(long double)で実行されることを示します(例:80ビットのdouble extended)。 は、FLT_EVAL_METHOD == 1すべての内部中間式を倍精度で実行します(オペランドがlong doubleでない場合)。 は、FLT_EVAL_METHOD == 0各演算が各演算子の最大幅のオペランドの精度でのみ評価されることを指定します。 指定された精度のオペランドの中間結果の型は、隣の表にまとめられています。
FLT_EVAL_METHOD == 2は、数値的に不安定な式に影響を与える丸め誤差のリスクを制限する傾向があり(IEEE 754の設計原理を参照)、 x87ハードウェア用に設計されたデフォルトの方法ですが、不注意なユーザーには直感的でない動作をもたらします。 [ 11 ]は、もともとK&R CFLT_EVAL_METHOD == 1で使用されていたデフォルトの評価方法で、式内のすべてのfloatをdoubleに昇格しました。また、一般的に使用され、オペランドの厳密な「型に評価」を指定します。(gccでは、32ビットx86では がデフォルト、64ビットx86-64では がデフォルトですが、オプション-mfpmath=387を使用してx86-64で指定できます。)C99より前では、特にx87浮動小数点ハードウェアを使用している場合、コンパイラは中間結果を一貫性なく丸めることがあり、コンパイラ固有の動作につながりました。 [ 12 ]このような不一致は、C99に準拠したコンパイラでは許可されていません(付録F)。 FLT_EVAL_METHOD == 0FLT_EVAL_METHOD == 2FLT_EVAL_METHOD == 0FLT_EVAL_METHOD == 2
例
連分数関数を計算するための次の注釈付き C99 コード例は、主な機能を示しています。
#include <assert.h>#include <fenv.h>#include <float.h>#include <math.h>#include <stdio.h>#include <stdbool.h>#include <tgmath.h>ダブルcompute_fn (ダブルz ) { // [1]#pragma STDC FENV_ACCESS ON // [2]アサート( FLT_EVAL_METHOD == 2 ); // [3]if ( isnan ( z )) { // [4]puts ( "zは数値ではありません" );}もし( isinf ( z )) {puts ( "zは無限大" );}ロングダブルr = 7.0 - 3.0 / ( z - 2.0 - 1.0 / ( z - 7.0 + 10.0 / ( z - 2.0 - 2.0 / ( z - 3.0 )))); // [5, 6]feclearexcept ( FE_DIVBYZERO ); // [7]bool raised = fetestexcept ( FE_OVERFLOW ); // [8]if (発生した) {puts ( "予期しないオーバーフローが発生しました。" );}rを返します。}int main ( void ) {#ifndef __STDC_IEC_559__puts ( "警告: __STDC_IEC_559__ が定義されていません。IEEE 754 浮動小数点が完全にサポートされていません。" ); // [9]#endif#プラグマ STDC FENV_ACCESS オン#ifdef TEST_NUMERIC_STABILITY_UPfesetround ( FE_UPWARD ); // [10]#elif TEST_NUMERIC_STABILITY_DOWNfesetround ( FE_DOWNWARD );#endifprintf ( "%.7g \n " , compute_fn ( 3.0 ));printf ( "%.7g \n " , compute_fn ( NAN ));0を返します。}脚注:
- コンパイル:
gcc-std=c99-mfpmath=387-otest_c99_fptest_c99_fp.c-lm - この関数では IEEE 754 ステータス フラグが操作されるため、最適化時にコンパイラがこのようなテストを誤って並べ替えるのを防ぐために、この #pragma が必要です。(プラグマは通常、実装定義ですが、接頭辞が付くものは
STDCC 標準で定義されています。) - C99 では、限られた数の式評価方法が定義されています。現在のコンパイル モードをチェックして、コードが記述されたときの想定を満たしていることを確認できます。
- NaNや正または負の無限大などの特殊な値をテストおよび設定できます。
long doubleIEEE 754拡張倍精度または4倍精度(利用可能な場合)として定義されます。中間計算に必要な精度よりも高い精度を使用することで、丸め誤差を最小限に抑えることができます[ 13 ](typedefはdouble_t、すべての で移植可能なコードに使用できますFLT_EVAL_METHOD)。- 評価対象となるメイン関数。この連分数への引数(例えば3.0)はゼロ除算エラーを引き起こすように見えますが、実際には関数は3.0で適切に定義されており、0で割ると単に+無限大が返され、結果として有限値が正しく得られます。IEEE 754は、デフォルトでこのような例外をトラップしないように定義されており、このケースのように、多くの場合は無視できるように設計されています。( が
FLT_EVAL_METHOD2と定義されている場合、定数を含むすべての内部計算はlong double精度で実行されます。FLT_EVAL_METHODが0と定義されている場合、追加のキャストや定数をlong doubleとして明示的に指定するなど、このことを確実にするために追加の注意が必要です。) - この場合、発生したゼロ除算フラグはエラーではないため、後続のコードで使用できるようにフラグをクリアするために、単に無視することができます。
- 場合によっては、オーバーフローなどの他の例外がエラーと見なされることがあります (ただし、この場合は実際には発生しないことが示されます)。
__STDC_IEC_559__「附属書 F IEC 60559 浮動小数点演算」がコンパイラと C ライブラリによって完全に実装されている場合にのみ定義されます (このマクロは、定義されるべきでないときに定義される場合があることをユーザーは認識する必要があります)。- IEEE 754のデフォルトの丸めモードは、最も近い値への丸め(中間値の場合は偶数丸めルール)ですが、明示的に+および-無限大方向への丸めモードを設定することで(
TEST_NUMERIC_STABILITY_UPこの例ではデバッグ時になどを定義することで)、数値不安定性を診断することができます。[ 14 ]この方法は、別途コンパイルされたバイナリライブラリの一部であっても使用できますcompute_fn()。ただし、関数によっては、数値不安定性を検出できない場合もあります。
バージョン検出
標準マクロは、 C99サポートが利用可能であることを示す__STDC_VERSION__値で定義されています。C90のマクロと同様に、このマクロを使用して、C90コンパイラとC99コンパイラで異なるコンパイル結果になるコードを記述できます。この例では、どちらの場合でも が利用可能であることを保証します(C90ではリンカーエラーを回避するために を に置き換えています)。 199901L__STDC____STDC_VERSION__inlinestatic
#if __STDC_VERSION__ >= 199901L /* "inline" はキーワードです */ #else # inline static を定義します#endif実装
ほとんどの C コンパイラは、C99 で導入された機能の少なくとも一部をサポートしています。
歴史的に、マイクロソフトはVisual C++ツールに新しいCの機能を実装するのが遅く、代わりにC++標準の開発をサポートすることに主に重点を置いてきました。[ 15 ]しかし、Visual C++ 2013の導入により、マイクロソフトはC99の限定的なサブセットを実装し、これはVisual C++ 2015で拡張されました。[ 16 ]
| コンパイラ | サポートレベル | C99互換性の詳細 |
|---|---|---|
| エイコーンC/C++ | 部分的 | 公式ドキュメントには、「ほとんどの」コンパイラ機能と「一部の」ライブラリ関数がサポートされていると記載されています。 |
| AMD x86 Open64 コンパイラスイート | たいてい | GCCと同等のC99サポートを持っています。[ 17 ] |
| cc65 | 部分的 | C89およびC99の完全なサポートは実装されていません。これはプラットフォームの制限( MOS Technology 6502 )によるところが大きいです。_Complexや64ビット整数(long long)などの一部のC99型のサポートは予定されていません。[ 18 ] |
| チ | 部分的 | 主要なC99機能をサポートします。[ 19 ] |
| カラン | たいてい | C99浮動小数点プラグマを除くすべての機能をサポートします。[ 20 ] |
| コンプサート | たいてい | 正式に正当性が証明された認定コンパイラ。C99複素数とVLAを除くすべての機能をサポートし、switch文には若干の制限がある(Duffのデバイスはサポートされない)。[ 21 ] |
| cパーサー | 満杯 | C99の機能をサポートします。[ 22 ] |
| C++ビルダー | 後者はCLangフォークなので64ビットモードのみ | |
| デジタルマーズC/C++コンパイラ | 部分的 | < tgmath.h >や_Pragmaなどの一部の機能がサポートされていません。 [ 23 ] |
| GCC | たいてい | 2021年7月現在、標準プラグマとIEEE 754/IEC 60559浮動小数点サポートはGCCのメインラインでは欠落しています。さらに、一部の機能(拡張整数型や新しいライブラリ関数など)はC標準ライブラリで提供する必要があり、GCCのスコープ外です。[ 24 ] GCCの4.6および4.7リリースも同じレベルの準拠を提供しています。[ 25 ] [ 26 ]ハードウェアが準拠している場合でも、IEEE 754のサポートは部分的です。誤った最適化を回避するために一部のコンパイラオプションが必要になる場合があります(例:-std=c99および-fsignaling-nans)が、が使用されている場合でも、方向付き丸めモードの完全なサポートは欠落しています-frounding-math。[ 27 ] |
| グリーンヒルズソフトウェア | 満杯 | |
| IBM C for AIX, V6 [ 28 ]およびXL C/C++ V11.1 for AIX [ 29 ] | 満杯 | |
| IBM Rationalロジスコープ | 満杯 | Logiscope 6.3までは、C99の基本構造のみがサポートされていました。C99はLogiscope 6.4以降のバージョンで正式にサポートされています。[ 30 ] |
| ポートランドグループPGI C/C++ | 満杯 | |
| IAR システムズ組み込みワークベンチ | たいてい | UCN(ユニバーサルキャラクタ名)はサポートされていません。ARM、Coldfire、MSP430、AVR、AVR32、8051などの組み込みターゲット向けコンパイラです。x86ターゲットには対応していません。 |
| Intel C++コンパイラ | たいてい | |
| マイクロソフトビジュアルC++ | 部分的[ 16 ] | Visual C++ 2012 以前では C99 をサポートしていませんでした。[ 31 ] [ 32 ] [ 33 ] Visual C++ 2013 では、一般的なオープンソース プロジェクトのコンパイルに必要な C99 の限定されたサブセットが実装されています。[ 34 ] [ 35 ] Visual C++ 2015 では、コンパイラでまだサポートされていないコンパイラ機能に依存するライブラリ機能を除いて、C99 標準ライブラリが実装されています (たとえば、< tgmath.h > は実装されていません)。[ 16 ] Visual C++ 2019 (16.6) では、C99 準拠のプリプロセッサのオプトイン サポートが追加されました。[ 36 ] |
| Watcomを開く | 部分的 | 標準規格の中で最も一般的に使用される部分を実装しています。ただし、これらは文書化されていないコマンドラインスイッチ「-za99」を通じてのみ有効になります。C99の3つの機能は、v1.0より前からC90拡張としてバンドルされています。C++スタイルのコメント(//)、柔軟な配列メンバー、列挙型宣言における末尾のカンマの許可です。[ 37 ] |
| ペレスC | 満杯 | C99のすべての機能をサポートします。[ 38 ] |
| ポータブルCコンパイラ | 部分的 | C99 準拠に向けて取り組んでいます。 |
| サンスタジオ | フル[ 39 ] | |
| アムステルダムコンパイラキット | いいえ | C99 フロントエンドは現在調査中です。 |
| 小さなCコンパイラ | 部分的 | 複素数はサポートされていません。[ 40 ] [ 41 ]可変長配列はサポートされていますが、関数の引数としてはサポートされていません。開発者は「TCCはISOC99への完全準拠を目指しています」と述べています。[ 42 ] |
| vbcc | 部分的 |
今後の課題
1999年のC標準の承認以来、標準ワーキンググループは、組み込み処理のサポート強化、文字データ型の追加(Unicodeサポート)、境界チェック機能強化を備えたライブラリ関数に関する技術レポートを作成しました。10進浮動小数点、数学特殊関数の追加、動的メモリ割り当て関数の追加に関する技術レポートの作成作業は継続しています。CおよびC++標準委員会は、スレッドプログラミングの仕様策定に協力してきました。
C標準の次の改訂版であるC11は2011年に承認されました。[ 43 ] C標準委員会は、既存の実装でテストされていない新機能の採用を制限するガイドラインを採択しました。シーケンスポイントを明確にし、スレッドプログラミングを サポートするために、メモリモデルの開発に多大な労力が費やされました。
参照
| C++言語の改訂 |
|---|
- CとC++の互換性
- Cプログラミング言語の概要
- C++ 技術レポート 1
- IEEE 754の使用法に関する詳しい説明については、IEEE 754 を参照してください。
参考文献
- ^ 「ISO/IEC 9899:1999 - プログラミング言語 - C」 . Iso.org. 2011年12月8日. 2014年4月8日閲覧。
- ^ a b「C99におけるIEEE 754のサポート」(PDF) . IEEE . 2017年10月28日時点のオリジナル(PDF)からアーカイブ。 2021年7月15日閲覧。
- ^ 「標準 - GNUコンパイラコレクション(GCC)の使用」 Gcc.gnu.org . 2014年4月8日閲覧。
- ^ 「C方言オプション - GNUコンパイラコレクション(GCC)の使用」 Gcc.gnu.org、2009年5月6日。 2014年4月8日閲覧。
- ^ 「GNUコンパイラコレクション(GCC)の使用:指定初期化子」 gnu.org 2019年9月18日閲覧。
- ^ 「GNUコンパイラコレクション(GCC)の使用:複合リテラル」gnu.org . 2016年1月31日閲覧。
- ^ Ulrich Drepper (2007年10月23日). 「すべてのプログラマがメモリについて知っておくべきこと」 . LWN.net . 2015年4月3日閲覧。
- ^ ISO/IEC 9899:1999 仕様、TC3 (PDF)。p. 119、§ 6.7.5.3関数宣言子(プロトタイプを含む)パラグラフ 7。
- ^「"char s[static 10 ""のような関数の配列パラメータ内のstaticキーワードの目的は何ですか?」]。
- ^「配列パラメータを持つ 'static'? おやまあ!」 .
- ^ Doug Priest (1997). 「IEEE 754実装間の相違点」 .
- ^ジャック・ヴェール(1997年11月1日)「ウィリアム・カーハンとの会話」。
- ^ウィリアム・カーハン (1996年6月11日). 「コンピュータベンチマークが応用数学、物理学、化学に及ぼす有害な影響」(PDF) .
- ^ William Kahan (2006年1月11日). 「浮動小数点演算における丸めの無思慮な評価はどれほど無駄か?」(PDF) .
- ^ Peter Bright (2013年6月29日). 「C99がついに承認され、MicrosoftはC++14への道筋を示す」 Ars Technica . 2015年1月9日閲覧。
- ^ a b c Brenner, Pat. 「Visual Studio 2015 の Visual C++ の新機能」。Microsoft Developer Network 。 2015年4月27日閲覧。
- ^ 「x86 Open64 コンパイラスイートの使用」(PDF) . Developer.amd.com. 2022年1月24日時点のオリジナルよりアーカイブ(PDF) . 2022年3月2日閲覧。
- ^ 「cc65 - 6502ベースシステム用のフリーウェアCコンパイラ」 。 2011年9月14日閲覧。
- ^ 「C/C++インタープリタCh C99の機能」 SoftIntegration, Inc. 2008年2月15日. 2008年2月15日閲覧。
- ^ 「Clangコンパイラユーザーズマニュアル」 。 2017年10月14日閲覧。
- ^ 「CompCert C 検証済みコンパイラのドキュメントとユーザーマニュアル(バージョン 3.10)」 2021年11月19日. 2022年3月3日閲覧。
- ^ "libfirmホームページ" . 2014年2月4日閲覧。
- ^ 「C言語実装 - Digital Mars」 。 2011年9月14日閲覧。
- ^ 「GCCにおけるC99機能の現状」 Free Software Foundation, Inc. 2021年7月28日. 2021年8月13日閲覧。
- ^ 「GCC 4.6におけるC99機能の現状」 Free Software Foundation, Inc. 2013年5月23日. 2013年5月23日閲覧。
- ^ 「GCC 4.7におけるC99機能の現状」 Free Software Foundation, Inc. 2013年5月23日. 2013年5月23日閲覧。
- ^ 「GCCにおける浮動小数点演算のセマンティクス」 2018年7月20日。 2018年8月12日閲覧。
- ^ 「IBM C for AIX V6.0 がC99標準をサポート」 2002年7月2日. 2016年1月31日閲覧。
- ^ 「IBM - XL C/C++ for AIX」 。 2016年1月31日閲覧。
- ^ 「IBM Rational Logiscope の C99 標準サポート - 米国」 2012年2月24日. 2016年1月31日閲覧.
- ^ 「読者Q&A: VC++とC99についてはどうですか?」Sutter's Mill、2012年5月3日。 2016年1月31日閲覧。
- ^ 「A.27 C99可変長配列の使用」 Microsoft . 2016年1月31日閲覧。
- ^ 「MicrosoftがC99開発者にISO C++の使用を勧告」 InfoQ 2016年1月31日閲覧。
- ^ 「Visual Studio 2013でのC99ライブラリのサポート」。Microsoft。2013年7月19日。 2016年1月31日閲覧。
- ^ 「VS 2013 における C++11/14 STL の機能、修正、および重大な変更点」。Blogs.msdn.com。2013 年 6 月 28 日。2014年4 月 8 日閲覧。
- ^ 「MSVCでのC/C++準拠プリプロセッサの完全サポートを発表」 Microsoft、2020年3月27日。 2020年9月17日閲覧。
- ^ 「Open WatcomのC99準拠」 。 2015年5月3日時点のオリジナルよりアーカイブ。2015年9月25日閲覧。
- ^ “Pelles C Overview” . 2013年1月. 2022年3月13日時点のオリジナルよりアーカイブ。 2022年3月2日閲覧。
- ^ 「Sun Studio 12: C コンパイラ 5.9 Readme」 . Sun Microsystems, Inc. 2007年5月31日. 2012年9月23日閲覧。
- ^ 「Tiny C コンパイラリファレンスドキュメント」 。 2016年1月31日閲覧。
- ^プロジェクトのTODOリストによると、複合型はC99で唯一欠けている機能である。可変長配列はTCC 0.9.26で追加された[1]。
- ^ 「TCC: Tiny C Compiler」 . 2016年1月31日閲覧。
- ^ 「標準 - GNUコンパイラコレクション(GCC)の使用」 Gcc.gnu.org . 2014年4月8日閲覧。
さらに読む
- N1256 (C99 標準の最終草案および TC1、TC2、TC3); WG14; 2007. ( HTML および ASCII バージョン)
- ISO/IEC 9899:1999 (公式 C99 標準)。ISO ; 1999。
- C99 の根拠; WG14; 2003。
- Cheng, Harry (2002年3月1日). 「C99と数値計算」 . Dr. Dobb's Journal .
- Seebach, Peter (2004年3月24日). 「C99を使用したオープンソース開発」 . developerWorks . IBM .