【初心者お断り】ガチ規格準拠C専用スレ Part133
>>935 じゃあc89に「完全」対応してる処理系を挙げてみろよ。
>>942 話を逸らすなよみっともない (´ー`)y─┛~~
たとえC99完全準拠コンパイラを使おうとも、C99の機能なんか使うべきではない
C89やC++への移植性が失われる上に、単独でも有害な機能ばかりだ
>>940 それはもう規格スレの範囲じゃないような。
規格的にはOKでしょ。心情的に気に入らないみたいだけど
>>941 間違いではない。
const外しは規格として問題がないはず。
ただし、その結果は保証されないだけ。w
結果が保証されない、というのは弱い言い方だな
要は未定義だ
そもそも
>>927がC99でもコンパイルエラーだと指摘するのが先決ではないだろうか。
この中で927が一番C99を語る資格がないと思う。
950 :
947:2009/06/01(月) 02:31:06
>>948 違う。いわゆる未定義ではない。
記述としては正しいが、書き込んだ先が
ROMでないことは保証されないだけ。
言語規格と実行環境は別の話。
ROMなんて言葉を使ってないで、規格を読んでください。
952 :
デフォルトの名無しさん:2009/06/13(土) 22:16:24
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
>>952 例えば、32bit符号無し整数の変数があり、
先頭から8bitごとにARGBを表しているとする。
(32bit画像の1画素)
すると例えば、値を使用する前に2つを分離しなければならないから、
以下のようにする。
a = (x >> 24);
r = 0xFF & (x >> 16);
g = 0xFF & (x >> 8);
b = 0xFF & x;
954 :
953:2009/06/13(土) 22:34:12
なんだ、コピペか。
普段読まないスレなので、答えてしまった。
スレ汚しスマソ。
普段読まないスレにきてスレ違いの話題に答えていくってどんな荒らしだよw
よくあること。
暇なら規格書読んどけ。
C言語を始めようと思うのですが、ビットシフトはありますか?
Rationale for American National Standard for Information Systems - Programming Language - C 3.3.7 Bitwise shift operators
ISO/IEC 9899:1999 (E) 6.5.7 Bitwise shift operators
ISO/IEC 9899:201x WG14/N1336 6.5.7 Bitwise shift operators
を参照してください。
960 :
デフォルトの名無しさん:2009/06/16(火) 08:34:50
あります
Type 型オブジェクトの配列への参照を受け取る関数を定義するとき
f( Type* array, size_t size ) と f( Type array[], size_t size ) は
どのように使い分けるのでしょうか?
あんま意識してないが、元が配列なら array[]、
そうでなけりゃ *array に (だったら名前として array はないが)
してる…かなあ。
そういや、&配列名って正式にOKになったんだっけ?
>>962 その区別にたいした意味はない。
使い分けなんか考えずに、かならず
ポインタ型にしとくのがいいと思う。
>>964 大昔からおk。
そもそも同義だから、使い分けはコーディングスタイルの管轄
うどんがヤバイのですが、どうしたらいいですか?
ゆですぎただけなら冷水でしめてしまえばいいよ。
乾麺のカビなら、餅と同様に取ればいい、が、面倒。
まず匂いかいでみたら?
以下を実行した後は必ず b == p は成り立つでしょうか?
Type* p = malloc( sizeof( Type ) );
size_t a = (size_t)p;
Type* b = (Type*)a;
それは、size_t≧ポインタという保証はあるか、ってことか。
ついでに低レベルなことを聞かせてくれ、すべてのポインタ型が同じサイズという保証はあるの?
>>970 C99§6.3.2.3¶5
> An integer may be converted to any pointer type.
> Except as previously specified, the result is implementation defined,
> might not be correctly aligned, might not point to an entity of the referenced type,
> and might be a trap representation.
ただし "previously specified" は整数定数0から空ポインタへの変換に関する規定を指している。
C99§6.3.2.3¶6
> Any pointer type may be converted to an integer type.
> Except as previously specified, the result is implementation-defined.
> If the result cannot be represented in the integer type, the behavior is undefined.
> The result need not be in the range of values of any integer type.
ただし "previously specified" はポインタから_Boolへの変換に関する規定を指している。
一般の整数型とポインタ型の型変換に関して定められているのは以上のみで、
変換可能性については定義されているが、値が同じになるかどうかはわからない。
C99§7.18.1.4で、intptr_tとuintptr_tに関しては、
全ての汎用ポインタをこれらの型に変換したものを汎用ポインタ型に逆変換すると
もとと等しい値になることが保証されている。但し、これらの型の実装はオプショナル。
すなわち、次のコードは期待通りに動く:
| Type* p = malloc( sizeof( Type ) );
| intptr_t a = (intptr_t)(void*)p;
| Type* b = (void*)a;
| assert(p == b);
C89やintptr_t/uintptr_tの存在しないC99処理系では、
一般にポインタ→整数→ポインタのラウンドトリップな変換をする方法はない。
完全に蛇足だが付け加えると、size_tがポインタを格納できる大きさだという保証はない。
>>972 なるほど C89 では特定の処理系を前提としないと無理みたいですね。
整数に単射変換できるとポインタ値をキーとした辞書を作ることができるのですが。
C++ の std::less<Type*> に相当するポインタ比較はできないかな。
>>974 uintptr_tを使えばいいじゃん。
なければ自分で定義したっていいんだし。
>>976 アホ?uintptr_tはC99以降だし、C99準拠でも存在すると限らない。
それに、標準Cの範囲内でuintptr_tを使わずにuintptr_tを定義することは出来ない。
>>977 アホ?
Cは自分で動作保証するもの。
わかったうえでtypedefするなら問題ない。
別のスレいけよカス
・規格に準拠した実装を自分でしたい奴
・規格に準拠した実装にこだわる奴
どっちでもよかろう。けんかすんな。
質問者は標準Cの範囲内で出来るかどうか効いているのに、
なんで自分でtypedefしろとか言い出すわけ?意味不明だわ。
完全にスレ違いだろ。
動きゃええんや
標準なんてクソ食らえやwwwwwwwww
俺が標準だ!
動かなくても<丶`∀´>ケンチャナヨ
>>981 標準Cにtypedefがあるからじゃないの?
・標準Cでtypedefをしたところで、uintptr_tと全く同じものを作ることはできない
・標準Cでは実現できない部分をしっかり把握した上でtypedefすればよい
という話だと思う。よくわからんけど。
別にtypedef派を擁護する気はないが、
規格に準拠した上で、typedefしていれば、
私はこのスレの趣旨と合っていると思う。
規格を無視した発言をする方はさっさと巣に帰ってくれ。
$ sed -n 117,130p /usr/include/stdint.h
/* Types for `void *' pointers. */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned long int uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int intptr_t;
# define __intptr_t_defined
# endif
typedef unsigned int uintptr_t;
#endif
私の環境では、#define __WORDSIZE 32だった。
これと同じことは、C89でも可能だから。
もっとも、>974のstd::less<Type *>がどのようなものかは知らないが、
a pointer to an object同士の比較演算は規定されている。ANSI C 3.3.8 Relational operators
任意のポインタはvoid *に変換できる。また、void *から元のオブジェクトのポインタへ変換できる。ANSI C 3.2.2.3 Pointers
わかんないなら黙ってろよ…
さすがに外しすぎ。
問題:
処理系に依存せずにuintptr_t相当の型を定義できるか?
>986の答:
__WORDSIZEという処理系独自マクロを使えばok。
規格書も見ないでヘッダファイルを見る男の人って。
>>986 以下の &a, &b, &c 間の関係演算の結果は未定義なので以下が通ってしまうことがある。
確か std::less<ポインタ> は推移的だったような気がする。
int a, b, c;
assert( &a<&b && &b<&c && &c<&a );
>>987 自分が分かってないことすら分かってない人にそんなこと言っても無駄です。