ライブラリの仕様

exeGCC for SOLID s002 ライブラリ仕様

  • ライブラリの共通設定

    s002 ツールチェーンには様々なターゲット向けのライブラリが付属していますが、全てのライブラリは以下の設定でビルドされています。設定が異なるユーザープログラムとライブラリをリンクした際の動作は保証されません。-mno-unaligned-access 以外のオプションは必須です。

    • char 型は signed。(-fsigned-char)
    • 列挙型は 32 bit。(-fno-short-enums)
    • aligned data access。(-mno-unaligned-access)
  • C11/C++14 標準関数サポート

    • libc と libm は NetBSD-7.0 ベース

      注釈

      非標準の関数や BSD 由来の関数は、過去の exeGCC との互換性のためや、ライブラリ内部で使用している等の理由により存在していますが、サポート範囲外となります。もし必要な場合は自己責任で使用してください。ヘッダには存在しますが、実体が存在しない関数も多数あります。

    • 以下の標準関数は KMC による実装です。

      abort, exit, perror, setjmp, longjmp, strerror(_r), signal, raise

      time.h

      clock, difftime, mktime, time, asctime, ctime(_r), gmtime, localtime(_r), strftime

      • time.h の仕様
      • time_t は 64 bit です。
      • clock はダミー実装です。初回の呼び出しは必ず 0 になり、2 回目以降は 10msec 精度カウンタの前回呼び出し時との差分を返します。
      • time_t はうるう秒未考慮です。
    • ロケールは "C" のみサポート

      • XXX_l (locale) 関数は、対応する XXX 関数と同じ挙動となります。
    • OS の機能を使用するような関数は、ターゲットのサポートに依存。

      以下は VLINK 有効時にサポートされる仕様。

      • signal.h はダミー関数です。

        signal, raise

      • stdio.h の printf やファイル関係の関数、tmpnam など。

      • stdlib.h の getenv, setenv など。 system は未サポート。

      • time.h の clock, time, utime

      • 以下の非標準関数(KMC による実装)

        rename, getcwd, getwd, open, creat, close, lseek, read, write, unlink, tell, dup, dup2, access, chdir, rmdir, findfirst, findnext, stat, fstat, lstat, mkdir, chmod, mktemp, sleep, usleep

        • stat, fstat, lstat, utime の制限

          MS-DOS Data and Time (FILETIME) を使用しているので、保証されるのは 1980/1/1-2107/12/31 の範囲です。

        • usleep の制限

          millisecond 精度です。

未サポートの機能

  • long double

    math.h, complex.h ヘッダの XXXl 関数など。

    例: long double sinl(long double x)

    nexttoward, nexttowardf, nexttowardl

  • C99

    math.h

    fma, fmaf, fmal

  • C11

    uchar.h

    time.h

    struct timespec, timespec_get

    stdio.h

    fopen mode 「x」

    Remove gets

    Annex F/G/K/L [Optional]

    • C++11

      random ヘッダ

      random_device

    • マルチスレッド

      • C11

        stdatomic.h, thread.h ヘッダ [Optional]

      • C++11

        thread, mutex, future, condition_variable ヘッダ。

      • TLS (Thread Local Storage)

        GCC 拡張の __thread, C11 の _Thread_local, C++11 の thread_local キーワード。

ワイド文字(列)の扱いについて

ワイド文字型 wchar_t は 4 バイト(UTF-32 LE)です。(GCC/Clang の仕様)

C11 の uchar.h は未サポートです。

ワイド文字列リテラル L"..." と C11 の U"..." は同じ意味となり、-fexec-charset オプションによる文字集合指定とは無関係に、必ず UCS4 (Unicode) コードポイントの配列になります。

注釈

つまり、仮に -fexec-charset=cp932 を指定したとしても、JIS X 0208 のコードポイント配列にはならないため、ワイド文字列リテラルをソースコード中に直接記述することはできません。これは GCC の仕様です。Clang はそもそも -finput-charset/-fexec-charset オプション未サポートなので、常に UCS4 文字集合を UTF-8/32 エンコーディングで扱う仕様となります。

ライブラリがサポートするロケールは "C" のみですが、マルチバイト文字列(mbs)とワイド文字列(wcs)を変換する際に必要となる、LC_CTYPE のみ、"C", "utf-8", "cp932" が指定可能です。デフォルトの LC_CTYPE"C" となります。UTF-8(ASCII の範囲外の文字)を使用する場合は setlocale(LC_CTYPE, "utf-8") 呼び出しが mbs/wcs 系関数を呼び出す前に必要です。

ワイド文字列からマルチバイト文字列への変換サンプル:

#include <locale.h> /* setlocale */
#include <stdlib.h> /* wcstombs */

/* ... */

wchar_t wcstr[] = L"この文字列は UCS4 文字集合を UTF-32 LE エンコーディングしたものとなります。";
int result;
char utf8buf[256];

/* 確認のため SOLID OS の syslog を使用します。 */
syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_INFO));

result = wcstombs(utf8buf, wcstr, 256);

/* デフォルトの "C" = ASCII 範囲外の文字を含むため失敗します。*/
if (result < 0) {
    syslog(LOG_INFO, "XFAIL: please setlocale()");
}

/* utf-8 に設定します。*/
syslog(LOG_INFO, "setlocale:%s", setlocale(LC_CTYPE, "utf-8"));

/* UTF-32 LE -> UTF-8 */
result = wcstombs(utf8buf, wcstr, 256);

if (result < 0) {
    syslog(LOG_INFO, "FAIL");
} else {
    syslog(LOG_INFO, "SUCC: %s", utf8buf);
}

TeraTerm (UTF-8) での出力例:

XFAIL: please setlocale()
setlocale:UTF8
SUCC: この文字列は UCS4 文字集合を UTF-32 LE エンコーディングしたものとなります 。