sizeof(char)が必ず1でも、省略すべきではないat TECH
sizeof(char)が必ず1でも、省略すべきではない - 暇つぶし2ch2:デフォルトの名無しさん
07/08/19 20:10:10
>>1
YOU死んじゃいなYO

3:デフォルトの名無しさん
07/08/19 20:10:21
そんなに悔しかったか。

4:デフォルトの名無しさん
07/08/19 20:12:35
何もたてなくても・・・

5:デフォルトの名無しさん
07/08/19 20:12:55
sizeof(char) => sizeof(*s) じゃだめか?と俺が言った。

6:デフォルトの名無しさん
07/08/19 20:15:45
>>1 
こういうのが孤軍奮闘して、単に議論がダラダラと続いているだけなのに、最終的には
「宗教論争」と言い出して「どちらでもいい」ということにしてしまうんだよなぁ。

2chの片隅で、そんなことをしても、なにがどうなるってわけでもないんだけど、
弱い人は、精神防衛せずにはいられないんだろうなぁ。

7:デフォルトの名無しさん
07/08/19 20:17:16
>>5
それもいいかもね。
ただ、charとワイド文字の切り替えを意識してるコードだって知らない人がみたら、意図をつかみにくいかも。

8:デフォルトの名無しさん
07/08/19 20:25:17
>>7
切り替えがなくとも、
sの指す先の型を人間が手作業で書くのは良くないので、
ミス防止のためには、コンパイラに仕事させたほうがいいと思う。

9:デフォルトの名無しさん
07/08/19 20:25:26
可読性だけの問題なのかね。

10:デフォルトの名無しさん
07/08/19 20:28:27
複数箇所に
malloc(strlen(s)+1)
のようなコードを書くこと自体が間違い。

最低でも関数でラップすべきだし、
C++ならstd::basic_stringを使うべきだろう。

11:デフォルトの名無しさん
07/08/19 20:34:31
>>8
char固定なら、いらないじゃん。

12:デフォルトの名無しさん
07/08/19 20:39:21
>>10
ぜんぜんOK

それにラッパー書かなくても、フツーはstrdup()使う。

13:デフォルトの名無しさん
07/08/19 20:51:41
ちんちんが臭いんです><

14:デフォルトの名無しさん
07/08/19 21:03:28
>>11
char固定であることを人間が保証してやるなんて馬鹿馬鹿しい。

>>12
可哀想に。恵まれない職場にいるんだね。

15:デフォルトの名無しさん
07/08/19 21:31:44
sizeof(char)は必ず1である事が定義されてるんだから
別にいいじゃんねぇ

16:デフォルトの名無しさん
07/08/19 21:35:30
そもそも strlen はcharの文字列の長さを求める関数であって
多バイト文字の文字数を求めるなら strlen を使っちゃダメだろ。

17:デフォルトの名無しさん
07/08/19 22:03:17
#define sizeofchar 1

18:デフォルトの名無しさん
07/08/19 22:04:24
>>14
ええ? malloc()のラッパーって話じゃなくて、malloc(strlen(s)+1)のラッパーってことだよね?
職場のヘンなコードばっかり見てないで、いろいろコードを見たほうがいいと思われ。



19:デフォルトの名無しさん
07/08/19 22:05:45
>>14
strlen()使うんだから、char以外は使えないじゃん。

20:デフォルトの名無しさん
07/08/19 22:07:49
>>16
文字列複製用のメモリ確保だと思われるから、長さはバイト数でいいんじゃね?

21:デフォルトの名無しさん
07/08/19 22:30:08
意味の問題。

mallocの引数は「バイト数」
strlenの返り値は「文字数」


22:デフォルトの名無しさん
07/08/19 22:45:24
sizeof(char) == 1バイト

23:デフォルトの名無しさん
07/08/19 22:55:28
>>22
保証は無い。(まだそんなマシン動いてるかどうかはともかく)


24:デフォルトの名無しさん
07/08/19 22:57:39
>>23
100%保障。
sizeof(char)が1でないコンパイラがあったら捨てたほうがいい。

25:デフォルトの名無しさん
07/08/19 23:01:36
一応ANSIならとかつけたほうがいいんでねぇの?
sizeof( char ) != 1の環境は見たこと無いけど・・・

26:デフォルトの名無しさん
07/08/19 23:01:37
問題なのはバイトの方!


27:デフォルトの名無しさん
07/08/19 23:04:00
>>26
だからcharは1バイトだって。

28:デフォルトの名無しさん
07/08/19 23:10:32
>>25
何も書いてない時の ANSI 縛りは、暗黙の了解事項だろ。

そうでないとなんでもありありになっちゃうし。

29:デフォルトの名無しさん
07/08/19 23:13:32
まえスレの人は、charが1バイトってくらいは分かったうえで、いろいろ言ってる様な印象だったけど、
ちがう人と交代したのかな?

30:デフォルトの名無しさん
07/08/19 23:13:51
牛乳タンクの容量を割り当てる関数があるとしよう。引数はリットル型だが、実はintのtypedefだ。

箱の中に複数本の牛乳パックが入っている。
本数を問い合わせる関数があるとしよう。返り値は本数型だが、実はintのtypedefだ。

箱の中の牛乳パックを開けてタンクに入れようとする。
同じintのtypedefだからといって、
リットル型の引数に、本数型を渡していいものだろうか。

俺はダメだと思うね。
たとえ1本1Lと決まっていても、本数型からリットル型に変換する段は踏むべきだ。

31:デフォルトの名無しさん
07/08/19 23:18:49
いちいち
hoge = (type*)malloc(sizeof(type)*size) ;
なんて書いてる人いるの?

初心者だって、
#define MALLOC(type, size) ((type)*)malloc(sizeof(type)*(size))
くらいして、
hoge = MALLOC(char, strlen(s)+1) ;
って書くだろ?

だいたい、いまどきCオンリーなんて、なにか理由があるときくらいなもので、
普通はC++だから、文字列クラスを使うだろう。

いまだにチマチマとstrlenとかstrcpyとかやってるから、
つまらないバグやセキュリティホールを作り込んでしまうんだよ。

32:デフォルトの名無しさん
07/08/19 23:20:21
>>30
strlen()のリターン値は文字数==バイト数で、malloc()引数もバイト数じゃん。

33:デフォルトの名無しさん
07/08/19 23:23:55
>>30
強いtypedefのあるD言語をお使いください。

34:デフォルトの名無しさん
07/08/19 23:23:57
>>31
> 初心者だって、 ・・・って書くだろ? 

それ、たとえば誰が書いてるの?
職場の先輩とか?

35:デフォルトの名無しさん
07/08/19 23:23:57
malloc()の戻り値をcastするやつはバカ

36:前スレ980
07/08/19 23:33:02
俺は*sizeof(char)は付けない派だが。(付いてても気になら無いけど)

>>31
これはちょっと全体的に反対。

>#define MALLOC(type, size) ((type)*)malloc(sizeof(type)*(size))
そんな訳の分からないマクロ作るぐらいなら、素直にcalloc使うよ。

>普通はC++だから、文字列クラスを使うだろう。
そんな普通は無いだろ。

37:デフォルトの名無しさん
07/08/19 23:36:35
>>36
名前欄消し忘れた・・・。
是非スルー頼む。orz

38:デフォルトの名無しさん
07/08/19 23:41:53
>>36
全体的に賛成だがcallocになるのか?ラッパー関数とかじゃなくて?

39:デフォルトの名無しさん
07/08/19 23:42:29
> 普通はC++だから
www

40:デフォルトの名無しさん
07/08/20 00:00:32
>>32
たまたま 文字数==バイト数 なだけじゃん。

41:デフォルトの名無しさん
07/08/20 00:06:15
>>40
「規格上」文字数==バイト数。
たまたまじゃない。

42:デフォルトの名無しさん
07/08/20 00:08:37
>>35
Cではキャストは不要だがC++では必要。
まぁ、C++でmallocを使うこと自体がおかしいが。

43:デフォルトの名無しさん
07/08/20 00:09:23
>>41
たまたま「規格上」一致する組み合わせ


44:デフォルトの名無しさん
07/08/20 00:16:28
>>38
>>31のマクロだと「型と要素数を指定してメモリを獲得する」機能が欲しそうだったんで、
指定の仕方が近いcallocを持ってきただけだよ。

>>1やらの話なら、文字列長渡してメモリのアドレス返すラッパならアリじゃないかなぁ。
個人的には面倒だからやらないけども。

45:デフォルトの名無しさん
07/08/20 00:18:40
>>40
たまたまじゃないよ。
あつかってる文字セットが収まる範囲を1バイトにしてるんじゃん。

46:デフォルトの名無しさん
07/08/20 00:22:57
ここで文脈を読まずに文字数==バイト数なのはASCIIコードだけだとかいってみる

47:デフォルトの名無しさん
07/08/20 00:23:18
>>44
すでに_strdupがあるもんな。

「文字列の尻には\0があるから、+1文字分の領域が必要」
ということに対処するコードは一ヶ所だけにまとめておくべきで、
プログラム全体に散在させるべきではないよね。
それが後で変るかどうかは関係ない。

あちこちにmalloc(strlen(s)+1)と書けばいいと言う人間は、
構造化プログラミングを否定していると思う。

48:デフォルトの名無しさん
07/08/20 00:24:19
>>45
牛乳パック1本が1リットルと決まっているからといって、
リットル数を与えるべきところに本数を与えていいと思うか?

49:デフォルトの名無しさん
07/08/20 00:29:47
>>47
malloc(strlen(s) + sizeof(char)) って書くってこと?

50:デフォルトの名無しさん
07/08/20 00:30:11
恒久的に一本一リットルなら何の問題もないだろ。

51:デフォルトの名無しさん
07/08/20 00:41:20
>>50
恒久的にってのもだけど、論理的にも一文字1バイトだし。

52:5
07/08/20 00:42:54
俺もsizeof(char) == 1 だと思ってたけど、TCHARがWindowsのAPIがらみの定義らしいとこまで調べたので、strlenもwindowsの特殊仕様な可能性を考えてました。
(引数の型がTCHARとやらに変わるなど、思い込み)
無知なのに口だしてごめんなさい。

strlenがchar固定。sizeof(char)==1バイトが、規格から明らかならば、
sizeof(char)はいらないよね。

察するに>>40,>>43は「バイト数」と言う言葉と、「文字数」という言葉を
厳格に分けたいというところかな?

それに対して、1バイト==sizeof(char)は規格上定義されているから
分けて考える必要はないという反論。ってことですね。私はこっち派。

>>47,>>49
このスレで議論の中心になってるのは、+1ではなくて、
>>1の1行目、"sizeof(char)*" -charのサイズを掛けている-部分だと思うよ。

53:デフォルトの名無しさん
07/08/20 00:46:53
>>49
どこから、そういう発想がでてくるのだろ。

size_t CalcRequiredMemoryForString(const char* s) {
return sizeof(char)*(strlen(s)+1) ;
}

もっと細かく分けて

size_t ScanAscizStringLength(const char* s) {
return strlen(s)+1 ;
}

size_t CalcRequiredMemoryForString(const char* s) {
return sizeof(char)*ScanAscizStringLength(s) ;
}

とかでもいい。

そしたら、
char* s2 = malloc(CalcRequiredMemoryForString(s)) ;
と書けるようになるっしょ。

54:デフォルトの名無しさん
07/08/20 00:47:20
論点は、 (1)charのサイズの問題 (2)sizeof(char)を書くか なのかな。

(1)はラッパを書く、(2)は書いたら弊害があるのか? でダメ?

55:デフォルトの名無しさん
07/08/20 00:55:43
>>53
strlen()+1だけの関数とか、そんなのつかってるのオタクの職場くらいですよ。

56:デフォルトの名無しさん
07/08/20 00:58:56
>>53
壮大な釣り?
>size_t ScanAscizStringLength(const char* s) {
string lengthはどう考えてもstrlen()の戻り値そのままだろ。
stringに形容詞がつくだけで長さが変わるなんて気色悪い。
getStringSize()って名前なら判らんでもないが。

で、malloc(sizeof(char) * stringSize)なら「あ~あ、一一書いているよ」で済むが、
malloc(CalcRequiredMemoryForString(string))なんて書いていたら「戯け」の一喝だな。
# CalcRequiredMemoryForDoublePrecReal()なんてのも作るのか?

57:デフォルトの名無しさん
07/08/20 01:00:09
>>55
ふつう文字列クラス使うよな。

strlenとかstrcatとかstrcpyなんて直接使わないもの。

58:デフォルトの名無しさん
07/08/20 01:01:31
>>56
ふつうC++なので、やるとしてもテンプレート関数だな。

59:デフォルトの名無しさん
07/08/20 01:06:54
>>57
mallocとか使ってることから、ここはC限定ではないのかな?

>>53
そこまで書くんだったら >>49 程度で済ました方が良いと思う。それと、その関数名だと長すぎて使いたくない。


60:デフォルトの名無しさん
07/08/20 01:06:55
>>54の(2)sizeof(char)を書くか
URLリンク(www.kouno.jp)

一般的には、どっちでも良いってよ。

61:デフォルトの名無しさん
07/08/20 01:09:02
ポイントとしては、
無知やうっかりミスによってバグを生じさせない
ということ。

+1が必要なことを知らない人もいるし、
+1を書き忘れることもあるし、
sizeとlengthを書き間違えることもある。

じゃぁどうすればいいか。
Cを捨ててC++で文字列クラスを使うべき。

62:デフォルトの名無しさん
07/08/20 01:13:01
>>59
C++でもmalloc使う人いるんだよねぇ。

> >>49 程度で済ました方が良いと思う。

strlen(s) + sizeof(char)
これこそ意味不明だねぇ。

1文字分ってことなら、
sizeof(char)
ではなく
sizeof(char)*1
としないとねぇ。

そうするなら
sizeof(char)*(strlen(s)+1)
になるわなぁ。

> その関数名だと長すぎて使いたくない。

いちいち手でタイプする人いるんだよねぇ。
ミスタイプしたりするからコピペが基本よ。



63:デフォルトの名無しさん
07/08/20 01:17:55
>>62
長い数式を書かない人なんだね・・・

64:デフォルトの名無しさん
07/08/20 01:22:01
>>53
まあ、常識的に考えてこんな関数つかわねーよな。

65:デフォルトの名無しさん
07/08/20 01:24:23
>>53とか>>55>>56とか
void *getBufByLen(int length)
{
 return malloc(length + 1);
}

まぁこのぐらいのラッパなら良いんじゃないの?
strlen(str)+1がどのぐらい出てくるかにもよるんだろうけどさ。

どうしても「+1」をソースコードから出来るだけ消したいなら、俺なら
#define LEN2SIZE(x) ((x)+1)
でも作って、LEN2SIZE(strlen(str))で書くか。
したら、今度は副作用がどうとか言われんのかねぇ。

66:デフォルトの名無しさん
07/08/20 01:29:49
>>65
そこまでして+1を消すと、かえって読みにくくなるよ。
strlen(s) + 1 と直に書くのがいちばん素直なCのコード。
技巧に走りすぎてもよくない。

67:デフォルトの名無しさん
07/08/20 01:38:58
>>66
そうは思うけどさ。
たまに上司の好みで結構色々言われんのよ。
(俺も多分好みで妙なコード書いてるとは思うけど)

んで、そこで激論しても時間無駄だから、
まぁ良いかと思えることは従うことにしてる。

今のところ「+1消せ」は言われたことないけど、
そういう指示が出たらこうするかな、ってぐらいのモン。

68:59
07/08/20 01:42:50
>>62
ごもっともです。

ところで、もともとの質問主の環境は VC++6.0 みたいですね。
素直にC++の文字列クラスを使うのがいいのかな...


69:デフォルトの名無しさん
07/08/20 04:32:26
>>65
getBufByLenではなくallocBufByLenにしたほうがいいと思う。


70:デフォルトの名無しさん
07/08/20 11:05:39
>>62
>C++でもmalloc使う人いるんだよねぇ。
それは酷い。

71:デフォルトの名無しさん
07/08/20 11:39:01
ひょっとしてJavaに移植するときとか、そこまで考えてるのか?
Cだけなら sizeof(char)==1 が仕様で定義されてるけど

72:デフォルトの名無しさん
07/08/20 11:47:13
乱れる倫理。10歳以下のセミヌード!
URLリンク(www11.big.or.jp)

73:デフォルトの名無しさん
07/08/20 11:49:09
うわ・・本当に脱いでる・・・

74:デフォルトの名無しさん
07/08/20 11:51:22
蝉の脱皮だろ

この板では空気を読む必要は無い。

75:デフォルトの名無しさん
07/08/20 11:52:25
>>71

#include <stdio.h>

int main()
{
printf("%d\n",sizeof(char));
return 0;

}

をCでコンパイルしてみたか?
C++でもコンパイルしてみたか?

76:デフォルトの名無しさん
07/08/20 11:55:31
>>72
これはアブラゼミだね

77:デフォルトの名無しさん
07/08/20 11:56:31
>>75
CとC++でsizeof(char)は絶対1なのは仕様で保証してるんだけど・・・

78:デフォルトの名無しさん
07/08/20 13:19:39
1バイトは8ビットとは限らないが、charは1バイトと規格で決まっている。
ってことでしょ?

79:デフォルトの名無しさん
07/08/20 13:37:00
>>75
もう帰れ無能。

80:デフォルトの名無しさん
07/08/20 13:40:04
>>43
Cの規格での「文字」の定義は「1バイトに納まるビット表現」。
規格書ちゃんと嫁。

81:デフォルトの名無しさん
07/08/20 13:43:49
>>80
文字っつーかcharな。単に文字とか言うとまた噛み付いてくるで。

82:デフォルトの名無しさん
07/08/20 14:01:07
>>81
>単に文字とか言うと
規格に於ける定義の話をしてるんだが。

83:デフォルトの名無しさん
07/08/20 14:25:58
>>82
それならきっちり「文字型」といった方が誤解ないよねとか
文字とだけ言うとシングルバイト文字とマルチバイト文字を
ごっちゃにするやつが出てくるから 規格話するなら正確に
みたいあn

84:デフォルトの名無しさん
07/08/20 14:40:08
>>75
関係ない話なんだが、
sizeof演算子の結果の型はsize_tだけど、こういう場合はintにキャストしなくていいの?

85:デフォルトの名無しさん
07/08/20 15:08:04
>>70
C++だろうとmallocは使えるでしょう?
mallocしたものをdeleteしたりしなければ。

86:デフォルトの名無しさん
07/08/20 15:12:41
>>80
charが1バイトなのは当然として、
1を掛けるのを省略して書いて良いのかどうか
という問題だろう。



87:デフォルトの名無しさん
07/08/20 15:21:31
>>85
使えるけど、new があるのに
>mallocしたものをdelete
する危険を冒してまで態々使う意味が判らない。

>>86
「省略しちゃいけない」とする理由が
「文字数とバイト数は意味が違うから」であれば、
規格上は「文字」=「1バイト文字」であり
「文字数=バイト数」であるから
「省略しても問題ない」よね?という確認。

88:デフォルトの名無しさん
07/08/20 15:35:24
問題は無いね
どうすべきかとなると宗教論争になりそうだ

89:デフォルトの名無しさん
07/08/20 15:37:25
>>86
C FAQにあるよ

90:デフォルトの名無しさん
07/08/20 15:42:03
つきつめるとCHAR_BITすら意味をなさないからあまり気にするものでもないと思うが

91:デフォルトの名無しさん
07/08/20 15:45:13
>>87
> 「文字数=バイト数」であるから

それは数値の一致であって、意味の一致ではない。
あくまでも「1バイト文字」の「文字数」なのだから。

省略してもプログラムは意図した通りに動くが、
プログラムが動けば何だっていいというのは間違い。


92:デフォルトの名無しさん
07/08/20 15:54:11
>>91
はあ…
>それは数値の一致であって、意味の一致ではない。
意味の一致だってばさ。頭悪いなあ。
「規格では、strlen() はバイト数を戻す」
これで納得した?

93:デフォルトの名無しさん
07/08/20 16:06:54
charやstrlenをハードコーディングしちゃうなら*sizeof(char)を書く意味はほとんど無いと思うなぁ。

>>87
new使ったってその危険はdeleteとdelete[]を間違える危険にかわるだけじゃね?

94:デフォルトの名無しさん
07/08/20 16:10:40
なんつーか
みんな暇なの?

95:デフォルトの名無しさん
07/08/20 16:11:19
規格では、strlen() はバイト数と等しい値を返す
だろ?

96:デフォルトの名無しさん
07/08/20 16:25:08
strlenの返す値の意味がバイト数ではなく文字数だと言いたいんですかね。

97:デフォルトの名無しさん
07/08/20 16:43:09
そんなに不安ならコメント書いとこうぜ

98:デフォルトの名無しさん
07/08/20 16:46:35
>>96
格納するのに必要なバイト数
ではないのは確かだな。

99:デフォルトの名無しさん
07/08/20 17:09:30
>>1
アルファベット=レターと非アルファベット記号=キャラクターとストリングの意味からして、strlenが間違い。

100:デフォルトの名無しさん
07/08/20 17:39:16
外人は文字が2バイトかもしれないなんて考えてないから、
strlenという関数名なんだろ。


101:デフォルトの名無しさん
07/08/20 17:50:26
>>94
意味のない議論をしたがる厨房が集まってるだけだろ

102:デフォルトの名無しさん
07/08/20 17:54:08
このスレ、すんごい伸びだな。

103:デフォルトの名無しさん
07/08/20 18:01:54
>>84
整数型の暗黙の変換ルールがあるから問題ない。
ただ、size_tは符号無しだから、
intに変換されることで情報が失われるかも分からんね。

104:デフォルトの名無しさん
07/08/20 18:05:52
>>100同感
2バイトあれば全世界の文字が収まると勘違いしていたしな。


105:デフォルトの名無しさん
07/08/20 18:14:57
してません

106:デフォルトの名無しさん
07/08/20 18:22:55
このさい8バイトでいいだろ。

107:デフォルトの名無しさん
07/08/20 18:23:09
>>100
記号一つに2バイトなんて無意味だし不可能。
strlenが誕生した時代は数バイトのメモリが数万円。

108:デフォルトの名無しさん
07/08/20 18:30:18
んなわけないだろ

109:デフォルトの名無しさん
07/08/20 18:36:58
そんなにsizeof書きたくないんだったら高級言語つかえよ

110:デフォルトの名無しさん
07/08/20 18:40:09
なんじゃそりゃ

111:デフォルトの名無しさん
07/08/20 18:42:46
そんなにsizeof書きたいんだったら高級言語使うなよ

112:デフォルトの名無しさん
07/08/20 18:44:08
>>108
PDP-11は、メモリ64KB程度搭載で、1万ドルくらいだったそうだな。
当時の為替レートからすると、360万円か。

数バイト数万円は違うが、数Kバイト数万円くらいだな。

113:デフォルトの名無しさん
07/08/20 18:44:38
>>111
C言語は高級言語ではないな。

114:デフォルトの名無しさん
07/08/20 18:52:11
>>112
メモリのコストはその一部でしょう

115:デフォルトの名無しさん
07/08/20 18:53:46
>>1
#defineで定義しておけ。


116:デフォルトの名無しさん
07/08/20 18:54:59
>>114
昔のコンピュータは、メモリのコストは一部なんてもんじゃなく、かなりを占めていたのよ。

117:デフォルトの名無しさん
07/08/20 18:56:14
MSXの32KB増設RAMカートリッジが1万円以上だったのを
思い出したような

118:デフォルトの名無しさん
07/08/20 18:58:40
Cができたのってやっとシリコンメモリが普及し始めたころだっけ?

119:デフォルトの名無しさん
07/08/20 19:03:27
>>84
キャストするべき。
size_tがintと同じサイズである保証は全くない。
sizeof(int) == sizeof(long)の環境に限定するなら、省略するのもありかも試練が。

120:デフォルトの名無しさん
07/08/20 19:25:26
C FAQを見てはいけないスレはここですか?

121:デフォルトの名無しさん
07/08/20 19:32:08
>>118
PDP-11の頃

>>120
C FAQは聖典ですか?

122:デフォルトの名無しさん
07/08/20 19:40:30
聖典w

123:デフォルトの名無しさん
07/08/20 20:38:51
>>121
>C FAQは聖典ですか?
いいえ、常識です。

124:デフォルトの名無しさん
07/08/20 20:43:43
>>100
>>107
UTF-16とか思い出してあげてください。

125:デフォルトの名無しさん
07/08/20 23:07:54
>>123
C FAQ では、sizeof(char)を使うのは、プログラムがわかりやすくなるから、一興だと言ってるが?

126:デフォルトの名無しさん
07/08/20 23:10:14
>>124
UTF-16は1文字=2バイトじゃねーよ

127:デフォルトの名無しさん
07/08/20 23:13:15
>>125
ぜんぜんいらねーよ。

とも書いているね。まあどっちも正しいってことだな。

128:デフォルトの名無しさん
07/08/20 23:15:32
書かなかったからといって不正なプログラムというわけではない。

ということだな。

129:デフォルトの名無しさん
07/08/20 23:25:35
>>126
小学生からやり直せ

130:デフォルトの名無しさん
07/08/20 23:37:29
>>129
Cにおいてsizeof(char)=1は仕様だが、
1バイトが8ビットなのは仕様ではない。

131:デフォルトの名無しさん
07/08/21 00:08:16
つまんねー内容をだらだらだらだら
何を言い合ってんのおまえら (w

132:デフォルトの名無しさん
07/08/21 00:19:55
ここの人達が、同じプロジェクトに放り込まれたら、
どうなるんだろう...
C FAQ は理解しやすくなる「かも」とかいてあるけど、
逆に意図が分からなくて困惑する人もいるかも。

133:デフォルトの名無しさん
07/08/21 00:22:53
同じプロジェクトに入ったら個人レベルでソースファイルを分割し
他人が担当しているソースファイルは一切見ないようにすればOK。
レビューとかあれば、同じ信念をもち曲げないメンバーでする。

そんなプロジェクトやだなぁw

134:デフォルトの名無しさん
07/08/21 00:44:11
>>130
>>100>>107がC言語の規格が決まった当時の話をしてるのに、
>>124はもっと最近の話をしてるところが突っ込みどころなわけであって。

ナニコレ。
>UTF-16は1文字=2バイトじゃねーよ

>Cにおいてsizeof(char)=1は仕様だが、
>1バイトが8ビットなのは仕様ではない。

誰がUTF-16の1文字=2バイトとか言ってんだ?
んー・・・もしやUTF-16は1バイトが8ビットの環境て使うべきでない、
とかそういう意見をお持ちの方?

135:デフォルトの名無しさん
07/08/21 01:57:32
>>134
charは文字だろ

って話の寄り道だったんじゃないか?

136:デフォルトの名無しさん
07/08/21 07:54:41
マロック・ストラレン

137:デフォルトの名無しさん
07/08/21 08:07:00
文字の型を隠蔽してsizeof(TCHAR)でいくね

138:デフォルトの名無しさん
07/08/21 10:44:54
>>137
C++ のクラスをWin32とWinCEで使いまわす俺には必須だぜ!

ところで、>>129 がどこに突っ込んでるのかが知りたい。
UTF-16の1文字は2バイトとは限らないし
2オクテットとも限らないわけだが。

139:デフォルトの名無しさん
07/08/21 11:46:27
1バイトのビット数ってこの話にはあんまり関係ないような

140:デフォルトの名無しさん
07/08/21 11:57:51
>>138
根本的にズレてるって意味だろう。
>124 は別にUTF-16が1文字=2バイトだとは言ってないから。

141:デフォルトの名無しさん
07/08/21 12:21:34
>>138
Win32でもUnicodeでやればいいじゃんかー。

142:デフォルトの名無しさん
07/08/21 12:33:10
スレの趣旨がわからなくなってきた

143:デフォルトの名無しさん
07/08/21 13:37:16
1nibble=4bit

144:デフォルトの名無しさん
07/08/21 14:46:42
1nibble=4bit
1byte=8bit
1word=16bit
1dword=32bit
だっけか
環境とか詳しいことは知らんが

145:デフォルトの名無しさん
07/08/21 14:59:30
1ワードは36bitだよ。

146:デフォルトの名無しさん
07/08/21 15:12:29
1byte=8bitとは限らない。

147:デフォルトの名無しさん
07/08/21 15:25:06
32ビット256Kワードとかよくある話だな

148:デフォルトの名無しさん
07/08/21 20:46:59
>>142
暇つぶし

149:デフォルトの名無しさん
07/08/21 21:40:25
結論。
必ず1だから省略すべし。

150:デフォルトの名無しさん
07/08/21 21:53:41
省略するのは最適化コンパイラの仕事であって人間の仕事ではない。

151:デフォルトの名無しさん
07/08/21 22:00:31
コンパイラは省略しません。そういう意味では無駄にコストが発生します。
# 勿論、コンパイルのね。

152:デフォルトの名無しさん
07/08/21 23:06:13
>>151
いや、定数の演算だから消えてなくなるだろ

153:デフォルトの名無しさん
07/08/21 23:08:54
もう、どっちなんですか!!!?

154:デフォルトの名無しさん
07/08/21 23:20:24
>>152
消えてなくなると言うことは、コンパイラは省略せずにちゃんと最適化したということですね。

155:デフォルトの名無しさん
07/08/21 23:24:28
意味はあっても価値はない。ってところかしら?
価値が無いからと言って、消して良いのか?
でも最適化でけされるよ。
消されなかったら実行時のコストだな。
じゃあ、今、消しておこう。

156:デフォルトの名無しさん
07/08/22 02:04:18
消してしまったsizeof(char)を復元する必要が出てきたときに
莫大なエネルギーが消費されるからそのままにしておいたほうがいいお。

仕事でスパゲッティコードをリファクタリングしたときに、
元のコードをコメントで残しとけとか言われて非常に苦労した覚えがあるお。

157:デフォルトの名無しさん
07/08/22 02:13:07
>元のコードをコメントで残しとけ
リファクタリングもへったくれもありませんな。

158:デフォルトの名無しさん
07/08/22 02:23:23
>>156
>復元する必要が出て来たとき。
上の方で誰か書いてたけど、ラッパー関数にするか、マクロにするかして、
一度に変えられる様にしておけば良い。
復元してもどうせ1だからそのまま使う訳じゃないだろう。

159:デフォルトの名無しさん
07/08/22 09:47:48
>>156
>sizeof(char)を復元する必要
Cの仕様が変更にならない限りその必要は無いからな
どうだろうな

160:デフォルトの名無しさん
07/08/22 12:46:00
subversionでいいじゃん

161:デフォルトの名無しさん
07/08/22 21:07:24
…そう言って通る職場なら良いけどな

162:デフォルトの名無しさん
07/08/22 21:54:59
svn厨は退場してください

163:デフォルトの名無しさん
07/08/22 22:36:22
じゃあCVSで・・・ごめん、悪かった

164:デフォルトの名無しさん
07/08/22 22:51:41
それならよし!

165:デフォルトの名無しさん
07/08/22 23:00:05
それでいいんかい!

166:デフォルトの名無しさん
07/08/23 01:40:32
ふつーbzr

167:デフォルトの名無しさん
07/08/23 20:54:00
もうねmallocなんてあちこちで書いてちゃだめなんだよ。
ラッパーとか言うのも違うな。
構造化だよ。オブジェクトを作る段でだけ利用するんだ。
そもそもC++の偉い人がnewなんてすばらしい関数を
用意してくれているんだから、new使えよ。

168:デフォルトの名無しさん
07/08/23 21:34:07
Dの偉い人が動的配列なんてすばらしい機能を
用意してくれているんだから、動的配列使えよ。

169:デフォルトの名無しさん
07/08/23 21:54:16
vector使うお!!

170:デフォルトの名無しさん
07/08/24 00:15:47
え?newって関数なの?演算子かと思ってたんだが・・・

171:デフォルトの名無しさん
07/08/24 00:20:10
C++のnewは演算子だな。


172:デフォルトの名無しさん
07/08/24 00:32:18
newだって寿命管理はプログラマがやらなきゃいけないわけで、
mallocと同じように、
考えて使うところを狭めないと、
収拾が付かなくなる。

173:デフォルトの名無しさん
07/08/24 00:32:33
ってことはoperator newでオーバーロードできたりするの?

174:デフォルトの名無しさん
07/08/24 01:24:37
>>173
何を今更。だからやろうと思えばOS管理外からメモリを引っ張ってくる事だってできる。

175:デフォルトの名無しさん
07/08/24 01:44:33
smart_ptr<T> ptr = Allocator<T>();
みたいなカスタムアロケータ用意するとか

176:デフォルトの名無しさん
07/08/24 09:39:31
演算子は全て関数だと乱暴な言い方も当然出来る。

177:デフォルトの名無しさん
07/08/24 11:39:47
>>176
挙動が違うんだけど。

178:デフォルトの名無しさん
07/08/24 19:45:47
で、sizeof(char)の省略いいの?わるいの?

179:デフォルトの名無しさん
07/08/24 19:48:27
いい

180:デフォルトの名無しさん
07/08/24 20:52:42
文法的にも、プログラム的にも、省略するのは間違いではない。
だが、
プログラムを人間が読んで理解する上では、省略しないほうがよい。

181:デフォルトの名無しさん
07/08/24 22:22:15
>180みたいな人間に合わせるために、省略しない方がいい。
>180みたいな人間が見ることがないコードなら、遠慮することなく省略していい。

182:デフォルトの名無しさん
07/08/25 00:29:12
>>180
そもそも理解の妨げにならない、という話をしてるんじゃないのか。

183:デフォルトの名無しさん
07/08/25 03:38:00
>>180
逆、コンピューターの作法に人間が合わせてるだけ。
人間様はシンプルな方が理解しやすい。

184:デフォルトの名無しさん
07/08/25 09:16:43
>>182
>>180 は理解が足りない、って話じゃないの?

185:デフォルトの名無しさん
07/08/25 11:05:48
書く目的が、、、
(1).人間が理解しやすい、と言うなら、
「無くても理解できる。」、「無駄なコードに見える」
(2).char -> wchar_t や処理系固有の文字型に変更する可能性のためなら、
strlen はchar専用、またsizeof(char)と直接書くのも適切ではない。より汎用的に書くべき。
また#if などで、文全体を置き換えるとすれば、(1).より、無くても良い。
必要な型の場合のみ書く。
(3).その処理系はsizeof(char)自体が、1ではない。
このスレの前提「必ず1でも」に一致しないので、除外する。

186:デフォルトの名無しさん
07/08/25 13:54:03
>>185
>181

187:デフォルトの名無しさん
07/08/25 14:24:25
#define SZCHAR 1

p = (char*)malloc(SZCHAR*strlen(ps));

if(p == NULL)
{
return ERR;
}

こうすればいいじゃね

188:デフォルトの名無しさん
07/08/25 14:37:13
>>187
aho


189:デフォルトの名無しさん
07/08/25 14:44:33
>>187
βακα..._〆(゚▽゚*)

190:デフォルトの名無しさん
07/08/25 15:23:52
>>187
Ma nuke.

191:デフォルトの名無しさん
07/08/25 15:29:12
>>185
汎用的に書くからには、それで正しく動作するように書き、テストもすべきだ。
見かけ倒しで実際にはダメなんてのは迷惑。
だから、charでしか正しく動作しないのであれば、charで書いておくべきだ。

192:デフォルトの名無しさん
07/08/25 23:38:06
VCならTCHAR使えってこった。

193:デフォルトの名無しさん
07/08/26 01:33:34
_TCHARとTCHARの違い、わかって言ってる?

194:デフォルトの名無しさん
07/08/26 04:15:18
>>188
気やすくAhoと言うな。

AWKを作った偉い人の名前だぞ。

195:デフォルトの名無しさん
07/08/26 05:37:47
/*sizeof(char)*/

196:デフォルトの名無しさん
07/08/26 14:29:20
なんかchar型のサイズが1バイトって前提の話になってるけど
C++だとcharのサイズって1(単位なし)だよな。
で、各型のサイズはcharのサイズの整数倍であることが保証されている。

でも1=1バイトかどうかは環境依存だよな?
#あくまで企画上の話なので実際にcharのサイズが1バイトじゃない環境出せとかいうのはなしね。


197:デフォルトの名無しさん
07/08/26 14:37:23
>>196
1バイトが8ビットであることも決まっていない。
CHAR_BITは8以上となっているから、1バイト=7ビットでは規格合致できないけど。

198:デフォルトの名無しさん
07/08/26 14:58:19
>>196
C、C++は 絶対何があってもsizeof(char)は1バイト
と規格で定めてる。
それ以外の環境はありえないし存在しない。

1バイトが8ビットかどうかはこのスレでは論じていない。

199:デフォルトの名無しさん
07/08/26 15:02:07
>>197
とりあえず、規格上のサイズ指定に使われている単位と
環境上で実際にサイズ指定に使われている単位って違うよなってことを
指摘したかっただけなんだ。

で、指摘の件だけど、それはcharのサイズ=1=2バイト(今の話なら14ビット)
で定義してやればその要件は満たすんじゃね?
CHAR_BITはcharを構成するビット数であって1バイトを構成するビット数の
話じゃないよな?

あと、バイトの出自ってIBMの内部呼称でbit octetからきてると思ったんだが
今はなんかビット数に関して不問にするみたいなのってあるのかな?

200:デフォルトの名無しさん
07/08/26 15:12:09
>>199
そういうこと。外から見てcharが2オクテットだったとしても、
CHAR_BIT == 16にして、sizeof (char) == 1にすれば規格合致できる。

いずれにせよ、198の言うとおりこのスレで話すようなことではないけどな。

201:デフォルトの名無しさん
07/08/26 15:47:31
>>198
プログラミング言語C第2版p44(ISBN4-320-02692-6)にはたしかに書いてあるね。
けどプログラミング言語C++第3版(ISBN-4-7561-1895-X)にはそんなこと書いてないよね。
charのサイズに関してはp110で言及してるけど、サイズが1であること、8ビット以上であること、
ほとんどの場合に8ビットバイトであることはかかれてるけど、1バイトとは書いてないよね。
#これよんで9ビットバイトって書いてもいいのかとは確かに思った。

まぁ、何が言いたいかというとcharのサイズが2バイトのC++環境とかだと
sizeof(char)をかけてもC++の仕様レベルで必要バイトサイズとれないよなって話。
#mallocの引数はバイト数なんだよね。

Cは厳密な話知らなかったから知らない。
#ちゃんとC++限定で話してたよね。

>>200
ということで、charのバイトサイズをべつに定義しておいてmallocに渡すときはそれを
使ってバイトサイズに変換しろっていうまとめをするとすれ違いにならないかな?


202:デフォルトの名無しさん
07/08/26 15:48:12
マルチバイトを扱うなら文字列関係は普通ライブラリ化する
不都合が発生してもそこだけ修正するので1の件は重要じゃない
反対にmalloc散らばりまくりの汚い実装なら
17文字余計にタイプすると人件費にして2円位になるから
わざわざ強要してもとコストがかさむだけでメリットがない

203:デフォルトの名無しさん
07/08/26 15:50:25
>>202
>17文字余計にタイプすると人件費にして2円位になるから
計算方法kwsk

204:デフォルトの名無しさん
07/08/26 15:56:25
>>201
wikipediaでもなんでも見ればいいだろ。

205:デフォルトの名無しさん
07/08/26 16:07:59
>>203
例えば1500円/人時で5秒2円位。17文字タイプだとその位にはなる

206:デフォルトの名無しさん
07/08/26 16:14:51
>>201
ISO/IEC 14882(C++の規格だ) の5.3.3 Sizeof にこう書いてある。

sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1;

207:デフォルトの名無しさん
07/08/26 16:20:56
>>206
いや、お前さんは流れ読めてなさ杉だろ。

208:デフォルトの名無しさん
07/08/26 16:21:29
#define sizeof(char) 1

209:デフォルトの名無しさん
07/08/26 16:24:36
>>207
>charのサイズが2バイトのC++環境とかだと
っていう>>201の前提がこれで無くなった っていうだけだよ

210:デフォルトの名無しさん
07/08/26 16:25:29
>>201後半
それはない。
そうだとすると、malloc(2)の返すポインタが
要素数2つのchar配列として使えないという意味になるではないか。

mallocが使う単位もまた、sizeofと同じ。

211:デフォルトの名無しさん
07/08/26 16:36:14
>>209
sizeofの単位がバイトとはどこにも書いてないだろう

212:201
07/08/26 16:36:27
>>209
いやいや。だから、規格だと1とは書いてあるけどそれが1バイトを意味するって書いてないよねってはなし。
たとえば1=1ワードとかあり得るわけで。昔とかだと1ワード9ビットとか10ビットのマシンってあったしね。
その1ってなんだ? っていうお話。

sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1;
じゃなくて、
sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1 byte;
ってかいてあるなら自分の言ってることは間違いってことになるけど。

>>210
そうだよ。だから、規格上ではホントにそれが保証できないって言いたいわけ。
malloc(8)の返すポインタが要素数2つのint配列として使えないのと同じってこと。

mallocが使う単位はbyteでsizeofの単位はC++に限って言うならcharのサイズを1とした環境依存。
実用上同じでないと使い勝手が悪いというのならそれには同意。


213:デフォルトの名無しさん
07/08/26 16:43:08
C99ではsizeofの結果はバイト数ってことになってるな。

> sizeof 演算子の結果は、そのオペランドの大きさ(バイト数)とする。

214:デフォルトの名無しさん
07/08/26 16:44:00
>>212
The sizeof operator yields the number of bytes in the object representation of its operand.

ってわけえ、sizeofはバイト数を返します

215:デフォルトの名無しさん
07/08/26 16:46:07
>>201
次のネタどうぞ

216:デフォルトの名無しさん
07/08/26 16:51:06
sizeof()の返り値はバイト数
malloc()の引数はバイト数

では、
strlen()の返り値は何?

バイト数なら、そのまま+1してmallocの引数に渡すのはOKだが、
文字数なら、sizeof(char)を掛けないと、バイト数にはならないよね。

217:デフォルトの名無しさん
07/08/26 16:56:47
The strlen function returns the number of characters that precede the terminating null character.

218:デフォルトの名無しさん
07/08/26 17:00:44
1を掛けても掛けなくても数値は変わらないよね

219:デフォルトの名無しさん
07/08/26 17:03:15
strlenの引数は char* だから文字数=バイト数と考えてよいのでは?
それとも漢字が混じるとそれも1文字として扱われるだろうか?
だとしたら、sizeof(char)掛けてもバイト数にはならないよね。

220:デフォルトの名無しさん
07/08/26 17:03:27
>>216
戻り値はキャラクタ数
1キャラクタは1バイト
よって戻り値はバイト数

ってことだね

221:デフォルトの名無しさん
07/08/26 17:05:29
それは数値の一致であって、意味の一致ではない。
あくまでも「1バイト文字」の「文字数」なのだから。

省略してもプログラムは意図した通りに動くが、
プログラムが動けば何だっていいというのは間違い。

222:デフォルトの名無しさん
07/08/26 17:15:13
仕様上キャラクタ=バイトです。
たまたま文字を意味するときだけ
わかりやすくキャラクタと表記します。
そのため、byte という型はありません。

だってさ。なるほどね。

223:デフォルトの名無しさん
07/08/26 17:19:42


224:デフォルトの名無しさん
07/08/26 18:17:13
>>221
1バイト文字の文字数がバイト数と等しいと見なすことの何がいけない。

225:デフォルトの名無しさん
07/08/26 18:25:17
プログラムのコードに現われない、暗黙の変換を行うから、いけない。


226:デフォルトの名無しさん
07/08/26 18:26:25
>>225
暗黙じゃないだろ・・・

227:デフォルトの名無しさん
07/08/26 18:34:00
>>225
こんな自明な事柄、変換じゃないだろ。

228:デフォルトの名無しさん
07/08/26 18:42:37
自明だからといって省略するのは、悪い癖だなぁ。

229:デフォルトの名無しさん
07/08/26 18:57:07
そもそも変換じゃないだろ。

230:201
07/08/26 19:23:37
>>213
>>214
これは知りませんでした。ご教授ありがとうございます。
たしかにsizeof(char)は常に1で、返すのはバイトサイズだからcharが
2バイトの環境ってあり得ないですね。
勘違いしてました。

>>215
ごめん。
俺の疑問は俺の誤解だったということで解決したから、次のネタはないの。。。
単発と言うことで許して。


231:デフォルトの名無しさん
07/08/27 01:09:02
お前ら、こんな下らない話で、よくここまでスレを伸ばしたなぁ。

いまどきmallocとstrlenを散在させるようなコードを書くほうがオカシイ。
strlenなんて使うか? ふつー。

232:デフォルトの名無しさん
07/08/27 01:14:17
最近はもうC自体あんまり使わない

233:デフォルトの名無しさん
07/08/27 01:23:27
>>231
話がループしてるからいくらでも伸びる気がする。
ところで、
「散在させる」ってのはどこから出てきた?
strlenを使わないなら何を使う?(あくまでCだとして)
sizeof(char)を省略すべきでない?


234:!= 231
07/08/27 01:25:34
ここでstrlen_sだなんて言ってみるテスト

235:デフォルトの名無しさん
07/08/27 01:28:31
>>231
くだらないからこそだろう

まさにこれこそが 「自転車置場の議論」 ってやつだな


236:デフォルトの名無しさん
07/08/27 01:35:19
>>233
マクロ、ライブラリ、クラスの中で使うのではなく、
ベタベタと書くコードの中で使う = 散在させる

ぶっちゃけ、適切に局在化されていれば、
多少マズいコードだろうと直せるので、
このスレで話しているようなことは、
どーでもよくなるんですよ。


237:デフォルトの名無しさん
07/08/27 01:39:54
そうだ、マルチバイト文字が存在するからいけないんだ!
今日から、みんな、英語で生活!
それで全員ハッピーだ!


238:デフォルトの名無しさん
07/08/27 01:57:57
Die job death car?

239:233
07/08/27 02:01:15
>>236
「散在させる」はスレの流れから読み取ったわけじゃないのね。

俺も同じ考えだけど、ちょっと論点がずれてる気がする。
「局在化」とか、「直せる」とかはこのスレには関係ないな。
局在化したその場所で「省略するかしないか」ってことが問われてる。
まあ、そこで、「どーでもよい」ってのが答えなんだろうけど。

240:デフォルトの名無しさん
07/08/27 04:21:09
ここで新たな判断基準を持ち込んでみる。

どちらが適切だと思うか主張する場合に、年収も書くこと。
年収の多い人のやり方が、すなわち、より成功に近い。

241:デフォルトの名無しさん
07/08/27 06:00:54
馬鹿発生

242:デフォルトの名無しさん
07/08/27 09:04:13
アホが来たよ・・・

243:デフォルトの名無しさん
07/08/27 09:28:33
>>231
C言語なら「普通」strlenを使うと思う。

NULL終端までのバイト数を取得する関数なんて作るのは、
まぁライブラリの標準関数が使えないプロジェクトぐらいじゃないの?

244:デフォルトの名無しさん
07/08/27 11:19:52
今時charの内部形式を意識しないといけない言語は使うな。

245:デフォルトの名無しさん
07/08/27 16:17:20
>>243
何かにつけてstrlenする、糞遅くて信頼性の低いプログラム書いてるのか。ご苦労さまです。

246:デフォルトの名無しさん
07/08/27 16:20:17
本当、何かにつけてstrlenの必要に迫られるCは疲れるよ。

247:デフォルトの名無しさん
07/08/27 16:25:11
>>245
C厨だがそこには同意

248:デフォルトの名無しさん
07/08/27 17:18:47
strlen

249:デフォルトの名無しさん
07/08/27 17:23:02
struct {
size_t bufferLen ;
size_t validLen ;
char szBuffer[1] ;
} ;
とかの構造体を使って、バッファの長さや有効長を管理したらいいじゃないか。
szBuffer[1]と言いながら、実際にはヒープから長い領域を貰うのは気持ちわるいかもしれないが。

250:デフォルトの名無しさん
07/08/27 17:36:12
>>245
自分がそうだからといって人もそうだとは限りません。
間抜けですね。

251:デフォルトの名無しさん
07/08/27 18:10:40
>>249
そこまでするくらいならC++使う。そもそも使えるときは使っている。

252:デフォルトの名無しさん
07/08/27 19:11:38
>>250
どんなコードを書いているのか披露してほしい。お手本にするから。

253:デフォルトの名無しさん
07/08/27 20:09:30
>>245
fgetsで文字列を読み込んだり、コマンドライン引数を受け取ったりした際に
得られた文字列長を調べるための、strlenより高速で信頼性のある方法を教えてくれまいか?

254:デフォルトの名無しさん
07/08/27 20:59:09
freadを使う

255:デフォルトの名無しさん
07/08/27 21:05:14
それはstrlenより高速で信頼性のある方法なのか?

256:デフォルトの名無しさん
07/08/27 21:29:46
>>253
まず、得られた文字列の長さを調べる必要が、本当にあるのかな。
次に、何かにつけてfgetsするのかな。

257:デフォルトの名無しさん
07/08/27 21:32:02
必要あるからする

258:デフォルトの名無しさん
07/08/27 21:34:11
本当は必要ないのに、必要だと思い込んでいる可能性を疑ってみた?

259:デフォルトの名無しさん
07/08/27 21:37:49
もちろん

260:デフォルトの名無しさん
07/08/27 21:38:54
で、strlenより高速で信頼性のある方法は?

261:デフォルトの名無しさん
07/08/27 21:44:29
じゃぁ>>253は具体的にコードを例示してね。

262:デフォルトの名無しさん
07/08/27 21:50:37
strlenより高速で信頼性のある方法マダー?

263:デフォルトの名無しさん
07/08/27 21:53:02
strlenよりも高速で信頼性のあるstrlen互換の関数の話ではないぞ。

264:デフォルトの名無しさん
07/08/27 21:55:18
基本的に、
気やすくstrlenやstrcpyを使わない
ってだけで、かなり速くなるし、安全性も高まる。


265:デフォルトの名無しさん
07/08/27 21:59:45
酷い例1
char buf[100] ;
char buf2[100] ;
fgets(buf, sizeof(buf), pFin) ;
if (strlen(buf) < sizeof(buf2)) { /* 無意味な長さチェック */
strcpy(buf2, buf1) ; /* ←無意味なコピー */
}

酷い例2
for (i=0 ; i<strlen(s) ; i++) { /* 無意味な有限回数のループ、無意味な毎度の関数呼び出し */
if (s[i] == 'X') { なんたら }
}


266:デフォルトの名無しさん
07/08/27 22:02:14
strlenよりも高速で信頼性のあるstrlen互換の関数マダー?

267:デフォルトの名無しさん
07/08/27 22:07:14
>>264
strlen,strcpyの安全性が低く感じるのは、呼び出し元の安全性が低いから。
速くなるってのは、一度取った長さを変数に入れておくとかってレベルの話かな?
いずれにしろ、これらに限らず「安易に使わない」って意味では同意できる。

268:デフォルトの名無しさん
07/08/27 22:25:48
>>267
> strlen,strcpyの安全性が低く感じるのは、呼び出し元の安全性が低いから。

人間はミスをするものだから、
機械的かつ強制的にチェックしなければ、
意味がない。

バッファの長さが十分であるという、
目に見えない約束なんてものは、
人間のミスには耐えられない。

> 速くなるってのは、一度取った長さを変数に入れておくとかってレベルの話かな?

そんな小手先の最適化ではなく、
strlenを本当に必要な場所でしか使わない、ということ。



269:デフォルトの名無しさん
07/08/27 22:28:11
安易に使わないってどゆこと?

必要だから使うんじゃないか。代替手段があるというのか?


270:デフォルトの名無しさん
07/08/27 22:29:30
>>269
実際にどんなコード書いてるの? 晒してみなよ。

271:デフォルトの名無しさん
07/08/27 22:30:02
253だが、257とか259とか俺じゃないんだが。

なんか>>261に指名されたんで、釣られてちょろっと書いてみる。
エラー処理が抜けてるのは行数削減のため。
引数に与えた文字列から始まる行を表示するプログラム。
fgetsでは無くて、引数の文字列長を取得する例なんで、
簡単のために最大255文字。

#include <stdio.h>
#include <string.h>
#define BUF_SIZE 256
int main(int argc, char *argv[])
{
int len = strlen(argv[1]);
char buf[BUF_SIZE];
FILE *fp = fopen("test.txt", "r");
while ((fgets(buf, BUF_SIZE, fp)) != NULL) {
if(strncmp(argv[1], buf, len) == 0) printf("%s", buf);
}
}

strlenぐらい普通に使うと思うんだけどねぇ。

272:デフォルトの名無しさん
07/08/27 22:32:33
なんかボーっとしてる間に、えらいスレ進んでてびっくりだ。
253と271とコレ以外は俺じゃないんで一応。

273:デフォルトの名無しさん
07/08/27 22:36:16
>>271
それは
「何かにつけてstrlenする」
には該当しないと思うが。

274:デフォルトの名無しさん
07/08/27 22:37:17
>>272
すまんね >>257>>259は俺だ
君の振りをしたつもりは無いんだけどね

275:デフォルトの名無しさん
07/08/27 22:50:29
こんなどうでもいいことを真剣に議論してるw
ワラタw

276:デフォルトの名無しさん
07/08/27 22:53:27
それはよかった

277:デフォルトの名無しさん
07/08/27 22:55:12
>>273
>>243に対して>>245だったから、strlenを全否定してるように見えたんで、
「まぁ使うんじゃないの?」ぐらいの感じで書いただけだよ。

ループ内とかで同じ文字列に対して何度もstrlen呼んだりとか
そういうのは無駄だと思うよ。

278:デフォルトの名無しさん
07/08/28 22:18:22
結論は出ましたか。

279:デフォルトの名無しさん
07/08/28 22:23:56
結論:
sizeof(char)は省略してもいい
strlenは必要な場合もある

280:デフォルトの名無しさん
07/08/28 22:28:44
上げんな糞
>>1死ね

281:デフォルトの名無しさん
07/08/28 23:30:57
adobePの新作期待age

282:デフォルトの名無しさん
07/08/28 23:46:39
>>1

sizeof(char)が必ず1なら
malloc(sizeof(char)*(strlen(s)+1))
ではなく
malloc(strlen(s)+1)
の方がいい

malloc(sizeof(char)*(strlen(s)+1))
だとsizeof(char) * が冗長

sizeof(char)が必ずしも1でないならわかるが

283:デフォルトの名無しさん
07/08/29 01:23:30
まあCとC++に限って言えば100% 1だからなぁ

284:デフォルトの名無しさん
07/08/29 01:26:43
いい加減ループしすぎ。

285:デフォルトの名無しさん
07/08/29 01:27:14
まぁスレタイがねループしてくださいって言ってるようなもんだからね

286:デフォルトの名無しさん
07/08/29 01:29:27
ループといえば for(;;) と while() の戦争もあったな
オレは意味なくdo~while派だけど

287:デフォルトの名無しさん
07/08/29 01:38:39
じゃあ俺はgotoを使うぜ!

288:デフォルトの名無しさん
07/08/29 01:41:03
三木は3つまでしかまとめられなかったので 3岐
後藤は5匹を統括してたから 5統

289:デフォルトの名無しさん
07/08/29 06:16:09
ナツカシス

290:デフォルトの名無しさん
07/08/29 06:40:54
ネオジオは100メガビット

291:デフォルトの名無しさん
07/08/29 07:43:01
>>288
三木は右手だからじゃなかったっけ?

292:デフォルトの名無しさん
07/08/29 11:02:31
それもあるな
なんかこう言葉遊びもあそこまで行くと芸術レベルだよな

293:デフォルトの名無しさん
07/08/29 13:07:42
>>284
今頃ノコノコ出てきて画期的なご意見を述べて行かれる
>>282 みたいな間抜けがいる限り、ループは不滅です。

294:デフォルトの名無しさん
07/08/29 21:26:11
exit(0);

295:デフォルトの名無しさん
07/08/29 21:49:41
いまどきマロックなんか使うかよw
newを使えnewを!

296:デフォルトの名無しさん
07/08/29 22:22:16
VirtualAllocは多用しますが何か?

297:デフォルトの名無しさん
07/08/29 23:13:24
sizeof(char)+1が必ず2でも、省略すべきではない
スレリンク(tech板)

298:デフォルトの名無しさん
07/08/29 23:20:02
再帰

299:デフォルトの名無しさん
07/08/30 19:28:14
おもしろいことに、関心と一般の議論の大きさは、
機能の重要性と反比例していることが多い。
その理由は、大きな機能より小さな機能のほうが明確な意見を持ちやすく、
流行のような、一時的な関心を引きやすいからだ。
~~Bjarne Stroustrup『C++の設計と進化』

300:デフォルトの名無しさん
07/08/30 22:41:51
>>299
そして、プログラムとは、小さな機能を集めて大きな機能を実現していく。
だから、小さな機能を議論することは、最終的に大きな機能
そして、重大な機能を議論することにつながるのである。

301:デフォルトの名無しさん
07/08/30 23:39:17
ああいえば上祐

302:デフォルトの名無しさん
07/08/31 00:56:46
URLリンク(msdn2.microsoft.com)(VS.80).aspx

世界一巨大なソフトウェア会社のコーディング例では、
len = _vscprintf( format, args ) // _vscprintf doesn't count
+ 1; // terminating '\0'
buffer = malloc( len * sizeof(char) );
のように、sizeof(char)を省略していない。

303:デフォルトの名無しさん
07/08/31 01:34:46
URLリンク(dist.dc.kumamoto-u.ac.jp)
の問題2
「自分なりの理由」があればどちらでも良い。
という答えな気がする。

304:デフォルトの名無しさん
07/08/31 01:41:50
>>303
純真な若者に示す手本として、
s = (char *)malloc(sizeof(char)*n + 1);
というのは、随分と酷いな。

s = (char *)malloc(n + 1);
ならともかく、
s = (char *)malloc(sizeof(char)*n + 1);
はダメだろう。

意味として間違ってる!

305:デフォルトの名無しさん
07/08/31 01:50:23
>>304
まあね、書くのならこのスレの様に
sizeof(char)*(n+1)
のようにヌル文字分も含めるべきだね。

306:デフォルトの名無しさん
07/08/31 01:53:05
>>303
どうしようもない問題集だな。特に問題4の辺りは終わっている。

307:デフォルトの名無しさん
07/08/31 02:23:04
演習3のプログラムも酷い。

例とはいえ、freeしないのは、どうかと。
それに、stdio.hしか#includeしてないぞ!!!

308:デフォルトの名無しさん
07/08/31 02:37:23
>>303のURLのソースを見ると、スタイルシート"masato.css"を使ってる。

URLリンク(www.kumamoto-u.ac.jp)
のトップページでmasatoを検索すると、
URLリンク(www.syst.cs.kumamoto-u.ac.jp)
がヒットする。似たようなセンスの問題が。

URLリンク(www.syst.cs.kumamoto-u.ac.jp)
の問題4は、>>303の演習3と似てる。

そして問題5は、
> 友情をテーマに,mallocと構造体を使った簡潔なプログラムを作りなさい.
という、涙が出そうな秀逸な問題だ。

ちなみに、URLを削って
URLリンク(www.syst.cs.kumamoto-u.ac.jp)
という研究室のWebのメンバーを見ると、助手らしい。

熊本大学だいじょうぶか?
こんな質の低い教育やってちゃイカんぞ。

309:デフォルトの名無しさん
07/08/31 02:49:46
だって、Apache インストール済みだもん。
URLリンク(dist.dc.kumamoto-u.ac.jp)

310:デフォルトの名無しさん
07/08/31 04:12:25
URLリンク(www.syst.cs.kumamoto-u.ac.jp)
> 問題2
> 以下のプログラムを見て,問に答えなさい.
> #include <stdio.h>
> #include <stdlib.h>
>
> #define SIZE 5
>
> int main()
> {
> int a[SIZE], i;
> int *b = (int *)malloc(sizeof(int)*SIZE);
>
> for (i = 0; i < SIZE; i++)
> a[i] = i * i;
>
> for (i = 0; i < SIZE; i++)
> b[i] = a[i];
>
> for (i = 0; i < SIZE; i++)
> printf("%d ", b[i]);
> printf("\n");
>
> return 0;
> }


311:デフォルトの名無しさん
07/08/31 04:12:51
>
> 1. 「配列aとmallocで確保された領域bの違いは,
> 静的に確保されるメモリ領域と,
> __に確保されるメモリ領域という違いがある.」
> __に入る適切な言葉を以下から選びなさい.
>
> a.愛ゆえ
> b.俺的
> c.仮想的
> d.動的
>
> 2. b[2]の型は何ですか?




312:デフォルトの名無しさん
07/08/31 04:15:56
これは問題の間違いを正しなさい、という課題なのかな。

配列aが「静的」だってよ。

313:デフォルトの名無しさん
07/08/31 04:16:42
さらに、for文の書き方が酷い。

同一行に書くのなら {} を省いても構わないが、
別の行に書くのなら {} は省くべきではないのに。

314:デフォルトの名無しさん
07/08/31 05:30:37
sizeof(char)の話に集中しましょうね。

大学のプログラミング演習の課題を添削するスレ
スレリンク(tech板)

315:デフォルトの名無しさん
07/08/31 09:32:49
>>302
そういうことやってるから細かいバグが残ったりなかなか取れなかったり
するんだろ。しっかりしろといいたい。

316:デフォルトの名無しさん
07/08/31 09:37:52
そうだな。

+1を人間がコーディングしていたら、+1し忘れて、バッファオーバーフローするわな。

317:デフォルトの名無しさん
07/08/31 10:12:40
世界一安定してる会社のコーディングスタイルならともかく、バグだらけの会社のそれを例に出されてもな

318:デフォルトの名無しさん
07/08/31 10:13:47
>>317
コード量が膨大だから、バグ含有率が低くても、バグ件数は膨大になるんだよ。

319:デフォルトの名無しさん
07/08/31 12:19:34
>>318
ああいうコードが積み重なってるからね
バグが多くなるのもうなずけるよ・・・

320:デフォルトの名無しさん
07/08/31 13:30:54
>>302
ほんと、あそこのサンプルコードってゴミばっかりだよな。

>>313
お前の推奨するスタイルなんかどーでもいいわけだが。

321:デフォルトの名無しさん
07/08/31 15:12:04
また1つごみを見付けたんで記念カキコ
URLリンク(msdn2.microsoft.com)(VS.80).aspx

pszSrc= new char(12);
if(pszSrc)
    pszSrc= "Hello world!";


322:デフォルトの名無しさん
07/08/31 15:41:38
>>321
酷すぎるww
その前にあるNULL代入も意味無いしw
constもキャストもないからコンパイルも通らんだろうなw

323:デフォルトの名無しさん
07/08/31 15:52:20
何がやりたいのかよくわかんねーソースだな

324:デフォルトの名無しさん
07/08/31 16:31:06
>>321
あれだな、
1.まず鍋を用意します。
2.次に鍋を投げ捨てます。
3.そして既に作っておいたカップラーメンを食べます。
みたいな感じか。

それにしても僅か8行でツッコミ所満載な上に
メモリリークのおまけ付きとか流石マイクロソフトだな。

325:デフォルトの名無しさん
07/08/31 16:36:02
>>321
非NULLは真になるよって言いたいんじゃまいか

326:デフォルトの名無しさん
07/08/31 16:36:14
せめてnew char[12]と書けよと思う。

327:デフォルトの名無しさん
07/08/31 17:10:02
strcpyしたかったのかな。"Hello world!"で12文字だからnew char[12]じゃ足りないけど。
str.CopyChars(str.GetBuffer(), "Hello world!", 12); と書いとけばいいのにw

328:デフォルトの名無しさん
07/08/31 19:35:39
>>321は良い踏み絵だな
判ってない奴が浮き出てきた

329:デフォルトの名無しさん
07/08/31 20:59:23
charというのは組込型ではなくクラスなのか?


330:デフォルトの名無しさん
07/08/31 21:23:47
>>328
何が?

331:デフォルトの名無しさん
07/08/31 21:24:49
>>329
ATL/MFC のコードなんだから C++。
なので char はクラスではない。

332:デフォルトの名無しさん
07/08/31 23:56:30
>>328
>>327みたいな奴の事だろう

333:デフォルトの名無しさん
07/09/01 01:06:20
>>332
>>327みたいな奴は何がわかってないの?

334:デフォルトの名無しさん
07/09/01 02:00:21
>>328
よく判ってないんで、>>321のソースを解説してはくれまいか?

335:デフォルトの名無しさん
07/09/01 11:25:14
// 動的に確保した領域のポインタをpszSrcに代入
pszSrc= new char(12);
// newに成功した場合
if(pszSrc)
// 動的に確保した領域を無視して、文字列リテラルのポインタをpszSrcに保存
// 動的に確保した領域はリークする
pszSrc= "Hello world!";

C言語しか分からんけど、newをmallocに読み替えるとこんなところ。
C++だと文字列リテラルの代入は、なんかstrcpyみたいな動きすんのか?

336:デフォルトの名無しさん
07/09/01 11:36:12
>// 動的に確保した領域のポインタをpszSrcに代入
>pszSrc= new char(12);
構文エラー。

>// newに成功した場合
>if(pszSrc)
newはNULLを返さない。

>// 動的に確保した領域を無視して、文字列リテラルのポインタをpszSrcに保存
>// 動的に確保した領域はリークする
>pszSrc= "Hello world!";
その通り。

>C言語しか分からんけど、newをmallocに読み替えるとこんなところ。
>C++だと文字列リテラルの代入は、なんかstrcpyみたいな動きすんのか?
しないしない。

>>324
寧ろ、こう。
・鍋を用意して一杯にお湯を沸かします(勿論、麺を入れたら溢れて大変ですね)。
・鍋は用意できましたか(当然である)?
・ではこちらに用意したカップラーメンをどうぞ(おいおい、鍋そのままw)。

337:デフォルトの名無しさん
07/09/01 12:01:38
>>335
  pszSrc= new char(12);
は、C だと↓こんな感じ。
  (pszSrc = malloc(1)) = 12;

338:デフォルトの名無しさん
07/09/01 12:02:26
あああ尻穴忘れた!
  *(pszSrc = malloc(1)) = 12;

339:デフォルトの名無しさん
07/09/01 12:15:23
>>336
12はcharの初期化子として有効。エラーにはならない。

340:デフォルトの名無しさん
07/09/01 15:08:20
エレガントなメモリリークだなぁ

341:デフォルトの名無しさん
07/09/03 04:22:12
mallocが失敗する可能性は考慮しないのか?
つーか、mallocってNULL以外が返ったとしても
実はメモリ確保に成功したかどうか不明だという
おそろしいバグがあるんだがLinuxって怖いよな

342:デフォルトの名無しさん
07/09/03 08:06:28
mallocやnewが失敗する状況って、かなりヤバいよね。

それらに対処するコードで、mallocやnewを使うと、ミイラ取りがミイラになる恐れがあるし、
OSの仮想メモリを食い尽くしている状況では、他のプログラムも動作続行が厳しくなっていて、
終了処理も正常に行えるか怪しい。予想もつかないような事態が次々に発生しそう。

だから、mallocやnewに失敗した時点で、OSから再インストールするハメになるわけで、
成功したかどうかチェックし、失敗したことがわかったところで、ろくに対処できないなら、
開き直って、mallocやnewをラップして、失敗したらexitしてしまい、
ラップしたものを使う側は、失敗することはないものとしてコードを書いてしまうのもアリかと。


343:デフォルトの名無しさん
07/09/03 09:14:15
>だから、mallocやnewに失敗した時点で、OSから再インストールするハメになるわけで、
おいおい、普通はrebootで充分だろ。

実際Gnomeなんか使っていると、malloc()に失敗する頃には事実上操作不能になっているから、
諦めてとっととexit()ってのはありだと思う。
私の仕事関係では、常駐型アプリケーションの起動は基本的にスクリプトから行ない、
アプリケーションが異常終了したときには可能ならそのアプリケーションを再起動するようにしている。

344:デフォルトの名無しさん
07/09/03 09:42:29
>>343
rebootで十分という保証があれば、ね。

OSの上で走るすべてのプログラムが、
設定やデータをファイルに書く時、
一貫性を保てるように書いてくれればいいが、
そうでないと、
不正で壊れたファイルを読むことになり、
こまったことになってしまう。

345:デフォルトの名無しさん
07/09/03 13:09:01
OSからとかねぇよw
書き込み中の電源断でさえジャーナルファイルシステムなら通常問題無いのに、
メモリ確保失敗くらいで整合性取れなくなるとかw

基幹システムなどなら、ソフトウェアとして既に品質に問題有りだし、
個人PCやグループサーバーレベルで再インストは潔癖過ぎだろ。

346:デフォルトの名無しさん
07/09/03 13:13:01
1GiBのメモリ確保しようとして失敗したって状況なら、
メモリ確保失敗したとユーザに通知したり、
そのために数KiBのメモリを確保したりしようとしてもいいと思う。

347:デフォルトの名無しさん
07/09/03 13:32:25
>>345
ファイルシステムのレベルで問題がなくても、ファイルの中身のレベルでは問題だよ。

ファイルの中身までトランザクションやジャーナルでやっていれば大丈夫だが、
そうでないプログラムの場合、ファイルの中身の一貫性が失われてしまう。

348:デフォルトの名無しさん
07/09/03 13:56:19
>>347
>そうでないプログラムの場合、ファイルの中身の一貫性
345の下2行の通り。
重要なシステムなら論外、DBMSなどで一貫性の確保は必須だし、
それでも抜けた異常はバックアップからリカバリさせる。
OSからとかダウンタイム長すぎだろ。

それにメモリ不足でOS壊すってどんな状況?
viがLILOの設定ファイル書き換える最中に死んだって、
書き換え前にバックアップくらいしてるだろ。

ユーティリティか何かがhttpd.conf壊したって、
OSどころかapacheから入れなおす馬鹿は居ないだろ。

349:デフォルトの名無しさん
07/09/03 16:41:48
>ユーティリティか何かがhttpd.conf壊したって、
>OSどころかapacheから入れなおす馬鹿は居ないだろ。
見たことあるな。
俺はこれをWindows病と名づけた。

350:デフォルトの名無しさん
07/09/03 18:53:50
あーいるいる、「取り敢えず再インストールしてみました」って香具師。

351:デフォルトの名無しさん
07/09/03 20:36:44
ネトゲのクライアントは、たまにWindowsの設定やらシステムファイルやらをぶち壊す奴が居る

352:デフォルトの名無しさん
07/09/03 20:37:39
あ、補足。
多分mallocは関係ない。

353:デフォルトの名無しさん
07/09/03 21:53:13
しばらく前、幻想三国志2っちゅーゲームでアホほど再起動かかってOSが不安定になった。
再起動の原因がメモリリークと気付くのが遅すぎた・・・。

HDDがガリガリ鳴り出したらセーブして再起動とか、
偽典女神転生を思い出して懐かしかった。

354:デフォルトの名無しさん
07/09/03 22:57:44
突然だがスレを激しくrollbackしていいかな。

sizeof(char)は確かに仕様で1と決まっているけど、省略しない方が良い。
コメントやsizeof(char)==1の理解が無くても、
ソースを見るだけで文字数→バイト数として扱いたい意図が明確になる。
それにコンパイラの最適化でどうせコストは0だ。

ただ、そんな冗長なソースが散在しているのが嫌だというのも同意出来る。
しかしそれ以前に、文字列の操作なんて普通はラップしないか?

>malloc(sizeof(char)*(strlen(s)+1))
>malloc(strlen(s)+1)
両方とも、非常に短い関数以外でこんなん出てきたらどうかと思うんだが。

char*    strmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(char   ));}
wchar_t* wcsmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(wchar_t));}
void strfree(const char*    s){free(s);} // 確保/解放を対とするためfreeを単純にラップ
void wcefree(const wchar_t* s){free(s);} // 確保/解放を対とするためfreeを単純にラップ

char* s2 = strmalloc(strlen(s));
strfree(s2);

これくらいは抽象化するだろ?お前らどうやってる?

355:デフォルトの名無しさん
07/09/03 23:21:41
>文字数→バイト数として扱いたい意図
ここは自明だろーがよ
というのが反対派の意見だと思う。

a++; // 1を足す
っていうコメントを読まされるような感じ というか

356:デフォルトの名無しさん
07/09/03 23:28:41
>>354
一方俺はC++を使った。

357:デフォルトの名無しさん
07/09/03 23:49:03
まぁ、俺も現実的にはC++使うな。
だけどC++使うからこそ観念的に省略しないんだけどな。

テンプレート関数とか作るとき
> ここは自明だろーがよ
> というのが反対派の意見だと思う。
そのはずの自明が、抽象化・総称化すればする程無くなっていく。
wchar_tの対応をしようとしただけで崩れる。
つまりその自明はあまり本質的でなかったということ。
むしろ、文字をchar型を扱うときに限り文字数とバイト数が同じになる、と考える。

文字列操作と言いながら型を強く意識するのは、やはりスマートとは思えないよ。

358:デフォルトの名無しさん
07/09/03 23:52:00
誤記は脳内保管で。

359:デフォルトの名無しさん
07/09/04 00:00:44
>>357
ぶっちゃけ未対応ソフトの多バイト文字対応をするときは
charをwchar_tに機械変換♥ なんて絶対しないから
もうその辺はすごい勢いでどうでもいい話だと思う。

360:デフォルトの名無しさん
07/09/04 00:11:32
そもそも文字型が独立しておらず、charやunsigned charが
整数型の1つである(JavaやC#でいうbyteにあたる型)という時点から
もう文字とバイトをごっちゃにするのは始まっている。

だから俺は文字 == バイトを甘んじて受け入れ、sizeof (char)を使わない。

361:デフォルトの名無しさん
07/09/04 00:15:20
機械変換とかじゃなくて、テンプレート関数の話な。
allocator((Tr::getlen(s)+1) * Tr::char_size);
みたいな感じで実装して、型はコンパイル時に決まる。

ちょっとした関数を総称化すると、
自分が自明だとか本質的だと思っていたものが、
そうでもないと気付かされるって話。

362:デフォルトの名無しさん
07/09/04 00:18:56
ぶっちゃげcharだけなんてXMLも扱えねぇよ最近。

363:デフォルトの名無しさん
07/09/04 00:28:46
>>360
文字とバイトがごっちゃというのは整理出来ていないから。

文字は文字集合として独立していて、バイトも文字集合とは関係無い。
その2つを繋いで、バイト列の上で文字を表現するルールがエンコーディング。
概念が頭の中で分かれていれば、unsinedだとかSJIS, UTF-8やらがあってもごっちゃにはならないはず。

364:デフォルトの名無しさん
07/09/04 00:30:07
型について、ちょい脱線するけど・・・。
時刻を保持する型を使ってて、8月中のデータを探すとき
(擬似コード。リテラルは変数に代入された値と思って)
if("2007/08/01" <= x && x <= "2007/08/31 23:59:59"){...}
のように書く奴が居る。

俺は
if("2007/08" <= x && x < "2007/09"){...}
と書く。月日は省略されると1、時間以下は0となる。(普通)

しかし、そう書く理由はソースが短くなるからじゃない。
if("2007/08/01 00:00:00" <= x && x < "2007/09/01 00:00:00"){...}
と書いても良い。
59:59だとか、9999だとかは、まずいサインだと思っている。
型を強く意識している場合は多いからだ、

上記の場合、この型がミリ秒まで保持することになったとき、
23:59:59は正確な最後ではなく、23:59:59.999と書く必要があり
僅かだが穴のあるプログラムとなる。

データ的にはピコ秒まで持てるようになったら?.999999...
精度の問題じゃない、結局は 「2007/09/01に限りなく近い値」となる
なら2007/09/01 00:00:00と比較すれば良い。

ソートで単に最後にしたいものに 9999 を入れるとか、
場合によってはハードコーディングとか、もう見てられない。

必要以上に型の精度に依存しないで欲しい。

365:デフォルトの名無しさん
07/09/04 00:33:50
ミリ秒以前にうるう秒

366:デフォルトの名無しさん
07/09/04 00:36:45
<= じゃなくて < を使えば済む話じゃないのか

367:デフォルトの名無しさん
07/09/04 00:48:33
>>366
そう、そういう話。
でも使ってる精度が日まで(時以降が00:00)で、Webフォームから期間を入れられた場合、
開始日~終了日という入力欄では終了日も含むので、
x < 終了日+1 とせず、単に x <= 終了日とする奴が中々多い。
右の方がシンプルだし、わからんでもないが。

それで登録日時(時分秒が有る)とかを検索する処理でも同じソース使って馬鹿がって結果になってた。

368:デフォルトの名無しさん
07/09/04 00:52:32
>>363
文字とバイトがごっちゃというのは俺に言っているのか?
俺は、CとC++が文字とバイトをごっちゃに扱っていると言ったつもりだ。
だから俺にそんなこと言われても、お門違い。


369:デフォルトの名無しさん
07/09/04 01:04:36
wchar.hなど有るし、文字とバイトをごっちゃに扱ってるようには思えないが・・・
それにchar==文字でなく、char*==nul終端文字ストリームというのがあったから
SJISなどをそれなりに扱えて来たわけだし。

370:デフォルトの名無しさん
07/09/04 01:20:30
ちなみに、java,C#などは文字型が本当の意味で独立してるわけじゃなく、
単に内部のエンコードを割り切ってUTF-16に統一してるだけ。
昔、C言語がasciiで十分と考えたように。

その利便性はもちろん大きいけど、その代償としてUTF-8などを読み書きするとき
エンコード変換のオーバーヘッドを受け入れている。
※よほど巨大なファイルでない限り対したオーバーヘッドじゃないけど。

371:デフォルトの名無しさん
07/09/04 01:27:26
UTF-16もサロゲートペアを考えるとchar==1文字とならない。
Unicode領域で固定バイトが出来るのはUTF-32だけ。
でもascii1文字に4byteも使うことと、
サロゲートペアの文字があまり重要でないことからUTF-32で扱っているシステムは少ない。

未来の言語のcharは32bitかもしれない。

372:デフォルトの名無しさん
07/09/04 02:46:39
おれは>>355と同じように考える。
>>357,>>361で抽象化とか総称化とかって話がでてるけど、
そのようなケースになったときは、そう書けばいい。

しかし、このスレでは‘sizeof(char)’は抽象化されてない。
あくまで、>>1の記述に的を絞って考えたらやっぱり冗長かなーと。。。


373:デフォルトの名無しさん
07/09/04 02:49:51
>>354
> char*    strmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(char   ));}

len=0のときにNULLにしてしまうのは、ちょっと馴染みがないんだが。


374:デフォルトの名無しさん
07/09/04 02:53:44
え?

375:デフォルトの名無しさん
07/09/04 02:55:50
>>354
その引数lenの型は、size_tにして、条件演算子は排除。


376:デフォルトの名無しさん
07/09/04 02:58:23
>>373
len<0が0を含むっていうのは、ちょっと馴染みがないんだが。

377:373
07/09/04 03:40:49
ごめん、寝ぼけてた。
真と偽を逆に見てた。

378:デフォルトの名無しさん
07/09/04 07:21:37
>>375
あ、確かに、size_tだな。size_tってunsignedって保証あるんだったっけ?
\0を入れられない、len==-1(len+1が0に)でNULL以外が帰ると都合が悪いので負の数を弾いてた。

379:デフォルトの名無しさん
07/09/04 07:48:25
>>369
例えばmemsetなどのmem~関数がごっちゃにしている例。

wchar_tはいいが、後付なのでここでは省きたい。

Shift_JISなどはマルチバイト文字なのだから、
char1つで表せないのは当たり前のことだ。

>>370
charが単に16ビット符号無し整数型とは別に存在するだろ。
Javaにはそんな整数型は無いが、いずれにせよcharが
整数として演算可能な型ではないことを言いたかっただけ。

>>371
D言語はUTF-32も扱える

380:デフォルトの名無しさん
07/09/04 09:19:06
>>379
「D言語は」って・・・Cだと扱えないのか?

381:デフォルトの名無しさん
07/09/04 11:33:12
>>379
そりゃmem*でも文字列は扱えるけど、普通は str* wcs* を使うだろう。
文字列にmem*使う奴が悪いと思うが。

>wchar_tはいいが、後付なのでここでは省きたい。
Cの規格自体、かなり昔から何度も改訂されてるし、
今ではwchar_tも正式な仕様なのに、後付け扱いはあんまりかと・・・。
まぁCではtypedefなんで後付け感は確かにあるけど。

> charが単に16ビット符号無し整数型とは別に存在するだろ。
> Javaにはそんな整数型は無いが、
> 整数として演算可能な型ではないことを言いたかっただけ。
javaのcharは16ビット符号無し整数で、整数として演算可能だよ。

> D言語はUTF-32も
プログラミングで言えばlinuxのgccのwchar_tも32bitだっだはず。
俺が言いたかったのはUTF-32を内部コードとして使ってるOS,ライブラリ,ソフトウェアが少ないってこと。

>>380
UTF-32用の組み込み型があるって意味だと思う、
(Dはそもそも強いtypedefがあるから、組み込みでなくても問題ないけど)
「標準」っていうことが重要になる。

標準でないと、各々作ってしまう。
typedef unsigned longならまだいいけど、
構造体やクラス化されると他ライブラリとの互換性がね・・・。

382:デフォルトの名無しさん
07/09/04 16:19:11
>>378
size_tは普通 signed な何かです。

383:デフォルトの名無しさん
07/09/04 16:37:46
いいえ、unsigned intかunsigned longであることのほうが普通です。

384:デフォルトの名無しさん
07/09/04 17:09:44
ssize_tと間違えていたよ

385:デフォルトの名無しさん
07/09/04 21:43:25
>>371
D言語はUnicodeを知っていて、UTF-8,-16,-32の変換は勝手にやってくれるらしいぜ。

import std.stdio;
void main() {
string s = "AΑあ"; // UTF-8の配列
writefln(s.length); // 当然長さは、6
foreach(i, dchar c; s) // UTF-32で取り出す
writefln(i); // 0, 1, 3 ... 自動でUnicodeスカラ値単位に区切ってくれる!
}

386:デフォルトの名無しさん
07/09/04 21:51:22
> // 当然長さは、6
当然?

素直に考えれば、長さは3だと思うけど。


387:デフォルトの名無しさん
07/09/04 21:54:37
string は const(char)[] のaliasだから、ただのUTF-8シーケンスなのです。
だから、長さは6なのです。

388:デフォルトの名無しさん
07/09/04 21:59:16
Dはちょっと見ないあいだにますます変な機能が追加されてんだな

const(char)[] って何だよw

389:デフォルトの名無しさん
07/09/06 07:48:16
D言語って、そんなに悪くないと思うよ。
同じことをC++でベタベタとコードを書いたり、
可読性の酷くわるいマクロや、テンプレートを駆使しすぎるよりは。

390:デフォルトの名無しさん
07/09/06 22:55:15
385はうそっぱちなので真に受けないでください

391:デフォルトの名無しさん
07/09/06 23:49:44
デーげんごっていつのまにかたいへんなことになってんだな

392:デフォルトの名無しさん
07/09/14 20:35:08
さすがに、みんな飽きたな。
次のネタを検討しようか。

引数を1つしか取らないようなprintfを書くな。
そういうコード例の参考書は買ってはいけない。

ってのはどうよ。

Cの標準化の人達は、なんで、print を用意しなかったのかな。
putsとカブっているとはいえ、引数1つのprintfが氾濫するよりはマシだろうに。

393:デフォルトの名無しさん
07/09/14 21:13:54
puts は最後に改行文字を出すぞ

394:デフォルトの名無しさん
07/09/14 21:18:32
文盲?

395:デフォルトの名無しさん
07/09/14 21:24:10
コンパイラが最適化するからどうでもいいんじゃないの?

396:デフォルトの名無しさん
07/09/14 21:37:40
>>393
よくあるprintfの酷い使い方。

printf("==== ほげほげ version 1.0 ======\n") ;
printf("Programed by foobar\n") ;

一行ずつ別々にprintfを呼ぶなら、putsでもいいんじゃないか。


397:デフォルトの名無しさん
07/09/14 21:39:13
>>395
そんな変な最適化をするコンパイラなんて捨ててしまえ。

そういうのに慣れていると、
printf("私のコードは100%safeです。\n") ;
なんていう恐ろしいことをやる馬鹿が出てくるんだよ。

398:デフォルトの名無しさん
07/09/14 21:42:51
puts, gets, putchar, getchar, printf, scanfまるごとなくしてしまえ。
f版でいいよ。

gets, putsとfgets, fputsは微妙に挙動が違うのが癪だが。

399:デフォルトの名無しさん
07/09/14 22:09:27
少なくともgccはフォーマット文の中身まで見て最適化するよ

400:デフォルトの名無しさん
07/09/14 22:35:27
gccが最適化するからprintfを変な使い方をしてもいい、というのは間違いだと思う。
すでに書かれてしまった膨大なコードのために、変態な最適化をしてくれるのだと思う。


401:デフォルトの名無しさん
07/09/14 22:37:51

void OutputMessage(char* s) {
printf(s) ;
}

こんな関数があったとしたら、
OutputMessage("100%safe") ;
なんて呼び出す輩が出てくる。

gccがprintfの引数を見て最適化してくれればバグが顕在化しないが、
最適化しない環境に持っていけばバグが顕在化してしまう。

402:デフォルトの名無しさん
07/09/14 22:38:28
>>397
俺的には-Wallで警告出るから問題ない


403:デフォルトの名無しさん
07/09/14 22:43:11
>>402のようなのは警告でないっしょ?

404:デフォルトの名無しさん
07/09/15 00:03:52
でるよ。

405:デフォルトの名無しさん
07/09/15 00:54:17
>>401
俺は何でもかんでもprintf使う方だけど、コレは無いなぁ・・・。

void OutputMessage(char* s) {
printf("%s",s);
}


puts、fputsなんてここ5年ぐらい使ってない。
対話なCUI作るときは(滅多に作らないけど)cursesなことが多いし、
ログ出力は定型で吐くラッパ作ることが多いし、
出力部分をgrepするのに、いちいち正規表現やなんかで色々指定するのダルい。

406:401
07/09/15 01:53:37
>>405
そのまさかをやる人間が少なくないのですよ。

printfに渡す文字列に対してサニタイジングを行うべし
なんて真顔で言う人間までいる。


407:デフォルトの名無しさん
07/09/15 02:09:08
あたしゃprintf("<>")なんてのはやるがね。

408:デフォルトの名無しさん
07/09/17 16:14:37
>>400
一般論だが、
想定外の変なデータにあわせてプログラムを書き換えるというのは
たいていあとでほころびが出たりしますよな。


409:デフォルトの名無しさん
07/09/18 00:01:27
ん? printf("\n") ;  がだめってことか?

何で悪いのか判らん・・・


410:デフォルトの名無しさん
07/09/18 00:59:50
別にいいと思うよ。

411:デフォルトの名無しさん
07/09/18 01:10:15
かつては、printfをどこかで使ってるなら出力は全部printfにしたほうが、
さらにもう一つputs関数がリンクされてしまうよりも
実行ファイルが小さくなるという効能があったのではないかと思う。


412:デフォルトの名無しさん
07/09/18 01:37:58
>>1
死ね

413:デフォルトの名無しさん
07/09/18 01:42:07
そもそもputsとfputsの挙動が違うのがな
今日の言語設計者は気持ち悪くて、そんなことできないと思う。

414:デフォルトの名無しさん
07/09/18 03:22:46
しょうがない。

もとはと言えば64KB程度のメモリで動いていたマシンのOSと、OSの上で動くプログラムを書くとき、
メモリを節約するために共通コードを関数としてライブラリ化したような代物だから。

415:デフォルトの名無しさん
07/09/29 23:17:00
ところで、sizeof(char)=sizeof(short)=sizeof(int)=2っていう設定のトンデモコンパイラがあるらしい。
一応、C言語の規格上これは間違っていない。(型のサイズは決められてないからね。)

416:デフォルトの名無しさん
07/09/29 23:39:37
kwsk

417:デフォルトの名無しさん
07/09/29 23:49:13
sizeof(char)=2は規格上まずいだろ

418:デフォルトの名無しさん
07/09/30 00:00:53
>>415
>>206

419:デフォルトの名無しさん
07/09/30 14:43:58
もちろん、Cでもsizeof(char)は1だと明確に定められてるから。よろしく。

420:デフォルトの名無しさん
07/09/30 15:02:18
>>415
「だから sizeof(char) は省略すべきではない」という主張?...でもなさそうだな。
このスレタイは「必ず1でも」って条件付きだから関係ないよね。


421:デフォルトの名無しさん
07/09/30 15:50:12
無次元の1と1バイトって同一視して話していいんだっけ。


422:デフォルトの名無しさん
07/09/30 16:21:03
数学で毎回全ての問題の全ての数字に (注意:これは10進数)
みたいな但し書きをかかれるようなものだろ。

423:デフォルトの名無しさん
07/09/30 17:20:15
415はsizeof(char)が2になるトンデモコンパイラをはやく晒してくれ

424:デフォルトの名無しさん
07/10/01 00:01:05
論理1バイトが物理2バイトだったらどうか。
自分でも書いててよくわからんが。

425:デフォルトの名無しさん
07/10/01 01:23:46
>>424
charが、1バイトが、16ビットの可能性はあるかもしれない

それでも1バイトは1バイトだ

426:デフォルトの名無しさん
07/10/01 01:47:50
>>419
それどこに書いてる?
ISOかJISの規格票のどちらかでいいから教えて

427:デフォルトの名無しさん
07/10/01 02:04:21
>>426
ISO/IEC 9899とか。
ついでにググったらすぐ出てきた


6.5.3.4 The sizeof operator の抜粋な
2. The sizeof operator yields the size (in bytes) of its operand....
3 When applied to an operand that has type char, unsigned char, or signed char,
(or a qualified version thereof) the result is 1.

428:デフォルトの名無しさん
07/10/01 02:22:05
なるほど
さんくす

429:デフォルトの名無しさん
07/10/13 20:00:42
>>415
> ところで、sizeof(char)=sizeof(short)=sizeof(int)=2っていう設定のトンデモコンパイラがあるらしい。
> 一応、C言語の規格上これは間違っていない。(型のサイズは決められてないからね。)

それどこが出してる?
製品名と会社のweb siteのどちらかでいいから教えて


430:デフォルトの名無しさん
07/10/13 21:04:48
>>429
ひょっとしたら、sizeof(char*)=sizeof(short*)=sizeof(int*)と完治害してんじゃね?


431:デフォルトの名無しさん
08/01/21 00:49:50
未だにsizeof(char)を書いてる人っているの?

432:デフォルトの名無しさん
08/01/21 01:54:36
javaのcharは2バイトって聞いたぜ。
…どうでもいいか。

433:デフォルトの名無しさん
08/01/21 19:55:24
Cプログラマの為に、ポイントをまとめたドキュメントを販売しています。
プロのプログラマでもあまりにレベルが低い人が多すぎます。
そんな人に限って、自分のレベルの低さを自覚していない、、、

本人は構わないかもしれませんが、その下についた新人プログラマは
たまったものではありません。(私が経験しました。)

今になって分かりました。
彼らもまた、理解できていなかったのです。

プログラミング言語の一番の習得の近道はきちんと理解している人にアドバイスをもらうこと。です。
(何といったって、参考にしようとする市販の本さえ、 きちんと説明してくれていないのですから、
 その証拠にC言語の学習で悩む人がどんなに多いことか)

私のC言語に取り組んだ7年間をすべてぶつけたつもりでテキストを作りました。

私の会社の後輩からは、どんなテキストよりもわかりやすかった!や、
今まで教えてくれていた先輩や、テキストたちが、ちゃんと理解できていないことがわかりました。
と、嬉しいコメントをたくさんもらいました。

そしてなにより、彼らの社内での評価がとても高いということが、私の誇りです。

宣伝と言ってしまえば、そうなってしまうかもしれませんが、ひとりでも多くのプログラマを救いたい。

プログラムの世界そのものの実力を底あげに貢献し、
無意味なバグに、残業したり、悩んだりして欲しくないのです。

興味がある方はどうか、下のサイトをみてみてください。
URLリンク(mori.eco.to)

434:デフォルトの名無しさん
08/01/21 20:09:56
>コンピュータの専門学校に入学、在学中に情報系の国家試験である、基本情報処理技術者、ソフトウエア開発を取得。
専卒かよ。

435:デフォルトの名無しさん
08/01/22 00:51:04
>>433
ブラクラ注意

436:デフォルトの名無しさん
08/01/23 02:12:26
専門学校wwwwwwwwwwwwwwwwwwwwwwwwww

437:デフォルトの名無しさん
08/02/28 13:45:03
>>431
templateで間接的になら

438:デフォルトの名無しさん
08/03/04 17:38:06
sizeof (TCHAR)で間接的になら

439:デフォルトの名無しさん
08/03/21 00:22:32
>>435
おいおい、ブラクラではなかったぞ。

>>434
学歴は関係ないと思う。

8,800円払って中身みたわけではないのだが、
大学の教授が書いているC言語入門書にも、
とんでもなく酷い本があるのだから、
もはや学歴や肩書きは関係ないと思うのよ。

BASIC時代のPRINTをそのまま引きずった、
printf("Hello, world\n");
なんてのが平然と書かれている本を見るたびに、
こんなので勉強したら無駄な時間を食うのは当然だなと思うし。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch