JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.2: C ユーザーガイド
search filter icon
search icon

ドキュメントの情報

はじめに

1.  C コンパイラの紹介

2.  C コンパイラ実装に固有の情報

3.  C コードの並列化

4.  lint ソースコード検査プログラム

5.  型に基づく別名解析

6.  ISO C への移行

6.1 基本モード

6.1.1 -Xc

6.1.2 -Xa

6.1.3 -Xt

6.1.4 -Xs

6.2 古い形式の関数と新しい形式の関数の併用

6.2.1 新しいコードを書く

6.2.2 既存のコードを更新する

6.2.3 併用に関する考慮点

6.3 可変引数を持つ関数

6.4 拡張: 符号なし保存と値の保持

6.4.1 背景

6.4.2 コンパイルの動作

6.4.3 例 1 : キャストの使用

6.4.4 ビットフィールド

6.4.5 例 2 : 同じ結果

6.4.6 整数定数

6.4.7 例 3 : 整数定数

6.5 トークン化と前処理

6.5.1 ISO C の翻訳段階

6.5.2 古い C の翻訳段階

6.5.3 論理的なソース行

6.5.4 マクロ置換

6.5.5 文字列の使用

6.5.6 トークンの連結

6.6 const と volatile

6.6.1 右辺値 (lvalue) 専用の型

6.6.2 派生型の型修飾子

6.6.3 const は readonly を意味する

6.6.4 const の使用例

6.6.5 volatile は文字どおりの解釈を意味する

6.6.6 volatile の使用例

6.7 複数バイト文字とワイド文字

6.7.1 アジア言語は複数バイト文字を必要とする

6.7.2 符号化の種類

6.7.3 ワイド文字

6.7.4 変換関数

6.7.5 C 言語の機能

6.8 標準ヘッダーと予約名

6.8.1 標準ヘッダー

6.8.2 実装で使用される予約名

6.8.3 拡張用の予約名

6.8.4 安全に使用できる名前

6.9 国際化

6.9.1 ロケール

6.9.2 setlocale() 関数

6.9.3 変更された関数

6.9.4 新しい関数

6.10 式のグループ化と評価

6.10.1 定義

6.10.2 K&R C の再配置の権利

6.10.3 ISO C の規則

6.10.4 括弧

6.10.5 as if 規則

6.11 不完全な型

6.11.1 型

6.11.2 不完全な型を完全にする

6.11.3 宣言

6.11.4 式

6.11.5 正当性

6.11.6 例

6.12 互換型と複合型

6.12.1 複数の宣言

6.12.2 分割コンパイル間の互換性

6.12.3 単一のコンパイルでの互換性

6.12.4 互換ポインタ型

6.12.5 互換配列型

6.12.6 互換関数型

6.12.7 特別な場合

6.12.8 複合型

7.  64 ビット環境に対応するアプリケーションへの変換

8.  cscope: 対話的な C プログラムの検査

A.  機能別コンパイラオプション

B.  C コンパイラオプションリファレンス

C.  ISO/IEC C 99 の処理系定義の動作

D.  C99 でサポートされている機能

E.  ISO/IEC C90 の処理系定義の動作

F.  ISO C データ表現

G.  パフォーマンスチューニング

H.  K&R Solaris Studio C と Solaris Studio ISO C の違い

索引

6.3 可変引数を持つ関数

以前の実装では、関数が期待するパラメータの型を指定できませんでした。しかし、ISO C でプロトタイプを使用すれば、これを指定できます。printf() などの関数をサポートするために、プロトタイプの構文では特別な省略記号 (…) が終了を示す記号として使用されます。 実装によっては可変引数を処理するために特別なことを行う必要があるため、ISO C では、すべての宣言とこのような関数などの定義が末尾に省略記号を含むべきであると規定しています。

パラメータの「…」部分には名前がないため、stdarg.h に含まれている特別なマクロにはこれらの引数へアクセスするための関数が含まれています。初期のバージョンではこのような関数は varargs.h に含まれている同様なマクロを使用しなければいけませんでした。

次に、これから書こうとする関数が errmsg() というエラーハンドラであると仮定します。この関数は void を返し、固定パラメータとして、エラーメッセージの詳細を指定する int だけを持つと仮定します。このパラメータのあとには、ファイル名または行番号 (あるいは、その両方) を指定できます。そして、ファイル名または行番号のあとには、(printf() のような) エラーメッセージのテキストを指定する書式と引数を指定できます。

初期のコンパイラで前述の例をコンパイルするには、ISO C コンパイルシステム専用に定義されたマクロ __STDC__ を多く使用する必要があります。したがって、適切なヘッダーファイルにおける関数の宣言は次のようになります。

#ifdef __STDC__
    void errmsg(int code, ...);
#else
    void errmsg();
#endif

errmsg() の定義を持つファイルは、古い形式と新しい形式を併用できます。まず、インクルードするヘッダーはコンパイルシステムによって異なります。

#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <stdio.h>

そのあとで fprintf() と vfprintf() を呼び出すため、stdio.h をインクルードしています。

次は関数の定義です。識別子 va_alist と va_dcl は古い形式の varargs.h インタフェースの一部です。

void
#ifdef __STDC__
errmsg(int code, ...)
#else
errmsg(va_alist) va_dcl /* Note: no semicolon! */
#endif
{
   /* more detail below */
}

古い形式の変数引数メカニズムでは固定パラメータを指定できないため、固定パラメータは、可変部分の前でアクセスされるように配置しなければいけません。また、パラメータの「… 」部分に名前がないため、新しい va_start() マクロは 2 番目の引数 (「…」の直前にあるパラメータの名前) を持ちます。

拡張として、Solaris Studio ISO C では、固定パラメータなしで関数を宣言および定義できます。

int f(...);

このような関数の場合、va_start() は 2 番目の引数を空にして呼び出す必要があります。

va_start(ap,)

次は関数の本体です。

{
    va_list ap;
    char *fmt;
#ifdef __STDC__
    va_start(ap, code);
#else
    int code;
    va_start(ap);
    /* extract the fixed argument */
    code = va_arg(ap, int);
#endif
    if (code & FILENAME)
        (void)fprintf(stderr, "\"%s\": ", va_arg(ap, char *));
    if (code & LINENUMBER)
        (void)fprintf(stderr, "%d: ", va_arg(ap, int));
    if (code & WARNING)
        (void)fputs("warning: ", stderr);
    fmt = va_arg(ap, char *);
    (void)vfprintf(stderr, fmt, ap);
    va_end(ap);
}

va_arg() と va_end() マクロは両方とも古い形式と ISO C バージョンで同様に動作します。va_arg() は ap の値を変更するため、vfprintf() への呼び出しを次のようにすることはできません。

(void)vfprintf(stderr, va_arg(ap, char *), ap);

マクロ FILENAME、LINENUMBER、および WARNING の定義は、おそらく、errmsg() の宣言と同じヘッダーに含まれています。

errmsg() への呼び出しの例は次のようになります。

errmsg(FILENAME, "<command line>", "cannot open: %s\n",
argv[optind]);