表 D-1 K&R Sun C と Sun ANSI/ISO C との非互換性
項目
|
Sun C (K$R)
|
Sun ANSI/ISO C
|
main() の envp 引数
|
main() の 3 番目の引数として envp を使用できる。
|
3 番目の引数として使用できるが、この使用法は厳密には ANSI/ISO C 規格に準拠しない。
|
キーワード
|
識別子 const 、volatile 、signed を普通の識別子として扱う。
|
const 、volatile 、signed はキーワードである。
|
ブロック内の extern と static 関数宣言
|
これらの関数宣言をファイルスコープに拡張する。
|
ANSI/ISO 規格は、ブロックスコープ関数宣言がファイルスコープに拡張されることを保証しない。
|
識別子
|
識別子でドル記号 ($ ) を使用できる。
|
$ は使用できない。
|
long float 型
|
long float 宣言を受け入れ、double として処理する。
|
このような宣言は使用できない。
|
複数バイト文字定数
|
int mc = `abcd';
は、次を生成する。
abcd
|
int mc = `abcd';
は、次を生成する。
dcba
|
整数定数
|
8 進数のエスケープシーケンスで、8 または 9 を使用できる。
|
8 進数のエスケープシーケンスで、8 または 9 を使用できない。
|
代入演算子
|
次の演算子の組み合わせを 2 つのトークンとして処理するため、演算子の間に空白を使用できる。
*=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
|
1 つのトークンとして処理するため、演算子の間に空白を使用できない。
|
式の符号なし保存の意味解釈
|
符号なし保存をサポートする。つまり、unsigned char/short は unsigned int に変換される。
|
値の保持をサポートする。つまり、unsigned char/short は int に変換される。
|
単精度計算と倍精度計算
|
浮動小数点式のオペランドを double に拡張する。
float を返すように宣言された関数の戻り値は、常に double に拡張される。
|
float の演算を単精度計算で行うことができる。
このような関数に float の戻り型を使用できる。
|
struct または union のメンバーの名前空間
|
メンバー選択演算子を使用する struct 、union 、および算術型は、他の struct または union のメンバーを操作できる。
|
すべての一意な struct または union は、独自の一意な名前空間を持たなければならない。
|
左辺値 (lvalue ) としてのキャスト
|
lvalue としてのキャストをサポートする。 例 :
(char *)ip = &char;
|
この機能はサポートしない。
|
暗黙の int 宣言
|
明示的な型指定子なしの宣言をサポートする。num; などの宣言は、暗黙の int として処理される。
例 :
num; /* num は暗黙の int */
int num2; /* num2 は明示的に宣言された int */
|
num; 宣言 (明示的な型指定子 int なし) はサポートされず、構文エラーとなる。
|
空の宣言
|
空の宣言を使用できる。
例 :
int;
|
タグを除いて、空の宣言を使用できない。
|
型定義の型指定子
|
typedef 宣言で unsigned 、short 、long などの型指定子を使用できる。
例 :
typedef short small;
unsigned small x;
|
typedef 宣言は型指定子で変更できない。
|
ビットフィールドで使用できる型
|
すべての整数型のビットフィールドを使用できる (名前なしビットフィールドも含む)。
ABI は、名前なしビットフィールドと他の整数型のサポートを必要とする。
|
型 int 、unsigned int 、および signed int だけのビットフィールドをサポートする。他の型は未定義。
|
不完全な宣言におけるタグの処理
|
不完全な型宣言を無視する。次の例では、f1 は外側の struct を参照する。
struct x { . . . } s1; { struct x; struct y {struct x f1; } s2; struct x { . . . }; }
|
ANSI/ISO 準拠の実装では、不完全な struct または union 型指定子は、同じタグで囲んだ宣言を隠す。
|
struct 、union 、または enum 宣言での不一致
|
入れ子にされた struct または union 宣言において、タグの struct 、enum 、uion 型の不一致を許可する。次の例では、2 番目の宣言は struct として処理される。
struct x { . . . } s1;
{union x s2;. . .}
|
外側のタグを隠し、内側の宣言を新しい宣言として処理する。
|
式内のラベル
|
ラベルを (void * ) lvalue として処理する。
|
式内ではラベルを使用できない。
|
switch 条件型
|
int に変換することで、float と double を使用できる。
|
整数型 (int 、char 、列挙型) だけを switch 条件型として評価する。
|
条件付きインクルード指令の構文
|
プリプロセッサは #else または #endif 指令の後にあるトークンを無視する。
|
このような構文は使用できない。
|
トークンの結合と ## プリプロセッサ演算子
|
## 演算子を認識しない。トークンの結合を行うには、結合される 2 つのトークンの間にコメントを置く。
#define PATE(A,B) A/* 任意のコメント */B
|
## をトークンの結合を実行するプリプロセッサ演算子として定義する。例:
#define PASTE(A,B) A##B
さらに、Sun ANSI/ISO 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
注: iropt と cg は次のオプションを指定したときだけ呼び出される。
-O -xO2 -xO3 -xO4 -xa -fast
inline は、インラインテンプレートファイル (file.il ) を指定した場合だけ呼び出される。
|
プリプロセッサ (cpp ) は acomp に直接組み込まれる。したがって、-Xs モードを除き、cpp は直接呼び出されない。
コンパイルで使用される要素は次のとおり。
cpp (-Xs モードのみ)
acomp iropt cg ld
注: iropt と cg は次のオプションを指定したときだけ呼び出される。
-O -xO2 -xO3 -xO4 -xa -fast
|
バックスラッシュによる行の連結
|
行の連結では、バックスラッシュ文字を認識しない。
|
改行文字の直前にバックスラッシュ文字を指定しなければならない。
|
文字列リテラル内の 3 文字表記
|
この ANSI/ISO C の機能はサポートしない。
|
|
asm キーワード
|
asm はキーワードである。
|
asm は通常の識別子として処理される。
|
識別子のリンケージ
|
初期化されていない static 宣言を仮定義として処理しない。この結果、2 番目の宣言が「再宣言」エラーを生成する。例:
static int i = 1;
static int i;
|
初期化されていない static 宣言を仮定義として処理する。
|
名前空間
|
struct 、union 、enum のタグ、struct 、union 、enum のメンバー、および、その他すべてのうち 3 つだけを識別する。
|
ラベル名、タグ (キーワード struct 、union 、enum の後に続く名前)、struct 、union 、enum のメンバー、および、通常の識別子のうち 4 つの名前空間を認識する。
|
long double 型
|
サポートしない。
|
long double 型の宣言を使用できる。
|
浮動小数点定数
|
浮動小数点の接尾辞 f 、l 、F 、L はサポートされない。
|
|
接尾辞なしの整数定数は異なる型を持つことができる。
|
整数定数の接尾辞 u と U はサポートされない。
|
|
ワイド文字定数
|
ワイド文字定数についての ANSI/ISO C 構文を使用できない。
例:
wchar_t wc = L'x';
|
この構文をサポートする。
|
`\a' と `\x'
|
文字 `a' と `x' として処理する。
|
特別なエスケープシーケンス `\a' と `\x' として処理する。
|
文字列リテラルの連結
|
ANSI/ISO C の隣接する文字列リテラルの連結はサポートしない。
|
|
ワイド文字の文字列リテラル構文
|
ANSI/ISO C のワイド文字の文字列リテラル構文はサポートしない。
例:
wchar_t *ws = L"hello";
|
この構文をサポートする。
|
ポインタ void * と char *
|
ANSI/ISO C の void * 機能をサポートする。
|
|
単項プラス演算子
|
この ANSI/ISO C の機能はサポートしない。
|
|
関数のプロトタイプ - 省略記号
|
サポートしない。
|
ANSI/ISO C は可変引数パラメータリストを示すための省略記号「...」の使用を定義する。
|
型定義
|
typedef は、同じ型名を持つ別の宣言により、内側のブロックで再宣言できない。
|
typedef は、同じ型名を持つ別の宣言により、内側のブロックで再宣言できる。
|
extern 変数の初期化
|
明示的に extern と宣言した変数の初期化はサポートしない。
|
明示的に extern と宣言した変数の初期化を定義として処理する。
|
集合体の初期化
|
ANSI/ISO C の共用体または自動構造体の初期化はサポートしない。
|
|
プロトタイプ
|
この ANSI/ISO C の機能はサポートしない。
|
|
前処理指令の構文
|
第 1 桁に # がある指令だけを認識する。
|
ANSI/ISO では、# 指令の前に空白文字を使用できる。
|
プリプロセッサ演算子 #
|
ANSI/ISO C のプリプロセッサ演算子 # はサポートしない。
|
|
#error 指令
|
この ANSI/ISO C の機能はサポートしない。
|
|
プリプロセッサ指令
|
#ident 指令とともに、2 つのプラグマ unknown_control_flow と makes_regs_inconsistent をサポートする。プラグマを認識できないとき、プリプロセッサは警告を発行する。
|
認識できないプラグマに対する動作は指定されていない。
|
事前定義されたマクロ名
|
次の ANSI/ISO C 定義のマクロ名は定義されていない。
__STDC__
__DATE__
__TIME__
__LINE__
|
|