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 constvolatile

6.6.1 右辺値 (lvalue) 専用の型

6.6.2 派生型の型修飾子

6.6.3 constreadonly を意味する

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.4 拡張: 符号なし保存と値の保持

1990 ISO C 規格の「Rationale」(論理的根拠) 節に、次のような情報があります。「QUIET CHANGE」(メッセージなしの変更)。符号なし保存演算変換に依存するプログラムは、おそらくはメッセージを発行せずに、異なる動作を行います。これは、現在広く行われている慣習に対して委員会が行なったもっとも重大な変更であると考えられます。

この節では、この変更がコーディングにどのように影響するかを説明します。

6.4.1 背景

K&R の『プログラミング言語 C』によると、unsigned は 1 つだけの型を指定していました。つまり、unsigned charunsigned shortunsigned long はありませんでした。しかし、ほとんどの C コンパイラにはすぐにこれらの型が追加されました。unsigned long を実装せず、残りの 2 つだけを実装するコンパイラもあります。当然、式の中でこれらの新しい型がほかの型と併用されている場合、実装によって異なる型拡張規則が適用されました。

ほとんどの C コンパイラでは、より簡単な規則「符号なし保存」が使用されています。 つまり、unsigned 型を拡張する必要があるときは unsigned 型に拡張します。そして、unsigned 型が signed 型と混合されているときも、unsigned 型に拡張されます。

ISO C では、「値の保持」という規則も指定されています。この規則では、拡張結果の型は、オペランドの型の相対的なサイズによって異なります。unsigned char または unsigned short を拡張するとき、int がより小さい型の値をすべて表現できる大きさである場合は、拡張結果の型は int になります。それ以外の場合、unsigned int になります。この「値の保持」規則に従えば、ほとんどの式が無難な演算結果になります。

6.4.2 コンパイルの動作

ISO C コンパイラは、移行モード (-Xt) または ISO 以前のモード (-Xs) では、符号なし保存拡張規則を適用します。準拠モード (-Xc) および ISO モード (-Xa) では、値保持拡張規則を使用します。

6.4.3 例 1 : キャストの使用

次のコードでは、unsigned charint より小さいと仮定します。

int f(void)
{
    int i = -2;
    unsigned char uc = 1;

   return (i + uc) < 17;
}

前述のコードを使用すると、-xtransition オプションを使用したときに、次の警告が発行されます。

line 6: warning: semantics of "<" change in ISO C; use explicit cast

加算の結果の型は int (値保持) または unsigned int (符号なし保存) です。しかし、どちらの場合でもビットパターンは同じです。2 の補数を使用するマシンでは、次のようになります。

    i:       111...110 (-2)
+   uc:      000...001 ( 1)
===================
        111...111 (-1 or UINT_MAX)

このビット表現は、int では -1 に対応し、unsigned int では UINT_MAX に対応します。したがって、結果の型が int の場合、符号付き比較が使用され、「より小さいか」の答えは真になります。結果の型が unsigned int の場合、符号なしの比較が行われ、「より小さいか」の答えは偽になります。

キャストの加算を使用すると、2 つの動作のうち、どちらを希望するかを指定できます。

value preserving:
    (i + (int)uc) < 17
unsigned preserving:
    (i + (unsigned int)uc) < 17

コンパイラが異なれば同じコードに対する解釈も異なるため、この式は曖昧になる可能性があります。キャストの加算を使用することにより、コードが読みやすくなると同時に、警告メッセージも発行されなくなります。

6.4.4 ビットフィールド

同じ動作が、ビットフィールド値の拡張にも適用されます。ISO C では、int または unsigned int ビットフィールド内のビットの数が int 中のビットの数よりも少ない場合、拡張される型は int です。それ以外の場合、拡張される型は unsigned int です。ほとんどの古い C コンパイラでは、明示的な符号なしビットフィールドの場合、拡張される型は unsigned int です。それ以外の場合は int です。

この場合も、キャストを使用することにより、曖昧になることを防ぐことができます。

6.4.5 例 2 : 同じ結果

次のコードでは、unsigned shortunsigned char の両方が int よりも狭いと仮定します。

int f(void)
{
    unsigned short us;
    unsigned char uc;
    return uc < us;
}

この例では、2 つの自動変数は int または unsigned int のどちらかに拡張されます。したがって、比較対象は符号なしになることも、符号付きになることもあります。しかし、どちらを選んでも結果は同じなので、警告は発行されません。

6.4.6 整数定数

式と同様に、ある整数定数の型の規則も変更されました。K&R C では、接尾辞なしの 10 進定数の型は、その値が int に収まる場合だけ int でした。接尾辞なしの 8 進定数または 16 進定数の型は、その値が unsigned int に収まる場合だけ int でした。それ以外の場合、整数定数の型は long でした。したがって、値が結果の型に収まらないことがありました。1990 ISO/IEC C 規格では、定数の型は、次のリストのうち、値を格納できる最初の型となります。

ISO C コンパイラで -xtransition オプションを使用するとき、定数の型規則によって式の動作が異なる場合は警告が発行されます。古い整数定数の型規則は、移行モード (-Xt) だけで適用されます。ISO モード (-Xa) と準拠モード (-Xc) では、新しい規則が適用されます。


注 - 接尾辞なしの 10 進定数の型規則は、1999 ISO C 規格に従って変更されています。「2.1.1 整数定数」を参照してください。


6.4.7 例 3 : 整数定数

次のコードでは、int が 16 ビットであると仮定します。

int f(void)
{
    int i = 0;

    return i > 0xffff;
}

16 進定数の型は int (2 の補数を使用するマシン上で - 1 の値を持つ) または unsigned int (65535 の値を持つ) のどちらかです。比較結果は、ANSI 以前モード (-Xs) と移行モード (-Xt) では真で、ANSI モード (-Xa) と準拠モード (-Xc) では偽です。

この場合も、キャストを適切に使用することにより、コードが読みやすくなり、警告も発行されなくなります。

-Xt, -Xs modes:
    i > (int)0xffff

-Xa, -Xc modes:
    i > (unsigned int)0xffff
       or
    i > 0xffffU

接尾辞 U 文字は ISO C の新しい機能であるため、古いコンパイラではおそらくエラーメッセージが生成されます。