【初心者お断り】ガチ規格準拠C専用スレ Part133

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
このスレは標準C規格や規格に合致した移植性の高い記法・技法に関するスレです。
C言語初心者の初歩的な質問、GUIなどの標準Cではできない事の質問、
ソース丸投げ、宿題、書籍 などは専門の別スレッド↓があるのでそちらへ。

C言語なら俺に聞け(入門篇) Part 24
http://pc11.2ch.net/test/read.cgi/tech/1201083176/
【初心者歓迎】C/C++室 Ver.47【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1200464091/
C/C++の宿題を片付けます 103代目
http://pc11.2ch.net/test/read.cgi/tech/1200318925/

【書き込む前に】
・まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。
・質問する前には最低限検索を。
・エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。

【参考文献】
C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/250-7563469-9920244

【このスレのログ】
前スレ:http://pc11.2ch.net/test/read.cgi/tech/1190261457/
他の過去ログ:http://nssearch.hp.infoseek.co.jp/clang/

【このスレ住人としての心得】
わざとスレ違いあるいはごく低レベルな質問を繰り返して
流れを妨害する荒らしがいます。適当に誘導して放置してください。
2デフォルトの名無しさん:2008/01/24(木) 15:02:44
<`∀´>ニダニダ!
3デフォルトの名無しさん:2008/01/24(木) 15:10:37
>>2
こりゃ低レベル
4デフォルトの名無しさん:2008/01/24(木) 15:13:22
>>1市ね
5デフォルトの名無しさん:2008/01/24(木) 15:22:05
>前スレ1000
こりゃひどい
6デフォルトの名無しさん:2008/01/24(木) 16:57:34
なんぞこのタイトル
7デフォルトの名無しさん:2008/01/24(木) 17:07:59
スレタイが不適切だという指摘と
最近のスレの傾向を鑑みて
適切なスレタイを考えてるうちに
スレがつぶれそうになったので
とりあえず前に書いてあったタイトルを修正してつけた

もっといいのがあるなら次からそれにしてくれ
8デフォルトの名無しさん:2008/01/24(木) 17:27:54
確かにこういうスレも必要かも知れん

…が、そのスレの次スレとして立てるのは如何なモノかと思うぞ。
9デフォルトの名無しさん:2008/01/24(木) 17:32:23
JISのPDFダウンロードできるじゃん
ってダウンロードしたけど、全ページ黒塗りだった。
なんとかしてくんろ
10デフォルトの名無しさん:2008/01/24(木) 18:53:16
いいスレタイだな。
これなら流石にスレチは減るだろう。
11デフォルトの名無しさん:2008/01/24(木) 23:24:43
先生, 質問!
はじめて, MS の処理系で業務に使うものを作る事になりそうなんだけど
規格準拠してる?
最低限でも, stdint.h とか stddef.h が規格準拠しててほしいわけだが…
12デフォルトの名無しさん:2008/01/24(木) 23:27:39
>>11
VSスレ辺りで聞いてみてはどうか。
13デフォルトの名無しさん:2008/01/24(木) 23:33:42
>>12 そもそもVSスレって何???
まじで, Windows ほとんど触った事ねぇし
俺的には Windows == ユーザが要求してくる使いたくもない MS-word を書く
あるいはゲームをやるための環境なんだが
14デフォルトの名無しさん:2008/01/24(木) 23:37:24
>>13
VisualStudio
15デフォルトの名無しさん:2008/01/25(金) 00:41:47
前スレではMSのコンパイラは過去に準拠してなかった部分があるらしいという話は出ていた
現在ではざっと調べた限りでは準拠してると謳ってるようなので
問題起こったらMSのせい、でいいと思うが
16デフォルトの名無しさん:2008/01/25(金) 00:55:40
C89では//コメントとかアウトだよね。
17デフォルトの名無しさん:2008/01/25(金) 00:56:05
フリー、シェア含めて今一番ガチC言語の規格に沿ったコンパイラって何だろ?
C99用のコンパイラになるのか?
18デフォルトの名無しさん:2008/01/25(金) 01:38:48
お前ら落ち着けよ
いまどきWindowsでC++じゃなくC?
ありえん
19デフォルトの名無しさん:2008/01/25(金) 01:46:04
>>18
ゲイツに侵されすぎwww
20デフォルトの名無しさん:2008/01/25(金) 04:17:13
>>9
暗号化PDFを読めるリーダーを使え
21デフォルトの名無しさん:2008/01/25(金) 20:56:36
エスパーしてみると、最新のFoxitReaderには黒塗りになるバグがある。
22デフォルトの名無しさん:2008/01/26(土) 01:04:53
>>17
gcc -Wall -ansi -pedantic-errors
かな?C89だけど
23デフォルトの名無しさん:2008/01/27(日) 17:30:20
C99激しくいらない
24デフォルトの名無しさん:2008/01/27(日) 17:40:56
C++0x に導入されるような機能は欲しい。
C++0x に導入されないような機能はいらない。
25デフォルトの名無しさん:2008/01/28(月) 07:17:37
C99って誰が望んだんだ?
26デフォルトの名無しさん:2008/01/28(月) 10:21:02
C++あがりが望んだんじゃないの
27デフォルトの名無しさん:2008/01/28(月) 11:08:58
誰もが望んでいたものもそれなりに入ったような気もするが?
28デフォルトの名無しさん:2008/01/28(月) 14:35:15
望んでいたものの半分以上はC++にあるものの劣化版だったから困る
29デフォルトの名無しさん:2008/01/28(月) 18:45:42
C99は糞
K&Rの第3版が出ないのが何よりの証拠
30デフォルトの名無しさん:2008/01/28(月) 21:40:03
望んでいたというか有名どころの拡張を追認しただけというか
31デフォルトの名無しさん:2008/01/28(月) 21:44:39
C++ との互換性が無いのは致命的だよな。
C で作った関数の中には C++ から呼べない物も・・・なんて嫌だわ。
32デフォルトの名無しさん:2008/01/29(火) 02:00:41
>>22
-std=c99もつけてあげて
33デフォルトの名無しさん:2008/01/29(火) 21:12:35
GCCはC99に準拠していない。
34デフォルトの名無しさん:2008/01/29(火) 21:34:28
>>33
> GCCはC99に準拠していない。

具体的に。
35デフォルトの名無しさん:2008/01/29(火) 21:39:25
ググレカス
36デフォルトの名無しさん:2008/01/29(火) 23:01:18
準拠状況が書いてあるとこがあったな。
完全ではなかったのは覚えてる。
37デフォルトの名無しさん:2008/01/30(水) 05:18:37
つーかC99完全準拠の環境なんてあるのか?現状
38デフォルトの名無しさん:2008/01/30(水) 07:28:23
Comeau の準拠状況ってどうなんだろうか?
39デフォルトの名無しさん:2008/01/30(水) 07:30:35
>>37
Intel C++は100%C99標準準拠だよ
40デフォルトの名無しさん:2008/01/31(木) 13:02:51
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
41デフォルトの名無しさん:2008/01/31(木) 13:03:31
>>40
スレタイ読め
42デフォルトの名無しさん:2008/01/31(木) 13:26:45
>>41
ビットシフトはなんの役に立つのでしょうか
でぐぐれ
43デフォルトの名無しさん:2008/01/31(木) 19:47:50
>>40 ビット単位でシフトしたい時に役に立つ
44デフォルトの名無しさん:2008/02/01(金) 15:53:26
>>42
やっぱりこれテンプレにいれとかないとダメだな
45デフォルトの名無しさん:2008/02/01(金) 20:16:45
ビットシフトはなんの役に立つのでしょうかでググれ に一致する日本語のページ 約 766 件
46デフォルトの名無しさん:2008/02/01(金) 21:02:34
47デフォルトの名無しさん:2008/02/02(土) 17:48:40
ふと思ったんだが…

各種処理系のヘッダで NULL が以下のように宣言されているのはなぜ?

#if !defined(__cplusplus)
#define NULL ((void *)0)
#else
#if defined(__LP64__)
#define NULL (0L)
#else
#define NULL 0
#endif /* __LP64__ */
#endif /* !__cplusplus */

つか, C でも (void *)にキャストする必要はないと思われるんだが,
(void*)にキャストしておくとなんかご利益あったりする?
48デフォルトの名無しさん:2008/02/02(土) 17:55:00
int p = NULL; がエラーになる。
49デフォルトの名無しさん:2008/02/02(土) 17:58:48
NULLを'\0'と間違えて使うような馬鹿を摘発したりとか、型チェックの面でご利益がある。
50デフォルトの名無しさん:2008/02/02(土) 19:01:20
#if defined(__LP64__)
#define NULL (0L)

これ処理系依存っぽくて鬱陶しいな
51デフォルトの名無しさん:2008/02/02(土) 19:03:41
処理系自身がそう定義してるのなら
その処理系で大丈夫っつーことだから問題はないだろう
52デフォルトの名無しさん:2008/02/02(土) 19:04:07
>>50
printf の可変長引数対策じゃないか?
53デフォルトの名無しさん:2008/02/02(土) 19:06:36
つーかそういう処理系依存を覆い隠すためにヘッダがあるわけで
ヘッダの定義をのぞき見てあれこれ言っても
このスレ的に意味があるのか疑わしい
54デフォルトの名無しさん:2008/02/02(土) 19:06:54
処理系定義であるポインタのサイズを、NULLの定義の形を借りて記述しているんだよ
55デフォルトの名無しさん:2008/02/02(土) 20:16:17
ポインタのサイズが型ごとに異なったりする処理系もあるんじゃなかった?
56デフォルトの名無しさん:2008/02/02(土) 20:58:41
MS-DOSのミディアムモデルやコンパクトモデルが典型的だな
57デフォルトの名無しさん:2008/02/02(土) 21:18:16
型ごとにというかデータのポインタとコードのポインタのサイズが違う事はあるな
関数ポインタと通常のポインタに互換性がないのはそのため
58デフォルトの名無しさん:2008/02/03(日) 00:51:14
pimpl パターンとか見てる分には
データ同士だとポインタのサイズはかわらないはずだとは思ってるが、
規格のどこに書いてあるかとかは知らんなあ。
59デフォルトの名無しさん:2008/02/03(日) 01:46:52
pimplのどこに異種ポインタの変換が介在するのですかね。
60デフォルトの名無しさん:2008/02/03(日) 02:53:14
スレ違い
61デフォルトの名無しさん:2008/02/03(日) 02:57:46
変換は関係ないだろう。
構造体/クラスの中身が分からなくても
ポインタのサイズが決まるようじゃないと
pimpl パターンは使えないという話だ。

ただ、組み込み型との間でもサイズが等しいかどうかは分からんね。
これだけだと。
62デフォルトの名無しさん:2008/02/03(日) 05:15:44
構造体/クラスの宣言(通常はヘッダファイル)があれば型が分かるから
中身見なくてもポインタのサイズは決まると思う
63デフォルトの名無しさん:2008/02/03(日) 05:38:48
ポインタのサイズって32bitCPUなら4バイト固定だと思ってた
64デフォルトの名無しさん:2008/02/03(日) 10:02:56
Intel + Windows で 16-bit アプリケーションなら 32-bit CPU でも
2 バイトのポインタが使われたりする
が 32-bit アプリケーションならポインタは 4 バイト固定

要するに CPU 依存でなくコンパイラ依存

void* と int* でサイズが違う処理系があるらしいが見てみたいな
65デフォルトの名無しさん:2008/02/03(日) 11:06:04
void* (char*) と int* でアドレッシングが違う処理系があると聞いたが、
それの間違いではなくて?
66デフォルトの名無しさん:2008/02/03(日) 11:11:12
規格ではポインタのサイズはどこまで規定されている?
構造体型を指すポインタのサイズはすべて等しい?
67デフォルトの名無しさん:2008/02/03(日) 16:20:19
処理系依存ってことはつまり、ユーザープログラムより下にあるコンパイラからアーキテクチャから
すべてひっくるめて依存。データ型についてうるさいアーキテクチャもあるかもしれない。
(タグビットでデータ型を指定するような)

仕様では、6.3.2.3 で、任意のデータ型へのポインタから void * へ、
void * にしたものから元の型へ、という変換は保証されることになっている。
(関数へのポインタに関しては規定がない)

整数と任意のポインタ(関数へのポインタ含む)との変換は、処理系定義。
ポインタを入れることができる整数の型として intptr_t(uintptr_t) が 7.18.1.4 に。
68デフォルトの名無しさん:2008/02/03(日) 17:46:07
>>66
> 構造体型を指すポインタのサイズはすべて等しい?
少なくとも、これは処理系によらず保証されている。
69デフォルトの名無しさん:2008/02/03(日) 17:58:44
同サイズの整数型限定だっけ? >整数/ポインタ キャスト
intptr_t はどのポインタと等しいサイズの整数型なんだろう。
それとも、全てのポインタ型のサイズが等しいと保証されているのか?
70デフォルトの名無しさん:2008/02/03(日) 18:00:06
intptr_tはポインタを格納できればいいのであって、
ポインタと同じ大きさである必要は無いだろう。
71デフォルトの名無しさん:2008/02/03(日) 18:04:23
>>69-70
(u)intptr_tに変換できるのはvoid*だけ。

int i = 42;
intptr_t p = (void*)&i;
int j = *(int*)(void*)p;
72デフォルトの名無しさん:2008/02/03(日) 18:39:20
そしてobjectを指すポインタであればどれでも、voidへのポインタに変換後、元に戻せる。
つまり、voidへのポインタのサイズは少なくとも関数ポインタ以外のすべてのポインタ以上。
73デフォルトの名無しさん:2008/02/03(日) 20:06:00
>>71
70に対する反論になっていない
74デフォルトの名無しさん:2008/02/03(日) 20:28:45
反論したつもりはないよ。
75デフォルトの名無しさん:2008/02/03(日) 20:54:06
なるほど。
基本型同士、あるいは基本型と構造体型との間で
ポインタのサイズが違ってても良さそうではあるな。
76デフォルトの名無しさん:2008/02/03(日) 21:16:41
int *とunsigned int*みたいな、指示先型の符号の有無だけが異なる場合、ポインタのサイズは等しい。
77デフォルトの名無しさん:2008/02/03(日) 21:18:39
>>74
じゃあ何で一見関係ありそうで全然関係ない話をしたの?
78デフォルトの名無しさん:2008/02/03(日) 21:33:08
79デフォルトの名無しさん:2008/02/03(日) 21:35:13
>>77
何でアンカー間違えただけでそんなに責められないといけないんですか><
80デフォルトの名無しさん:2008/02/04(月) 19:59:51
先に「間違えた」と言わないから。
81デフォルトの名無しさん:2008/02/04(月) 21:58:01
>>79
条件の後出しはやめろと。
82デフォルトの名無しさん:2008/02/04(月) 23:19:53
いじめが好きな人達が集まるスレ
83デフォルトの名無しさん:2008/02/04(月) 23:56:02
といいつつ自分の非を棚に挙る人が責められるスレ
84デフォルトの名無しさん:2008/02/05(火) 20:48:59
>>82-83
それはどのスレでもそう
85デフォルトの名無しさん:2008/02/18(月) 15:22:26
ふと気になったんだけど
>50の、0Lをかっこでくくる必要あるの?
86デフォルトの名無しさん:2008/02/18(月) 20:02:18
>>85
#include <stdio.h>

#define HOGE 0L
#define CAT2(a, b) a ## b
#define CAT1(a, b) CAT2(a, b)
#define CAT(a, b) CAT1(a, b)

#define STR2(a) # a
#define STR1(a) STR2(a)
#define STR(a) STR1(a)

int main() {
long double a = CAT(0., HOGE);
printf("%Lf\n", a);
printf("%s\n", STR(CAT(0., HOGE)));
return 0;
}
87デフォルトの名無しさん:2008/02/18(月) 20:43:53
マクロNULLをトークン連結演算子に投げ込むような状況があるとは思えんが
88デフォルトの名無しさん:2008/02/18(月) 20:45:36
そういう問題じゃない
89デフォルトの名無しさん:2008/02/18(月) 20:50:11
あってもこまらないし
あればもしかしたら役に立つかもしれないから

一般的にはある必要はない
90デフォルトの名無しさん:2008/02/18(月) 20:51:38
あってもこまらないし
あればもしかしたら役に立つかもしれないから
とりあえずつけておけ
91デフォルトの名無しさん:2008/02/19(火) 23:04:55
超カメレスなんだが >>64
ワードアドレッシングのマシンの場合,
ワードアドレス + オフセット
ここで, ワードアドレス == レジスタサイズ
が, バイトポインタになり得ますが…
92デフォルトの名無しさん:2008/02/20(水) 14:01:41
可変引数型の関数にいくつ引数が入力されたか、
数える方法はありますか?
93デフォルトの名無しさん:2008/02/20(水) 14:09:30
標準では、ない
9492:2008/02/20(水) 14:44:34
>93
サンクス
95デフォルトの名無しさん:2008/02/21(木) 23:25:37
そう言えばさぁ...
左辺がキャストできなくなったのは C89 からで ok ?
int c; (char)c = 1;
みらいやつ
96デフォルトの名無しさん:2008/02/22(金) 02:33:43
*(char *)&c = 1;ならおk
ただしcharは必ず整合するけどもっと大きな型だとむやみなキャストは
境界に整合しなくなるおそれがある
97デフォルトの名無しさん:2008/02/22(金) 07:32:26
それはキャストはしてるけど、
キャストした後の値に直接代入してる訳じゃないよね。
98デフォルトの名無しさん:2008/02/22(金) 13:23:07
>>95
というかそれが出来た時期なんかあったのか
どういう処理になるの?
99デフォルトの名無しさん:2008/02/22(金) 13:30:53
>>95
少なくとも現在より前に制定された規格で、
(type)variable を左辺値として認めたものは一つもない。

たしか、gcc, msvcともにラフなモードではコンパイルとおるけど、
結果が違うようになったと思う。
100デフォルトの名無しさん:2008/02/22(金) 13:35:11
ああ、C++で(type)が参照型なのは除く。
101デフォルトの名無しさん:2008/02/22(金) 13:36:16
ちなみにC++だと(char&)c = 1って書ける。
102デフォルトの名無しさん:2008/02/22(金) 19:10:21
>>98
*(char*)c = 1; と同じになった気がする。
K&R C あたりではできると聞いた事があるような気がするが、
詳しい事は俺は知らん。
103デフォルトの名無しさん:2008/02/22(金) 20:01:18
K&Rではできた。
104デフォルトの名無しさん:2008/03/08(土) 01:50:20
Cでは符号なし整数をビットシフトすると論理シフト、符号有り整数をビットシフトすると算術シフトになるんですか?
105デフォルトの名無しさん:2008/03/08(土) 01:53:58
右シフトはそのとおり。
左シフトは論理/算術の区別が無い。
106デフォルトの名無しさん:2008/03/08(土) 01:54:59
わかりました。
早いレスありがとうございます。
107デフォルトの名無しさん:2008/03/08(土) 01:55:53
符号あり整数をビットシフトして算術シフトになるかどうかは
C の規格では規定されていない。
ただ、実際問題そういう実装が多いだろうね。
108デフォルトの名無しさん:2008/03/08(土) 01:57:02
unsignedは論理シフトになる
signedが算術シフトになるかどうかは処理系依存
109デフォルトの名無しさん:2008/03/08(土) 02:59:55
規格見直したら、負の数を右シフトしたときは結果の値が処理系定義になるって
書いてあった。つまり、算術シフトとも論理シフトとも違う結果が得られてもおかしくない
わけだ。

あと、型が signed でも値が負じゃなければ unsigned と同じ動作って決められてた。
110デフォルトの名無しさん:2008/03/08(土) 03:03:49
2の補数表現じゃない環境だと
算術シフトにならない実装になってるだろうね。
111デフォルトの名無しさん:2008/03/08(土) 09:37:18
ただしどうなるかは(規格準拠の処理系なら)マニュアルに明記されていなければならない
112デフォルトの名無しさん:2008/03/08(土) 20:29:31
明記されていればry
113デフォルトの名無しさん:2008/04/02(水) 23:13:23
最近レスが無いので、ビットシフトについて質問してもいいですか?
114デフォルトの名無しさん:2008/04/03(木) 00:24:28
負の数の右シフトが算術シフトになるか論理シフトになるかは処理系依存です。
115デフォルトの名無しさん:2008/04/03(木) 00:29:04
負の数の左シフトは?
116デフォルトの名無しさん:2008/04/03(木) 00:42:31
「場合によって未定義」でいいのかな?
http://f4.aaa.livedoor.jp/~pointc/105/No.27873.htm
のNo.27888がわかりやすく解説してくれてる。
117デフォルトの名無しさん:2008/04/03(木) 02:34:20
>>116
リンク先読んだら、負の数は全部未定義としか読めない。
118デフォルトの名無しさん:2008/04/03(木) 06:56:17
The behavior is undefined if the right operand is negative,
or greater than or equal to the length in bits of promoted left operand.
119デフォルトの名無しさん:2008/04/03(木) 06:57:38
それはシフト数の方の話だった。
120デフォルトの名無しさん:2008/04/04(金) 13:58:33
そろそろビットシフトの質問の出番ですか?
121デフォルトの名無しさん:2008/04/07(月) 21:51:36
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
122デフォルトの名無しさん:2008/04/07(月) 22:33:59
スレ違い
123デフォルトの名無しさん:2008/04/08(火) 03:27:19
規格上未定義になってる処理を書いたら例外吐いて止まるコンパイラきぼう

いちいち覚えるの面倒
124デフォルトの名無しさん:2008/04/08(火) 10:47:47
ベンダーに言え
125デフォルトの名無しさん:2008/04/08(火) 12:31:00
もしさまざまなマシンでどのように実行されるか知らなければ、
知らないということが自分を守る助けとなるかもしれ ない

              from K&R
126デフォルトの名無しさん:2008/04/09(水) 00:45:45
例外吐かれるより警告がうれしいな・・・
127デフォルトの名無しさん:2008/04/09(水) 20:48:04
エラーでいいよ。
どうせ警告も0にしてるんだし。
128デフォルトの名無しさん:2008/04/09(水) 22:05:24
俺は信号を見ないけど車は俺をよけて通れよ!
なんて高らかに宣言しなくても・・・
129デフォルトの名無しさん:2008/04/10(木) 17:31:25
エラーでも警告でもアラーとでもいいけど、
そこで止まられるのは、、ちょっとやだな。
130デフォルトの名無しさん:2008/04/10(木) 17:49:13
過疎スレ
131デフォルトの名無しさん:2008/04/10(木) 22:07:09
結構前に、アラーメッセージというのがあったな・・・
132デフォルトの名無しさん:2008/04/10(木) 22:31:01
アッラーアクバル!
133デフォルトの名無しさん:2008/04/23(水) 20:00:31
http://pc11.2ch.net/test/read.cgi/tech/1206196600/637

の件なんですが、こういうことに出くわした場合、
コンパイラはどういう風に振舞わなければならないとなってるのでしょうか?
それとも未定義?
134デフォルトの名無しさん:2008/04/23(水) 20:55:12
>>133
未定義
コンパイラの実装依存です
リンカのオプションでエラーにする設定もおそらくあります

src1.c と src2.c で変数 a の型が違ってたりすると悲惨です
135デフォルトの名無しさん:2008/04/23(水) 21:01:07
C の仮定義ってファイルまたぐと適用外だっけ?
136デフォルトの名無しさん:2008/04/23(水) 22:13:29
>>134
未定義と実装依存は違うし、そもそもコンパイラにとっては正しいソース
なので、

> コンパイラはどういう風に振舞わなければならないとなってるのでしょうか?

普通に振舞うだけ。

大抵の環境ではリンカでエラーになるはず。
(そのスレでは、エラーにならないと言い張ってるが。)
137デフォルトの名無しさん:2008/04/23(水) 22:19:34
>>136
未定義なので実装依存と書けばいいの?
gcc なら警告無し
borland C++ compiler なら警告あり

大抵の環境って何が基準?
138デフォルトの名無しさん:2008/04/23(水) 22:30:12
VC++2008でも警告無しだな
139デフォルトの名無しさん:2008/04/23(水) 22:31:34
みんなあんまり適当な事言うなよ?

>>133
あまり知られていないが、これは 「仮定義(tentative definition)」 という仕様。
extern も static もついていない、初期化を伴わないグローバル変数の宣言は 「仮定義」 と見なされる。
対する、extern も static もついていない、初期化を伴うグローバル変数の宣言は 「外部定義(external definition)」 と見なされる。

外部定義は必ず実体定義を伴う。
外部定義が複数あると、二重定義となりエラーとなる。

しかし、仮定義は他に実体定義がなければ実体を定義し、
他に実体定義があれば実体定義を伴わない単なる宣言と見なされる。
複数の仮定義を書いた場合、実体は1つだけ定義され、それらの仮定義は実体を共有する。

つまり、>>133 は仕様。
140デフォルトの名無しさん:2008/04/23(水) 22:35:35
ちなみにこの仕様は C++ で廃止された。
C++ では仮定義がなくなり、
extern も static もついていない、初期化を伴わないグローバル変数の宣言も
外部定義と見なされ、実体定義を伴う。

このあたりの違いの話は C++ の規格の付録に書いてある。
141デフォルトの名無しさん:2008/04/23(水) 23:14:40
>>137
> 未定義なので実装依存と書けばいいの?

違う。

未定義は何が起っても文句を言うなと言うこと。
(実行したらPCが壊れるような実行ファイルを生成しても規格には違反しない。)

実装依存は何が起るかは環境によって違うけど、環境毎に何が起るかは決まってい
ると言うこと。

>>137, >>139-140
すまん、仮定義のことすっかり忘れてた。
142デフォルトの名無しさん:2008/04/23(水) 23:23:02
未定義は規格は挙動を定義しないということで、
何が起こっても規格に反しないということではあるが、
処理系独自に挙動を定義することまでを禁止する物でもない。
もちろん、それに頼ったコードは通常移植性が低い訳だが。

処理系依存は処理系ごとに挙動を定義することが求められている。

未規定は未定義と似ているが、
正常なコードの中で挙動がきちんと定められていないものを言う。
関数の引数に書かれた式の評価順とか。
143デフォルトの名無しさん:2008/04/24(木) 00:20:37
仮定義は初耳でした、勉強になりました
ありがとうございます
144デフォルトの名無しさん:2008/04/24(木) 00:30:36
うげ、仮定義って翻訳単位跨いでも使えるのか。
知らなかった。
145デフォルトの名無しさん:2008/04/24(木) 00:49:31
本当に翻訳定義またいで使えたっけ?
146デフォルトの名無しさん:2008/04/24(木) 01:24:54
規格を見る限り、仮定義があると翻訳単位の一番下に = 0 で初期化された宣言があると見なされるようだ。
複数の翻訳単位がある場合は二重定義になりそう?
147デフォルトの名無しさん:2008/05/05(月) 14:08:05
>>141-142
処理系依存・実装依存は処理系定義(implementation-defined)だけじゃない。
適当なこと言うなよ。

未定義・未規定・処理系定義
どれも処理系の実装に依存してるだろ。

148デフォルトの名無しさん:2008/05/05(月) 14:20:11
処理系定義は実装には依存しないだろ。
149デフォルトの名無しさん:2008/05/05(月) 14:22:21
実装によって挙動が違うことを規格が許している、ことを
実装に依存している、と言うのであって、
処理系定義は実装に依存していると思うが?
150デフォルトの名無しさん:2008/05/05(月) 14:28:03
処理系定義は仕様としての表明であり、実装とは切り離されている。
具体的なモノとは分けて考えるべきだろう。
151デフォルトの名無しさん:2008/05/05(月) 15:08:26
JISでは処理系と訳されてるけどimplementation definedだから「実装」だべ
152デフォルトの名無しさん:2008/05/05(月) 15:18:25
その文脈で
>>147
>どれも処理系の実装に依存してるだろ。
の意味を説明できるのか?
153デフォルトの名無しさん:2008/05/05(月) 15:28:53
>>147 おおむねこんな意味かい?

処理系定義: 動作も結果も保証しないがどうのような振る舞いを示すかは
処理系が保証しなければならない
未規定: 動作の保証はないし処理系の振る舞いによって何が起るかは
不明
未定義: 何が起っても文句は言えない.
処理系自体も振る舞いを規定する必要はない
154デフォルトの名無しさん:2008/05/05(月) 15:31:09
そもそもX3010に〜依存って言葉はあるんでしょうか?
155デフォルトの名無しさん:2008/05/05(月) 15:36:43
>>153
未規定:規格が動作を明示することを求めいていない
例)関数の実引数は、どれから評価してもよいし、明示する必要もない。
156デフォルトの名無しさん:2008/05/05(月) 15:37:40
ない。
一部の人間が勝手にimplementation definedと混同してるだけ。
>>136とか>>141とか>>142とか
157デフォルトの名無しさん:2008/05/05(月) 16:07:28
「規格が明確に定義していない」には3種類あって、以下のように定義されている。

・処理系定義(implementation defined)の動作
どう動作するかを実装が選択する。そのプログラムがコンパイルできないというのは許されない。
(この構成概念を使ったプログラムは誤りというわけではない。)
(実装が)何を選んだかは(コンパイラの作者が)文書にしておかなければならない。
規格が合法な動作をいくつか用意していてそこから選ぶことができるかもしれないし、
必要条件をとくに課していないかもしれない。

・未規定(unspecified)の動作
処理系定義の動作に似ている。ただし、どういう動作を選んだかは文書にする必要がない。

・未定義(undefined)の動作
本当に何が起きても不思議はないことを意味する。規格は何の必要条件も課さない。
コンパイルできないかもしれないし、誤った動きをするかもしれないし
(クラッシュしたり黙って誤った結果を出したり)、
あるいはたまたまプログラマの意図したとおりの動きをするかもしれない。


以上、CFAQより抜粋
158デフォルトの名無しさん:2008/05/05(月) 17:52:27
もうメタ議論くらいしかすることないのな
159デフォルトの名無しさん:2008/05/05(月) 21:08:20
うん。
160デフォルトの名無しさん:2008/05/06(火) 01:46:45
>154 >156
ただ、CFAQには「実装依存」を「処理系定義の動作」という意味で使っている場所がある。
正確ではないが、その言葉に出くわして意味を解釈する必要があるときは、そのように読むのが一般的であるかもしれない。
161デフォルトの名無しさん:2008/05/06(火) 05:08:14
それはimplementation definedの正確でない訳だったりしないの?
162>>136:2008/05/06(火) 11:07:05
一般的な機論において、特に混乱するわけでもないから「〜依存」って
書いてるだけ。後出しで X3010 出してきて混同してるとか言われても、
「また KY 君かよ」としか思えない。
163デフォルトの名無しさん:2008/05/06(火) 11:13:34
>>161
当たったところ、原文では implementation-defined と書いてあった。
ただそもそも日本語で実装依存といった場合におおよそ何を意味するかという話であるので
(だから正確でないのは承知の上であることは書いた)。
164デフォルトの名無しさん:2008/05/06(火) 22:59:28
つまり
「実装依存」は場面によって指している物が違うから
implementation definedの訳としては使わないほうがよい。
ということだな。
165デフォルトの名無しさん:2008/05/07(水) 00:01:21
implementationは普通に訳せば実装という意味だから処理系定義という訳もアレかもしれんがな

「実装依存」そのまんまの意味であるimplementation-dependentはかなり広く使われてるようだが特定の言語に限った話じゃないしね
166デフォルトの名無しさん:2008/05/07(水) 01:26:51
一般の議論ではよく使われる「依存」だが、このスレでは非推奨の
用語ということにしたほうがよさそうだな。
このスレでは直訳した「実装定義」か、JIS用語の「処理系定義」、
「未規定」、「未定義」を使い分けるということで。
167デフォルトの名無しさん:2008/05/16(金) 13:13:18
C++ が存在するのに新しい C 言語の仕様を策定するのは、C++ のコンパイラは
実装が難しいからですか?
168デフォルトの名無しさん:2008/05/16(金) 13:32:46
C++はCの上位集合ではありませんが?
169デフォルトの名無しさん:2008/05/16(金) 15:05:56
上位集合ではないが、ほとんどの場合ソースを変更する必要がないか、
少し変えれば両方で動くようになる。
C99 のように C++ との互換性に問題を作ってまで新しい仕様を作る
必要はないんじゃないか?
170デフォルトの名無しさん:2008/05/16(金) 15:49:33
C++なんかどうでもよくね
171デフォルトの名無しさん:2008/05/16(金) 20:03:05
C99なんて誰も必要としていない
172デフォルトの名無しさん:2008/05/16(金) 23:16:34
inlineとか変数宣言のブロック先頭縛り廃止とかのC++追随と
vsnprintfにlong longなど有名どころの独自拡張の追認だけにしておけば、
もう少し広まった気がする。
173デフォルトの名無しさん:2008/05/16(金) 23:21:10
Bjarne 先生に相談しないで仕様を決めてしまったのかな。
174デフォルトの名無しさん:2008/05/17(土) 00:14:23
スレ違い
175デフォルトの名無しさん:2008/05/17(土) 09:22:23
構造体の宣言と同時に初期化は有用
176デフォルトの名無しさん:2008/05/17(土) 09:27:21
C++も0xで対応するんじゃなかったっけ
initializer_listとか
177デフォルトの名無しさん:2008/05/17(土) 11:17:20
いちいち構造体のタグ名の前に struct を付けないといけないのは面倒くさい。
typedef しなくてもタグ名をそのまま型名として使えるようにしてほしい。
178デフォルトの名無しさん:2008/05/17(土) 12:01:17
C++でもつかっとけ
179デフォルトの名無しさん:2008/05/17(土) 13:19:14
コンストラクタはいらないがデストラクタが欲しい。
180デフォルトの名無しさん:2008/05/17(土) 17:11:10
typedef すればいいから正直あまり困らないな >struct
181デフォルトの名無しさん:2008/05/17(土) 23:03:42
自分へのポインタを持つ構造体宣言するときにちょっと書くワードが多いくらいだろう
大した問題じゃない

というか自分はC++でも typedef struct … しちゃうな、なんとなく気持ち悪くて
182デフォルトの名無しさん:2008/05/18(日) 01:22:06
自分へのポインタを持つ構造体も、事前に typedef しとけば・・・
って、その typedef を書く必要があるから結局は面倒なんだが。
183デフォルトの名無しさん:2008/05/18(日) 03:02:46
Cでstruct tagを自動でtypedefしないのは、名前空間の問題にひっかかるからかな?
184デフォルトの名無しさん:2008/05/18(日) 03:08:40
特に理由はなかったんだろう。
何となく struct を付けた方がいいんじゃね? と思って仕様を作った。
でも、実際には面倒臭かったので C++ では必須ではなくなった。
それだけのことなんだろう。
185デフォルトの名無しさん:2008/05/18(日) 03:24:45
名前空間は、新規格で導入しない理由のひとつではあると思う。
構造体(共用体)タグが「通常の識別子」として扱われる改定がされた場合でも、
逆に従来の構造体タグ名前空間のままでtypedefされる改定となった場合でも、
もし過去にそうならないことに因って書かれたコードがあったらコンパイルできなくなる。

どちらでもない新しい名前空間を作るにしても、旧来のコンパイラを改良する手間は
名前空間の管理に手を入れる関係上、それなりの手間が必要になる。
そこまでして導入するほどの問題では絶対にない。と思う。気がする。
186デフォルトの名無しさん:2008/05/18(日) 04:01:36
structってつけてくれた方が構文解析が楽だから、とかはさすがにないか。
187デフォルトの名無しさん:2008/05/18(日) 11:01:15
多分そうだと思う。
変数がブロックの先頭でしか宣言できないのも抽象構文木の構造に自然に合うからだと思う。
現在の C から派生した言語はほとんどこういう制限はない。
188デフォルトの名無しさん:2008/05/18(日) 11:37:50
昔はマシンが非力だったから
少しでも楽にしたかったのかもしれないね。
189デフォルトの名無しさん:2008/05/18(日) 12:12:20
配列の境界検査をしない、という仕様がまさにそれ
190デフォルトの名無しさん:2008/05/18(日) 12:13:10
しないと言い切るとこのスレ的には間違ってるか
境界検査をしなくてもよい、だな
191デフォルトの名無しさん:2008/05/18(日) 12:41:11
C++ の std::vector も境界チェックを行う at と行わない operator[] を用意してるから
非力だったからやらない、というわけではないと思われ。
192デフォルトの名無しさん:2008/05/18(日) 12:44:49
安全と効率を天秤に掛けて、効率を取る漢らしい言語なんです
193デフォルトの名無しさん:2008/05/18(日) 12:46:03
[]で境界チェックしないのはCとの互換性のためだろ
未定義動作に互換性もへったくれもない気がするけど
194デフォルトの名無しさん:2008/05/18(日) 12:46:22
可能な限り、安全は言語でサポートするものではなく
ライブラリでサポートするべき、って感じだな。
最大限の効率を約束する。
195デフォルトの名無しさん:2008/05/18(日) 12:46:57
>>193
std::vector は C にないから
互換性なんてどうでもいいと思われるが。
196デフォルトの名無しさん:2008/05/18(日) 13:10:54
VRAM直書きの時、境界検査されたらちょっとヤだな。
197デフォルトの名無しさん:2008/05/18(日) 13:26:26
論理エラーまでチェックしていたら OS なんて書ける性能はでないよ。
198デフォルトの名無しさん:2008/05/18(日) 15:06:53
>>195
メモリ配置の連続性要求はCとの互換性のため
199デフォルトの名無しさん:2008/05/18(日) 15:08:34
>>198
連続性要求と境界チェックは別の話だっしょ。
200デフォルトの名無しさん:2008/05/18(日) 15:30:03
境界チェックしてほしいなら /RTCs を付ければいいよ。VC 以外は知らない。
201デフォルトの名無しさん:2008/05/18(日) 16:06:54
>>199
連続性要求と境界チェックは同じだとは言っていない。
「互換性なんてどうでもいい」なら連続性要求も必要ないはずだと言いたいだけ
202デフォルトの名無しさん:2008/05/18(日) 16:12:50
俺のカンでは話がかみあってないな
203>>136:2008/05/18(日) 16:13:31
>>196
VRAM サイズの配列を宣言して、VRAM のアドレスにマップできるようにすればいいだけ。

>>197
いつの時代だよ。

爺は早めに引退しとけ。
204デフォルトの名無しさん:2008/05/18(日) 16:14:08
>>201
普通の配列の話じゃなくて std::vector の話なんだけどな。
普通の配列に関しては互換性も理由の1つだろう(それだけじゃないとは思うが)。
205デフォルトの名無しさん:2008/05/18(日) 16:14:46
>>203
そうやってどんどん OS を重くしてるから
Vista みたいに叩かれるんだよ
206デフォルトの名無しさん:2008/05/18(日) 16:33:09
>>204
配列じゃなくてstd::vectorに連続性要求があるんだけど
207デフォルトの名無しさん:2008/05/18(日) 16:52:19
まぁ「レガシーAPIにstd::vector渡せますか?」
というのはC++のFAQだよな

次の規格ではstd::stringもそうなるんだっけ
208デフォルトの名無しさん:2008/05/18(日) 16:57:42
std::string::c_str() があるのにそんな必要あるの?
209デフォルトの名無しさん:2008/05/18(日) 17:07:54
現在のc_strはコピーが発生する可能性があってパフォーマンスに響くかもしれない。
210デフォルトの名無しさん:2008/05/18(日) 17:10:49
どう考えても>193がおかしい
Cにはvectorが存在しないのだから互換性が問題になるはずがない
211デフォルトの名無しさん:2008/05/18(日) 17:12:25
Cで書かれたライブラリとのバイナリ互換性とか
212デフォルトの名無しさん:2008/05/18(日) 17:50:29
>>206
だから連続性要求の話なんて誰もやってないんだってば・・・。
境界チェックの話だ。
213デフォルトの名無しさん:2008/05/18(日) 17:53:11
そもそもだなぁ
なんで std::string::c_str() な話がこのスレで出てくる?
214デフォルトの名無しさん:2008/05/18(日) 18:11:46
もし境界チェックを行う必要が無いという仕様が
大昔はマシンパワーが弱かったからという問題で作られたのなら
C++ を作る時に std::vector で at でも operator[] でも境界チェックをすれば良かった。
でもそうしなかったということは、それだけの問題じゃないってことだろう。
という話。
215デフォルトの名無しさん:2008/05/18(日) 18:16:35
だからCもC++も基本的に効率側に仕様を倒すんだよ

安全性はライブラリで頑張る方針
216デフォルトの名無しさん:2008/05/18(日) 18:22:08
そういうこと。
昔マシンパワーが弱かったからじゃなくて、
マシンパワーに関わらず効率を取るってこった。
217デフォルトの名無しさん:2008/05/18(日) 18:31:08
マシンパワーが高くなっても 10 分かかっている処理は速い言語で 5 分にしたいよ。
アプリにもよるけど。
218デフォルトの名無しさん:2008/05/18(日) 18:32:57
>>215
> 効率側に仕様を倒す

ちゃう, 特に C に関しては高級言語だと思ってはいけない

freestanding な環境でも動作可能, つか, 標準ライブラリを使用せず
(libgcc とかは微妙だけど)に動作可能なバイナリを吐き出せる事も
求められている.

実際 crt.o を自前で書けば, 標準ライブラリを使わずに実行イメージを
作ることが可能(しつこいけど libgcc とかは微妙)

境界チェックに関しては微妙だけど...
219デフォルトの名無しさん:2008/05/18(日) 18:34:22
>>212
だから境界チェックしてない理由(の1つ)に連続性要求と同じ理由は考えられないのかと
言ってるだけなんだが。
std::vectorがCにないから互換性の問題がないなら
operator[]で境界チェックをやることだって互換性の問題を起こさない
220デフォルトの名無しさん:2008/05/18(日) 18:39:34
>>219
連続性要求は C++98 ではなく C++03 で導入された。
221デフォルトの名無しさん:2008/05/18(日) 19:19:52
>>203
世の中Cで書いたプログラムのターゲットは3GHzクラスばかりじゃないんだよ。
222デフォルトの名無しさん:2008/05/18(日) 19:37:35
>193は自分のレスをもう一回冷静に読み直せ
>191はvectorの境界チェックのみの話しかしていない
だからそもそも互換性や連続性の話は関係ない
お前が勝手にoperator[]全般の話を持ち出したから話がかみ合ってないだけだ
223デフォルトの名無しさん:2008/05/18(日) 19:43:16
これは俺のカンだけど
>>193はoperator[]はあらゆるオブジェクトで同じもんだと思ってるね
でなきゃ互換性なんてセリフ出るはずがない
224デフォルトの名無しさん:2008/05/18(日) 19:48:39
>>219
vectorの連続性要求の理由はそのほうが直感的かつ便利だからであってCとの互換性からではない。
なぜならvectorはCに存在しないから。C++にしか存在しないものがCとC++の間での互換性で問題になる は ず が な い 。
225デフォルトの名無しさん:2008/05/18(日) 19:50:43
>>224 だったらスレタイ読んで出直してこい
226デフォルトの名無しさん:2008/05/18(日) 19:53:11
>>225
お前はレスの流れを読むべきだな
227デフォルトの名無しさん:2008/05/18(日) 21:48:21
>>221
で、それがどうかしたのか?

非常にタイトな部分には、チェックをはずせるようにしとけばいいだけだろ。

しょぼい環境の奴は、頭もしょぼいのか? (w
228デフォルトの名無しさん:2008/05/18(日) 21:52:24
仕様と処理系の区別もつかないくらい耄碌してるのか。
229デフォルトの名無しさん:2008/05/18(日) 23:26:28
「ディフォルトは検査するが、指定した部分の検査をしなくてもいいように指示できる」

と言う言語仕様にすればいいだけ。

どこに処理系の話が出てくるんだ?

# 耄碌爺って他人を耄碌してると思いたがるよな。(w
230デフォルトの名無しさん:2008/05/18(日) 23:33:09
C言語の仕様は
「チェックなんて効率の悪い事はデフォルトではしない。検査は各々自己責任でやれ」
というスタンスなんだよ
231デフォルトの名無しさん:2008/05/19(月) 00:14:36
耄碌してんじゃなくて若くて無知なだけだったか。
232デフォルトの名無しさん:2008/05/19(月) 00:21:52
>>230-231
はぁ? いまごろ何言ってんの?

そんなこと >>192 に書いてある。

耄碌爺はちょっと前のレスすら覚えてないらしいな。

病院に行った方がいいぞ。
233デフォルトの名無しさん:2008/05/19(月) 01:14:18
話の整理

197 「Cぐらい男らしい言語じゃないとOSなんて組めないよねー」
  ↑ 偏見というほどでもないがたぶん誇張
203 「そんなことはない、今のマシンのスペックなら(他の言語でも)十分いけるよ」
  ↑ 正しいとは言い切れないが間違いではない
221 「そんな高スペックの環境ばかりじゃないんだよ」
  ↑ ここがずれてる 203はそんな環境でCでない(チェックの厳しい)言語を使えとは言ってない
227 「低スペックな環境なら(その言語の機能で)チェック外すようにできればいいだろ」
  ↑ まあ正論
230 「Cはそういう言語じゃないんだよ」
  ↑ Cでない言語の話をCの話と勘違いしている

というわけで話の理は203にある
だが煽るのはやめろ
234デフォルトの名無しさん:2008/05/19(月) 02:40:18
自演乙、と言えばいいのか?
235デフォルトの名無しさん:2008/05/19(月) 05:16:42
すっかり違う言語にかわっちゃうような機能を、オプションでつけはずし?
配列とポインタが交換可能なのはC言語の特徴ですよ。
ポインタが配列を指してるかどうかのチェックからするんですか?
236デフォルトの名無しさん:2008/05/19(月) 05:47:52
ああ、そうか、>>203は最初からC言語の話なんかしてないのか。
>>233 解説ありがとう。

ということで、スレ違いだな。
237デフォルトの名無しさん:2008/05/19(月) 12:44:06
C言語は最適化のヒントを与える機能を追加すれば後は拡張しなくていいよ。
C言語の役割はある程度ポータビリティーがあって可能な限り性能を出すこと。
どんなに CPU の性能が上がってもこの需要はなくならない。
238デフォルトの名無しさん:2008/05/19(月) 15:40:22
できることが増えるスピードよりやりたいことが増えるほうが速いからな
239デフォルトの名無しさん:2008/05/19(月) 22:33:30
>>235
相変わらず、頭固いネェ。

> 配列とポインタが交換可能なのはC言語の特徴ですよ。

未だに配列アクセスよりポインタアクセスの方が常に速いとか
思ってるんだろうな...。
240デフォルトの名無しさん:2008/05/20(火) 06:08:38
頭の固い人間 VS 論点がズレている人間
の対決はいつ見ても不毛
241デフォルトの名無しさん:2008/05/20(火) 10:01:59
>>239
君の脳内言語の話はスレ違いだ。
242デフォルトの名無しさん:2008/05/20(火) 22:05:48
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
243デフォルトの名無しさん:2008/05/20(火) 22:23:18
>>242
それなんてコピペ?

こんな感じでよろしいか?
244デフォルトの名無しさん:2008/05/20(火) 22:27:14
おk
245デフォルトの名無しさん:2008/05/21(水) 00:41:16
>>241
反論できなくなったら、脳内言語ときたか。

だったら、>>221 あたりでそう書きゃいいと思うが、
しょせん耄碌爺には無理か。(w
246デフォルトの名無しさん:2008/05/21(水) 01:18:38
煽るな
247デフォルトの名無しさん:2008/05/21(水) 01:38:16
248デフォルトの名無しさん:2008/05/21(水) 10:51:11
>>245
つまりこういう事だな。
「脳内言語だって気が付くのが遅せーんだyp」
249デフォルトの名無しさん:2008/05/21(水) 23:45:16
昔の知識で煽ったら、反撃くらって撃沈しただけだろ。
250デフォルトの名無しさん:2008/05/22(木) 01:22:46
俺言語の話なんかする奴が悪いな
251デフォルトの名無しさん:2008/05/22(木) 04:36:43
俺言語君の知識は、最近のCPUは速いって事だけだったからな。
反論する余地は無いな、たしかに。
252デフォルトの名無しさん:2008/05/22(木) 07:42:58
お前らも煽るな
253デフォルトの名無しさん:2008/05/22(木) 10:44:54
大勢のフリした一人だろ。煽っているのは。
254デフォルトの名無しさん:2008/05/22(木) 11:51:11
おやそくの一言が出ました。
255デフォルトの名無しさん:2008/05/22(木) 11:55:57
お夜食?
256デフォルトの名無しさん:2008/05/22(木) 12:18:30
↓ タイプミスをプギャーして勝ち誇るAAをどーぞ
257デフォルトの名無しさん:2008/05/22(木) 12:19:49
m9(^д^)
258デフォルトの名無しさん:2008/05/22(木) 17:41:00
ぐぐってもプギャーの意味分からなかった。
259デフォルトの名無しさん:2008/05/22(木) 22:44:05
> 俺言語君の知識は、最近のCPUは速いって事だけだったからな。
> 反論する余地は無いな、たしかに。

にもかかわらず反論してた爺は哀れだな。(w
260デフォルトの名無しさん:2008/05/23(金) 05:38:05
いつまでも爺爺言ってる奴が根に持ちすぎてて怖い
将来犯罪起こしそうだな
261デフォルトの名無しさん:2008/05/23(金) 07:38:27
脳内言語だと解ってからは、だれも反論なんかしちゃいないのにな。
262デフォルトの名無しさん:2008/05/23(金) 23:57:40
>>261
> 脳内言語だと解ってからは、だれも反論なんかしちゃいないのにな。

>> 反論してた

爺は日本語も不自由らしい。(w
263デフォルトの名無しさん:2008/05/24(土) 01:01:27
俺言語の話してるのに、C言語の話だと思って反論してやんのプギャー
こうですね、よくわかります。

264デフォルトの名無しさん:2008/05/24(土) 01:50:10
ひっかかった、くやしいムキー。
こうですね、よくわかります。
265デフォルトの名無しさん:2008/05/24(土) 02:09:10
いつまでやってんの!
266デフォルトの名無しさん:2008/05/24(土) 02:26:07
ケンカはやめて(><)
267デフォルトの名無しさん:2008/05/24(土) 11:46:20
爺で検索すればいいからわかりやすいな
268デフォルトの名無しさん:2008/05/24(土) 17:49:54
C89 との違いのみを完全に全て列挙したような資料ってありますか?
269デフォルトの名無しさん:2008/05/24(土) 17:51:43
C89 と C99 との違い・・・です。
270デフォルトの名無しさん:2008/05/24(土) 18:03:32
完全かどうかは知らないけど
http://seclan.dll.jp/c99d/
とか
271デフォルトの名無しさん:2008/05/26(月) 17:40:59
!0の値は1ですか?不定ですか?
272デフォルトの名無しさん:2008/05/26(月) 17:42:57
1です
273デフォルトの名無しさん:2008/05/26(月) 17:49:09
ありがとう
274デフォルトの名無しさん:2008/05/26(月) 19:06:31
>>270
結構詳しいですが、完全なんですかね・・・。
何か漏れがあるとかいう話はないんでしょうか。
275デフォルトの名無しさん:2008/05/28(水) 22:52:00
究極的にはC99の規格票買ってきて突き合わせるしかないだろ
276デフォルトの名無しさん:2008/06/01(日) 12:22:33
意味情報を利用しても、C (C89) の文法はLALR(2)ではないかという
疑問がありますので質問です。

構文規則はK&Rのものしか参照できないので、もしかしたら仕様書の
ものと違うかもしれないのですが、

compound-statement:
 { declaration-list_opt statement-list_opt }

という構文規則で、

int foo;

typedef int foo; /* 型名とグローバル変数の名前空間は独立 */

void bar(void)
{
 foo ?? /* ?? を読むまで、fooは宣言の一部であるとしてシフトするか、
     文の一部であるとして、宣言を空にリダイレクションするか、決められない */

と思うのですが、間違いがどこかにありますでしょうか?
277デフォルトの名無しさん:2008/06/01(日) 12:30:47
>型名とグローバル変数の名前空間は独立
この仮定が間違ってる。
278デフォルトの名無しさん:2008/06/01(日) 12:57:24
型名も変数名も全て「一般の識別子」だよ
違うのは構造体タグだろ
279デフォルトの名無しさん:2008/06/01(日) 15:10:44
識別子と言うことと、名前空間の管理は全然別の話だよ。
280デフォルトの名無しさん:2008/06/01(日) 16:14:06
Cの名前空間は4種類。
・ラベル
・タグ
・メンバ
・その他すべて(typedefした型名や一般の変数の名前を含む)
つまり二つのfooは同じ名前空間を持つ。
これを同じスコープ(この場合ファイルスコープ)で使ったら当然衝突する。
スコープが異なるなら識別子の優先順位と隠蔽によってまったく問題なく処理できる。
281デフォルトの名無しさん:2008/06/01(日) 17:07:45
C言語 名前空間 でググルとほとんどどんぴしゃの内容が...

http://uyota.asablo.jp/blog/2006/08/24/497407
282デフォルトの名無しさん:2008/06/01(日) 17:11:45
>>281
まちがってるなぁ
そこでa a;が許されるのはスコープが違うからであって名前空間が違うからじゃない
283デフォルトの名無しさん:2008/06/01(日) 20:47:48
グローバルな型名はローカル変数名でシャドウされる?
284デフォルトの名無しさん:2008/06/01(日) 21:40:28
されるよ。
285284:2008/06/01(日) 21:43:56
たとえば、

typedef int a;
a main(){
a a;
a b; // error
return 0;
}
286デフォルトの名無しさん:2008/06/02(月) 05:48:23
型を宣言するとき
defineではなくtypedefを使わないといけない明確な理由って
なんですか?

今まで普通に使ってきたけど、新人にどう説明すればいいか
悩んでいます。
287デフォルトの名無しさん:2008/06/02(月) 06:04:08
>>286
typedef char * pchar;
pchar a, b;
sizeof(b)=?

#define pchar char *
pchar a, b;
sizeof(b)=?
288デフォルトの名無しさん:2008/06/02(月) 06:38:47
>>286
あと、たとえば型size_tを要求する関数があったとして、
#define size_t int
とかやると、size_tの変数を渡してもintで宣言した変数渡しても、コンパイラには区別がつかない。
289デフォルトの名無しさん:2008/06/02(月) 07:12:47
>>286
typedef char *pchar;
const pchar a;   → a が const

#define pchar char *
const pchar a;   → *a が const

主にポインタ関連で困ったことになる。
290デフォルトの名無しさん:2008/06/02(月) 13:46:28
>>288
もともとCのtypedefは弱いtypedefだから区別ないけどね
291デフォルトの名無しさん:2008/06/02(月) 13:48:33
>>286
関数ポインタ形とか配列型だと、構文の都合上で#defineではできないってのもあるね。
292デフォルトの名無しさん:2008/06/02(月) 21:08:43
defineじゃデバッグ時にこまるじゃん
293デフォルトの名無しさん:2008/06/02(月) 23:22:48
typedefにはスコープがある。
defineには無い。
294デフォルトの名無しさん:2008/06/03(火) 21:24:03
typedefにはスープがある。
defineには無い。
295デフォルトの名無しさん:2008/06/04(水) 01:19:44
define には名前空間がない。
296デフォルトの名無しさん:2008/06/04(水) 07:28:02
typedefにも名前空間はない
297デフォルトの名無しさん:2008/06/04(水) 07:44:55
我輩には名前がない。
298デフォルトの名無しさん:2008/06/04(水) 10:16:06
うちの女房にゃひげがある
299デフォルトの名無しさん:2008/06/04(水) 17:02:02
さぁみんな、微妙に勘違いする仕事に戻るんだ!
300デフォルトの名無しさん:2008/06/04(水) 21:50:30
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?

こうですね、わかります
301デフォルトの名無しさん:2008/06/05(木) 21:54:55
全てのビットが0のポインタを得るにはどうすればいいでしょうか。
次のようなのを考えましたがなんかイマイチ。

void *p;
p = (void*)(1-1);
p = (void*)!1;
p = (char*)1-1;
memset(&p, 0, sizeof p);
302デフォルトの名無しさん:2008/06/05(木) 22:00:00
この中では memset(&p, 0, sizeof p); が最も確実。
上の2つはもしかしたら上手くいかないかもしれない。
3つ目は明らかに間違い。
303デフォルトの名無しさん:2008/06/05(木) 22:21:41
いや、3つ目もいいんじゃないか?
304デフォルトの名無しさん:2008/06/05(木) 22:27:52
一番下以外は未定義動作
305デフォルトの名無しさん:2008/06/05(木) 23:23:38
こういうのは?
p = (void*)(int)0;
306デフォルトの名無しさん:2008/06/05(木) 23:27:42
整数をポインタにキャストした場合の動作は定義されない。
307デフォルトの名無しさん:2008/06/05(木) 23:58:57
>>306 んなこたーない。
308デフォルトの名無しさん:2008/06/06(金) 00:40:19
ポインタ型は、(何らかの)整数型と情報を失わずに相互変換できる。
309デフォルトの名無しさん:2008/06/06(金) 00:41:02
別に0というリテラルがヌルポインタとして使えると定義されてるわけじゃないぞ。
コンパイル時に0になると決定できる定数式は全部ヌルポインタとして使える。
だから
p = (void*)(1-1);
p = (void*)!1;
はヌルポインタ。
310デフォルトの名無しさん:2008/06/06(金) 11:28:03
>>309
だから、NULLポインタは全ビット0とは限らない、って話だろうが
311デフォルトの名無しさん:2008/06/06(金) 11:38:15
だから上二つは上手くいく保証がないってことだろ
312デフォルトの名無しさん:2008/06/06(金) 20:05:28
上3つでねーの
313デフォルトの名無しさん:2008/06/06(金) 22:02:13
memset() の第2引数が定数の0だと本当にビットパターンが0になるの?
bzero() がもともとそういう仕様だから確実じゃない?
314デフォルトの名無しさん:2008/06/06(金) 22:09:41
>>313
もちろん。関数の引数は常に値渡しだ。
ということは memset() が受け取った値0は必ず変数に代入されて処理される。
変数0がヌルポインタに変換されることは絶対にない。
315デフォルトの名無しさん:2008/06/06(金) 22:25:46
> void *memset(void *s, int c, size_t n);
> memset() は s で示されるメモリ領域の先頭から n バイトを c で埋める。

man にはこれくらいしか書いていないけど、c が int だと意味が分かりにくい。
一旦 c が char に変換されてから n バイト書き込むということか?
316デフォルトの名無しさん:2008/06/06(金) 22:42:53
1の補数表現を許しているから
"0"が"+0"や"-0"という場合があって
それで(charにして)埋めた場合にどうか、という話だろうな。

俺は知らん。
317デフォルトの名無しさん:2008/06/06(金) 23:38:36
>>316
考えにくいけど、もし通常の定数0が-0だったとしても、
ヌル文字が全ビットゼロであることが保証されているから、
少なくとも文字定数\0は全ビット0のはずだね
というわけでmemsetでゼロクリアするときは\0を使おう
318デフォルトの名無しさん:2008/06/06(金) 23:43:20
なんでわざわざ難しく考えるんだ?
実際、仕事でプログラムを作るときは仕様などを考えることに
時間を割くのに、お前達はコーディングに時間を割きそうだな。
319デフォルトの名無しさん:2008/06/06(金) 23:48:20
プログラム板で仕様を語ってどうするよ
ここはガチ規格スレだぜ
320デフォルトの名無しさん:2008/06/07(土) 00:54:09
糞仕様書のせいでコーディングに時間を割かなければいけないことならよくあります。
321デフォルトの名無しさん:2008/06/07(土) 13:04:29
>>311
違う。
上手くいかない保証があるってことだ。
322デフォルトの名無しさん:2008/06/07(土) 13:06:28
>>317
通常の整数定数0の全ビットが0であることも保証されていると記憶しているが。
323デフォルトの名無しさん:2008/06/07(土) 13:11:35
定数の全ビットが0でもメモリに記憶されたときもそうなるの?
324デフォルトの名無しさん:2008/06/07(土) 14:10:15
>>321
上手くいかない保証って...、なんだそりゃ。
325デフォルトの名無しさん:2008/06/07(土) 17:28:14
>>323
ならなかったらビット演算で死ねるだろ
326デフォルトの名無しさん:2008/06/07(土) 18:22:05
メモリ上でどうなっていても演算の結果が正しければいいんだよ。
327デフォルトの名無しさん:2008/06/07(土) 21:29:54
C で言う所のメモリ上のビット配列ってのは
整数型の変数でビット演算によって参照できる値だっしょ。
328デフォルトの名無しさん:2008/06/08(日) 14:47:38
C89で、名前は同じで引数の有無や個数が異なるマクロを複数定義することって認められてたっけ?

つまり、
#define A 0
#define A(x) x
329デフォルトの名無しさん:2008/06/08(日) 14:52:31
前スレで話が出て、できるってことだったような
330デフォルトの名無しさん:2008/06/08(日) 15:12:28
gcc でエラーになるけど。
331デフォルトの名無しさん:2008/06/08(日) 15:14:47
>>329
情報d
前スレ見てきたところ、同じ名前のマクロを同時に複数定義することはできないと書いてあったわ。
332デフォルトの名無しさん:2008/06/08(日) 15:53:16
>>331
ごめん完璧まちがって記憶してたわ
333デフォルトの名無しさん:2008/06/08(日) 16:17:14
ここにいる人って、アプリ屋?それともファーム屋?
なんか、話だけを見ると、アプリ屋のほうが多いような気が・・・
334デフォルトの名無しさん:2008/06/08(日) 16:20:07
>>333 その区別に何の意味がある?区別のしかたもよくわからんしな。
335デフォルトの名無しさん:2008/06/08(日) 17:53:26
まるでファーム屋が多くて然るべきだと言いたげに読めるのは、俺の日本語力が弱いせいですか?
336デフォルトの名無しさん:2008/06/08(日) 18:12:04
スレ違いだと思う
337デフォルトの名無しさん:2008/06/08(日) 19:18:53
ファーム屋(笑)
338デフォルトの名無しさん:2008/06/08(日) 19:21:21
マ板でやれ
339デフォルトの名無しさん:2008/06/08(日) 19:42:49
俺はいわゆるファーム屋だが、
アプリ屋>>>>>ファーム屋
という印象がある。
はっきりいって、組込みソフト開発者はC言語と少しのハードウェア知識があれば、
あとは、仕様理解で仕事ができる。

様々な新しい技術を吸収し、開発しているアプリ屋のほうが技術は高い。
340デフォルトの名無しさん:2008/06/08(日) 20:34:39
組み込み系のスレあたりを見てる印象だと、
組み込み屋には実装至上主義で、仕様ナニソレ、という雰囲気がある。

このスレにいるのは、なんちゃってであっても自分で処理系を書いたり
したことがあるような、アプリよりはシステム寄りの人が多いんでは?
341デフォルトの名無しさん:2008/06/08(日) 21:19:06
そりゃ偏見だ。
アプリ屋だろうがファーム屋だろうが底辺を見ればやっぱり底辺。
上をみればちゃんとしたひとも居る。

ただ、ちゃんとしたアプリ屋がシステム方面に行ってしまうのと同様に
ちゃんとしたファーム屋はハードに行っちゃう事が多い。
342デフォルトの名無しさん:2008/06/08(日) 21:33:49
最近組み込みは年々ハードが高性能化、開発サイクルの短期化で、
少人数の職人的な開発者での開発は限界に来てますよ

これからはアプリに近い開発方法論でやっていこうという欧米の流れ
343デフォルトの名無しさん:2008/06/08(日) 22:49:36
>>339
> 様々な新しい技術を吸収し、開発しているアプリ屋のほうが技術は高い。

新しい技術って Ajax とか Web 2.0 とかのこと?

まあ、そう言う新しい言葉を理解するのも技術力のひとつではあるが。
344デフォルトの名無しさん:2008/06/08(日) 23:12:15
…(^^;;
345デフォルトの名無しさん:2008/06/08(日) 23:54:00
>様々な新しい技術を吸収し、
訳:新しくリリースされたアプリの使い方を覚えて、
346デフォルトの名無しさん:2008/07/02(水) 21:38:00
アプリ屋の俺から言わせてもらえば、
 アプリ屋→頭ゆるゆるで使えない奴が多い
 ファーム屋→頭かたすぎて使えない奴が多い
347デフォルトの名無しさん:2008/07/02(水) 22:09:04
自称技術者の93.2%は使えないから、そんなもんhだろう。
348デフォルトの名無しさん:2008/08/06(水) 14:15:43
int a = 3; { int a = a; printf( "%d", a ); }

このとき表示される数字は 3 ですか?それとも不定ですか?
JIS X 3010-1993 を少し読んだんですが分かりませんでした。
349デフォルトの名無しさん:2008/08/06(水) 14:22:43
>>348
規格を見ずに gcc でテストしてみたところ
2147344384
と出力された
350デフォルトの名無しさん:2008/08/06(水) 14:47:43
>>349
規格的には不定だよ. {} の中では新たなスコープが有効になるので
{} 内の a が 宣言された瞬間に {} 外の a は shadow される
# 言い方が厳密じゃないんだけど、言いたいこと分かってね

Lisp 系言語の
(let ((a 3)) (let ((a a)) (???? a))) ==> (let ((a 3)) (lambda (a) (??? a)) a)
みたいな物を, 求めてはいけない
351349 (>>348 じゃないよ):2008/08/06(水) 14:56:08
>>350
こういうのはOKですか?
int a = 3; { int b = a; int a = b; printf( "a=%d b=%d", a, b ); }
352デフォルトの名無しさん:2008/08/06(水) 15:01:52
>>351 いや、だから…
言い方が悪かったのかorz
{} 外の名前が {} 内で宣言されたら shadow される

処理系によっては「{} 外の a」が意味をなす場合もあるかも知れないが
可搬なプログラムを書こうと思ったら、その事実に依存してはならない
353349:2008/08/06(水) 15:07:08
>>352
規格では変数の宣言順序に関係なく
同一スコープ内で同名の変数が現れた場合には
外側の変数は見えなくなる

だから >>351 は次のようにしないと動作の保証ができないということですね
int a = 3; { int b = a; { int a = b; printf( "a=%d b=%d", a, b ); } }
354デフォルトの名無しさん:2008/08/06(水) 16:13:40
JIS X 3010-1993 には以下のように書いてあるけどこれからは判断できなかった。

6.1.2.1 識別子の有効範囲
識別子は、有効範囲(scope)と呼ぶプログラムテキストの範囲にあるときだけ、可視(visible)
(すなわち、使用可能)とする。有効範囲は、関数、ファイル、ブロック、及び関数原型の4種類とする。

識別子を宣言する宣言子又は型指定子がブロック内又は関数定義の仮引数宣言子の並びに現れる場合、
その識別子はブロック有効範囲(block scope)をもち、その範囲は対応するブロックを閉じる}によって
終了する。

字句的に同一な識別子のより外側の宣言が同一の名前空間にある場合、外側の宣言は現在の
有効範囲が終了するまで不可視となり、その後再び可視となる。

二つの識別子は、有効範囲が同じ場所で終わる場合、そしてその場合に限り同じ有効範囲を持つ。
355デフォルトの名無しさん:2008/08/06(水) 16:48:27
そうか?
はっきり書いてあると思うんだが。
356349:2008/08/06(水) 23:17:37
>>354 を読んで解釈のひとつとして

int a, *p=&a; // これは OK
int *q=&b, b; // これは NG

ということは有効範囲とは変数の宣言順序によって変化するのではないか?
>>351 の int b=a; の時点ではブロック内で変数 a が未定義であるため
外側の a が可視だから動作が保障されるのでは?
357デフォルトの名無しさん:2008/08/06(水) 23:58:57
いや、shadowされているが未定義である状態。
358349:2008/08/07(木) 00:23:41
>>357
>>354 のこの部分
>識別子を宣言する宣言子又は型指定子がブロック内又は関数定義の仮引数宣言子の並びに現れる場合、
>その識別子はブロック有効範囲(block scope)をもち、その範囲は対応するブロックを閉じる}によって
>終了する。

これは有効範囲の終わりについてのみ言及しており、
変数自体は変数宣言以降から有効になるのではないの?
359デフォルトの名無しさん:2008/08/07(木) 00:29:19
だからそういっているんだが。
360349:2008/08/07(木) 00:52:52
shadow されるのは
1.同一変数名の定義されているブロックの開始部分からなのか
2.それとも同一変数名が宣言された後なのか

というところで 2 で解釈可能では?

ちなみに下記のコードで gcc および Borland C++ Compiler では、警告も無し

// 出力結果は a=2.000000 *p=3 が保障される?
#include<stdio.h>
int main(){
int a=3;

{
int *p=&a;
double a=2.0;
printf("a=%f *p=%d\n", a, *p);
}
return 0;
}
361349:2008/08/07(木) 01:15:04
>>360
int *p=&a;
の行が規格としては
1.エラーになるべきか
2.未定義(実装依存、鼻から悪魔)か
が知りたいのですが

>>357 さんは 2 ということでしょうか?
362349:2008/08/07(木) 01:16:35
>>361 に追記
3.定義済み (>>360 のコードは規格に沿っている)
363デフォルトの名無しさん:2008/08/07(木) 01:17:28
ISO の、ダウンロードできるドラフトでは >354 が引用した部分の直後にスコープの開始位置に
ついての説明があった。それによると、変数名のスコープが始まるのは変数宣言内の変数名の
直後。

ってことで >351 は OK 。
364349:2008/08/07(木) 01:20:49
>>363
ありがとうございます
スッキリしました
これでゆっくり眠れます
365デフォルトの名無しさん:2008/10/16(木) 08:59:54
真偽値は非ゼロとゼロ、というのは環境依存でしょうか
それとも規格上間違いなく非ゼロが真、ゼロが偽でしょうか
366デフォルトの名無しさん:2008/10/16(木) 10:34:25
規格上決まってる
367デフォルトの名無しさん:2008/10/16(木) 12:29:25
>366
ありがとうございます
368デフォルトの名無しさん:2008/11/16(日) 23:28:03
http://pc11.2ch.net/test/read.cgi/tech/1225320579/951-

int main(){/* ... */}が標準準拠かどうか揉めてます
識者の見解をお願いします
369デフォルトの名無しさん:2008/11/17(月) 00:03:47
>>368
X 3010:2003 (ISO/IEC 9899:1999)より抜粋
> 5.1.2.2.1 プログラム開始処理 プログラム開始処理において呼び出される関数の名前は,main とする。
> 処理系は,この関数に対して関数原型を宣言しない。この関数は,次の4 種類の方法のいずれかで定義し
> なければならない。
> − 返却値の型int をもち仮引数をもたない関数
> int main(void) { /* ... */ }
> − 二つの仮引数をもつ関数(仮引数は,これらが宣言された関数に対して局所的であるため,どのよう
> な名前を使用してもよいが,ここではargc 及びargv とする。)
> int main(int argc, char * argv[]) { /* ... */ }
> − 上に掲げた二つの方法のいずれかと等価な方法(9)
> − 上に掲げた三つの方法のいずれでもない処理系定義の方法

最後の処理系定義(文書化)が遵守されている処理系において厳密でないほうの規格合致プログラムだな
370デフォルトの名無しさん:2008/11/17(月) 00:10:42
Cでは基本的に () と (void) は異なるが、
関数定義においては同じとされていたはず。
GCC ではそうなってなかった気はするが・・・。
371デフォルトの名無しさん:2008/11/17(月) 00:40:22
そもそも組込みには必ずしもmain()はない・・・というのはここでは禁句かな?
しかし、いくらC言語の規格に準拠していても、MISRAに準拠していないと言うことで
プログラムの作りかえをさせられるのはウザイ・・・
逸脱手順を書くのもウザイ・・・
372デフォルトの名無しさん:2008/11/17(月) 22:48:37
>>368
言いだしっぺです。
int main() が標準準拠かどうか?でもめているのではなく、(そういうことならいうまでもなく標準準拠に決まっています。)
int main(void) を標準としたのは馬鹿じゃないの?ということです。
昔 fj でもめたのを受け売りしただけですね、はい。
373デフォルトの名無しさん:2008/11/17(月) 22:53:25
>>372
main() は K&R 準拠だろ
374デフォルトの名無しさん:2008/11/17(月) 23:32:05
>>371
ホスト環境とスタンドなんとか環境ですね
375デフォルトの名無しさん:2008/11/19(水) 03:21:32
>>372
int main(void) 以外の何を標準にするべきで、そうすると何がうれしいと思ってるの?
376デフォルトの名無しさん:2008/11/19(水) 05:04:56
>>375
int main(void) は削除するのがいいでしょうね。
int main() という書き方が現在でも有効であるのに、なぜわざわざ int main(void) というセンスのない書き方をまかり通すのか理解に苦しみます。
そのこころは、つhttp://pc11.2ch.net/test/read.cgi/tech/1225320579/962
377デフォルトの名無しさん:2008/11/19(水) 08:41:44
こちらは将来的に削除される予定
> int main()
378デフォルトの名無しさん:2008/11/19(水) 11:05:40
>>376
リンクされたスレは既に dat 落ちで見れない。
379デフォルトの名無しさん:2008/11/19(水) 12:25:34
>>376
センスがないって、どのように?
380デフォルトの名無しさん:2008/11/19(水) 18:55:51
(void)にセンスがないというのは理解できる。
空の()で引数がないことを表すことにしたC++の英断は素晴らしい。
381デフォルトの名無しさん:2008/11/19(水) 18:58:42
Cの方は過去のしがらみもあったしな
382デフォルトの名無しさん:2008/11/19(水) 20:11:19
くだらねぇぇぇぇ
383デフォルトの名無しさん:2008/11/19(水) 20:17:17
引数チェックのない時代の名残だからな。
384デフォルトの名無しさん:2008/11/19(水) 21:03:20
>>379
呼び出し側は引数の有無にかかわらず同じだったとしたら、呼び出し側の実際と違う宣言をなんの躊躇もなく記述するところ。
385デフォルトの名無しさん:2008/11/19(水) 21:07:22
>>384
main の呼び出し側はスタートアップ関数であって、
スタートアップ関数はコンパイラが提供するものだろ・・・。
386デフォルトの名無しさん:2008/11/19(水) 22:13:58
>>384
呼び出し側の実際の宣言は何だと思っている?
387デフォルトの名無しさん:2008/11/19(水) 22:52:01
ソースコード側でC言語の管轄外の世界に勝手な仮定置いちゃダメだろ
標準的に考えて
388デフォルトの名無しさん:2008/11/19(水) 23:08:45
>>387
プログラム開始処理(program startup)が main を呼ぶ事は
5.1.2.2.1 プログラム開始処理 に規定されている。
389デフォルトの名無しさん:2008/11/19(水) 23:09:40
きっとOSが「いんとめいんかっことじかっこ…」とかコマンド打ち込んでると思ってるんだろう
390デフォルトの名無しさん:2008/11/19(水) 23:14:16
>>388
プログラム開始処理がmainを呼ぶ時に引数をチェックしないなんて規定されてたっけ
391デフォルトの名無しさん:2008/11/19(水) 23:18:19
>>390
多分お前の話したい奴は別の奴だ。
392デフォルトの名無しさん:2008/11/19(水) 23:24:13
スタートアップ処理はコンパイラが用意するから
main がどうなっていようと良きに計らってくれるっしょ。
393デフォルトの名無しさん:2008/11/19(水) 23:58:18
main関数の定義でint main()と書いてるんだから
引数なし以外ありえない。
関数宣言での引数省略と勘違いしてるんだろうね
394デフォルトの名無しさん:2008/11/20(木) 00:07:12
>>385
スタートアップ関数は引数の有無にかかわらず同じだったとしたら、スタートアップ側の実際の違う宣言を躊躇なく記述することに疑問を感じています。
395デフォルトの名無しさん:2008/11/20(木) 00:10:41
>>386
実際のところ、
int main(int argc, char **argv, char **env)
でしょうか。私のところの某処理系では環境変数がコンパイル時スタックをつぶしてしまうので可能なときは再コンパイルしていました。
これってヘッダをさわっただけではどうにもならなかったですよね。
396デフォルトの名無しさん:2008/11/20(木) 00:11:12
>>387
だから int main() なのでは?
397デフォルトの名無しさん:2008/11/20(木) 00:12:11
>>389
某処理系のfork()やexec*()の存在くらいは知っています。
398デフォルトの名無しさん:2008/11/20(木) 00:12:42
>>392
それはそうですね。
399デフォルトの名無しさん:2008/11/20(木) 00:14:51
>>393
それはそうですね。
コンパイラ側が勝手に stdcall をデフォルトとしている世界であれば、逆に int main(void) でないと困るのかもしれません。
んー ms-pascal?
400デフォルトの名無しさん:2008/11/20(木) 00:29:00
>>390
プログラム開始処理が main() のために引数を整えている、と理解していますが、実際のところは誰がしているのでしょうか?
401デフォルトの名無しさん:2008/11/20(木) 00:33:38
>>400
ご明察の通り、スタートアップルーチンがお膳立てします。
402デフォルトの名無しさん:2008/11/20(木) 00:39:02
osとcrt
403デフォルトの名無しさん:2008/11/20(木) 00:41:42
>>376
実は main は関係無くて、引数無しの関数の引数リストが void なのが不満なだけなのか?
404デフォルトの名無しさん:2008/11/20(木) 00:42:51
不満なら書かなきゃいいだけの話では?
405デフォルトの名無しさん:2008/11/20(木) 00:43:24
>>394
>スタートアップ関数は引数の有無にかかわらず同じだったとしたら、

その仮定がおかしい
406デフォルトの名無しさん:2008/11/20(木) 00:47:08
実際同じじゃね?
呼び出し側で積んだ引き数は、呼ばれた側が無視しても全く問題ないわけだし。

例えばint func() {return 0;}という関数を宣言なしでfunc(0)と呼ぶときと事情は変わらない。
407デフォルトの名無しさん:2008/11/20(木) 00:51:44
>>402
os? shell ではないのですか?
というか shell と crt との役割分担は?あー ms-dos以外の場合で、てことで。
408デフォルトの名無しさん:2008/11/20(木) 00:53:54
>>405
ん、たしかに stdcall がデフォルトのコンパイラがあったとしたら、その場合スタートアップ関数は int main(int c, char **v) と int main(void) とでは異なるでしょうね。
409デフォルトの名無しさん:2008/11/20(木) 00:54:44
>>403
ん、そです。
410デフォルトの名無しさん:2008/11/20(木) 00:55:48
>>409
すると、>406のようなfuncも気に入らないと。

>>408
>406
411デフォルトの名無しさん:2008/11/20(木) 01:00:18
>>410
int func(void) {return 0;}と書いておきながら、func(0)と呼ぶのが気に入らないだけなんですが。
412407:2008/11/20(木) 01:01:11
>>402
shell の末尾は exec*() でしたね。失礼しました。
413デフォルトの名無しさん:2008/11/20(木) 01:06:17
>>409
古い(規格化以前?の) C では、引数リストが空の関数宣言は引数の数や個数を指定せずに
関数を宣言するものとなっていた。規格化にあたってそういった過去のコードを不正としないように
配慮した。そういうことだと思う。規格を決めた人が馬鹿だったわけじゃないでしょ。
414デフォルトの名無しさん:2008/11/20(木) 01:30:17
>>413
そうではなくて、
func() に必要な引数はないけれども、func(0, 1, 2, 3 ... ) と呼び出さざるを得ない状況で
func() の宣言をどうするか?
という問題です。
このとき、int func(void) と宣言するのは、
すっごくやです。
415デフォルトの名無しさん:2008/11/20(木) 01:41:31
int func(...);
416デフォルトの名無しさん:2008/11/20(木) 01:45:50
>>415
%gcc test.c
test.c:3 error: ISO C requires a named argument before ...



417408:2008/11/20(木) 02:18:24
>>410
>>408
> >406
ん?stdcall はreturn時に呼び出され側でスタックを払うから、呼び出し側は呼び出され側の引数を完全無欠に知っておかなければならないかと。
418デフォルトの名無しさん:2008/11/20(木) 02:53:28
>すっごくやです。
し ら ね え よ
419デフォルトの名無しさん:2008/11/20(木) 03:10:51
>>414
> func() に必要な引数はないけれども、func(0, 1, 2, 3 ... ) と呼び出さざるを得ない状況で

>416 のとおり、そういうことはできないことになっている。
420デフォルトの名無しさん:2008/11/20(木) 03:14:04
>>418
論理的な思考の根源には、ある種の好き嫌いの視点からの判断が含まれることも多々あるのですが、
お気に召さないのであれば、いいなおしましょうか。
「int main(void)は、main() の呼び出し側に思いを馳せていない、という点で、規約としては問題があるかと思います。」
421デフォルトの名無しさん:2008/11/20(木) 03:21:36
>>419
いいえ、>>416 は、
不定長引数の場合はすくなくとも一つの引数には名前がついていなければならない、と述べているにすぎません。
コンパイル単位が別であれば、
int func(void) { return 0; }
に対して、
func(0, 1, 2, 3, 4, 5, 6, 7)
を呼び出すことは可能です。リンカもエラーは吐きません。
422デフォルトの名無しさん:2008/11/20(木) 03:30:19
>>420
なら、main(void)用とmain(int argc, char **argv)用のスタートアップルーチンを用意して、
プログラムに合うように選択する処理系があったらint main(void)でも構わないのか?

……自分で書いていて詭弁のガイドラインに抵触するような気がしてきた。
423デフォルトの名無しさん:2008/11/20(木) 03:33:37
>>421
あるコンパイル単位では int func(int a, ...) と宣言して、別のコンパイル単位で
int func(void) で定義するってこと?

それなら未定義動作だよ。コンパイルできてもリンクできても議論に値しない。
424デフォルトの名無しさん:2008/11/20(木) 04:03:29
>>423
正確には、あるコンパイル単位では int func(void) と定義しておいて、
別のコンパイル単位から func(0, 1, 2, 3) と呼び出します。
未定義であることの記述があれば教えてください。

というより、cdecl と stdcall の話は処理系依存といえますから、この手の話が規約に載ることもないでしょう。
でも stdcall ならば可変長引数は困難ですし、でも cdecl/stdcall の話が可変長引数に絡むし、そして可変長引数は定義されていますし、
実装によっては不可能な仕様というものでも定義されているのは、どういうことなのでしょうか?

それはそうと、ほとんどのコンパイラでは、スタートアップと main() とのリンクは、上述のようになっているのですが‥‥‥。
425デフォルトの名無しさん:2008/11/20(木) 04:04:22
>>422
そういうことになります。お目にかかったことはありませんが、完全無欠のstdcall仕様のコンパイラがあれば。
426デフォルトの名無しさん:2008/11/20(木) 04:12:55
>>424
「別のコンパイル単位」では宣言無しで呼び出すってことか。
どっちにしても未定義動作だけどな。

6.5.2.2 Function calls p6 より
> 6 If the expression that denotes the called function has a type that does not include a
> prototype, ...
(snip)
> If the number of arguments does not equal the number of parameters, the
> behavior is undefined. If the function is defined with a type that includes a prototype, and
> either the prototype ends with an ellipsis (, ...) or the types of the arguments after
> promotion are not compatible with the types of the parameters, the behavior is undefined.


ちなみに、スタートアップと main() とのリンクについては処理系ごとに好きにすればいい話で、
引数リストとかもう関係ない。
427デフォルトの名無しさん:2008/11/20(木) 04:25:55
>>426
なるほど。
これを見る限り、可変長引数も「実は未定義」なんでしょうか?んー、prnitf() はどうなるのでしょうか?

>スタートアップと main() とのリンクについては処理系ごとに好きにすればいい話
それでは、なおさら、int main(void) を標準的な記法として盛り込むの問題かと。int main(void) は現実から乖離しています。いらない子です。
428デフォルトの名無しさん:2008/11/20(木) 04:35:26
>>427
可変長引数は ... を含むプロトタイプ付き関数として定義されている。

main() とのリンク方法が処理系依存でも、処理系に食わせるプログラム自体は
移植性を持つ必要がある。全然関係ない話。

main() の話がしたければ >>375 の質問に対して主観を排除した答えを出せ。
429デフォルトの名無しさん:2008/11/20(木) 06:46:29
>>428
ん?引用された文章をみると、
> If the function is defined with a type that includes a prototype, and
> either the prototype ends with an ellipsis (, ...) or
(略)
> the behavior is undefined.
だから「... を含むプロトタイプ付き関数」すなわち可変長引数の振る舞いは "undefined" なのでは?

> 処理系に食わせるプログラム自体は移植性を持つ必要がある。
おっしゃる意味がよくわかりません。移植性をもたせることと int main(void) の表記とどのような関係があるのでしょうか?

>主観を排除した
ではhttp://pc11.2ch.net/test/read.cgi/tech/1225320579/962を再掲します
>> c でよく採用された実装では、呼び出され側のコードは、呼び出し側の引数の個数や種類に依存しない、というもの。....※
>> 個々の関数は翻訳単位を別にとることが可能ですよね。無論、呼び出し側・呼び出され側の引数のチェックがあればそれにこしたことはないのですが。
>> で、main() についても呼び出し側でなんらかの仮定があり、それに対応して main() 記述側で記述するわけです。
>> ※によりmain() 呼び出し側は main() の記述側で必要な引数がどうであれ、常に同じものがリンクされるといっていいと思います。
>> そうであれば、main(void) と書くのは、main() 呼び出し側の仮定と食い違う書き方をしているわけですね。

>主観を排除した
主観がふくまれていたからといって意見として劣るわけではありますまい。そもそも主観・客観ってなんですか?
430デフォルトの名無しさん:2008/11/20(木) 06:49:01
>そもそも主観・客観ってなんですか?
バカじゃねぇの?
431デフォルトの名無しさん:2008/11/20(木) 06:54:28
コンパイラは int main(void) を見つけたときと int main(int argc, char* argv[]) を見つけたときで
スタートアップルーチンを自由に変えることが可能。
432デフォルトの名無しさん:2008/11/20(木) 06:57:56
>>429
君が略した部分を飛ばして読むとそう読めるね。
なんて都合のいい引用の仕方。ふう。
433デフォルトの名無しさん:2008/11/20(木) 10:25:35
>>427
スレタイ読めないの?
初心者お断りだよ
434デフォルトの名無しさん:2008/11/20(木) 10:59:56
main() の呼び出しが通常の関数呼び出しと同じだと思いこんでるのが間違いなんだな。
435デフォルトの名無しさん:2008/11/20(木) 12:02:00
>>429
> 移植性をもたせることと int main(void) の表記とどのような関係があるのでしょうか?

main() の引数リストについて移植性を保証できる表記を定めることに意味があるということ。

スタートアップからの呼び出し方法が自由だからといって main() の引数リストについて
何の規定もおかないでいると、移植性を保証することができない。

そして引数無しと2引数のものが移植性を保証できるものとして選ばれた。引数無しの
ものの記法については >413 のとおり。
436デフォルトの名無しさん:2008/11/20(木) 17:21:26
>>422
それが本当は正道なはずだな
437デフォルトの名無しさん:2008/11/20(木) 18:47:05
test
438デフォルトの名無しさん:2008/11/20(木) 19:17:09
>>434
全くだ。
そこは既にCの規格の範疇外の話だ。
439デフォルトの名無しさん:2008/11/20(木) 21:22:24
>>431
確かにそのような手はあると思います。完全にstdcall なコンパイラならそうするしかないでしょう。
>> http://pc11.2ch.net/test/read.cgi/tech/1225320579/951
>>399 >>408
440デフォルトの名無しさん:2008/11/20(木) 21:23:55
>>432
え?ether A or B の B を略しただけですが?
B を略するかしないかで大きく意味が変わる文章なんですか?
441デフォルトの名無しさん:2008/11/20(木) 21:24:28
>>433
どこが初心者だと感じたのか、詳細を記述いただければ幸いです。
442デフォルトの名無しさん:2008/11/20(木) 21:31:37
>>435
移植性を保障するためにある一定の枠組みを定めておくところについては同意いたします。しかし、
私見では、
int main(int, char **)
のみで十分と思われるのですが、あえて
int main(void)
を規定した意味については、どう考えておられるのでしょうか。
皆さんと私との意見の違いは、この部分にあると考えておりますので、差し支えなければ教えてください。

stdcall/cdecl あるいは別の呼び出し規約も視野にいれて規定されたのであれば、私としても依存はありません。
>>http://pc11.2ch.net/test/read.cgi/tech/1225320579/951
443デフォルトの名無しさん:2008/11/20(木) 21:32:08
444デフォルトの名無しさん:2008/11/20(木) 21:33:31
>>438
ん?main() といえども、他の関数と同じ、というのがもともとの心なのでは?
単にスタートアップコードから呼ばれる、というだけで。
#main() を recursive call するのは、違反でしたっけ?
445デフォルトの名無しさん:2008/11/20(木) 21:36:31
446デフォルトの名無しさん:2008/11/20(木) 21:44:05
>>400
are not compatible with the types of the parameters
を略するなよ。おまえ、構文が読み取れてないだろ。
447デフォルトの名無しさん:2008/11/20(木) 21:52:52
>>444
再帰しようが、別にそのプログラム中でつじつまが合っていれば問題なかろう。
448デフォルトの名無しさん:2008/11/20(木) 21:54:43
>>442
引数使わない時にまで引数書くのめんどくせーじゃん。
449デフォルトの名無しさん:2008/11/20(木) 21:56:29
そもそも何で呼び出し規約が関係するんだよ・・・。
最悪スタートアップルーチンを main によって変えれば済むだけの話じゃん。
450429:2008/11/20(木) 21:57:52
>>446
私は、元の引用文を
If 
1) the function is defined with a type that includes a prototype, and
2) either 2.a) the prototype ends with an ellipsis (, ...) 
   or 
          2.b) the types of the arguments after promotion 
               are not compatible with the types of the parameters, 
the behavior is undefined.
と考えましたが間違っているのでしょうか?
差し支えなければ、あなたの解釈を教えてください。
451デフォルトの名無しさん:2008/11/20(木) 21:59:48
>>449
だからそれはすでに述べられ済み。
http://pc11.2ch.net/test/read.cgi/tech/1225320579/951
452デフォルトの名無しさん:2008/11/20(木) 22:06:24
>>449
呼び出し規約、具体的には stdcall と cdecl とではスタックを払うのが呼び出し側か呼び出され側にあるか、という違いがあります。
すなわち、呼び出し側で仮定した引数と呼び出され側で仮定した引数とが異なってもよいか、それとも完全に一致しなければならないか、という違いを意味します。
スタートアップコードが main() を呼ぶときにスタックに積む引数と、main() がスタックに積んであると仮定している引数とが一致しなくてもいいのか、それとも一致しなければならないか、ということです。
stdcall では main() がスタックを払うので、両者は一致しなければなりません。
453デフォルトの名無しさん:2008/11/20(木) 22:08:01
>>448
その論法でいけば、引数がないときには
int main()
とすれば、もっと楽ではないでしょうか。
454デフォルトの名無しさん:2008/11/20(木) 22:25:32
どうでもいいけどおまえら2chのレスをソースにするなよwww
455デフォルトの名無しさん:2008/11/20(木) 22:32:51
一体何を問題に従ってるのかさっぱりわからん
456デフォルトの名無しさん:2008/11/20(木) 22:33:42
読んでて混乱するから以前の自分の発言を話の前提にしたいならレス番を名前に入れろ
457デフォルトの名無しさん:2008/11/20(木) 22:36:53
>>451
何度dat落ちしたスレのアドレスを張る気だ
458デフォルトの名無しさん:2008/11/20(木) 22:47:16
頑張って読んだ

要するにお前の主張は
「int main(void)って書くの気持ち悪い!気持ち悪いよねお前らもそう思うだろ!!」
だな?

じゃあそれに対する答えは
「規格が許してるんだから書きたいやつが書いて何も問題ねえしお前の好みなんか知るかボケ」
だよ
459デフォルトの名無しさん:2008/11/20(木) 23:00:06
呼び出し規約とか関係ねぇから
460デフォルトの名無しさん:2008/11/20(木) 23:02:42
>>452
main を見てスタートアップコードを作るんだろ・・・。
何で先にスタートアップコードがあるんだよ。
バカかよ。
461デフォルトの名無しさん:2008/11/20(木) 23:03:55
voidって空って意味だから、int main(void)って書いて
引数リストが空だってことを明示している方がわかりやすい。
int main()だと、引数リストがvoidなのかdon't careなのか不明確。

int main(void)が気持ち悪いってやつは英語のセンスがないんだろうね
462デフォルトの名無しさん:2008/11/20(木) 23:05:03
>>453
規格上はそれで問題ない。
関数定義での () は (void) と規格上は等価だから
(関数原型ではもちろん () と (void) は別だが)。
でも、その規格に準拠していないコンパイラがあるから
已む無く (void) をつけているに過ぎない。
463デフォルトの名無しさん:2008/11/20(木) 23:10:15
>>457
dat落ちしてるなら内容も貼って欲しいよね。

http://pc11.2ch.net/test/read.cgi/tech/1225320579/951
951 名前:デフォルトの名無しさん[sage] 投稿日:2008/11/16(日) 21:46:28
>>949
個人的には、int main(void); という書き方に不満があります。私なら int main(); とします。でも、cdecl でも stdcall でも通用するようにしたいのでしょうけれども。
464デフォルトの名無しさん:2008/11/20(木) 23:11:25
では採決します。

int main(void)が気持ち悪いと思う人いますか?
465デフォルトの名無しさん:2008/11/20(木) 23:12:16
気持ち悪くないが C++ やってると面倒くさいとは思う。
466デフォルトの名無しさん:2008/11/20(木) 23:12:49
>>456
発言したが私であることを特に問題にはしていないのですけれども。
467デフォルトの名無しさん:2008/11/20(木) 23:13:20
>>457
それはあなたの事情であって私の知ったことではありません。
468デフォルトの名無しさん:2008/11/20(木) 23:15:45
>>466
単発のレス読んでると何が言いたいかワカンネってんだよ
469デフォルトの名無しさん:2008/11/20(木) 23:17:42
>>458
main() に与えられる引数を使用しない場合に int main(void) と特に規定したのはどういう理由だろうか?
という点です。その理由が基本的によくわからない(ある程度の推測はあるにしても)し、普通の関数ではそんなふうには書かないので、
これは問題ではないか、ということを問題にしています。

規格そのものを問題にしている以上、「規格が許しているんだから」は答えにならないのは自明なのですが。
470デフォルトの名無しさん:2008/11/20(木) 23:17:53
>>468
あなたの理解力不足を人のせいにするのはやめてくれませんか?
471デフォルトの名無しさん:2008/11/20(木) 23:19:14
>>469
普通の関数でも void 書くだろ・・・。
472デフォルトの名無しさん:2008/11/20(木) 23:19:46
>>469
ダウト。
普通の関数でも引数リストでhoge(void)って使います。
473デフォルトの名無しさん:2008/11/20(木) 23:20:14
>>460
いいえ、スタートアップコードがあって、main() がそれにリンクするのです。
スタートアップコードを使い分けるにしても、それは同じこと。
大体スタートアップコードを使い分けているコンパイラがありますか?
そんな処理系は printf() をはじめとする可変長引数の関数が一切使えないのではないかと。
474デフォルトの名無しさん:2008/11/20(木) 23:20:19
>>469
          ,、‐ ''"  ̄ ``'' ‐- 、
        /イハ/レ:::/V\∧ド\
       /::^'´::::::::::::i、::::::::::::::::::::::::::::\
     ‐'7::::::::::::::::::::::::ハ:ハ::|ヽ:::;、::::::::::::丶
     /::::::::::::::/!i::/|/  ! ヾ リハ:|;!、:::::::l
    /´7::::::::::〃|!/_,,、   ,、==、、''`‐ly:::ト
      /|;ィ:::::N,、‐'゛_,,.\   !"r‐、ヽ  !;K
        ! |ハト〈  ,r''"゛  ,   ヽ゚,シ リイ)|
          `y't     ヽ'    ,,ィァ  //  
         ! ぃ、  ト─=ニニ‐ノ 〃
         `'' へ``'ー─‐‐'´,  .イ
              `i;、     / l
                〉 ` ‐ ´   l`ヽ
            / !        レ' ヽ_
         _,、‐7   i|      i´   l `' ‐ 、_
     ,、-‐''"´  ノ,、-、 / 、,_ ,.、- {,ヘ   '、_    `ヽ、_
   / i    ,、イ ∨ l.j__,,、..-‐::-:;」,ハ、 '、` ‐、_   ,`ヽ
  /  l ,、‐'´ // ',/!:::::::::;、--ァ' /  `` ‐   `'7゛   ',
475デフォルトの名無しさん:2008/11/20(木) 23:21:26
int foo(void)なんて喜んで書く人は、悪いけどプログラミングのセンスを疑いますよ
バカにしてるとさえ感じますね
コンパイラや保守者や、Cという言語に対しても
476デフォルトの名無しさん:2008/11/20(木) 23:22:12
>>472
あなたとは仕事をしたくない
477デフォルトの名無しさん:2008/11/20(木) 23:22:26
void 書かないと引数書き放題だろ・・・。
バカか、こいつ。
478デフォルトの名無しさん:2008/11/20(木) 23:24:44
>>461
引数を指定するのに呼び出し側を考慮しないのはどうかと思います。
それに、スタートアップで引数をスタックに積んでいる以上、main() の場合は do not care のほうが適当かと。

>英語のセンスが
英語のセンスなど別にどうでもいいです。
479デフォルトの名無しさん:2008/11/20(木) 23:25:17
>>463
恐縮です。
480デフォルトの名無しさん:2008/11/20(木) 23:25:48
>>475
アマチュアの方ですか?
CはC++みたく引数までシグネチャーに含んでくれないので、
型チェックはコンパイル頼みになるのです。
引数なしの関数をチェックさせるために(void)って書くんですよ。

まぁあなたみたいに一人でオナニープログラム書いている人には
関係ないでしょうが。
481デフォルトの名無しさん:2008/11/20(木) 23:26:38
>>473
使い分ける必要のある環境なら
main のあるソースをコンパイルする時に
自動的にそれに対応したスタートアップを追加するか、
あるいはリンカが main によってリンクするスタートアップコードを変えるか、
そういう実装になるはずだろう。
482デフォルトの名無しさん:2008/11/20(木) 23:27:20
>>471
「普通の関数でも 引数指定部分のvoid は好まない」とは一言ももうしあげておりません。
483デフォルトの名無しさん:2008/11/20(木) 23:27:37
>>478
まず、int main() { } の () は don't care ではなく void だ。規格上は。
484デフォルトの名無しさん:2008/11/20(木) 23:27:46
>>478
>それに、スタートアップで引数をスタックに積んでいる以上、
>main() の場合は do not care のほうが適当かと。
ダウト。
引数をスタックに積むとは限らない。
処理系依存。
485デフォルトの名無しさん:2008/11/20(木) 23:28:58
>>472
言葉が足りませんでしたね。
呼び出し側で引数を指定しているのに、コール先で引数なしとすることはないと思います。
これが呼び出し側:スタートアップ、コール先:main() であっても同じなのではないでしょうか?
486デフォルトの名無しさん:2008/11/20(木) 23:29:22
>>485
ダウト。
常に呼び出し側で引数を指定しているとは限らない。
487デフォルトの名無しさん:2008/11/20(木) 23:31:19
>>484
ん、広く範囲をとれば、それはそういうことになるとは思います。確かに引数をスタックに積むとはかぎりらないでしょうね。
488デフォルトの名無しさん:2008/11/20(木) 23:31:22
型チェックってのは1つ以上の引数を渡した時に、間違った型として扱わないために必要なのであって
もともと引数取らない関数にとってはどうでもいいことです
だいたい引数取らない関数に引数なんか渡したら誰だって間違いと気付きます

ちなみにC++が引数なし関数までシグネチャに含むのはデフォルト引数があるからです
489デフォルトの名無しさん:2008/11/20(木) 23:32:18
>>483
詳説を希望いたします。
490デフォルトの名無しさん:2008/11/20(木) 23:32:50
>>485
>呼び出し側で引数を指定しているのに、
>コール先で引数なしとすることはないと思います。
ダウト。
それはあなたの思い込み。
言語仕様上そういうことが可能ならば、間違いは必ずおきます。
プロならばそれを回避しようとするのは当然。
491デフォルトの名無しさん:2008/11/20(木) 23:32:53
>>488
コンパイラは間違いに気づきません。
コンパイラが気づかなかった事により、人間も気づかないかもしれません。
例えば引数の数を変えた時とか。
そもそも引数の数によって引数チェックが必要か必要ないかが変わることこそ気持ち悪い。
492デフォルトの名無しさん:2008/11/20(木) 23:33:47
>>489
>>462

何度も同じ事を言わせるな。
493デフォルトの名無しさん:2008/11/20(木) 23:33:56
引数をスタックに積まない実装など見たことがありません
今までに存在したとも思えないし、これから登場することも考えられません
(ネタやお遊びで作った実用性のない環境は知りませんよ)

規格の無意味な汎用性への配慮の産物がint main(void)という醜悪な構文なのです
494デフォルトの名無しさん:2008/11/20(木) 23:34:04
>>488
>だいたい引数取らない関数に引数なんか渡したら誰だって間違いと気付きます
んー、コンパイル単位を別にとれば、問題なくコンパイル/リンク可能で、かつ、大概の環境では問題もないのですが。
495デフォルトの名無しさん:2008/11/20(木) 23:35:04
>>488
>ちなみにC++が引数なし関数までシグネチャに
>含むのはデフォルト引数があるからです
ダウト。
C++にはオーバーロードがあるからです。
知ったかすんな
496デフォルトの名無しさん:2008/11/20(木) 23:35:23
>>492
これは申し訳ない。調べておきます。
497デフォルトの名無しさん:2008/11/20(木) 23:36:16
>>493
ヒント:ニンテンドーDS
498デフォルトの名無しさん:2008/11/20(木) 23:36:57
>>493
レジスタ渡しとかも普通にするだろ。
499デフォルトの名無しさん:2008/11/20(木) 23:37:06
>>491
そもそも間違って渡したから何だというのでしょう
引数に名前は付いてないので関数からは手出しできません
だから何かを壊すことはありません
せいぜい値渡しの無駄なコピーが何回か増えるだけです
型チェックのコストの方が高いという判断はありうることです
500デフォルトの名無しさん:2008/11/20(木) 23:37:54
なんだか釣りにしか見えなくなってきたな
501デフォルトの名無しさん:2008/11/20(木) 23:38:05
>>499
やっぱ引数欲しいや、って増やす事だってあるだろ。
その時に変な引数渡されるかもしれない。
502デフォルトの名無しさん:2008/11/20(木) 23:38:59
>>489
483じゃないが。

X3010:2003の6.7.5.3の中ほど。
> 並びの中の唯一の項目がvoid型で名前の無い仮引数であるという特別な場合、関数が仮引数を持たないことを指定する。
(中略)
> 関数定義の一部である関数宣言子で識別子並びが空の場合、関数が仮引数を持たないことを指定する。
> 関数定義の一部で無い関数宣言子の識別子並びが空の場合、仮引数の個数および型の情報がないことを指定する。

でもこれって、C99なんだよね。C89とか規格書持っていないから俺は分からない。
503デフォルトの名無しさん:2008/11/20(木) 23:39:40
>>495
オーバーロードはデフォルト引数が導入されてからずっと後にC++に取り込まれました
オーバーロードも理由の一つではありますが、そもそもはデフォルト引数です
そちらこそ知ったかはおやめ下さい
504デフォルトの名無しさん:2008/11/20(木) 23:40:15
>>499
>そもそも間違って渡したから何だというのでしょう
間違って"渡さない"場合もあるだろ。
そしたらクラッシュするよ。

>型チェックのコストの方が高いという判断はありうることです
型チェックのコスト?
コンパイル時だからコストなんてかかんないよ
505デフォルトの名無しさん:2008/11/20(木) 23:40:37
>>481
純粋な意味でのリンカがオブジェクトファイルを個別にチェックするのはちょっと考えられませんが。
昔の処理系では、生成したオブジェクトのほかスタートアップを陽にリンクするような方法も紹介されていました。(bccとか)
506デフォルトの名無しさん:2008/11/20(木) 23:41:02
>>499
引数の数が間違っているとリターンがうまくいかないstdcallやpascalのことも忘れないでください。
507デフォルトの名無しさん:2008/11/20(木) 23:42:17
>>505
なら前者を採用すればいい話だ。
508デフォルトの名無しさん:2008/11/20(木) 23:43:10
>>504
引数をとらない関数に引数を間違って渡すとはどういう事でしょうか
意味がわかりません

引数を1個とる関数は当然に型チェックが必要ですよ
その1個の引数に間違った型でアクセスしたら大変なことになりますからね
でも引数をとらない関数は、そもそも引数自体にアクセスが出来ないのです
アクセスできない所に何が積まれようと知ったことではないのです
509デフォルトの名無しさん:2008/11/20(木) 23:44:01
間違えました

>>504
引数をとらない関数に引数を間違って"渡さない"とはどういう事でしょうか
意味がわかりません
510デフォルトの名無しさん:2008/11/20(木) 23:45:14
>>502
感謝です。
では、特に int main(void) という規約は必要ないことになるのですが、なぜわざわざ int main(void) という書き方を規約としたのでしょうか?
int main(void) を陽に指定する必要はないと思われるのですが。
511デフォルトの名無しさん:2008/11/20(木) 23:45:56
>>505
int main(void)とint main(int argc, char **argv)でなくて恐縮だが、
VC++などでは、main/wmain/WinMain/wWinMainのどれが定義されているかによって、
リンクするスタートアップルーチンが変わるようになっている。
512デフォルトの名無しさん:2008/11/20(木) 23:46:15
>>510
int main(void) と等価な書き方も許されるから
int main() も規格合致。
513デフォルトの名無しさん:2008/11/20(木) 23:46:38
>>508
ばかだなぁ。
int hoge();
は、引数をとらないんじゃなくて、
どんな引数を渡してもいいって意味なんだよ。
わかる?
514デフォルトの名無しさん:2008/11/20(木) 23:47:46
>>513
それも意味的には違うな。
引数に関して何も関知しないってことだな。
() は (...) とは意味が違う。
515デフォルトの名無しさん:2008/11/20(木) 23:48:16
>>507
まあそれはそうですが、すでにその話は私のみならず他の方からも指摘されていたりするのです。>>422
516デフォルトの名無しさん:2008/11/20(木) 23:49:33
>>515
>>422>>481 と同じ主張だ。
517デフォルトの名無しさん:2008/11/20(木) 23:50:28
>>503
>オーバーロードはデフォルト引数が導入されてからずっと後にC++に取り込まれました
>オーバーロードも理由の一つではありますが、そもそもはデフォルト引数です
>そちらこそ知ったかはおやめ下さい
ダウト。
多重定義導入時にマングリングが導入された。
518デフォルトの名無しさん:2008/11/20(木) 23:50:47
>>511
それは、リンカを制御する上位構造があるから、ではありますね。そのへんは理解しているつもりです。
519デフォルトの名無しさん:2008/11/20(木) 23:51:18
なんでアホの好みの問題に振り回されてんの?
520デフォルトの名無しさん:2008/11/20(木) 23:52:07
>>519
暇だからw
521デフォルトの名無しさん:2008/11/20(木) 23:52:41
>>519
何か話題pls.
522デフォルトの名無しさん:2008/11/20(木) 23:53:28
>>518
>リンカを制御する上位構造があるから
523デフォルトの名無しさん:2008/11/20(木) 23:54:52
リンカオプションのことか
524デフォルトの名無しさん:2008/11/20(木) 23:55:03
ん、やっと自らの過ちに気づいたかな?
今頃顔真っ赤かな?
525デフォルトの名無しさん:2008/11/20(木) 23:55:39
そろそろISOにint main(void)の抹殺を嘆願する署名を集めてもよろしいでしょうか?
526デフォルトの名無しさん:2008/11/20(木) 23:56:15
どうやらヤツは壮絶に勘違いしてたようだね
>>508のレスが証拠だね
527デフォルトの名無しさん:2008/11/20(木) 23:57:43
>>525
お断りします
   ハハ
   (゚ω゚)
  /  \
((⊂ )  ノ\つ))
   (_⌒ヽ
   丶 ヘ |
εニ三 ノノ J
528デフォルトの名無しさん:2008/11/20(木) 23:57:44
>>525
どうぞどうぞ
529デフォルトの名無しさん:2008/11/20(木) 23:58:13
>>523
昔はコンパイラとリンカは別だったのですが。
その辺のニュアンスを含めて、「純粋なリンカ」と書きましたが、昔話ですみません。
530デフォルトの名無しさん:2008/11/20(木) 23:58:55
今も別だろ・・・。
531デフォルトの名無しさん:2008/11/21(金) 00:00:12
>>530
それは知りませんでした。多謝。
532デフォルトの名無しさん:2008/11/21(金) 00:00:29
>>510
確かにint main()と書いても規格の意味するところは何も変わらない。
533デフォルトの名無しさん:2008/11/21(金) 00:00:30
もうだめだ
534デフォルトの名無しさん:2008/11/21(金) 00:01:40
実質的に一緒でしょう
今時本当にコンパイルしかしないコンパイラなんてごく稀ですよ
明示的にリンクを抑止するオプションでも指定しない限り
535デフォルトの名無しさん:2008/11/21(金) 00:01:56
>>532
意味する所は変わらんが、
意味を正確に知るには別の箇所(6.7.5.3)も読まないといけないのが面倒だな。
536デフォルトの名無しさん:2008/11/21(金) 00:02:28
>>534
それはコンパイラがリンカを呼んでるんだよ・・・。
537デフォルトの名無しさん:2008/11/21(金) 00:02:37
やっとみなさんのおっしゃることがわかりました。
文法の誤解というか、勉強不足のところがありました。
お騒がせして申し訳ありませんでした。
538デフォルトの名無しさん:2008/11/21(金) 00:04:07
>>534
コンパイラ単品ではあまりないかもしれないけど、
リンカ単品売りはあるよ。
539デフォルトの名無しさん:2008/11/21(金) 00:06:07
>>518
VC++の場合、コンパイラを介さずともリンカにmainとかWinMainとかを持ったobjを食わすだけで判別する。
540デフォルトの名無しさん:2008/11/21(金) 00:07:18
関数宣言で仮引数リストが空の場合と関数定義で空の場合で大違いなので
どっちの方を指してるのかちゃんと書き分けておくれ
541デフォルトの名無しさん:2008/11/21(金) 00:08:13
>>540
お断りします
   ハハ
   (゚ω゚)
  /  \
((⊂ )  ノ\つ))
   (_⌒ヽ
   丶 ヘ |
εニ三 ノノ J
542デフォルトの名無しさん:2008/11/21(金) 00:08:18
main は関数原型を書かないから
関数定義に決まってる
543デフォルトの名無しさん:2008/11/21(金) 00:08:44
そういやC言語ってC++0xみたいなのって進んでるの?
544デフォルトの名無しさん:2008/11/21(金) 00:10:59
C99 の先は一応議論されてはいるみたいだが、
あまり熱心ではなさそうだ。
C99 でもう C としては十分だろうし・・・。
これ以上追加していくと C++ になりそうだ。
545デフォルトの名無しさん:2008/11/21(金) 00:12:43
C99でさえなかったことにされてるのにその先なんて…
546デフォルトの名無しさん:2008/11/21(金) 00:13:22
>>542
書いたらダメなの?
547デフォルトの名無しさん:2008/11/21(金) 00:15:05
>>542
そうとは限らんよ
http://binary.nahi.to/b2con2006_sato.pdf

まぁ相当変態なケースだけどなw
548デフォルトの名無しさん:2008/11/21(金) 00:16:28
restrict とか [const] とかはやり過ぎだとは思うが
局所変数宣言位置自由とか inline とか
main での return 省略とかは地味に良いんだがなあ・・・。
549デフォルトの名無しさん:2008/11/21(金) 00:18:17
C99なんかCじゃない
sizeofがコンパイル時に確定しないような変態言語がCを名乗るな
550デフォルトの名無しさん:2008/11/21(金) 00:18:51
gcc拡張が標準化されればいいや
551デフォルトの名無しさん:2008/11/21(金) 00:19:27
>>549
kwsk
552デフォルトの名無しさん:2008/11/21(金) 00:21:39
void f(int n)
{

}
553デフォルトの名無しさん:2008/11/21(金) 00:22:06
int a[n]; の時の sizeof a が実行時に決まるってだけだ
554デフォルトの名無しさん:2008/11/21(金) 00:22:13
おっと途中送信
void f(int n)
{
  char c[n];

}
555デフォルトの名無しさん:2008/11/21(金) 00:22:51
この2chブラウザあかんわ
556デフォルトの名無しさん:2008/11/21(金) 00:23:22
>>543
こういう感じらしい。
ttp://www.hi-matic.org/diary/?20081117#17-4
557デフォルトの名無しさん:2008/11/21(金) 00:24:12
>>547
おもしれーなw
558デフォルトの名無しさん:2008/11/21(金) 00:25:12
>>553
thx!
むしろint a[n]; ができる方がすげー
559デフォルトの名無しさん:2008/11/21(金) 00:26:42
alloca みたいなもんだな。
スタック上に確保されるだろうから
大きな値を使われるとオーバーフローするかもな。
560デフォルトの名無しさん:2008/11/21(金) 10:58:31
馬鹿ばっか
561デフォルトの名無しさん:2008/11/21(金) 11:01:31
longjmpで抜けた場合には解放される保証がないということから、処理系によってはヒープ上かも
562デフォルトの名無しさん:2008/11/21(金) 17:56:36
mainを呼ぶWinMainを書いたことがある俺
563デフォルトの名無しさん:2008/11/21(金) 18:59:13
main = 0x909090C9;
564デフォルトの名無しさん:2008/11/21(金) 23:42:04
>>561
> longjmpで抜けた場合には解放される保証がない
ここを詳しく
565デフォルトの名無しさん:2008/11/21(金) 23:49:03
longjmpで抜ければ、普通スタックは巻き戻される。
つまりスタックにallocateしているなら、解放される。

mallocしたメモリと同じようにヒープに確保して、
暗黙のうちに関数のエピローグでfreeしているとすると
longjmpで抜けてしまうと関数のエピローグを通らないから
freeされない。つまり、解放される保証がない。
566デフォルトの名無しさん:2008/11/22(土) 00:18:34
保証が無いってのが微妙な表現だな。
スタック使っても、ヒープ使っても、
サイズによってどっち使うか決めても規格合致ってことか。
567デフォルトの名無しさん:2008/11/22(土) 00:33:57
>>564
longjmpのところに↓のようなことが書かれてる

EXAMPLE The longjmp function that returns control back to the point of the setjmp invocation
might cause memory associated with a variable length array object to be squandered.
#include <setjmp.h>
jmp_buf buf;
void g(int n);
void h(int n);
int n = 6;
void f(void)
{
int x[n]; // OK, f is not terminated.
setjmp(buf);
g(n);
}
void g(int n)
{
int a[n]; // a may remain allocated.
h(n);
}
void h(int n)
{
int b[n]; // b may remain allocated.
longjmp(buf,2); // might cause memory loss.
}
568デフォルトの名無しさん:2008/11/22(土) 00:38:09
なるほど。may に might か。
開放される実装になってても規格違反ってわけじゃないのね。
569デフォルトの名無しさん:2008/11/22(土) 06:35:20
関係ないけど、そのsetjmpの使い方、未定義ですな
570デフォルトの名無しさん:2008/11/22(土) 11:40:43
知らんがな(´・ω・`)
571デフォルトの名無しさん:2008/11/23(日) 09:05:10
setjmpは条件式の中からしか呼べないんだっけ?
572デフォルトの名無しさん:2008/11/23(日) 13:03:50
なんだ? そのわけわかめな制限は。
573デフォルトの名無しさん:2008/11/23(日) 13:35:20
setjmp の使い方を考えれば至極妥当だと思うが・・・。
無限ループになるぜ。
574デフォルトの名無しさん:2008/11/23(日) 13:38:23
無限ループになるかどうかも未定義か
575デフォルトの名無しさん:2008/11/23(日) 13:40:44
An invocation of the setjmp macro shall appear only in one of the following contexts:
- the entire controlling expression of a selection or iteration statement;
- one operand of a relational or equality operator with the other operand an integer
constant expression, with the resulting expression being the entire controlling
expression of a selection or iteration statement;
- the operand of a unary ! operator with the resulting expression being the entire
controlling expression of a selection or iteration statement; or
- the entire expression of an expression statement (possibly cast to void).
If the invocation appears in any other context, the behavior is undefined.

・・・だそうだ
576デフォルトの名無しさん:2008/11/23(日) 13:43:11
環境限界 setjmp マクロの呼出しは,次に示すいずれかの文脈にしか現れてはならない。

・選択文又は繰返し文の制御式全体
・他方のオペランドが整数定数式である関係演算子又は等価演算子の一方のオペランド。
 この場合,関係演算子又は等価演算子による式は,選択文又は繰返し文の制御式全体でなければならない。
・単項 ! 演算子のオペランド。この場合,単項 ! 演算子による式は,選択文又は繰返し文の制御式全体でなければならない。
・式文の式全体(void にキャストされていてもよい。)。
 setjmp マクロの呼出しがこれ以外の文脈に現れた場合,その動作は,未定義とする。

要するに、
・「if(A)」「switch(A)」「while(A)」「for(X;A;Y)」のどれかのAの場所に、
「setjmp(buf)」「setjmp(buf) op Z」「Z op setjmp(buf)」「!setjmp(buf)」(opは> < >= <= == !=のどれか)
のいずれかの形で出てくるか
・単に「setjmp(buf);」「(void)setjmp(buf);」の形で出てくるか

どっちかでないと鼻から悪魔
577デフォルトの名無しさん:2008/11/23(日) 13:45:52
なら別にそのまま使ってもいいのか。
578デフォルトの名無しさん:2008/11/23(日) 14:04:21
制御文の中で直接真偽判定する以外にその値を使ってはいけないってことかな
579デフォルトの名無しさん:2008/11/23(日) 14:10:20
longjumpから帰ってきたかどうかを示す値が揮発性だってこと?
580デフォルトの名無しさん:2008/11/23(日) 22:36:28
sequence point間に単独で置いとけってことだろう。
581372:2008/11/24(月) 09:28:32
関連の規約をチェックしました。>>537 は実は別人ですが、同じ気持ちです。感謝です。
>>502, >>535 ポインタを紹介していただきありがとうございました。非常に勉強になりました。
なお、>>508 は私ではありません。
582デフォルトの名無しさん:2008/11/24(月) 15:09:46
久しぶりに覗いてみたら、かつてのfj.lang.cなみのマジキチぶりにワロタ
583デフォルトの名無しさん:2008/11/24(月) 15:36:09
>>582
それは賛辞に取られかれない危険な発言かと。
584デフォルトの名無しさん:2008/11/24(月) 23:39:27
fj.lang.cってどこのサイトですか?
585デフォルトの名無しさん:2008/11/25(火) 00:05:57
>>584
http://ja.wikipedia.org/wiki/Fj_(%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97)
586デフォルトの名無しさん:2008/11/25(火) 00:16:53
>>585
トン。
理解力ないんでよくわかんなかったw
スレタイよくみたら初心者お断りなので帰ります。。。λ
587デフォルトの名無しさん:2008/11/27(木) 13:57:38
>>584
マジレスするとネットニュース。
Webからアクセスできるゲートウェイも存在するが、
「どこのサイト?」とか言っちゃうあたり時代はかわったんだなぁと思った。
588デフォルトの名無しさん:2008/11/27(木) 14:11:53
俺は>>584ネタかと思ったよ
589デフォルトの名無しさん:2008/12/10(水) 00:27:10
俺はパソコン通信からやってるけど
本格的にインターネットを使いだしたのが
遅かったので知らない。
590デフォルトの名無しさん:2008/12/10(水) 09:27:58


■■■■■■
591デフォルトの名無しさん:2008/12/10(水) 09:35:00
■■■■■■■■■■■
592デフォルトの名無しさん:2008/12/10(水) 11:55:31
>>589
まだナツメネットとかアスキーNETとかw
593デフォルトの名無しさん:2008/12/10(水) 13:41:40
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
2ちゃんねるという馬鹿な掲示板を削除してくでさい
ドコモ規制するとか頭おかしいんじゃねーの?

のんたん
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
■■■■■■■■■
594デフォルトの名無しさん:2008/12/10(水) 13:47:50
      __     ,.-、
.      l _ヽ     .l ri.ヽ
     l l ヽヽ.  // l. !
     l l,.- '  ̄  ̄ ! .,
.      l  rn  ,.、 n ,.イ,.-   _
    二l- `'' ヽニノ- _,フー‐  r ,.-- '
.    -‐`ーr'´ 〉 ´  、 `ヽ ,! l
         ヽ-r'     ヽ' ノ /
         ヽ、      .l' ´
          /´  /   !
         ⊂._,.!   _/
              ̄
595デフォルトの名無しさん:2008/12/10(水) 17:42:48
ご冥福をお祈りします
596デフォルトの名無しさん:2008/12/22(月) 01:21:46
あげ
597デフォルトの名無しさん:2008/12/24(水) 21:10:13
a.cでint iというグローバル変数を定義して
b.cでint iという同名のグローバル変数を定義しても
多重定義にならないのは何故ですか?
598デフォルトの名無しさん:2008/12/24(水) 21:19:07
>>597
>>133-
599デフォルトの名無しさん:2008/12/24(水) 21:21:53
>>598
ありがとうございます。
600デフォルトの名無しさん:2008/12/26(金) 19:39:16
http://d.hatena.ne.jp/ku-ma-me/20081017/p1
これってどうなの?
601デフォルトの名無しさん:2008/12/26(金) 22:47:14
>>600
似たような話で、規格にはプログラムのサイズについて規定は無いが、実際には有限だ。

関数定義が CPU インストラクションの列で実装されていれば、対象環境の
プログラム配置領域サイズによって制限を受ける。

同じように、自動記憶域がスタックで実装されていれば、対象環境でのスタックの
サイズに応じてプログラムが制限を受ける。

そういうことだと思う。つまりは、言語の規格は上記のような制限の無い仮想マシンに
ついての動作を規定するもので、実装方法や実際の動作環境によって生じる制限には
関知しない、と。
602デフォルトの名無しさん:2008/12/27(土) 00:01:54
現実のコンピュータでCの規格に完全準拠することは理論上不可能
ってことでいいのか。ありがとう、すっきりした。
603デフォルトの名無しさん:2008/12/27(土) 00:06:30
理論上はそうなってしまうので、規格には最低限満たして欲しい基準が補足で書かれてる
604デフォルトの名無しさん:2008/12/27(土) 00:10:00
>>603
どこ?
605デフォルトの名無しさん:2008/12/27(土) 00:10:28
処理系限界が下限に限らず存在することが規定されている
606デフォルトの名無しさん:2008/12/27(土) 00:15:38
>>602
ブログの人はそういってるけど 601 は違うといってるんだが。
607デフォルトの名無しさん:2008/12/27(土) 00:19:16
>>606
じゃあ理論上可能なの?
608デフォルトの名無しさん:2008/12/27(土) 00:19:38
Cでは基本的に「ハードウェアのやることはなんでもあり」であって、
規格はハードウェアに発する命令の体系を既定しているに過ぎない。
ハードウェアの能力が足りなくて要求を実現できないのと、
実装が規格に準拠しているかどうかはまったく別の問題。
609デフォルトの名無しさん:2008/12/27(土) 00:24:06
>>607
601 を読んだうえで、不可能だと思う理由を述べてください。
610デフォルトの名無しさん:2008/12/27(土) 00:24:12
>>604
AnnexB
611デフォルトの名無しさん:2008/12/27(土) 00:41:21
>>608
メモリ無限の仮想マシンの上で動くバイナリを出力するコンパイラなら
理論上は作れる。実行はできないが。
ってこと? そういうことなら納得。

>>610
Annex BはLibrary summaryになってる。
手元にC99のCommittee Draftしかないんだけど。
612デフォルトの名無しさん:2008/12/27(土) 02:34:54
>>611
いや、言語として規定はないから作れる。実行も出来る。
ただ実行した時の結果・挙動についてまでは保証しませんよってこと。

C言語としてはこの場合、「無限再帰呼び出しを行うマシンコードが生成される」
ところまでしか保証しない(コンパイラによっては警告出すかもしらんが)。
それを実行した結果、何が起こるかかまでは規定できないし、しない。

int *p = 0; *p = 100;
このコードがコンパイル出来ますか?実行出来ますか?
って問題と同じだろう。コンパイルも実行も可能だが、結果は環境に依存する。
613デフォルトの名無しさん:2008/12/27(土) 14:44:56
末尾再帰だからループに直すのだ!
614デフォルトの名無しさん:2008/12/27(土) 16:52:07
>>612
> int *p = 0; *p = 100;
これは未定義だってはっきりしてるじゃん。別の話。
615デフォルトの名無しさん:2008/12/27(土) 19:26:24
int *p = 0; *p = (int*)100;じゃないとコンパイル通らなくないか?
616デフォルトの名無しさん:2008/12/27(土) 19:31:13
>>615 試してから書けよ。
617デフォルトの名無しさん:2008/12/27(土) 19:34:15
ごめんポインタ2つ宣言してるように見えてた
618デフォルトの名無しさん:2008/12/27(土) 19:41:07
>>611
その理解であってると思う。極端な話、現実のCPUやOSは物理的に故障する可能性が
あるのに、その上でC言語の仕様に完全に準拠するなんて不可能だ。

>>612
コンパイラの仕事は、入力したソースコードの意味と同じ意味を持つ実行ファイルを
出力すること。実行ファイルの意味はCPUやOSの仕様が規定している。CPUやOSが自身の
仕様通りに動くときは「実行した時の結果・挙動」を保証しないと、「C言語の仕様に
準拠したコンパイラ」とは言えない。

ってか、C言語の仕様は実現方法を規定しないから、「無限再帰呼び出しを行うマシン
コードが生成される」ことも保証されないぞ。
619デフォルトの名無しさん:2009/01/20(火) 21:40:47
setbuf, setvbuf 関数で自らバッファをmallocして設定したとき、fcloseしたらそのバッファもfreeされるのでしょうか?
もしくはそのバッファは(gccでは)どういう運命をたどるのでしょうか。
620デフォルトの名無しさん:2009/01/20(火) 21:57:51
RTFM
621デフォルトの名無しさん:2009/01/22(木) 00:05:37
>>619
glibcだとユーザーが定義したバッファは開放されないみたい。
622デフォルトの名無しさん:2009/01/22(木) 01:00:00
>>621
ありがとうございます。
linux manをみても、NULLの場合は開放とあるのですがユーザ設定のときは言及もなく未定義とも書いてなかったので。
623デフォルトの名無しさん:2009/01/22(木) 04:44:41
ユーザがセットしたバッファがfreeして良い(すなわち、mallocされている)のか、
静的に確保されたメモリ領域など、freeしてはならないのかは、
fcloseには分らないから、fcloseの実装でユーザがセットしたバッファを
freeすることはあり得ない。
624デフォルトの名無しさん:2009/01/22(木) 04:55:22
>>619
フツーに考えたら、freeされないと思う。
根拠はオレ。

仕様的には実装におまかせのはず。
625デフォルトの名無しさん:2009/01/22(木) 22:34:44
複数行マクロを書くときの体裁なんですが、
伝統的なdo{}while(0)ではなくvoidキャストを使うというのを見かけました
たとえばこんなんです

#define macro() { /* 処理 */; }(void)0

確かにこれでうまくいきそうに見えるのですが、本当の本当に大丈夫でしょうか
626デフォルトの名無しさん:2009/01/22(木) 22:36:44
>>625
if(hoge)macro();else foo;
でアウツだろ。
627デフォルトの名無しさん:2009/01/22(木) 22:42:23
なるほど

#define macro() if(1){ /* 処理 */; }(void)0

なら大丈夫ですか?
628デフォルトの名無しさん:2009/01/22(木) 22:43:55
違うか

#define macro() if(1){ /* 処理 */; }else (void)0

629デフォルトの名無しさん:2009/01/22(木) 22:47:55
問題は無いと思う。
まあ、そこまでするなら do { } while(0) の方がシンプルでいいと思うが。
これの問題は条件式が定数式の場合に警告吐くコンパイラがあるという点だが、
それが解決されてるわけでもないしね。
630デフォルトの名無しさん:2009/01/22(木) 22:54:28
>>628 にはまだこの問題があるようだ。
macro(), foo(); /* foo() は実行されない */
631デフォルトの名無しさん:2009/01/23(金) 09:01:12
それはdo〜whileでも駄目なのでは?
632デフォルトの名無しさん:2009/01/23(金) 17:38:36
do〜whileはコンパイルエラーになってくれる
628はコンパイル通って実行しないからタチが悪い
633デフォルトの名無しさん:2009/01/24(土) 08:47:00
#define macro() { /* 処理 */; }
だけではだめなんですか?
634デフォルトの名無しさん:2009/01/24(土) 08:58:37
if (hoge)
 macro(); /* ← 使う側はどういう定義になっているか知らないのでセミコロンをつけて書いちゃった */
else
 foo();

で文法エラーになる。
常に if に { } を付けるスタイルなら問題は無いが。
635デフォルトの名無しさん:2009/01/24(土) 09:41:12
なるほど。
636デフォルトの名無しさん:2009/01/24(土) 09:42:54
ともあれこのスレは、Cのイディオムについて語り合うスレではないな。
637デフォルトの名無しさん:2009/01/24(土) 12:54:33
>>636
誰がそんなこと決めた
638デフォルトの名無しさん:2009/01/24(土) 18:00:48
文法エラーではじかれるならまだOKですね。
変に動いて誤作動するよりは。

基本ifには{}をつけるので
#define macro() { /* 処理 */; }
でも問題ないですが、これだとMISRA-Cに怒られる・・・
639デフォルトの名無しさん:2009/01/24(土) 18:43:46
inline macro() { /* 処理 */; }
が一番だな
640デフォルトの名無しさん:2009/01/24(土) 18:50:15
inlineの基準はコンパイラによって違うそうですが、たとえばgccではインラインされるかどうかのある程度基準(仕様)があるんですか?
641デフォルトの名無しさん:2009/01/24(土) 18:55:23
inlineじゃなくて、static宣言された関数では?
642デフォルトの名無しさん:2009/01/24(土) 18:55:54
>>641
C99でinlineが入ったんだよ。
643デフォルトの名無しさん:2009/01/24(土) 19:18:31
inlineとstaticは同じ基準でインライン展開されるんですか。
644デフォルトの名無しさん:2009/01/24(土) 19:19:07
よーわからんけど、extern inline が使えるってこと?
645デフォルトの名無しさん:2009/01/24(土) 20:40:50
>>643
コンパイラ次第。
最適化レベルによって基準に差が出たり出なかったりする、なんてこともある。
646デフォルトの名無しさん:2009/01/24(土) 20:41:26
>>644
inline 関数は常に内部リンケージ。
647デフォルトの名無しさん:2009/01/25(日) 02:27:15
最適化をしない設定ではinlineをしていしても無効になるコンパイラもあるしね。
648デフォルトの名無しさん:2009/01/25(日) 05:53:01
極端な話、今時inlineなんてregster程度の意味しかないと言ってもいい。
649デフォルトの名無しさん:2009/01/25(日) 10:58:41
register
 ・ C ではアドレスを取るとエラーになる(C++ では問題ない)
 ・ レジスタにするかどうかは 100% 無視される
inline
 ・ 最適化なしでは static 関数も inline 関数もインライン化されない
 ・ 最適化低では inline 関数はインライン化されるが static 関数はインライン化されない
 ・ 最適化高では static 関数も inline 関数もインライン化される

VC++ ではこんな感じだったと思う。
分岐する最適化レベルがいくらだったかは忘れた。
650デフォルトの名無しさん:2009/01/25(日) 16:20:26
>>649
ありがとうござます。
inlineはコンパイラによってインライン展開するかどうかは任意だと聞いてたんですけど、最適化を協力にすると任意じゃなくて必ず展開されるんですか
それと、static関数は必ずインライン展開されるんですか。困った話ですね。

ということは、インラインとしては展開できない関数はないですね(つまり必ずマクロ関数みたくなる)。
inlineは最適化から出てきた機能ですが(関数専用の)テンプレートに近くなっているということでしょうか。
651デフォルトの名無しさん:2009/01/25(日) 16:23:03
>>650
いやいや、必ず展開されるという意味で書いたわけじゃない。
「インライン化されない」と書いた部分は「必ずインライン化されない」が、
「インライン化される」と書いた部分は「インライン化される可能性がある」の意味で書いた。
652デフォルトの名無しさん:2009/01/25(日) 16:44:33
今のハードなら展開されようが、されまいがどうでもいいんじゃないの。
関数呼び出しコストなんて測定できないような時間(ナノ秒単位)で、普通は参照渡し。
組み込みとかセットボックスみたいだとハード資源が限られてるからループ内部とかでやれば多少効果はあるかもしれない。
653デフォルトの名無しさん:2009/01/25(日) 16:53:46
画像処理とか激しいループは未だにあるもんだ。
654デフォルトの名無しさん:2009/01/25(日) 17:36:24
インライン展開することによる最適化も期待できるから
>>652 は世間知らずだな としか思えない。
655デフォルトの名無しさん:2009/01/25(日) 17:44:03
static以外の関数でも最適化を上げればインライン展開されると思うよ。
外部リンケージ用に、通常関数版も用意されるはずだけど。
656デフォルトの名無しさん:2009/01/25(日) 17:49:42
まあそこらへんは規格に反しない限りはコンパイラが自由にやっていいことだからなぁ
657デフォルトの名無しさん:2009/01/25(日) 18:53:36
ファイルのリンケージを考えれば、どっちでもいいということですね。
オブジェクトファイルのサイズが増えても今のハード(携帯なども含む)なら微々たる物でしょうし。
気にしているのは、DLLみたく他人がつかうとき、それが関数のつもりがマクロみたく展開されてると不都合が生じるってことです。
関数ポインタのときとか。
658デフォルトの名無しさん:2009/01/25(日) 22:09:36
>>657
> 気にしているのは、DLLみたく他人がつかうとき、それが関数のつもりが
> マクロみたく展開されてると不都合が生じるってことです。
> 関数ポインタのときとか。

意味わからん、inline の意味わかってるのか?
659デフォルトの名無しさん:2009/01/26(月) 00:18:35
実行時の関数呼び出しとコンパイル時のインライン展開の違いはわかってる?
660デフォルトの名無しさん:2009/01/26(月) 00:20:50
inline 関数の中に malloc があったとき
どっち側でメモリが確保されるのかは気にはなる。
661デフォルトの名無しさん:2009/01/26(月) 00:25:31
何側と何側の話をしているんだ
662デフォルトの名無しさん:2009/01/26(月) 00:29:45
DLL側とDLLを使用している側
663デフォルトの名無しさん:2009/01/26(月) 00:31:33
説明する気もうせる
664デフォルトの名無しさん:2009/01/26(月) 00:33:09
スレチだしな
665デフォルトの名無しさん:2009/01/26(月) 00:38:12
いいぞもっとやれ
666デフォルトの名無しさん:2009/01/26(月) 01:01:17
>>658-659

inline void func();

これを(*func)と関数ポインタで使うときどうなるんでしょうか?
例えばqsortに渡したりするときも、qsortみたいな関数ポインタを受け付けるAPIは実行時評価が目的の設計なので、
インライン展開されると不都合な気がするんですけど。

static関数もファイルスコープにおいて展開されるのは初耳だったんですけど、同じように実行時に不都合がありませんか?
667デフォルトの名無しさん:2009/01/26(月) 01:20:20
memcmp、strcmp、strncmpの返値だけど

The memcmp function returns an integer greater than, equal to, or less than zero,
accordingly as the object pointed to by s1 is greater than, equal to, or less than the object
pointed to by s2.

これはつまり、a > b > c だとしても、
memcmp(a, b, n)で100を返し、memcmp(a, c, n) で1を返してもいいんですよね?
0より大きいか小さいかだけが問題で。
accordinglyってのは、「大きい小さい等しい」に従うだけで
数値に従う必要はないですよね?
668デフォルトの名無しさん:2009/01/26(月) 01:21:53
うん。
669デフォルトの名無しさん:2009/01/26(月) 01:29:38
>>666
上で誰かが書いていたと思うけど、必要なら普通の関数のコードも併せて作るだけ。
670デフォルトの名無しさん:2009/01/26(月) 05:22:44
>>669
私だよん。

>>666
たまにはアセンブリ出力を眺めてみるもんだよ。
個々の行の意味が判らなくても、全体のボリュームとシンボルの位置でいろんなことが見えてくる。

>>667
その通り。実際、1,0,-1しか返さない処理系もあった筈だし、
最初に不一致だったバイトの差分を返す処理系もあった筈。
671デフォルトの名無しさん:2009/02/14(土) 05:16:14
ctype.h の関数を手持ちの char について使いたいときは、 char が符号付の場合を考慮して
unsigned char にキャストしないといけないことを理解しました。

でも toupper() の戻り値 int は引数と同じ範囲の値を取るので、そのまま char に戻すことが
できないように思います。

たとえば char 型の変数 c について、以下の条件をすべて満たすとき。
- (unsigned char)c == UCHAR_MAX
- UCHAR_MAX > CHAR_MAX
- toupper(UCHAR_MAX) == UCHAR_MAX ※変換なし
c = toupper((unsigned char)c) という式は char には収まらない UCHAR_MAX を
char に変換することになり、符号付整数のオーバーフローにより未定義動作と
なってしまいそうです。

任意の char 型の値を大文字に変換して結果を char 型で得る方法として、
未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか?

現実的には黙って char に変換すればいいように実装されてることが期待できるとは
思うのですが、ちょっと気持ち悪いです。
672デフォルトの名無しさん:2009/02/14(土) 07:29:40
なんか、とても杞憂な気がするるが、神経質にするならこうか?

c= isalpha((unsigned char) c) ? toupper((unsigned char)c) : c;
673デフォルトの名無しさん:2009/02/14(土) 07:42:03
気になってるのは、大文字アルファベットの表現がsinged charで負値になる環境とかだよね。

全く規格確認してないが、intの戻り値retについて、
CHAR_MINが負値でretがCHAR_MAXを超える場合、
自力でunsigned charをcharに変換するコードを書けば
とりあえず解決するんじゃね?

1バイト文字の英数がASCIIで無い処理系ってあんま想定したこと無いから分からないけども、
「ASCIIじゃなきゃダメ」って記述は規格には無かった気がするなぁ。
詳しい人フォローよろしく。
674デフォルトの名無しさん:2009/02/14(土) 07:44:12
fgetc() なんかも同じだよね。とりあえず EOF をチェックして、それが済んだら char として
扱いたいんだけど、変換できるの?っていう。
675デフォルトの名無しさん:2009/02/14(土) 09:13:41
>>671
そもそも規格上は unsigned char を signed long するだけでだめなケースがあるから

> 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか?

の答えは「ない」だよ。

>>673
> 「ASCIIじゃなきゃダメ」って記述は規格には無かった気がするなぁ。

汎用機用の C言語処理系で文字コードが EBCDIC のものがある。
676デフォルトの名無しさん:2009/02/14(土) 09:45:53
>>671
toupper に正しく小文字を与えれば、正しく大文字になるでしょ?
それ以上のものはないよ

UCHAR_MAXを toupper に与えたらUCHAR_MAXが返るだろうけど、
そもそもなんでその結果を signed char にキャストするの?
UCHAR_MAXを与えるということは signed char じゃなかったんでしょ?

>>674
toupper()やfgetc()の結果をcharと比較したい場合、
charに変換して戻すんじゃなくて、比較先をintにするのが普通では?

 int c = fgetc();
 if ( c == 'a' ){
   …
とか
677デフォルトの名無しさん:2009/02/14(土) 10:11:11
>676
明示的に UCHAR_MAX を与えるわけじゃなくて、unsigned char に変換すると UCHAR_MAX になる値が
char としてあった場合に、unsigned char にキャストしてから toupper に与えた場合とか。

> toupper()やfgetc()の結果をcharと比較したい場合、
比較ならいいけど、char に代入したくなったらどうするの?
例えば、文字列中の小文字を全て大文字に変換する関数 strupper(char*) を定義しようとかいう場合。
やっぱ >672 のように書けってことだろうか。
678デフォルトの名無しさん:2009/02/14(土) 10:13:56
>>676
> toupper()やfgetc()の結果をcharと比較したい場合、

単純比較なんて誰も悩んでないと思うが。
配列に入れて、printf() で出力したい時とか考えつかないわけ?
679デフォルトの名無しさん:2009/02/14(土) 11:51:23
signed char が -127〜127 で文字コードが 0〜255 の環境なら、
処理系は char を unsigned char 固定で扱うようになっているんじゃないのか?
じゃないと char が文字コードを収める事ができるという
最低条件をクリアできないじゃん。
680デフォルトの名無しさん:2009/02/14(土) 11:56:18
>>677
>>unsigned char にキャストしてから toupper に与えた場合とか。

だから、なんでキャストするの?

入力が signed char なら signed char → int に変換されても
UCHAR_MAX はありえない。

入力が unsigned char なら UCHAR_MAX はありうるけど、それは
変換前も変換後も UCHAR_MAX のままでしょ
681デフォルトの名無しさん:2009/02/14(土) 13:17:25
>>680
ふふ、
682デフォルトの名無しさん:2009/02/14(土) 13:24:25
一連のレスで、UCHAR_MAX は一例だと思うよ。
問題は、signed charで表せないのにunsigned charで表せる文字
ではなくて、signed charで負の値になるunsigned charの文字
ではなかろうか。このような文字を安全に
unsigned char から signed charに変換する標準的な方法が無いこと。

もう一つは、toupperの引数は非負が仮定されているので、
toupperの引数は(intだけど)数値としては実質的にunsigned char
を渡す事になる。

この二つの問題が絡み合っているのね。
683デフォルトの名無しさん:2009/02/14(土) 15:38:04
>680
unsigned char 範囲の値を渡せって規格で要求されてるから。
> 9899:1999 7.4
> The header <ctype.h> declares several functions useful for classifying and mapping
> characters. In all cases the argument is an int, the value of which shall be
> representable as an unsigned char or shall equal the value of the macro EOF. If the
> argument has any other value, the behavior is undefined.
684680:2009/02/14(土) 22:52:12
>>683
その文章は知ってるよ。
でもそれは toupper の引数は unsigned char でキャストしろ、って意味.じゃない
signed char を指定した場合で -2 〜 -128 の場合は undefined だよ、って言ってるだけ
(EOFが-1として)
685デフォルトの名無しさん:2009/02/15(日) 00:14:28
実際死ぬケースもあったな。マイナス与えると。
日本語扱うとよくある。
686デフォルトの名無しさん:2009/02/15(日) 00:16:35
> 未定義動作も実装依存も回避した移植性のある方法はあるのでしょうか?
最初っから全部unsigned charにしとけでイナフ
687デフォルトの名無しさん:2009/02/15(日) 00:23:38
>>679 についてはどうなんだ?
688デフォルトの名無しさん:2009/02/15(日) 01:03:33
>>684
未定義動作を回避するのに、 unsigned char にキャストするほかにどうすんの?
689デフォルトの名無しさん:2009/02/15(日) 01:06:46
>>679
basic character set に無い処理系依存の拡張文字の char としての値について、
符号も含めて規定は無いから、負の値が拡張文字に対応しても問題なさそう。

6.2.5 Types p3
> An object declared as type char is large enough to store any member of the basic
> execution character set. If a member of the basic execution character set is stored in a
> char object, its value is guaranteed to be nonnegative. If any other character is stored in
> a char object, the resulting value is implementation-defined but shall be within the range
> of values that can be represented in that type.
690デフォルトの名無しさん:2009/02/15(日) 01:11:07
>684
じゃ、
> signed char を指定した場合で -2 〜 -128 の場合
はどうすれば?
範囲チェックして toupper には渡すなって主張?

>687
0〜255 だというなら確かにそうかもね。
> 9899:1999 6.2.5/3
> If a member of the basic execution character set is stored in a
> char object, its value is guaranteed to be positive. If any other character is stored in a
> char object, the resulting value is implementation-defined but shall be within the range
> of values that can be represented in that type.
という記述を見ると basic execution character set 以外なら負値も認めているように読めるけど、
後は実装依存の闇の中、かな。
691デフォルトの名無しさん:2009/02/15(日) 01:22:17
int toupper(int c);
692デフォルトの名無しさん:2009/02/15(日) 01:22:20
なるほど・・・。
完全に環境無依存のコードは無理っぽいね。
693デフォルトの名無しさん:2009/02/15(日) 01:55:08
卓上の妄想なら不可能だが、現実的にはみんなやってるだろ
694デフォルトの名無しさん:2009/02/15(日) 01:59:26
なんで文字を扱ってるのに符号を気にしなきゃいけないんだよC言語のバカ!
695デフォルトの名無しさん:2009/02/15(日) 02:11:42
char の符号が未規定なのって
どんなケースを想定してのことなのだろうか。
符号つきの文字コードがあったらいけないから?
696デフォルトの名無しさん:2009/02/15(日) 02:18:33
8 bit 符号付でも ASCII の表現には十分だから実装任せで良いよね。
っていう話だと思う。

C++ では char を受けて char を返す toupper/tolower があるから、今さら
規格を変更する(変更を検討する)モチベーションも無いだろうしなぁ。
697デフォルトの名無しさん:2009/02/15(日) 04:13:14
リアルタイムの人間じゃないけど。
規格がまとまる前にsigned, unsigned両方の実装が出ていたから、
というのが最大の理由だったと思う。
そこから先は>>696のとおり。
698デフォルトの名無しさん:2009/02/15(日) 09:07:58
int は、ディフォルトで signed なのに、char のディフォルトを決めなかったのが
敗因だと思う。

まあ今時だとメモリも潤沢だからわざわざ char に詰め込もうなんて思わないけど、
当時だと short short int の役目もあったのかもしれないな。
699デフォルトの名無しさん:2009/02/15(日) 10:18:39
MS-cがオプションでcharをアンサインドにできる仕様だったからねぇ。
intとは事情が違うね。
700デフォルトの名無しさん:2009/02/15(日) 10:52:13
lattice-c(2のころ)はunsignedだったっけ?
701デフォルトの名無しさん:2009/02/15(日) 11:12:02
>>688
出力を未定義にしたくないなら、未定義にならない引数を与えろってこと。
toupper呼ぶ前に、入力文字の範囲チェックしないってことは無いだろう普通

それを unsigned char へのキャストで済ませられたらいいな、と
考えたのだろうけどそれじゃダメって話
702デフォルトの名無しさん:2009/02/15(日) 11:29:04
>>701
範囲をどうチェックするするべきだと言うの?
チェックで範囲外だとわかったらどうしろっていうの?
toupper() に渡さないと大文字にできんのだが。
703デフォルトの名無しさん:2009/02/15(日) 12:16:42
馬鹿なの?
大文字にしたければ小文字を渡せよ
if( isascii(c) && islower(c)) c = toupper(c);

これを
c = toupper((unsigned char)c);
とすると規格上不定になります(;_;)とか言ってるから
キャストするからだろ馬鹿、って言ってるんだ
704デフォルトの名無しさん:2009/02/15(日) 12:23:28
大馬鹿なの? toupper の前に islower なんかいらねーよ
705デフォルトの名無しさん:2009/02/15(日) 12:23:30
>>703
標準の範囲で実装依存せずにどうするかって話なのに、
非標準の isascii() とか入れてみたり勝手に ASCII 大文字だけに要求を絞ったり、
ギャグでやってるのか?
706デフォルトの名無しさん:2009/02/15(日) 12:37:08
いいえ、ボールギャグです。
707デフォルトの名無しさん:2009/02/15(日) 15:08:42
で、実際のところa-z|A-Zが符号付き表現で負になることはありえるの?
708デフォルトの名無しさん:2009/02/15(日) 15:11:34
それは知らないけど、
"C" locale以外ではa-z|A-Z以外でもislower/isupperが真になるということなら有り得ると思う。
709デフォルトの名無しさん:2009/02/15(日) 15:12:31
真になるってどういう事だよ。
710デフォルトの名無しさん:2009/02/15(日) 15:13:04
あ、空目してた。ごめんよ。
711デフォルトの名無しさん:2009/02/15(日) 15:14:32
結局は>>686
712デフォルトの名無しさん:2009/02/15(日) 16:26:35
>>707
そいつらは basic execution character set に入ってるから char 型の符号の有無に
かかわらず負にならないことが保証されてる。 ( >689,690 が引用してる箇所参照)
713デフォルトの名無しさん:2009/02/15(日) 17:39:56
>>712
素朴な疑問、EBCDIC な文字コードの処理系の場合どうなるんだ?
714デフォルトの名無しさん:2009/02/15(日) 18:09:27
>>713 文字コードは関係ない。( >689,690 が引用してる箇所参照)
715デフォルトの名無しさん:2009/02/15(日) 18:30:21
>>714
EBCDIC って 8bit だと MSB たってんじゃん, char 9bit 以上で実装しろって話?
716デフォルトの名無しさん:2009/02/15(日) 19:33:50
>>699
MS-C はシフトJIS でトラブル奴が多いからそういうオプションを
サポートしただけだろ。
717デフォルトの名無しさん:2009/02/15(日) 19:35:12
>>715 EBCDIC のコードを 8 bit char の値に使うなら char 型を unsigned にするしかないということ。
718デフォルトの名無しさん:2009/02/15(日) 20:08:24
>>717
fgetsやprintfやstrcmpなどの型も全部変更するの?
719デフォルトの名無しさん:2009/02/15(日) 20:11:42
>>718
きっと何か勘違いしてると思うけどそれらの関数でどういう問題が起きると思うの?
720デフォルトの名無しさん:2009/02/15(日) 21:19:58
>>718
unsigned charにするんじゃなくて、
char自体を符号無しにするってことだろ。
721デフォルトの名無しさん:2009/02/15(日) 22:46:22
>>717 ああ、それなら納得
>>712 char 型の符号の有無にかかわらず負にならない」
てな、書き方はやめてほしかった
722デフォルトの名無しさん:2009/02/26(木) 04:13:51
今現在、charをsignedで使う意味ってあるのかな。
723デフォルトの名無しさん:2009/02/26(木) 15:09:34
>>722
charを文字ではなく数値として使うこと考えれば。
intへの昇格も考えなきゃならんし。
724デフォルトの名無しさん:2009/03/01(日) 00:55:23
C言語なら俺に聞け(入門篇) Part 45
http://pc11.2ch.net/test/read.cgi/tech/1235044065/l50

こっちが埋まったんで、とりあえずageておく。
725デフォルトの名無しさん:2009/03/01(日) 03:16:58
あのグダグダを持ち込まれても困るんだが
726デフォルトの名無しさん:2009/03/01(日) 21:51:47
ネタ切れ? じゃぁ

問題:

int i, j;

int main()
{
i = 1;
j = i++ * i++;
printf("%d, %d\n", i, j);
}

このプログラムを実行するとどうなるか? どうなるべきか? 結果もしくは挙動を推測せよ。
(includeとかmainの型なんかは、適宜補え。文句言うな)
727デフォルトの名無しさん:2009/03/01(日) 22:17:00
jの右辺が未定義動作だから何が起こるかわからない

「3,6」と表示されるかもしれないし「3,9」と表示されるかもしれないし
「5196823, -98600289」と表示されるかもしれないし「qあwせdrftgyふじこlp;」と表示されるかもしれないし
プログラムが異常終了するかもしれないしOSがクラッシュするかもしれないし
PCが火を噴くかもしれないし地球が爆発するかもしれないし鼻から悪魔が出てくるかもしれない

常識だと思うが、今更どうした
728デフォルトの名無しさん:2009/03/01(日) 22:54:37
mainが値を返してないからコンパイルできない
729デフォルトの名無しさん:2009/03/01(日) 22:56:00
C99なら可だが
730デフォルトの名無しさん:2009/03/02(月) 11:15:52
鼻から悪魔は無いな、たぶん。
731デフォルトの名無しさん:2009/03/02(月) 20:09:45
出てきてからじゃ遅いんだよ、出てきてからじゃ。
732デフォルトの名無しさん:2009/03/02(月) 21:31:38
ネタ切れ? じゃぁ

問題:

int a[32], b[32], *p = a;
if (p < b || b + 32 <= p) printf("悪魔が出る。");
else printf("いずれにせよ悪魔が出る。");

このプログラムの断片について議論して。前後は適当に補ってね。
733デフォルトの名無しさん:2009/03/02(月) 21:50:06
どこにも悪魔は出ないだろ・・・
b + 32 は脱参照しなければ合法だし
ポインタは順序付け可能だ(どういう順序になるかは未規定だが)
734デフォルトの名無しさん:2009/03/02(月) 21:55:05
p < b の大小関係が未規定ゆえ、結果が未定義となる
735デフォルトの名無しさん:2009/03/02(月) 22:14:11
どういう順序になるかは未規定だが
順序付け可能とは定義されてるよ
736デフォルトの名無しさん:2009/03/02(月) 22:14:47
結果は未定義じゃなくて未規定
少なくとも鼻から悪魔は出ない
737デフォルトの名無しさん:2009/03/02(月) 22:17:06
When two pointers are compared,
<ばっさり省略>
In all other cases, the behavior is undefined.
738デフォルトの名無しさん:2009/03/02(月) 22:24:43
未規定の動作が生じうる可能性のうちのいずれかに依存したコードには可搬性があるというのか?
739デフォルトの名無しさん:2009/03/02(月) 22:25:46
ばっさり省略しすぎだろwww
同じ型なら比較可能だ
740デフォルトの名無しさん:2009/03/02(月) 22:28:54
>>739
俺も今6.5.8をみていたところだが

> 同じ型なら比較可能だ

これはどこに書いてある?
741デフォルトの名無しさん:2009/03/02(月) 22:29:03
>>739
同じ型でも違うオブジェクトであればだめだよ。
742デフォルトの名無しさん:2009/03/02(月) 22:40:59
ああ、Cだとダメなのか。
C++だといいからCでもいいのかと思った。
743デフォルトの名無しさん:2009/03/03(火) 21:56:44
>742
C++ でも駄目だろ、と思ったけど未規定なのな。
そして std::less とかだと全順序保証、と。
744デフォルトの名無しさん:2009/03/04(水) 00:43:13
Cだとポインタを二分探索木で管理するには
その先の値を見るしかないのか。
その先の値の順番に特に意味が無くても。
745デフォルトの名無しさん:2009/03/04(水) 00:54:51
>>744
先の値の順番に意味がなかったらなにを基準に木構成する気だ
746デフォルトの名無しさん:2009/03/04(水) 11:51:54
ポインタのアドレスそのもので探索する?
747デフォルトの名無しさん:2009/03/04(水) 13:05:25
連続メモリ空間上のポインタなら二分木で管理するまでもないし
そうでないなら比較の保障がない以前に意味がないだろ
748デフォルトの名無しさん:2009/03/04(水) 13:05:56
×空間上のポインタ
○空間上へのポインタ
749デフォルトの名無しさん:2009/03/04(水) 22:25:15
>>744
この世にはデリファレンスできないポインタも存在するわけだが。
750デフォルトの名無しさん:2009/03/04(水) 23:54:43
int にキャストして比較すれば良いんじゃない
751デフォルトの名無しさん:2009/03/04(水) 23:56:45
そしてオーバーフローするんですね、わかります
752デフォルトの名無しさん:2009/03/05(木) 10:58:14
>>750
その比較が意味のあるものとなる保障はない。
それに>>751がいうようにintじゃだめだろう。
753デフォルトの名無しさん:2009/03/05(木) 23:11:20
ポインタをポインタと同じサイズの整数型に変換可能な事は保証されてるから
uintptr_t 使うならええんでないかい?
754デフォルトの名無しさん:2009/03/05(木) 23:14:22
それなら問題ないよ。
755デフォルトの名無しさん:2009/03/21(土) 12:06:23
double v;
としてvがnanやinfinityであるかを判定するにはどうやるんでしょうか?
標準ライブラリ見てもそのような関数が用意されてないので困っています。
v!=vでnanなのは分かっているのですが、他に方法はないのでしょうか。
それと、実数のときと複素数のときの判定方法を教えてください。
一応GCCです。
756デフォルトの名無しさん:2009/03/21(土) 12:33:17
>>755
-std=c99 でisnan、isinfあたり。
757デフォルトの名無しさん:2009/03/21(土) 13:06:48
c99にすれば用意されているのですが、コンパイラ・オプションで指定しないと標準ではinf, nanは判定できないって事ですか?
758デフォルトの名無しさん:2009/03/21(土) 13:20:38
>>757
いちおう、 C99 は「標準」だよ。

gcc のデフォルトは C99 じゃないけど、拡張の一部として isnan, isinf は
使えたりするかもしれない。っていうか、試せばいいよ。
759デフォルトの名無しさん:2009/03/21(土) 13:40:11
そういえばinfinityの判定はやったことなかったけど、今までみんなはどうやってたんだろう・・
760デフォルトの名無しさん:2009/03/21(土) 13:42:21
>>756に書いてあるじゃんw
761デフォルトの名無しさん:2009/03/21(土) 13:54:44
古いAPIを読んでたのでなかったんですが、今後はコーディングするときはC99準拠で必ずやることにします。
762デフォルトの名無しさん:2009/03/21(土) 14:02:39
昔も標準でなかっただけで普通にあった。
isinfinity()の環境もあった。

> 今後はコーディングするときはC99準拠で必ずやることにします。

素晴らしいです。
763デフォルトの名無しさん:2009/03/22(日) 10:12:15
restrictとか可変長配列とか勝手に使うと迷惑になることもあるから気を付けろよ
個人ならいいけど
764デフォルトの名無しさん:2009/03/22(日) 14:04:37
>>763
kwsk
765デフォルトの名無しさん:2009/03/23(月) 13:18:20
>>764
c99ではrestrictは予約語。iccだとオプションを指定すればc++でも使える。
766デフォルトの名無しさん:2009/03/23(月) 16:59:58
ところで今の規格準拠コンパイラは複素数のinf, nanを判定できるのか?
767デフォルトの名無しさん:2009/03/28(土) 01:41:09
Cに複素数なんて概念あったっけ?
768デフォルトの名無しさん:2009/03/28(土) 05:50:48
>>767
c99
769デフォルトの名無しさん:2009/03/28(土) 06:37:18
いい加減、このスレの参加資格に、C99の規格書を読むことを入れとこうぜ
770デフォルトの名無しさん:2009/03/28(土) 09:36:52
771デフォルトの名無しさん:2009/03/28(土) 09:48:37
確かに2009年にもなってC99を知らんのはこのスレ的にはお断りだ
Cを知らないに等しい
772デフォルトの名無しさん:2009/03/28(土) 09:50:19
旧規格もそうと断ったうえでなら可だろ
事実上まだ現役だし
773デフォルトの名無しさん:2009/03/28(土) 10:24:27
C99を実際には使わなくても
知っていなくてはこのスレにいる資格は無いな
774デフォルトの名無しさん:2009/03/28(土) 10:34:44
まあ複素数は置いといて、何かを知らないことをもって C99 を知らないことにされたら
資格者ほとんどいないんじゃね?
775デフォルトの名無しさん:2009/03/28(土) 10:49:42
今規格をあたろうとすると必然的にC99になるからそうでもないと思うが
776デフォルトの名無しさん:2009/03/28(土) 10:58:12
それなら C99 を「知っている」のではなく「規格票にアクセスできる」ことが資格というべきではないか?
777デフォルトの名無しさん:2009/03/28(土) 10:59:29
# 今日はここまで、遊びに出かける
778デフォルトの名無しさん:2009/03/28(土) 11:00:14
でも最低でも>>770くらいのことは知っておいて欲しい
779デフォルトの名無しさん:2009/03/28(土) 12:46:04
コンパウンドリテラルとか便利だけどね。
ただどれがGCC拡張か規格機能なのかよく分からないことがよくある。
それよか、API文章をC99対応にしないと広まらないだろう。
とくにMSDNが率先してC99に対応しないとGNU方面の人たちだけになるんじゃないか?
MSはカオスだしそのうち空中分解しそうだけど。
780デフォルトの名無しさん:2009/03/28(土) 13:42:40
>>779
> MSはカオスだしそのうち空中分解しそうだけど。
突然それまでの話と関係ない一言を最後に入れるあたり、天声人語かと思った
781デフォルトの名無しさん:2009/03/28(土) 13:58:20
コンパウンドリテラルはC++にも欲しい
782デフォルトの名無しさん:2009/03/28(土) 14:24:48
コンストラクタ主義と
コンパウンドリテラルは合わない。

デフォルトコンストラクタのみなら、
リスト初期化子の記法で何とかなりそうではあるけど。
783デフォルトの名無しさん:2009/03/28(土) 14:28:01
配置newで乗り切る。
784デフォルトの名無しさん:2009/03/28(土) 15:09:28
配列のコンパウンドリテラルの代わりになるものは
C++0xにあるんだっけ?
785デフォルトの名無しさん:2009/03/28(土) 15:36:26
まだバタバタしてますがこれ。
Initializer List
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm

initializer-list constructorってのがあって(以下上の提案参照
786デフォルトの名無しさん:2009/03/28(土) 21:27:50
C90に準じていても、それをゆるさない車載標準規約であるMISRA-C。
マジでうざい規約です・・・
787デフォルトの名無しさん:2009/03/28(土) 22:21:01
>>785
かなりバタバタしてる雰囲気がするねw
788デフォルトの名無しさん:2009/03/29(日) 09:28:51
union { char a[4]; int i } u;

というような共用体があったとき、
u.a[0]〜u.a[3]に代入した後、それをu.iで参照するのは未定義でしょうか?
6.5のeffective typeの説明を読む限りではそうなってしまいそうなんですが。
未定義でないとすると、その根拠は規格のどの辺で規定されています?
789デフォルトの名無しさん:2009/03/29(日) 10:43:24
The effective type of an object for an access to its stored value ... ってとこ?
どこに未定義って書いてある?
790デフォルトの名無しさん:2009/03/29(日) 11:11:42
> 4. 規格合致性
> この規格では,このほかに,用語“未
> 定義の動作”を使うことによるか又は動作の明示的な定義を与えないことによって未定義の動作を示すこ
> ともある。
791デフォルトの名無しさん:2009/03/29(日) 11:13:29
>>788
参照はして構わない。値は未定義。
792デフォルトの名無しさん:2009/03/29(日) 12:31:08
多くの実装ではこちらが期待したとおりのビット列として読み出すことができる
しかし規格上は、ある型で与えた値を別の型で読み出せることは保障していない

結論:自己責任
793デフォルトの名無しさん:2009/03/29(日) 12:49:17
>>792
実装の説明には書かれているものなのかな?
たとえば、gccとか。
794デフォルトの名無しさん:2009/03/29(日) 12:54:16
規格で保証してないことを保証してるなら、書いてあることもある。

gccでは保証してないどころか、予想だにしない結果になるんじゃなかったっけ?
-O2 とかだと。
795デフォルトの名無しさん:2009/03/29(日) 13:04:43
いやalignとかpaddingとかオプションで指定できるし。> gcc
それにconfigureで確かめたり、実行時にassertしたりできるでしょ。

ただ何がやりたいのか不明だけど、勝手に想像すると、今時のマナーでは、
#include <stdint.h>
union { uint8_t a[4]; int32_t i; } u;
とするんじゃないのかな。

796デフォルトの名無しさん:2009/03/29(日) 13:08:39
何が今時なのか分からん。
797デフォルトの名無しさん:2009/03/29(日) 13:12:49
sizeof(int) == 4と仮定しない方がいい→今時
798デフォルトの名無しさん:2009/03/29(日) 13:13:10
>>796
サイズが同じなら、予想した動作になるってことかな?
799デフォルトの名無しさん:2009/03/29(日) 13:13:53
charとuint8_tが等価なのも今時なのか?
800デフォルトの名無しさん:2009/03/29(日) 13:18:32
粘着乙
801デフォルトの名無しさん:2009/03/29(日) 13:54:11
char だと 0x80 の値が使えないかもしれないジャマイカ
802デフォルトの名無しさん:2009/03/29(日) 13:57:04
charが9ビット以上である可能性がな・・・
803デフォルトの名無しさん:2009/03/29(日) 13:57:58
>>801
いや、もともとcharで切ってたならcharとしての使い方しかしないでしょ。
なんでuint8_tにするの?ってことなんだけど。
804デフォルトの名無しさん:2009/03/29(日) 14:11:03
>>803
何言っているか意味がわからんが?

> charとしての使い方しかしないでしょ。

ここはC++スレじゃないぜ?
805デフォルトの名無しさん:2009/03/29(日) 18:55:14
C++が何で関係あるのか分からんが
もともとcharで切ってる事自体、
本当によく考え抜かれたものか怪しいことは確か
806デフォルトの名無しさん:2009/03/29(日) 19:05:34
結局 >>788 批判ですかw
807デフォルトの名無しさん:2009/03/29(日) 20:06:01
C++が何で関係あるのか分からんやつは答えなくてよろし
808デフォルトの名無しさん:2009/03/29(日) 21:02:11
みなさま、ご回答ありがとうございます。
intとcharは例が悪かったかも知れませんが、
相談の主旨は

union U { t1 m1; t2 m2; } u;

(ただしt1とt2はcompatibleでない)

に対して、u.m1に書き込んだ値をu.m2で読み込んだときの
言語仕様についてでした。
例だと、

uの表すobjectのeffective typeはunion U
u.m1の表すobjectのeffective typeはt1
u.m2の表すobjectのeffective typeはt2

になるわけですが、u.m1とu.m2の表すobjectが同じものと考えれば、
1つのobjectがt1とt2という2つのeffective typeを持つ。
だから、u.m1に書き込んだ値をu.m2で読み込むのは許される。
ただし、読み込まれる値については未規定である。

という理解でよいのでしょうか?
809デフォルトの名無しさん:2009/03/29(日) 22:29:36
そだね。
810デフォルトの名無しさん:2009/03/29(日) 22:32:37
CとC++でcharの扱いが全く違うことは、
まあスレ違いなんで知らなくてもいいけど、
Cのcharがintegral typeでintegral promotionの対象、
ANSIでも"as is"が認められているだけってことは知っておかないと。
811デフォルトの名無しさん:2009/03/29(日) 23:44:30
>>809
適当なことを言わないように
812デフォルトの名無しさん:2009/03/31(火) 08:00:10
Cの言語仕様というと、俺はいまだにK&Rなんだが。
813デフォルトの名無しさん:2009/04/01(水) 22:59:50
>>788
どうせおもいっきり環境依存なんだから、
面倒なことしないで、
char a[4]; にセットして
*(int*)a で読んじゃえ。
814デフォルトの名無しさん:2009/04/01(水) 23:08:51
>808
> になるわけですが、u.m1とu.m2の表すobjectが同じものと考えれば、
とあるが、共用体のメンバに対応するオブジェクトはすべて同じなのか?
大きさも型も違うのに。

むしろ同じアドレスだけど、オブジェクトは別と考えるのが自然だと思う。
815デフォルトの名無しさん:2009/04/01(水) 23:15:21
static_assert(期待通りの値が入ってるかどうか) をどっかに入れておけばいい。
816デフォルトの名無しさん:2009/04/01(水) 23:15:40
>>813
strict aliasing rule違反じゃね?どうなの?
817デフォルトの名無しさん:2009/04/01(水) 23:30:28
>>816
大丈夫なCPUとダメなCPUがある。
x86系は大丈夫。

逆の方が適用可能な範囲が広いか。
int a; を ((char*)&a)[0〜3] で書く。
818デフォルトの名無しさん:2009/04/02(木) 02:58:14
>>816
違反。

逆に int a; を用意して (char*)&a 経由でセットし、その後 a を読むのなら OK 。
819デフォルトの名無しさん:2009/04/05(日) 00:23:29
なんでC言語には累乗計算の為の演算子がないのですか?
820デフォルトの名無しさん:2009/04/05(日) 00:43:38
累乗計算命令を積んでるCPUが少ないからだ
821デフォルトの名無しさん:2009/04/07(火) 22:39:16
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
822デフォルトの名無しさん:2009/04/07(火) 22:50:23
おーい誰か久弥の行方を
823デフォルトの名無しさん:2009/04/07(火) 23:08:39
>>821
スレタイ嫁
824デフォルトの名無しさん:2009/04/08(水) 01:25:20
ビットシフトってなんだっけ〜? あれえ〜
ビットを動かしたりするんかな〜僕ちゃんわかんない
825デフォルトの名無しさん:2009/04/08(水) 08:38:06
>>821
飽きた。
826デフォルトの名無しさん:2009/04/08(水) 11:15:48
しかし久しぶりに見たw
827デフォルトの名無しさん:2009/04/09(木) 10:33:48
ビットシフトって何?
828デフォルトの名無しさん:2009/04/09(木) 10:45:39
sprintf(str, "%s %d%d", str, arg1, arg2);
みたいな文字列追加をしたいんだけど、この書き方は未定義だよね

エレガントにかくためには
sprintf(strrchr(str, '\0'), "%d%d", arg1, arg2);
でいいのかな?
829デフォルトの名無しさん:2009/04/09(木) 10:49:16
>>828
最初のは出力先が入力とかぶってるんで未定義。

strchr() だと元々 '\0' の検索が入ってて引数の検索とダブるから、
sprintf(str + strlen(str), "%d%d", arg1, arg2) のほうがいいだろう。
830デフォルトの名無しさん:2009/04/09(木) 12:31:54
十分な領域を確保します。
831デフォルトの名無しさん:2009/04/09(木) 12:47:12
>>828
>829の寝言は無視して、str + strlen(str)かstrchr(str, '\0')か、strrchr(str, '\0')でもいい。
ちょっと考えてみれば判ることだが、どの関数も原則的に先頭から'\0'を探すと言う動作を一回しか行なわない。
もしどうしてもパフォーマンスが気になるのであれば、実測して較べるしかない。
832デフォルトの名無しさん:2009/04/09(木) 12:53:14
>>829
「ダブる」とは,具体的にどのような事象として定義されますか?
833デフォルトの名無しさん:2009/04/09(木) 17:04:26
ってかビットシフトって何なんだ?
聞いたことないが
834デフォルトの名無しさん:2009/04/09(木) 19:27:36
ggrks
835デフォルトの名無しさん:2009/04/09(木) 22:16:29
ビットシフトはググってもヒットしないが
836デフォルトの名無しさん:2009/04/09(木) 22:57:32
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
837デフォルトの名無しさん:2009/04/09(木) 23:22:08
ビットシフトの存在価値がよく分からないんですが・・・
838デフォルトの名無しさん:2009/04/10(金) 01:01:30
スレ違いなのでお帰りください
839デフォルトの名無しさん:2009/04/10(金) 02:11:06
ビットシフトがスレ違いだと……!?
840デフォルトの名無しさん:2009/04/10(金) 02:21:53
ビットシフトが何の役に立つのか分からない人は明らかにCの初心者です
このスレは初心者が来るスレではないのでスレ違いです
841デフォルトの名無しさん:2009/04/10(金) 02:26:42
>>831-832
strchr(p, c) の中では↓に相当するループが実行されることになるだろ。
for (; *p != '\0'; ++p) { if (*p == c) return p; }
ここで c が '\0' なら同じ比較が繰り返されてることになり、無駄。

効率以外に strchr() の意味を考えても、引数に '\0' を渡すことの意図を
理解するには追加の情報が必要になり、無駄。
842デフォルトの名無しさん:2009/04/10(金) 02:36:58
>>841
前半はともかく後半はおかしい
探索文字に\0を渡したらそれは終端を探してそのポインタを得るという意味に決まってる
843デフォルトの名無しさん:2009/04/10(金) 02:41:21
>>842
あぁ実際の仕様ではそうだな。

「文字列の中から文字を探す」という(名前から考えてごくあたりまえな)認識では
理解しにくいってことね。直感的にはヌル終端文字列の「中」に '\0' は含まれない。
844デフォルトの名無しさん:2009/04/10(金) 08:41:14
確かに'\0'は文字列の外という感じだな。
845デフォルトの名無しさん:2009/04/10(金) 09:20:22
strlen()派の意見は出尽くしたかな?
strchr(), strrchr()派の意見はない?w

私としては、「ナル文字を探す」という関数がない以上、strchr()でもいい気はするんだけどね。
(例によって)目的が若干違っても実装が変わらないから流用するパターンってことで。
寧ろ、>843の思想からすればmemchr()の方が適切なのか? それはそれで違う気がするけど。
846デフォルトの名無しさん:2009/04/10(金) 09:37:47
catsprintf()…標準外ですね
847デフォルトの名無しさん:2009/04/10(金) 09:52:21
>>841
どうでもいいけど実装するとしたらこう。
for (; *p != '\0'; ++p) { if (*p == c) break; }
if (*p == c) return p; else return NULL;

以下のように実装して'\0'ではうまく動かないlibcありそう。
for (; *p != '\0'; ++p) { if (*p == c) return p; }
return NULL;
848デフォルトの名無しさん:2009/04/10(金) 10:10:11
どうせそれを言うならこうだ

for( ; *p != c ; ++p) if(*p=='\0') return NULL;
return p;
849デフォルトの名無しさん:2009/04/10(金) 11:21:13
規格関連の話かと思ったら単なる「無駄だからやめれ」かよ
850デフォルトの名無しさん:2009/04/10(金) 11:41:59
あげればいいのかな?
851デフォルトの名無しさん:2009/04/10(金) 15:20:14
>以下のように実装して'\0'ではうまく動かないlibcありそう。
>for (; *p != '\0'; ++p) { if (*p == c) return p; }
>return NULL;

文字列の「中」に'\0'は含まれない派にとっては
こっちが正しい実装だな。
852デフォルトの名無しさん:2009/04/10(金) 15:21:29
規格上は終端ヌル文字も検索対象に含まれることになってる
853デフォルトの名無しさん:2009/04/10(金) 15:23:31
本質的には'\0'までで文字列だよ、無いということはありえないんだから
文字列の長さと文字列の大きさは違う
854デフォルトの名無しさん:2009/04/10(金) 15:45:40
末尾が\0なものを「文字列」というわけだが。
\0も文字列の一部であるに決まっておろう。
855デフォルトの名無しさん:2009/04/10(金) 16:04:31
>>853-854
こういう議論が発生したりそういう説明が必要になる点を指して >841 の
「追加の情報が必要に」って話だろ。やっぱり strlen() 使ったほうがマシだ。
856デフォルトの名無しさん:2009/04/10(金) 16:37:18
>>855
ガチすれで何を言っている。

規格に「文字列」の定義があるんだから
追加の情報も何も無い。自明なことだ。
857デフォルトの名無しさん:2009/04/10(金) 16:48:03
で、ビットシフトってどうやんの
858デフォルトの名無しさん:2009/04/10(金) 16:48:44
じゃあstrlenが返す値は何だよ。
長さの元の文字列に'\0'は入らないだろ。
859デフォルトの名無しさん:2009/04/10(金) 16:49:16
こうやるの。
a >>= 2;
a <<= 1;
860デフォルトの名無しさん:2009/04/10(金) 16:53:35
>>858
長さと大きさは違うと>>853が教えているだろうに。
861デフォルトの名無しさん:2009/04/10(金) 17:16:14
862デフォルトの名無しさん:2009/04/10(金) 21:24:44
863デフォルトの名無しさん:2009/04/10(金) 21:38:21
864デフォルトの名無しさん:2009/04/10(金) 21:53:54
865デフォルトの名無しさん:2009/04/10(金) 22:42:08
866デフォルトの名無しさん:2009/04/10(金) 22:43:20
7.21.5.2 The strchr function
Synopsis
1 #include <string.h>
char *strchr(const char *s, int c);
Description
2 The strchr function locates the first occurrence of c (converted to a char) in the
string pointed to by s. The terminating null character is considered to be part of the
string.
Returns
3 The strchr function returns a pointer to the located character, or a null pointer if the
character does not occur in the string.
867デフォルトの名無しさん:2009/04/11(土) 18:52:05
結局ビットシフトって何の役に立つんですか?
868デフォルトの名無しさん:2009/04/11(土) 19:08:34
ここに答えられる奴はいないからw
869デフォルトの名無しさん:2009/04/11(土) 20:10:37
きになる
870デフォルトの名無しさん:2009/04/12(日) 00:38:47
あげるか
871デフォルトの名無しさん:2009/04/12(日) 00:40:41
>>867
あなたにはこのスレは早すぎます
初心者スレで聞いてください
872デフォルトの名無しさん:2009/04/12(日) 13:21:00
あげるよ
873デフォルトの名無しさん:2009/04/14(火) 12:13:15
ください
874デフォルトの名無しさん:2009/04/14(火) 12:20:58
なるほど、「スレッドを上げる」という宣言に対して、意図的に「何かモノをあげる」とミスリードして
「ください」と返答すると言う、言葉遊びなわけですね? これは面白い。
875デフォルトの名無しさん:2009/04/16(木) 21:19:16
hoge_t *p = malloc(sizeof *p);

というのはC89で合法的ですか?
教えてください。
876デフォルトの名無しさん:2009/04/16(木) 21:28:37
なぜ合法的でないかもと思ったんだ?
877デフォルトの名無しさん:2009/04/16(木) 21:30:13
合法に決まっている
何もおかしいところはない

ただ、君が想像している動作を実行してくれるコードではないかもしれない
878デフォルトの名無しさん:2009/04/16(木) 23:01:28
>>876
変数のスコープがどこから始まるかわからなかったからです。
879デフォルトの名無しさん:2009/04/16(木) 23:05:11
そこまではいいが、なぜ便所の落書きに確認に来るんだ? 相手が違うだろー
880デフォルトの名無しさん:2009/04/16(木) 23:08:29
便所の落書きであっても人類の生み出した物である以上、
なんらかの意味を持っていると考えられるからです。
881デフォルトの名無しさん:2009/04/17(金) 04:05:37
>>874
「ミスリード」の用法覚えてから来い
882デフォルトの名無しさん:2009/04/17(金) 08:17:56
Verb
to misread (third-person singular simple present: misreads; present participle: misreading; simple past and past participle: misread)
 1. To read wrongly, normally by accident.
883デフォルトの名無しさん:2009/04/17(金) 11:21:50
英和辞書との一致 (1〜2件目 / 2件) 検索辞書:プログレッシブ英和中辞典 提供:JapanKnowledge

mislead
[動](-led, 〜・ing)(他) 1 〈人を〉誤った方向に導く[案内する];〈人を〉(…に)誤り導く((into ..., doing))
884デフォルトの名無しさん:2009/04/17(金) 22:19:29
Main Entry: mis・read
Pronunciation: \?mis-?r?d\
Function: transitive verb
Inflected Form(s): mis・read \-?red\ ; mis・read・ing \-?r?-di?\
Date: 1658
1 : to read incorrectly
2 : to misinterpret in or as if in reading <totally misread the lesson of history ? Christopher Hollis>


Main Entry: mis・lead
Pronunciation: \?mis-?l?d\
Function: verb
Inflected Form(s): mis・led \-?led\ ; mis・lead・ing
Date: before 12th century
transitive verb
: to lead in a wrong direction or into a mistaken action or belief often by deliberate deceit
intransitive verb
: to lead astray : give a wrong impression
885デフォルトの名無しさん:2009/04/19(日) 05:20:30
>>875
未初期化のポインタをデリファレンスしてるから未定義動作だな
sizeofの中だから実際に参照するわけではないとはいえ未定義は未定義
886デフォルトの名無しさん:2009/04/19(日) 06:53:50
sizeofのオペランドは評価されず、sizeof式の値はオペランドの型で決まる。
(ただし、オペランドが可変長配列の場合を除く)

よって>>885は誤り。
887デフォルトの名無しさん:2009/04/28(火) 22:53:31
0xFFFFFFFF
この定数は signed なのでしょうか、unsigned なのでしょうか、
それとも文脈によって判断されるのでしょうか?
888デフォルトの名無しさん:2009/04/29(水) 00:26:02
特に何もないかぎり、ほとんど全ての型はint型になる
つまり以下略
889デフォルトの名無しさん:2009/04/29(水) 00:38:48
規格は読んだこと無いが
いわゆる汎整数格上げと同様に扱われるとどこかで読んだ。
要はintで収まるならint、だめならunsigned int、それでも駄目ならlong、さらにはunsigned long、とね。
例えばintが16bitな環境ならば、unsigned longになるだろうし
同64bitであるならば(signedな)intになるだろう。
必要ならばUやLなどを付加して扱うことも出来る。

0xFFFFFFFFに関しては、unsigned longには確実に収まることが保証されているから
それ以上の幅を要する(独自拡張の)型として扱われることは無い。

ただし、C++においての''で囲まれた定数はcharやwchar_t(及びその符号有無の派生型)とされ
intとしては扱われないはず。
これらは、C(C89)においてはint。
890デフォルトの名無しさん:2009/04/30(木) 01:44:40
>>889
BCCでint64に代入したら-1になったぞ?
891890:2009/04/30(木) 01:50:09
ごめん勘違いだった
892デフォルトの名無しさん:2009/04/30(木) 22:45:38
フルートの最低音の C が出せないのですが、どうしたらいいですか?
893デフォルトの名無しさん:2009/04/30(木) 23:36:28
練習すればいい。
894デフォルトの名無しさん:2009/05/03(日) 05:58:49
どう練習したらいいですか?
895デフォルトの名無しさん:2009/05/03(日) 12:21:25
吹いて吹いて吹きまくれ
896デフォルトの名無しさん:2009/05/07(木) 12:23:20
>>892
オーパッキャラマド
897デフォルトの名無しさん:2009/05/14(木) 11:26:01
C99って、けっこう変な構文入ってたんだね。
VC++でも対応してくれないかな。
898デフォルトの名無しさん:2009/05/14(木) 11:52:46
>>897
変な構文って何?
899デフォルトの名無しさん:2009/05/14(木) 12:16:55
>>897
このスレで世間話たぁいい度胸だ!
900デフォルトの名無しさん:2009/05/14(木) 12:22:09
901デフォルトの名無しさん:2009/05/14(木) 16:29:10
いいよC99なんて廃れる一方だから
902デフォルトの名無しさん:2009/05/14(木) 16:54:54
名前で初期化は有用だろう?
903デフォルトの名無しさん:2009/05/14(木) 17:20:05
現在、マルチプラットフォーム(主にLinux向け)なフリーソフトウェア(フリーソフトウェア != オープンソースソフトウェア)
をISO/IEC 9899 : 1990 (E)[以下C90]準拠で開発中です。
ライブラリは、7割くらい完成しており、よりパフォーマンスをよくしたバージョン(ISO/IEC 9899 : 1999 (E)[以下C99]準拠)
も条件コンパイルなどでコンパイルできるようにしています。
つまり、最小限のC99準拠で作りつつC90でもコンパイル可能なようにしている状態です。

この度、マクロの引数が空の場合の性質、つまり、C99の6.10.3.2 The # operatorの
2 The character string literal corresponding to an empty argument is "".
という性質、を使いたいと考えています。

これをC90で同じようなにするにはどうすればよいでしょうか。
最悪の場合、今後はC99準拠だけで進めることも考えています。

ああ、C90の亡霊に取り付かれたか。C1xに期待しよう。
904デフォルトの名無しさん:2009/05/14(木) 18:56:33
>>898
コンパウンドリテラルだろ。jk

最近は慣れてきて、便利でラクだから
けっこう使うけど、冷静になるとやっぱり
ちょっとキモい。
905デフォルトの名無しさん:2009/05/14(木) 18:58:04
>>903
>この度、マクロの引数が空の場合の性質、つまり、C99の6.10.3.2 The # operatorの
>2 The character string literal corresponding to an empty argument is "".
これって具体的には何のこと?
906デフォルトの名無しさん:2009/05/14(木) 19:23:37
>>905
例えば、
$ cat hashop.c

#include <stdio.h>

#define Foo(Bar, Baz) \
fprintf(stderr, # Bar # Baz "\n")

int
main(void)
{
Foo(foo, bar);
Foo(foo, );
Foo(, bar);

return 0;
}

/* EOF */

$ ./hashop
foobar
foo
bar
のようになるわけです。
ちなみに、C90では、置換リストが空では、有効な文字列は作れないので未定義の動作です。
3.8.3.2 The # operator
... If the replacement that results is not a valid character string literal,
the behavior is undefined.

そこをなんとか似たようなマクロが作れないかと考えているところです。
907デフォルトの名無しさん:2009/05/14(木) 19:41:30
#define _ ""
Foo(_, _);
Foo(foo, _);
Foo(_, bar);
908デフォルトの名無しさん:2009/05/14(木) 19:52:03
>>907
しかしそれでは、プロジェクト全体で、
_
を使うなということになるではないですか。

いやもっと深刻な事に、
_
を含む標準関数や他のライブラリも使えないことになりますので、
まったく解決になっていませんね。
909デフォルトの名無しさん:2009/05/14(木) 20:00:19
>>909
まさか。_一文字の標準関数なんかあるもんかいw
910デフォルトの名無しさん:2009/05/14(木) 20:04:20
宿題スレでこんなのがあったぞ。

751 名前: デフォルトの名無しさん Mail: sage 投稿日: 2009/05/13(水) 09:23:27
じゃあ同じO(n)でももっと変態な方法を

typedef struct { int a, b; } intx2;

intx2 fib2(int n) {
if (n == 0) {
return (intx2){ 0, 1 };
} else {
intx2 s = fib2(n - 1);
return (intx2){ s.b, s.a + s.b };
}
}

int fib(int n) {
return fib2(n).a;
}
911デフォルトの名無しさん:2009/05/14(木) 21:22:47
>>910
C99のソースは無視しろ
オナニーに過ぎない
912デフォルトの名無しさん:2009/05/14(木) 21:26:49
ちゃんとコンパイルできるんだし別にいいじゃん。
コンパウンドリテラルや for (int i=0; ...) みたいな書き方や
ブロック内の文の後の宣言なんてもう普通に使うだろ?
913デフォルトの名無しさん:2009/05/14(木) 22:31:29
>>909
さすがに_が識別子な標準関数は、わたしも見たことないです。しかし、準拠と名乗る限り_は識別子として利用できないです。

C90
4.1.2 Standard headers
... All external identifiers that begin with an underscore are reserved.
All other identifiers that begin with an underscore and either an
upper-case letter or another underscore are reserved. If the program
defines an external identifier with the same name as a reserved
external identifier, even in a semantically equivalent form, the
behavior is undefined.
ということで、_, _identifier, _A, _B, ..., _Z, __は、予約済みのようで、
ぶつかったら未定義の動作です。

C99
7.1.3 Reserved identi?ers
- All identi?ers that begin with an underscore and either an uppercase letter or another
underscore are always reserved for any use.
- All identi?ers that begin with an underscore are always reserved for use as identi?ers
with ?le scope in both the ordinary and tag name spaces.
ということで、_A, _B, ..., _Z, __は、いろんな用途に備えて常に予約済みで、
_, _identifierは、普通の名前空間やタグ名の空間においてファイルスコープとして
識別子を使うことに備えて常に予約済みのようです。

identifierについては、それぞれの規格のidentifiersの項に従います。
C90では、使うべきでないで、C99は、ファイルスコープだから使っても良さそうかもです。

#define _ ""
は一応候補にあげさせていただきます。
C99準拠にすれば、すべて解決するわけで、さらばC90の亡霊forever~~といきたいところでもあります。

文字化け警告が出ています。このレスは文字化けをしているかもしれません。
914デフォルトの名無しさん:2009/05/14(木) 23:22:24
Intel C++はC99に100%準拠しているが俺にIntel C++を買えと申すか
GCCは100%C99に対応してないので使わないようにしている
915デフォルトの名無しさん:2009/05/15(金) 03:18:24
試しに
#define _ ""
がうまくいくかやってみました。
あっさりダメでした。おそらく、プリプロセッサのフェイズによるモノと思われます。
今日は忙しいので、休日にでも規格書を眺めようと思います。

しかし、ここで気がつきました。
$ cat hashop.c

#include <stdio.h>

#define ToStr(s) \
# s
#define Foo(Bar, Baz) \
fprintf(stderr, "%s%s\n", \
(ToStr(Bar)[0] == '#') ? "" : ToStr(Bar), \
(ToStr(Baz)[0] == '#') ? "" : ToStr(Baz) \
)

int main(void) {
Foo(foo, bar);
Foo(foo, #);
Foo(#, bar);

return 0;
}
例えば、このようなものを。
#は、プリプロセッサディレクティブの始めを表すため、
先頭は、空白であり、後ろは、ディレクティブである必要があります。
また、# operatorは、マクロ内でしか使えないので、#単独は、ありえない構文となってくれます。
本来、省略したかった引数ですが、#が必要になって少し美しくなくなりましたね。
結果は、>>906と同様。一連の流れ、>>903,905-909,913,915
916デフォルトの名無しさん:2009/05/15(金) 11:53:24
>>908
>_
>を含む標準関数や他のライブラリも使えないことになりますので
どういう勘違いなんだコレ。
917デフォルトの名無しさん:2009/05/15(金) 12:02:50
頭悪いだけだろ
918デフォルトの名無しさん:2009/05/15(金) 14:29:12
そんなトリッキーな書き方が必要なのは、そもそも
そういう書き方を必要とするコードというか、
やりかたのほうが間違ってる気がするんだけど...

#define Foo(A, B) A##B
#define Foo1(A) Foo(A, "")
#define Foo2(B) Foo("", B)

みたいなのではダメなのか
919デフォルトの名無しさん:2009/05/15(金) 14:52:11
だめだろ。
920デフォルトの名無しさん:2009/05/17(日) 19:39:43
なにもわかっちゃいねえな
921デフォルトの名無しさん:2009/05/26(火) 14:16:09
C99で
int a[i];
みたいに配列を扱えるようになったけど、
これってC++でもサポートされてる?
922デフォルトの名無しさん:2009/05/26(火) 16:08:16
>>921
貴様はスレタイ読めないのか…
923デフォルトの名無しさん:2009/05/30(土) 11:25:19
以下の13行目のキャストは、規格的に問題ないでしょうか。
知りたいのは、const外しをしていることです。
なぜ、このようにしているかは、ヒープからオブジェクトを作ったときにconstなメンバを初期化したいからです。
$ cat -n piyo.c
1
2 #include <stdlib.h>
3
4 struct foo{
5 int * const piyo;
6 };
7
8 int main(void)
9 {
10 struct foo *fuga = malloc(sizeof(struct foo));
11 int i = 0;
12
13 *(int **)&fuga->piyo = (int *)&i;
14
15 free(fuga);
16
17 return 0;
18 }
19
20 /* EOF */
21
実際には、もっと複雑ですが、動作する最小限のコードにしました。
一応、コンパイラとバージョンを以下に示しておきます。
$ gcc --version
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
924デフォルトの名無しさん:2009/05/30(土) 11:38:39
>>923
規格上問題は無いはず。

しかして*(int **)&fuga->piyo = &i;で十分ジャマイカ?
(int *)は冗長。
925デフォルトの名無しさん:2009/05/30(土) 12:55:47
つーか、fuga->piyo = &iでいいのでは?
926デフォルトの名無しさん:2009/05/30(土) 14:46:23
>>925
constが目に入らないの?
927デフォルトの名無しさん:2009/05/30(土) 15:00:37
>>923
C99なら複合リテラルとか。
*fuga = &(struct foo){&i};
928デフォルトの名無しさん:2009/05/30(土) 15:01:32
ま た C99厨 か
929デフォルトの名無しさん:2009/05/30(土) 15:21:58
#define const
930デフォルトの名無しさん:2009/05/30(土) 15:23:32
>>928過敏症いらね。
今の規格はC99です。
931デフォルトの名無しさん:2009/05/30(土) 15:32:05
>>930
10年たってもコンパイラがないようでは。
932デフォルトの名無しさん:2009/05/30(土) 15:34:57
>>930
そういう事
君の言っている事は現場では机上の空論に過ぎない
933デフォルトの名無しさん:2009/05/30(土) 15:47:56
既にあるものをないことにしたいんですね、判ります。
934デフォルトの名無しさん:2009/05/30(土) 15:48:45
GCCがC99にほとんど対応してだいぶたつのに、
ttp://gcc.gnu.org/c99status.html
まだ脳味噌が10年前な奴がこんなにいるのか。
935デフォルトの名無しさん:2009/05/30(土) 15:51:39
「ほとんど対応してだいぶたつ」というのは、
「いつまでたっても完全対応しない」ってことかな。
936デフォルトの名無しさん:2009/05/30(土) 15:52:07
>>934
ほとんどってどの位?
%で表してみ
どっかにステータス表があったと思うけど

それからお前は人にgccを使う事を強要する権利はない
937デフォルトの名無しさん:2009/05/30(土) 15:53:24
ただ存在すると書いているだけなのに、強要したことにしたいんですね、判ります。
938デフォルトの名無しさん:2009/05/30(土) 15:53:45
開発に使うコンパイラがC99対応してない
頭を切り替えてC89でコーディング->普通
頭を切り替えできずコンパイラをこき下ろす->開発者に向いてない

それだけ
939デフォルトの名無しさん:2009/05/30(土) 15:55:48
ISO/IECの認定を受けたからと言って既に終わってる言語はたくさんある
FULL-BASICとかLOGOとか
940923:2009/05/30(土) 15:58:00
多くの方ありがとうございます。話が別の方に行ってしまっているような気がしますが・・・。

>>924
たしかに、C言語では、不必要なキャストですね。

>>927
言うのを忘れていましたが、C89(ANSI X3.159-1989)準拠でお願いします。
C99(ISO/IEC 9899 : 1999 (E))準拠の方は、オナニーしたいだけでしょうか。

Rationale for American National Standard for Information Systems - Programming Language -C
の3.5.3 Type qualifiersには、The Committee considered making const and volatile storage classes,
but this would have ruled out any number of desirable constructs,
such as const members of structures and variable pointers to const types.
とあり、そもそもconstな構造体メンバを作るべきではない感じなのですよ。

同3.3.4 Cast operatorsには、It is possible to cast a pointer of some qualified type (§3.5.3)
to an unqualified version of that type. Since the qualifier defines some special access or aliasing property,
however, any dereference of the cast pointer results in undefined behavior.
とあり、可能である。しかし、修飾子は、特別なアクセスや別の属性?を規定するので、
キャストしたポインタのいかなる逆参照も未定義となる。
つまり、規格では、以下の形を未定義としているようです。
const T var; *(T *)&var;
今回の場合、typedef int *T;とすれば、規格未定義形と同じ形になります。
const T var => int * const varになりますから。

みたいなのですが、今回は、ヒープに取ったただのバイト列ですし、
ポインタなんてただのビット列ではないか、変更しても問題ないだろというのが私の結論です。

私では、解決できそうにないので、誰か優秀な言語弁護士さんは、いらっしゅいませんか。
-Wcast-qual付けると、警告してくれますので、やらない方がいいのかなといいのかな、と思いつつあります。
941デフォルトの名無しさん:2009/05/30(土) 16:00:07
結論、constを剥がしたいと思う時点で間違い。
間違いを承知で突き進むのなら、自分の思うがままに進めばいいだけ。
942デフォルトの名無しさん:2009/05/30(土) 16:09:33
>>935
じゃあc89に「完全」対応してる処理系を挙げてみろよ。
943デフォルトの名無しさん:2009/05/30(土) 16:19:47
>>942
話を逸らすなよみっともない (´ー`)y─┛~~
944デフォルトの名無しさん:2009/05/30(土) 17:03:33
たとえC99完全準拠コンパイラを使おうとも、C99の機能なんか使うべきではない
C89やC++への移植性が失われる上に、単独でも有害な機能ばかりだ
945デフォルトの名無しさん:2009/05/30(土) 17:31:56
>>940
それはもう規格スレの範囲じゃないような。
946デフォルトの名無しさん:2009/05/30(土) 19:49:37
規格的にはOKでしょ。心情的に気に入らないみたいだけど
947デフォルトの名無しさん:2009/05/30(土) 20:09:09
>>941
間違いではない。
const外しは規格として問題がないはず。

ただし、その結果は保証されないだけ。w

948デフォルトの名無しさん:2009/05/30(土) 21:21:11
結果が保証されない、というのは弱い言い方だな
要は未定義だ
949デフォルトの名無しさん:2009/05/30(土) 21:28:34
そもそも>>927がC99でもコンパイルエラーだと指摘するのが先決ではないだろうか。
この中で927が一番C99を語る資格がないと思う。
950947:2009/06/01(月) 02:31:06
>>948
違う。いわゆる未定義ではない。

記述としては正しいが、書き込んだ先が
ROMでないことは保証されないだけ。
言語規格と実行環境は別の話。
951デフォルトの名無しさん:2009/06/01(月) 08:39:39
ROMなんて言葉を使ってないで、規格を読んでください。
952デフォルトの名無しさん:2009/06/13(土) 22:16:24
C言語をはじめたばかりであまりわからないのですが、
ビットシフトはなんの役に立つのでしょうか?
953デフォルトの名無しさん:2009/06/13(土) 22:32:32
>>952
例えば、32bit符号無し整数の変数があり、
先頭から8bitごとにARGBを表しているとする。
(32bit画像の1画素)

すると例えば、値を使用する前に2つを分離しなければならないから、
以下のようにする。

a = (x >> 24);
r = 0xFF & (x >> 16);
g = 0xFF & (x >> 8);
b = 0xFF & x;
954953:2009/06/13(土) 22:34:12
なんだ、コピペか。
普段読まないスレなので、答えてしまった。
スレ汚しスマソ。
955デフォルトの名無しさん:2009/06/15(月) 03:04:50
普段読まないスレにきてスレ違いの話題に答えていくってどんな荒らしだよw
956デフォルトの名無しさん:2009/06/15(月) 03:14:38
よくあること。
957デフォルトの名無しさん:2009/06/15(月) 04:54:29
暇なら規格書読んどけ。
958デフォルトの名無しさん:2009/06/16(火) 03:22:24
C言語を始めようと思うのですが、ビットシフトはありますか?
959デフォルトの名無しさん:2009/06/16(火) 03:52:24
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
あります
961デフォルトの名無しさん:2009/06/16(火) 10:02:35
962デフォルトの名無しさん:2009/06/17(水) 14:17:40
Type 型オブジェクトの配列への参照を受け取る関数を定義するとき
f( Type* array, size_t size ) と f( Type array[], size_t size ) は
どのように使い分けるのでしょうか?
963デフォルトの名無しさん:2009/06/17(水) 15:29:46
あんま意識してないが、元が配列なら array[]、
そうでなけりゃ *array に (だったら名前として array はないが)
してる…かなあ。
964デフォルトの名無しさん:2009/06/17(水) 15:34:24
そういや、&配列名って正式にOKになったんだっけ?
965デフォルトの名無しさん:2009/06/17(水) 18:43:33
>>962
その区別にたいした意味はない。

使い分けなんか考えずに、かならず
ポインタ型にしとくのがいいと思う。

>>964
大昔からおk。
966デフォルトの名無しさん:2009/06/17(水) 23:34:00
そもそも同義だから、使い分けはコーディングスタイルの管轄
967デフォルトの名無しさん:2009/06/18(木) 18:33:21
うどんがヤバイのですが、どうしたらいいですか?
968デフォルトの名無しさん:2009/06/18(木) 18:45:19
ゆですぎただけなら冷水でしめてしまえばいいよ。
乾麺のカビなら、餅と同様に取ればいい、が、面倒。
969デフォルトの名無しさん:2009/06/18(木) 18:45:21
まず匂いかいでみたら?
970デフォルトの名無しさん:2009/06/24(水) 17:35:06
以下を実行した後は必ず b == p は成り立つでしょうか?

Type* p = malloc( sizeof( Type ) );
size_t a = (size_t)p;
Type* b = (Type*)a;
971デフォルトの名無しさん:2009/06/24(水) 18:04:40
それは、size_t≧ポインタという保証はあるか、ってことか。
ついでに低レベルなことを聞かせてくれ、すべてのポインタ型が同じサイズという保証はあるの?
972デフォルトの名無しさん:2009/06/24(水) 18:42:53
>>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がポインタを格納できる大きさだという保証はない。
973デフォルトの名無しさん:2009/06/24(水) 22:32:52
>>971
ない。
974デフォルトの名無しさん:2009/06/24(水) 22:44:52
>>972
なるほど C89 では特定の処理系を前提としないと無理みたいですね。
整数に単射変換できるとポインタ値をキーとした辞書を作ることができるのですが。
C++ の std::less<Type*> に相当するポインタ比較はできないかな。
975デフォルトの名無しさん:2009/06/25(木) 05:26:54
>>974
残念ながらできない。
976デフォルトの名無しさん:2009/06/25(木) 13:26:18
>>974
uintptr_tを使えばいいじゃん。
なければ自分で定義したっていいんだし。
977デフォルトの名無しさん:2009/06/25(木) 13:35:22
>>976
アホ?uintptr_tはC99以降だし、C99準拠でも存在すると限らない。
それに、標準Cの範囲内でuintptr_tを使わずにuintptr_tを定義することは出来ない。
978デフォルトの名無しさん:2009/06/25(木) 18:49:23
>>977
アホ?
Cは自分で動作保証するもの。
わかったうえでtypedefするなら問題ない。
979デフォルトの名無しさん:2009/06/25(木) 21:49:26
別のスレいけよカス
980デフォルトの名無しさん:2009/06/25(木) 21:56:19
・規格に準拠した実装を自分でしたい奴
・規格に準拠した実装にこだわる奴

どっちでもよかろう。けんかすんな。
981デフォルトの名無しさん:2009/06/25(木) 22:06:30
質問者は標準Cの範囲内で出来るかどうか効いているのに、
なんで自分でtypedefしろとか言い出すわけ?意味不明だわ。
完全にスレ違いだろ。
982デフォルトの名無しさん:2009/06/25(木) 22:32:42
動きゃええんや
標準なんてクソ食らえやwwwwwwwww
983デフォルトの名無しさん:2009/06/25(木) 22:41:48
俺が標準だ!
984デフォルトの名無しさん:2009/06/25(木) 23:10:41
動かなくても<丶`∀´>ケンチャナヨ
985デフォルトの名無しさん:2009/06/25(木) 23:17:50
>>981
標準Cにtypedefがあるからじゃないの?
・標準Cでtypedefをしたところで、uintptr_tと全く同じものを作ることはできない
・標準Cでは実現できない部分をしっかり把握した上でtypedefすればよい
という話だと思う。よくわからんけど。
986デフォルトの名無しさん:2009/06/25(木) 23:22:00
別に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
987デフォルトの名無しさん:2009/06/25(木) 23:40:01
わかんないなら黙ってろよ…
さすがに外しすぎ。
988デフォルトの名無しさん:2009/06/26(金) 19:25:51
問題:
 処理系に依存せずにuintptr_t相当の型を定義できるか?

>986の答:
 __WORDSIZEという処理系独自マクロを使えばok。
989デフォルトの名無しさん:2009/06/26(金) 19:34:10
規格書も見ないでヘッダファイルを見る男の人って。
990デフォルトの名無しさん:2009/06/26(金) 20:43:04
>>986
以下の &a, &b, &c 間の関係演算の結果は未定義なので以下が通ってしまうことがある。
確か std::less<ポインタ> は推移的だったような気がする。

int a, b, c;
assert( &a<&b && &b<&c && &c<&a );
991デフォルトの名無しさん
>>987
自分が分かってないことすら分かってない人にそんなこと言っても無駄です。