C言語関係掲示板

過去ログ

No.69. 処理系依存


LSI C-86 Ver.3.30 試食版 ユーザーズマニュアル内の
第3章 8086上への実現、3.3 データの内部表現の中で

"charは、標準ではunsigned charと同じ型ですが"

と書かれていますが、付録 3. データ型の内部表現
の中ではchar型には符合があるようになってるのですが。


>"charは、標準ではunsigned charと同じ型ですが"

char が unsigned であるか signed であるかは C では処理系依存です。
どっちで実装してもいいはず。

 ちなみに、C++ では、char と signed char と unsigned char は別の型。


本当ですね。付録 3. データ型の内部表現に注釈を記入しておきます。


便乗ですが、C言語には他にどんな処理系依存があるのですか?
たくさんあると思うのですが、知っておかないといつかポカやってしまいそうなので、重要なものだけでも把握しておきたいです。

・intのサイズ
・charの符号
・signedでのシフト演算
・ビットフィールドのレイアウト
くらいしか知りません。

処理系依存って大っ嫌いです…。


>便乗ですが、C言語には他にどんな処理系依存があるのですか?
>たくさんあると思うのですが、知っておかないといつかポカやってしまいそうなので、重要なものだけでも把握しておきたいです。
>
>・intのサイズ
>・charの符号
>・signedでのシフト演算
>・ビットフィールドのレイアウト
>くらいしか知りません。
>
>処理系依存って大っ嫌いです…。

signed系列の型で、例えばsigned int数値が
-65536 まで使えるか -65535 まで使えるのか、
charのビット数が8ビットではないものとか、
型の上限値を超えた値を入力したきの処理、キャスト、
あと、境界調整の仕方もいろいろあるようです。
このサイトでテスト用に使われている
LSI C-86 Ver.3.30 試食版には境界調整はありません。


ども。

>・intのサイズ
>・charの符号
>・signedでのシフト演算
>・ビットフィールドのレイアウト
>くらいしか知りません。

このうちのいくつかはlimits.hに#defineされています。
ので、

>処理系依存って大っ嫌いです…。

ちょっとは解消できるかもしれません。でも解消できると
いっても、解消するコードを書かなければならないという
ことになりますけど。

signedでのシフト演算は、ほとんどの処理系は最上位ビットを
コピーだと思います(未保証)。
(((~0)>>1)==(~0))で判定できるかな?(キャストが要るかも)

実数関係はfloat.hだったかな。

では。


>便乗ですが、C言語には他にどんな処理系依存があるのですか?

>・intのサイズ
>・charの符号
>・signedでのシフト演算
>・ビットフィールドのレイアウト
>くらいしか知りません。

・テキストの行末(MS-DOS系はCR・LF)
・漢字コード

とかも処理系依存ですね。

あと、処理系依存ではないのですが、LSI-C試食版で大きな関数を作ると
「Out of Memory」(メモリ不足)が出てコンパイルできません。
これは、関数サイズをコンパクトにすると回避できます。
(元々、こんなエラーを出すような大きな関数を作るのは問題ですが)

処理系依存で参考になりそうなのは
初級C言語Q&A
http://www.st.rim.or.jp/~phinloda/cqa/cqa9.html
ですね。

>処理系依存って大っ嫌いです…。

同感。本編で説明不足が多くご迷惑お掛けします。


こんにちは、返信ありがとうございます。

> signed系列の型で、例えばsigned int数値が-65536 まで使えるか -65535 まで使えるのか、
これって-32768と-32767の間違いでしょうか?
大抵は-32768〜+32767ですけど、中には-32767〜+32768のものもあるってことでしょうか?
初耳でした。これ困るなぁ…。
> charのビット数が8ビットではないものとか、
げ、charって8bitって決まってないんですね。
じゃあ typedef unsigned char byte; なんて使えないじゃないか、鬱だ…。

> このうちのいくつかはlimits.hに#defineされています。
汎用的なコードを書くとしたらこのヘッダを見て処理を分ければいいんですね。
でもビットフィールド関係は定義されてないみたいで残念です。
これが使えないの個人的にかなり痛いです。

> ・テキストの行末(MS-DOS系はCR・LF)
これってテキストモードで開いて処理する分にはまったく意識しなくて大丈夫なんでしょうか?
> LSI-C試食版で大きな関数を作ると「Out of Memory」(メモリ不足)が出てコンパイルできません。
幸い今のところ見たことないです。
でも #define でいろいろ遊んでたときに大きすぎでエラー出したことあります(^^;


>大抵は-32768〜+32767ですけど、中には-32767〜+32768のものもあるってことでしょうか?

LSIC試食版は char:-127〜+127 int:-32767〜+32767 ですね。

>げ、charって8bitって決まってないんですね。

このホームページを立ち上げたばかりにいただいた情報では、

 >こんな処理系も
 >左からchar int short long float double
 >Honeywell 6000
 >9 36 36 36 36 72 <-1bite=9bits
 >PDP-11
 >8 16 16 32 32 64
 >IBM360
 >8 32 16 32 32 64
 >とあるミニコン
 >8 32 16 32 32 54

実に、紛らわしいですよね。

>> ・テキストの行末(MS-DOS系はCR・LF)
>これってテキストモードで開いて処理する分にはまったく意識しなくて大丈夫なんでしょうか?

私の知っている範囲では大丈夫だと思います。

今思い出したのですが、VC++に「?」の#defineがない、というのもありましたね。
あと、VC++やBCBで、scanfやgetsの標準入力では「CTRL+Z」の入力で動作が
おかしくなる、というのもありました。これは、Windowsの環境で「CTRL+Z」
は「Undo」のショートカットキーだからだと思うのですが。
http://f1.aaa.livedoor.jp/~pointc/log25.html


ども。

型の長さは最低の長さが規定(たしかビット数でなく数値の範囲で規定)
されているだけだったと思います。
# ちなみにJAVAは全部かっちり決まっています

>>大抵は-32768〜+32767ですけど、中には-32767〜+32768のものもあるってことでしょうか?
>
>LSIC試食版は char:-127〜+127 int:-32767〜+32767 ですね。

大抵は絶対値が同じになってるようです。

数値の内部表現はまさに処理系依存に相当しますが、符号付き整数は
2の補数を仮定しても、まず問題は起こらないと思います。
したがって、範囲が-32767〜+32768(17bit必要)となるような処理系は
実際には無いかと(作れなくはないですが)。

>>げ、charって8bitって決まってないんですね。

まあ、現在の処理系ではこれも仮定しても問題ないかと(無責任)。
ワード(word)をtypedefしたくなったときのほうがけっこう悩むかも。

ちなみに。
「バイト」=8bitという単位は、実は慣習に過ぎなかったりします。
でも、非常に広く知られ、使われていて、この仮定が外れることは
まずありません。8bitを表すマイナーかつやや堅苦しい単位として
「オクテット」というのがあります。

>>> ・テキストの行末(MS-DOS系はCR・LF)
>>これってテキストモードで開いて処理する分にはまったく意識しなくて大丈夫なんでしょうか?
>
>私の知っている範囲では大丈夫だと思います。

DOSで作ったテキストをUNIXで開くと改行コードがうまくいかなかったような
気がします。気のせいかな??

>今思い出したのですが、VC++に「?」の#defineがない、というのもありましたね。

標準では?はもともとありませんね。でも、#defineさてれる場合でも
M_PI とか PI とかいろいろあったような気が。M_PIが割と多いかな?

>あと、VC++やBCBで、scanfやgetsの標準入力では「CTRL+Z」の入力で動作が
>おかしくなる、というのもありました。これは、Windowsの環境で「CTRL+Z」
>は「Undo」のショートカットキーだからだと思うのですが。
>http://f1.aaa.livedoor.jp/~pointc/log25.html

これはCの問題というよりはOSとかシェルの問題ですねー。どうやってEOFを
入力するか(アゲアシトリ)。

結局、現在、実際にある処理系をみて、それになるべく適応できる範囲で
プログラムするのが現実的かと(1バイトが7とか9bitの処理系で走らせる
可能性が本当にあるか?ということです)。


でもやっぱりLSI-Cを使っているときは、intの長さだけはときどき
困らせられますね。。

では。


> # ちなみにJAVAは全部かっちり決まっています
JavaとかC#とかいいな〜っていつも思いますです。
クラスとかはいいんですが、こういう細かいとこ羨ましいです。

> 2の補数を仮定しても、まず問題は起こらないと思います。
LSI-Cのマニュアル見ると「2の補数で表しています」って書いてあります。
なのに範囲が-32767〜+32767なのはなんでなんでしょう?(1の補数の間違い?)

> 「バイト」=8bitという単位は、実は慣習に過ぎなかったりします。
そういえば、一度に扱える単位がbyteでしたね。
じゃぁ typedef unsigned char byte; はこれでいいんですね。
でもたしかにwordは困りそう。

> 8bitを表すマイナーかつやや堅苦しい単位として「オクテット」というのがあります。
初めて聞きました。なんか音楽用語みたいですね(笑

> 標準では?はもともとありませんね。でも、#defineさてれる場合でも
> M_PI とか PI とかいろいろあったような気が。M_PIが割と多いかな?
?のスペルしらなくてPAIって定義してたころがありました。はい、バカです…。

JavaとかC#って高級言語だからこそ機種依存なくせたんでしょうか?
低レベル制御にも多く使われるCに機種依存なくせーって愚痴っても酷なのかな?

戻る


「初心者のためのポイント学習C言語」 Last modified:2001.11.15
Copyright(c) 2000-2002 TOMOJI All Rights Reserved