exeClang for SOLID s008(RISC-V RV32/RV64 共通)ライブラリ仕様

ライブラリの共通設定

ライブラリは以下の設定でビルドされています。

C17/C++17 標準関数サポート

  • 標準Cライブラリ(libc、libm)は NetBSD-9.3 ベース

    注釈

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

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

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

      time.h

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

      • time_t は 64-bit です。

      • clock() はダミー実装です。初回の呼び出しは必ず 0 になり、2 回目以降は 10msec 精度カウンタの前回呼び出し時との差分を返します。

      • time_t はうるう秒未考慮です。

      • タイムゾーン未考慮(UTC のみ、常に GMT=UTC)なため、デバッグ時のみご利用ください。

    • malloc, free, realloc, calloc は dlmalloc 2.8.6 を使用しています。

    • その他、musl libc のコードや FreeBSD の修正などが取り込まれています。詳細はインストーラに同梱されているマニュアルかソースコードを参照してください。

  • C99 の math_errhandling == MATH_ERREXCEPT 仕様に準拠

    注意

    数学関数(math.hcomplex.h)は -fno-math-errno 最適化を有効にするために errno を使用しない設定でビルドされています。数学関数のエラーチェックは errno ではなく fenv.h の関数を使用してください。

  • ロケールは "C" のみサポート

    • *_l (locale) 関数は、対応する _l の無い関数と同じ挙動となります。

  • OSの機能を使用するような関数は、VLINK 有効時のみサポート

    • 以下の関数は libvlink と libnosys の2種類のライブラリで実装されています。libvlink をリンクした場合は VLINK が有効になります。libnosys の場合は、全て -1 を返し errnoENOSYS を設定するだけのダミー関数がリンクされます。

    注意

    libvlinkはデバッグ用途にのみ使用し、実製品には組み込まないでください。

    注釈

    RISC-V ターゲットは VLINK 未サポートです。そのため libvlink は QEMU シミュレータ上でプログラムを実行する時のみ使用することになります。

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

      signal(), raise()

    • stdio.hprintf() やファイル関係の関数、tmpnam() など。(sprintf() などの文字列関数は常に使用できます。)

    • stdlib.hgetenv(), setenv() など。

      system() は常に未サポート。

    • time.hclock(), 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 精度です。

未サポートの機能

  • LLVM の float.hFLT_ROUNDS はFPUのステータスレジスタを参照するので、FPUが無いターゲットでは動作しません。fenv.hfegetround() で現行の丸めモードを取得してください。同様にFPUが存在するターゲットでは、fenv.h の関数はFPUのみを対象とします。そのため、IMAFなどのfloatのみをFPUで演算するターゲットでは、ソフトウェアエミュレーションされるdouble演算で発生した例外などを操作、取得することはできません。

  • long double

    math.hcomplex.h*l 関数など。

    例: long double sinl(long double x)

    nexttoward(), nexttowardf(), nexttowardl()

  • C11

    • time.h

      struct timespec, timespec_get()

    • stdio.h

      fopen()"x" モード。

      gets() の廃止。(常に有効です。)

      Annex K Bounds-checking interfaces(*_s 関数)

      Annex L Analyzability

    • C++03

      numeric_limits

      • std::numeric_limits<T>::tinyness_before (libc++ ではコンパイル時定数として実装。)

    • C++11

      chrono

      cstdalign (C++20 で廃止。LLVM libc++ では std オプションと無関係に常に廃止。)

      以下はヘッダが存在しますが、cstdalign と同様に C++17 で非推奨、C++20 で廃止です。

      ccomplex

      cstdbool

      ctgmath

      locale

      • std::isblank

      memory のガベージコレクション用関数。(C++23 で廃止。libc++ では常に廃止。)

      • std::declare_reachable

      • std::undeclare_reachable

      • std::declare_no_pointers

      • std::undeclare_no_pointers

      • std::get_pointer_safety

      • std::pointer_safety

      random

      • random_device

      system_error

      template 引数に ctype<char16_t>ctype<char32_t> を使用。

    • C++17

      filesystem

      数学の特殊関数(ゼータ関数、ベータ関数など。)

    • マルチスレッド

      注釈

      ユーザーコードで pthread API を実装することで、以下の機能も使用可能になります。それ以外の場合は、標準 C/C++ ライブラリ内部の排他制御に最低限必要な pthread API のみ、SOLID-OS が実装を提供します。その場合は以下の機能は使用できないので、SOLID-OS の API を使用してマルチスレッドプログラムを記述してください。

      • C11

        thread.h ヘッダ

      • C++11

        atomic, thread, mutex, future, condition_variable, call_once, future, promise

      • C++14

        shared_mutex

      • TLS (Thread Local Storage)

        C11 の _Thread_local, C++11 の thread_local キーワード

        注釈

        SOLID-OS が TLS を有効にしている場合は使用可能です。

      • 並列アルゴリズム

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

ワイド文字型 wchar_t は4バイト(UTF32LE)です。(Clangの仕様)

ClangはGCCの -finput-charset/-fexec-charset に相当するようなオプションを未サポートなので、ワイド文字列リテラル L"..." とC11の U"..." は同じ意味となり、必ずUCS4(Unicode)コードポイントの配列になります。

ライブラリがサポートするロケールは "C" のみですが、マルチバイト文字列(mbs)とワイド文字列(wcs)を変換する際に必要となる、LC_CTYPE のみ、以下の文字列にマッチする文字列を渡せます。

  • 有効な部分文字列(大文字小文字を区別しません)は以下になります。

    • "C" or "POSIX" (この2つは完全一致のみ)

    • "NONE"

    • "UTF-8" or "UTF8"

    • "cp932" or "MSKanji"

ただし、現在サポート(テスト)されているのは "C""UTF-8" のみです。例えばコンパイラのテストスイートのデフォルト設定でよくある "en_US.UTF-8"UTF-8 として認識されます。デフォルトの LC_CTYPE"C" となります。UTF-8(ASCII の範囲外の文字)を使用する場合は setlocale(LC_CTYPE, "utf-8") 呼び出しが mbs/wcs 系関数を呼び出す前に必要です。

以下がサンプルコードになります。

マルチバイト文字列とワイド文字列の相互変換サンプルコード