Cで左辺のキャストで質問

このエントリーをはてなブックマークに追加
1厨房エログラマ
unsigned long a = 0xcccccccc;
(unsigned char)a = 0xff;
このようなコードをみました。
VC++で試したところ、拡張子CPPではエラーになりましたが、
拡張子Cでは問題なく通り、aの値は 0xccccccff になりました。
この代入はC言語の規則上では正しいのでしょうか?
2名無しさん@お腹いっぱい。 :2000/09/12(火) 11:58
正しくない。
3名無しさん@お腹いっぱい。 :2000/09/12(火) 12:09
CPUのエンディアンによって結果が変わっちゃうだろ。
4名無しさん@お腹いっぱい。 :2000/09/12(火) 12:33
*((unsigned char*)&a) = 0xff;
こう書くのが正しい。
5名無しさん@お腹いっぱい。 :2000/09/12(火) 12:35
あと union つかったり
6名無しさん@お腹いっぱい。 :2000/09/12(火) 12:41
unsigned long a の下位の8ビットをすべて1にしたいなら
a |= (unsigned long)0xff
ですかね。
7名無しさん@お腹いっぱい。 :2000/09/13(水) 06:00
>>6
キャストする必要ないだろ??
8ビル・ジョブス :2000/09/13(水) 06:30
>1
C言語仕様からみれば正しい。
しかし、特別な理由が無い限りやってはいけない記述である。
特別なケースとしては処理系依存する話だが、構造体のメンバ
の順序が決まっていて、一部のメンバにアライメント境界が
必要な場合くらいだ。それも、unionで対応できるケド...
後はC言語の精神に反するがあえて処理系依存したい場合だな。
9>8 :2000/09/13(水) 07:47
そんな言語仕様あったか〜?
言語仕様というからにはANSI、百歩譲ってK&Rだよな
10>8 :2000/09/13(水) 08:15
ANSIでは(unsigned char)aは左辺値じゃないから代入文の左辺に
は置けない。これはANSIでは「処理系依存」ではない。

この記述ができるコンパイラはANSIに従っていない。このため
VC6も-ZaでこのMS拡張仕様を無効にする手段を用意している。

gccではコンパイルできるが結果は0xccccccffでなく
0x000000ffになる。同様に-ansi -pedanticをつけて厳格に
ANSIに準拠させるとエラーとなる。

言語仕様を(暗記せよとはいわないが)調べるぐらいしたら
1110>1 :2000/09/13(水) 09:08
どうでもよいが2chはいつからうち専属の質問箱に
なったんだ???
12名無しさん@お腹いっぱい。 :2000/09/13(水) 09:21
うちってなんですか。笑い。
1310 :2000/09/13(水) 10:09
よく分からんが、できれば勝手に10>1と書かないで欲しいのだが。。
14厨房エログラマ :2000/09/13(水) 11:11
いろいろ意見ありがとうございます。
>11
かなーり前からです。
2chのみなさんありがとう。
1510 :2000/09/13(水) 20:05
ついでにいえば、
char* p;
*((long*)p)++ = 0;
も(long*)pは左辺値でないので、厳密にはエラー。
*(long*)p = 0;
(long*)p = (long*)p + 1;
と置き換えてみると、それが顕著になる。
(char)a = 0xff;
ほどエキセントリックではないが、逆に言語仕様と思っている人が
多くて始末が悪い。。
16名無しさん@お腹いっぱい。 :2000/09/14(木) 17:50
っつーかCPUがリトルエンディアンかビックエンディアンかで完璧に動作が違うんだから使っちゃいかんよね。
17>16 :2000/09/14(木) 17:55
共用体も使っちゃダメと同義ではないか?
18>17 :2000/09/14(木) 22:13
同義じゃないよ。
共用体はさまざまな型を内包可能な型を作る場合にも使われる。
ちゅうかそっちが主な目的だろ。
19名無しさん@お腹いっぱい。
>>11
>>14
なんかやつらの会社の事情を垣間見るようだ。藁)