C言語の標準ライブラリ関数(ANSIライブラリ関数)は,標準Cをサポートする環境でライブラリ関数宣言および型やマクロの定義としてユーザに提供されている.ANSI C標準ではこれらのライブラリ関数は厳密に定義されていて,C言語の存在する任意のシステム上で互換性を持つ.したがって,標準ライブラリ関数で与えられる機能のみを使っているプログラムは,基本的には変更なしに1つのシステムから他のシステムへ移すことができる.
しかし,標準ライブラリ関数の実装に関するシステム依存部分として,次のような項目がある.
移植性を重視するプログラムでは,これらの実装依存部分に注意してコーディングする必要がある.
標準ライブラリ関数を使ってプログラムを作成する場合に移植上注意すべき事項をまとめる.
CHAR_BIT | : | charのビット数 |
CHAR_MAX | : | charの最大値 |
CHAR_MIN | : | charの最小値 |
INT_MAX | : | intの最大値 |
INT_MIN | : | intの最小値 |
LONG_MAX | : | longの最大値 |
LONG_MIN | : | longの最小値 |
SCHAR_MAX | : | signed charの最大値 |
SCHAR_MIN | : | signed charの最小値 |
SHRT_MAX | : | shortの最大値 |
SHRT_MIN | : | shortの最小値 |
UCHAR_MAX | : | unsigned charの最大値 |
UINT_MAX | : | unsigned intの最大値 |
ULONG_MAX | : | unsigned longの最大値 |
USHRT_MAX | : | unsigned shortの最大値 |
FLT_RADIX | : | 指数表現の基数 |
FLT_ROUNDS | : | 加算に対する浮動小数点の丸めモード |
FLT_DIG | : | 精度の10進桁数 |
FLT_EPSILON | : | 1.0 + x != 1.0であるような最小の数x |
FLT_MANT_DIG | : | 仮数部における基数FLT_RADIXの桁数 |
FLT_MAX | : | 浮動小数点数の最大値 |
FLT_MAX_EXP | : | FLT_RADIXn - 1が表現できるようなnの最大値 |
FLT_MIN | : | 正規化浮動小数点数の最小値 |
FLT_MIN_EXP | : | 10nが正規化された数であるようなnの最少値 |
DBL_DIG | : | 精度の10進桁数 |
DBL_EPSILON | : | 1.0 + x != 1.0であるような最小の数x |
DBL_MANT_DIG | : | 仮数部における基数FLT_RADIXの桁数 |
DBL_MAX | : | double浮動小数点数の最大値 |
DBL_MAX_EXP | : | FLT_RADIXn - 1が表現できるようなnの最大値 |
DBL_MIN | : | 正規化double浮動小数点数の最小値 |
DBL_MIN_EXP | : | 10nが正規化された数であるようなnの最少値 |
EDOM | : | 領域エラーを表すerrnoの値 |
ERANGE | : | 範囲エラーを表すerrnoの値 |
NULL | : | ヌルポインタ |
_IOFBF | : | setvbuf関数用のパラメータ(完全バッファ) |
_IOLBF | : | setvbuf関数用のパラメータ(行バッファ) |
_IONBF | : | setvbuf関数用のパラメータ(非バッファリング) |
BUFSIZ | : | setbuf関数用のバッファサイズ |
EOF | : | ファイルの終端 |
SEEK_SET | : | fseek関数用のパラメータ(0) |
SEEK_CUR | : | fseek関数用のパラメータ(1) |
SEEK_END | : | fseek関数用のパラメータ(2) |
EXIT_SUCCESS | : | exit関数用の終了ステータス |
EXIT_FAILURE | : | exit関数用の終了ステータス |
RAND_MAX | : | rand関数の返却する最大値 |
CLOCKS_PER_SEC | : | clcok関数の戻り値の補性用数値 |
__LINE__ | : | 現在の行番号を表す10進定数 |
__FILE__ | : | コンパイル中のファイル名を表す文字列リテラル |
__DATA__ | : | "Mmm dd yyyy"の形式のコンパイル日付けを表す文字列リテラル |
__TIME__ | : | "hh:mm:ss"の形式のコンパイル時刻を表す文字列リテラル |
__STDC__ | : | ANSI標準準拠の処理系では1に定義される |
移植上の問題があるライブラリ関数について,各ライブラリ関数ごとに以下の情報を記載する.
#include <locale.h> char *setlocale(int category, char *locale);
#include <locale.h> struct lconv *localeconv(void);
#include <signal.h> void (*signal(int sig, void (*func)(int)))(int);
SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERMただし,これらのシグナルもraise関数による明示的な呼び出しによる場合を除き,実装によっては生成されないものがある. また,上記シグナルのデフォルトの動作およびプログラム起動時の状態も実装依存である.
signal(sig, SIG_IGN); signal(sig, SIG_DFL);実装依存で追加された他のシグナルの初期状態はSIG_DFLである.
#include <stdarg.h> void va_start(va_list ap, lastfix); type va_arg(va_list ap, type); void va_end(va_list ap);
#include <stdio.h> int remove(const char *filename);
#include <stdio.h> int rename(const char *old, const char *new);
#include <stdio.h> FILE *tmpfile(void);
#include <stdio.h> char *tmpnam(char *s);
#include <stdio.h> int fflush(FILE *stream);
#include <stdio.h> int fprintf(FILE *stream, const char *format, ...); int printf(const char *format, ...); int sprintf(char *s, const char *format, ...);
#include <stdio.h> int sscanf(const char *s, const char *format, ...);
#include <stdio.h> int fgetpos(FILE *stream, fpos_t *pos); int fsetpos(FILE *stream, const fpos_t *pos); int ftell(FILE *stream);
#include <stdlib.h> int rand(void);
#include <stdlib.h> void *calloc(size_t nmemb, size_t size); void *free(void *ptr); void *malloc(size_t size); void *realloc(void *ptr, size_t size);
#include <stdlib.h> void abort(void);
#include <stdlib.h> int atexit(void (*func)(void));
#include <stdlib.h> void exit(int status);
#include <stdlib.h> char *getenv(const char *name);
#include <stdlib.h> int system(const char *string);
#include <stdlib.h> int abs(int x); div_t div(int number, int denom); long int labs(long int x); ldiv_t ldiv(long int number, long int denom);
#include <string.h> void *memcpy(void *dest, const void *src, size_t n);
#include <string.h> char *strcpy(char *dest, char *src); char *strncpy(char *dest, char *src, size_t n);
#include <string.h> char *strcat(char *dest, char *src); char *strncat(char *dest, char *src, size_t n);
数学関数の実行時のエラーに関して,以下の項目は実装依存である.
#include <math.h> double fmod(double x, double y);
char型では表わせられない文字セットを使用する場合,char型の代わりにwchar_t型を用いる必要がある.
複数バイト文字の変換を行なう以下の関数がある.
#include <stdlib.h> int mblen(const char *s, size_t n); int mbtowc(wchar_t *pwc, const char *s, size_t n); int wctomb(char *s, wchar_t wchar); size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n); size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
標準ライブラリ関数の移植性向上の観点からの使用上の注意点を示す. また,移植上の問題を持つ関数以外に,不定な動作や未定義な動作を持つ関数をまとめて示す.
処理系によっては,ANSI標準ライブラリ関数と機能は等価であるが,関数名やパラメータの並びの異なる関数を持つものがある.これらの関数を使用しているプログラムは,マクロ置換により対応するANSI標準ライブラリ関数に置き換えることによってANSI準拠の処理系に移植することができる.逆に,ANSI準拠の処理系から非準拠の処理系への移植の場合も同様である.
char *index(char *s, char c);
#define index strchr
char *rindex(char *s, char c);
#define rindex strrchr
int bcmp(char *s1, char *s2, int length);
#define bcmp memcmp
void bcopy(char *src, char *dest, int length);
#define bcopy(s1,s2,len) memmove((s2),(s1),(len))
void bzero(char *s, int length);
#define bzero(s,len) memset((s),0,(len))
void va_start(arg_ptr); type va_arg(arg_ptr, type); void va_end(arg_ptr);
#if defined(__STDC__) #include <stdarg.h> #else #include <varargs.h> #endif ....... #if defined(__STDC__) Msg(int err, char *fmt, ...) #else Msg(err, fmt, va_alist) int err; cahr *fmt; va_dcl #endif { va_list ap = 0; ........ #if defined(__STDC__) va_start(ap, fmt); #else va_start(ap); #endif ........ }