-
「Specific Features」の版間の差分
(ページの作成:「==機能特徴== HI-TECH Cコンパイラは、他のCコンパイラとほぼ互換の多くの特徴を持ち、より信頼できるプログラミング手段に貢...」) |
(相違点なし)
|
2017年11月11日 (土) 20:22時点における版
目次
機能特徴
HI-TECH Cコンパイラは、他のCコンパイラとほぼ互換の多くの特徴を持ち、より信頼できるプログラミング手段に貢献します。
ANSI C標準の互換性
これを記述している時点では、C言語のANSI規格のドラフトがとても進んだステージにありましたが、いまだ公式な規格ではありませんでした。そのため、規格の要求に応じることはできませんでしたが、ANSI規格のドラフトにおける新しい、変化した特徴の大部分を取り込んでいます。そのため、ある意味では多くの人はこれを"ANSI準拠"とみなすことでしょう。
型のチェック
以前のCコンパイラは型のチェックに緩いアプローチを採用していました。これはUNIX Cコンパイラに顕著で、ほとんどの任意の型の混在をexpression内で許可します。HI-TECH Cコンパイラはより厳格な型のチェックを行いますが、もし、そのエラーが害のないものと、ユーザーがわかった場合、ほとんどの場合はコンパイルの続行を許可しつつ警告メッセージを出します。これが起こるのは、例えば、INT型の数値がポインタ変数に割り当てられた場合です。生成されたコードはほとんどユーザーの意図したものでしょうが、実際には、ソースコードでエラーがあり、ユーザーはすぐに必要な場所をチェックして修正します。
メンバ名
初期のCコンパイラでは、例外的な状況以外は、異なる構造において区別されたメンバ名が要求されていました。HI-TECH Cはほとんどの最近のCの実装と同じく、異なる構造体や共用体において重複を許可します。メンバが定義されている構造体の型の、式(expression)のコンテクストにおいてのみメンバ名が認識されます??。実用的に言えば、これはメンバ名が"."もしくは"-"演算子の右項でのみ認識されるということを意味し、式の左項はもしくはメンバが定義されているのと同じ構造体、もしくは構造体へのポインタと同じです??。これは一つ以上の構造体で衝突を起こさずに構造体名の再利用を許可するだけでなく、メンバ使用の型チェックを許可します。他のCコンパイラとの共通のエラーは、違う型の構造体へのポインタを伴うメンバの使用、もしくはこれよりよりひどい単純な型へのポインタである変数です???
しかしながら、このように定義されない構造体のポインタや何かとして、ユーザーが使いたい場合にはここから外れるものもあります。これは型変換を使用するものです。例えば、いくつかのレジスタからなるメモリマップトI/Oデバイスにアクセスしたいと仮定します。定義は以下の通りです。
struct io_dev { short io_status; /* status */ char io_rxdata; /* rx data */ char io_txdata; /* tx data */ }; #define RXRDY 01 /* rx ready */ #define TXRDY 02 /* tx ready */ /* デバイスの(絶対)アドレスの定義 */ /* define the (absolute) device address */ #define DEVICE ((struct io_dev *)0xFF00) send_byte(c) char c; { /* wait till transmitter ready */ while(!(DEVICE->io_status & TXRDY)) continue; /* send the data byte */ DEVICE->io_txdata = c; }
図2.絶対アドレスでの型変換
この例では、問題となるデバイスは16bitのステータスポートで二つの8bitデータポートがあります。デバイスのアドレス(つまりステータスポートのアドレス)は(16進数の)-FF00として与えられます。このアドレスは必要な構造体ポインタへと型変換され構造体のメンバ名が使用可能になります。これで生成されるコードは要求通りに絶対メモリにアクセスできるものです。
右項とメンバ名のいくつかの例については図3て提示されています。
符号なしの型
HI-TECH Cはすべての整数型、つまりCHAR,SHORT,INT,LONG、に対して符号なしの変種を持ちます。 符号なしの値が右シフトした場合、論理シフトの役割を果たします。つまり、最も右のビットに入れるということです。同様に符号ありの値が右シフトした場合も最も右のビットに符号を追加します??
算術演算子
intよりも短い場合には算術演算子がより効果的に働く機器において、intよりも短いオペランドは必要がない場合にはint以上には拡大されません。
例えば、二つの文字が他の文字に保存される場合
struct fred { char a; int b; } s1, * s2; struct bill { float c; long b; } x1, * x2; main() { /* 誤り - cはfredのメンバではありません */ s1.c = 2; /* 正しい */ s1.a = 2; /* 誤り - s2 はポインタです */ s2.a = 2; /* 正しい */ x2->b = 24L; /* 正しいのですが、longからintの型変換に注意してください */ s2->b = x2->b; }
図3. メンバの用法の例
上記の例は8bitで算術的に計算されるので、8bitの先頭のオーバーフローは失われます。しかしながら、もし、二つの文字がintに保存される場合、正しい結果を保証するため、加算は16bitで行われます。
ANSIスタンダードのドラフトによれば、doubleよりもむしろfloatによる計算の処理の方が、double精度に変換して再び戻すよりも精度が短いです。