C ユーザーズガイド

付録 G K&R Sun C と Sun ANSI C の違い

この付録では、従来の K&R Sun C と Sun ANSI C の違いを説明します。

「K&R Sun C と Sun ANSI C との間の非互換性」では、Sun ANSI C との互換性がない従来の Sun C の機能を説明します。Sun C コンパイラで書いたソースコードを Sun ANSI C に移植するときにはこれらの違いについて注意する必要があります。

「キーワード」では、ANSI C 標準、Sun ANSI C、および Sun C が使用する予約語と、Sun ANSI と Sun C のプリプロセッサが定義する予約語のリストを示します。

K&R Sun C と Sun ANSI C との間の非互換性

表 G-1 K&R Sun C と Sun ANSI C との非互換性

項目 

Sun C 

Sun ANSI C 

main()envp 引数

main() の 3 番目の引数として envp を使用できる。

3 番目の引数として使用できるが、この使用法は厳密には ANSI C 規格に準拠しない。 

キーワード 

識別子 constvolatilesigned を普通の識別子として扱う。

constvolatilesigned はキーワードである。

ブロック内の externstatic 関数宣言

これらの関数宣言をファイルスコープに拡張する。 

ANSI 規格は、ブロックスコープ関数宣言がファイルスコープに拡張されることを保証しない。 

識別子 

識別子でドル記号 ($) を使用できる。

$ は使用できない。

long float

long float 宣言を受け入れ、double として処理する。

このような宣言は使用できない。 

複数バイト文字定数 

int mc = 'abcd';

は、次を生成する。 

abcd

int mc = 'abcd';

は、次を生成する。 

dcba

整数定数 

8 進数のエスケープシーケンスで、8 または 9 を使用できる。 

8 進数のエスケープシーケンスで、8 または 9 を使用できない。 

代入演算子 

次の演算子の組み合わせを 2 つのトークンとして処理するため、演算子の間に空白を使用できる。 

 

*=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=

1 つのトークンとして処理するため、演算子の間に空白を使用できない。 

式の符号なし保存の意味解釈 

符号なし保存をサポートする。つまり、unsigned char/shortunsigned int に変換される。

値の保持をサポートする。つまり、unsigned char/shortint に変換される。

単精度計算と倍精度計算 

浮動小数点式のオペランドを double に拡張する。

 

float を返すように宣言された関数の戻り値は、常に double に拡張される。

float の演算を単精度計算で行うことができる。

 

このような関数に float の戻り型を使用できる。

struct または union のメンバーの名前空間

メンバー選択演算子を使用する structunion、および算術型は、他の struct または union のメンバーを操作できる。

すべての一意な struct または union は、独自の一意な名前空間を持たなければならない。

左辺値 (lvalue) としてのキャスト

lvalue としてのキャストをサポートする。 例 :

 

(char *)ip = &char;

この機能はサポートしない。 

暗黙の int 宣言

明示的な型指定子なしの宣言をサポートする。num; などの宣言は、暗黙の int として処理される。

例 : 

 

num; /* num は暗黙の int */

int num2; /* num2 は明示的に宣言された int */

num; 宣言 (明示的な型指定子 int なし) はサポートされず、構文エラーとなる。

空の宣言 

空の宣言を使用できる。例 : 

int;

タグを除いて、空の宣言を使用できない。 

型定義の型指定子 

typedef 宣言で unsignedshortlong などの型指定子を使用できる。

例 : 

 

typedef short small;

unsigned small x;

typedef 宣言は型指定子で変更できない。

ビットフィールドで使用できる型 

すべての整数型のビットフィールドを使用できる (名前なしビットフィールドも含む)。 

 

ABI は、名前なしビットフィールドと他の整数型のサポートを必要とする。 

intunsigned int、および signed int だけのビットフィールドをサポートする。他の型は未定義。

不完全な宣言におけるタグの処理 

不完全な型宣言を無視する。次の例では、f1 は外側の struct を参照する。

 

struct x { . . . } s1; { struct x; struct y {struct x f1; } s2; struct x { . . . }; }

ANSI 準拠の実装では、不完全な struct または union 型指定子は、同じタグで囲んだ宣言を隠す。

structunion、または enum 宣言での不一致

入れ子にされた struct または union 宣言において、タグの structenumuion 型の不一致を許可する。次の例では、2 番目の宣言は struct として処理される。

 

*struct x { . . . } s1;

*{

union x s2;

. . .

}

外側のタグを隠し、内側の宣言を新しい宣言として処理する。 

式内のラベル 

ラベルを (void *) lvalue として処理する。

式内ではラベルを使用できない。 

switch 条件型

int に変換することで、floatdouble を使用できる。

整数型 (intchar、列挙型) だけを switch 条件型として評価する。

条件付きインクルード指令の構文 

プリプロセッサは #else または #endif 指令の後にあるトークンを無視する。

このような構文は使用できない。 

トークンの結合と ## プリプロセッサ演算子 

## 演算子を認識しない。トークンの結合を行うには、結合される 2 つのトークンの間にコメントを置く。 

 

#define PATE(A,B) A/* 任意のコメント */B

## をトークンの結合を実行するプリプロセッサ演算子として定義する。例: 

 

#define PASTE(A,B) A##B

 

さらに、Sun ANSI C プリプロセッサは Sun C の方法を認識しない。その代わりに、2 つのトークン間のコメントを空白として処理する。 

プリプロセッサの再走査 

プリプロセッサは再帰的に置換する。 #define F(X) X(arg) 

は、次を生成する。 

arg(arg) 

再走査中に置換リストに見つかったマクロは置換されない。 

#define F(X) X(arg) 

は、次を生成する。 

F(arg) 

仮パラメータリスト内の typedef

関数宣言中、typedef 名を仮パラメータ名として使用できる。つまり、typedef 宣言を隠す。

typedef 名として宣言された識別子を仮パラメータとして使用できない。

実装固有の集合体の初期化 

中括弧内で部分的に省略された初期設定子を構文解析および処理するときは、ボトムアップアルゴリズムを使用する。 

 

struct {int a[3]; int b;} ¥ 

w[] = {{1},2}; 

は、次を生成する。 

 

sizeof(w) = 16 w[0].a = 1, 0, 0 w[0].b = 2 

構文解析には、トップダウンアルゴリズムを使用する。例: 

struct {int a[3]; int b;} ¥ 

w[] = {{1},2}; 

は、次を生成する。 

 

sizeof(w) = 32 w[0].a = 1, 0, 0 w[0].b = 0 w[1].a = 2, 0, 0 w[1].b = 0 

include ファイルをまたがるコメント

#include ファイルで始まり、最初のファイルをインクルードしたファイルで終了するコメントを使用できる。

コンパイルの翻訳段階で、つまり、#include 指令が処理される前に、コメントは空白文字に置換される。

文字定数内の仮引数の置換 

置換リストマクロと一致したとき、文字定数内の文字を置換する。 

#define charize(c) 'c' 

charize(Z) 

は、次を生成する。 

'Z' 

文字は置換されない。 

#define charize(c) 'c'

charize(Z)

は、次を生成する。 

'c'

文字列定数内の仮引数の置換 

プリプロセッサは文字列定数内の囲まれた仮引数を置換する。 

#define stringize(str) 'str'

stringize(foo)

は、次を生成する。 

"foo"

プリプロセッサ演算子 # を使用しなければならない。 

#define stringize(str) 'str'

stringize(foo)

は、次を生成する。 

"str"

コンパイラの「フロントエンド」に組み込まれたプリプロセッサ 

コンパイラは cpp(1) を呼び出す。

コンパイルで使用される要素は次のとおり。 

 

cpp ccom iropt cg inline as ld

 

注: iroptcg は次のオプションを指定したときだけ呼び出される。

 

-O -xO2 -xO3 -xO4 -xa -fast

 

inline は、インラインテンプレートファイル (file.il) を指定した場合だけ呼び出される。

プリプロセッサ (cpp) は acomp に直接組み込まれる。したがって、-Xs モードを除き、cpp は直接呼び出されない。

 

コンパイルで使用される要素は次のとおり。 

 

cpp (-Xs モードのみ) acomp iropt cg ld

 

注: iroptcg は次のオプションを指定したときだけ呼び出される。

 

-O -xO2 -xO3 -xO4 -xa -fast

バックスラッシュによる行の連結 

行の連結では、バックスラッシュ文字を認識しない。 

改行文字の直前にバックスラッシュ文字を指定しなければならない。 

文字列リテラル内の 3 文字表記 

この ANSI C の機能はサポートしない。 

 

asm キーワード

asm はキーワードである。

asm は通常の識別子として処理される。

識別子のリンケージ 

初期化されていない static 宣言を仮定義として処理しない。この結果、2 番目の宣言が「再宣言」エラーを生成する。例:

 

static int i = 1;

 

static int i;

 

初期化されていない static 宣言を仮定義として処理する。

名前空間 

structunionenum のタグ、structunionenum のメンバー、および、その他すべてのうち 3 つだけを識別する。

ラベル名、タグ (キーワード structunionenum の後に続く名前)、structunionenum のメンバー、および、通常の識別子のうち 4 つの名前空間を認識する。

long double

サポートしない。 

long double 型の宣言を使用できる。

浮動小数点定数 

浮動小数点の接尾辞 flFL はサポートされない。

 

接尾辞なしの整数定数は異なる型を持つことができる。 

整数定数の接尾辞 uU はサポートされない。

 

ワイド文字定数 

ワイド文字定数についての ANSI C 構文を使用できない。例: 

 

wchar_t wc = L'x';

この構文をサポートする。 

'¥a''¥x'

文字 'a''x' として処理する。

特別なエスケープシーケンス '¥a''¥x' として処理する。

文字列リテラルの連結 

ANSI C の隣接する文字列リテラルの連結はサポートしない。 

 

ワイド文字の文字列リテラル構文 

ANSI C のワイド文字の文字列リテラル構文はサポートしない。例: 

 

wchar_t *ws = L"hello";

この構文をサポートする。 

ポインタ void *char *

ANSI C の void * 機能をサポートする。

 

単項プラス演算子 

この ANSI C の機能はサポートしない。 

 

関数のプロトタイプ - 省略記号 

サポートしない。 

ANSI C は可変引数パラメータリストを示すための省略記号「...」の使用を定義する。 

型定義 

typedef は、同じ型名を持つ別の宣言により、内側のブロックで再宣言できない。

typedef は、同じ型名を持つ別の宣言により、内側のブロックで再宣言できる。

extern 変数の初期化

明示的に extern と宣言した変数の初期化はサポートしない。

明示的に extern と宣言した変数の初期化を定義として処理する。

集合体の初期化 

ANSI C の共用体または自動構造体の初期化はサポートしない。 

 

プロトタイプ 

この ANSI C の機能はサポートしない。 

 

前処理指令の構文 

第 1 桁に # がある指令だけを認識する。 

ANSI では、# 指令の前に空白文字を使用できる。 

プリプロセッサ演算子 # 

ANSI C のプリプロセッサ演算子 # はサポートしない。 

 

#error 指令

この ANSI C の機能はサポートしない。 

 

プリプロセッサ指令 

#ident 指令とともに、2 つのプラグマ unknown_control_flowmakes_regs_inconsistent をサポートする。プラグマを認識できないとき、プリプロセッサは警告を発行する。

認識できないプラグマに対する動作は指定されていない。 

事前定義されたマクロ名 

次の ANSI C 定義のマクロ名は定義されていない。 

 

__STDC__ __DATE__

__TIME__ __LINE__

 

 

キーワード

次の表は、ANSI C 規格、Sun ANSI C コンパイラ、および Sun C コンパイラのキーワードのリストです。

次の表は、ANSI C 規格で定義されたキーワードのリストです。

表 G-2 ANSI C 規格のキーワード
 auto break case char
 const continue default do
 double else enum extern
 float for goto if
 int long register return
 short signed sizeof static
 struct switch typedef union
 unsigned void volatile while

Sun ANSI は、追加のキーワードとして asm を定義しています。しかし、asm-Xc モードではサポートされません。

次に、Sun C のキーワードのリストを示します。

表 G-3 Sun C (K&R) のキーワード
 asm auto break case
 char continue default do
 double else enum extern
 float for fortran goto
 if int long register
 return short sizeof static
 struct switch typedef union
 unsigned void while