1read 100read
2011年11月2期プログラム18: sizeof(char)が必ず1でも、省略すべきではない (569) TOP カテ一覧 スレ一覧 2ch元 削除依頼

sizeof(char)が必ず1でも、省略すべきではない


1 :07/08/19 〜 最終レス :11/11/24
malloc(sizeof(char)*(strlen(s)+1))
ではなく
malloc(strlen(s)+1)
と書くような糞コードばかり見て育った、
悪しき慣習を引きずった人は引退すべし

2 :
>>1
YOU死んじゃいなYO

3 :
そんなに悔しかったか。

4 :
何もたてなくても・・・

5 :
sizeof(char) => sizeof(*s) じゃだめか?と俺が言った。

6 :
>>1 
こういうのが孤軍奮闘して、単に議論がダラダラと続いているだけなのに、最終的には
「宗教論争」と言い出して「どちらでもいい」ということにしてしまうんだよなぁ。
2chの片隅で、そんなことをしても、なにがどうなるってわけでもないんだけど、
弱い人は、精神防衛せずにはいられないんだろうなぁ。

7 :
>>5
それもいいかもね。
ただ、charとワイド文字の切り替えを意識してるコードだって知らない人がみたら、意図をつかみにくいかも。

8 :
>>7
切り替えがなくとも、
sの指す先の型を人間が手作業で書くのは良くないので、
ミス防止のためには、コンパイラに仕事させたほうがいいと思う。

9 :
可読性だけの問題なのかね。

10 :
複数箇所に
malloc(strlen(s)+1)
のようなコードを書くこと自体が間違い。
最低でも関数でラップすべきだし、
C++ならstd::basic_stringを使うべきだろう。

11 :
>>8
char固定なら、いらないじゃん。

12 :
>>10
ぜんぜんOK
それにラッパー書かなくても、フツーはstrdup()使う。

13 :
が臭いんです><

14 :
>>11
char固定であることを人間が保証してやるなんて馬鹿馬鹿しい。
>>12
可哀想に。恵まれない職場にいるんだね。

15 :
sizeof(char)は必ず1である事が定義されてるんだから
別にいいじゃんねぇ

16 :
そもそも strlen はcharの文字列の長さを求める関数であって
多バイト文字の文字数を求めるなら strlen を使っちゃダメだろ。

17 :
#define sizeofchar 1

18 :
>>14
ええ? malloc()のラッパーって話じゃなくて、malloc(strlen(s)+1)のラッパーってことだよね?
職場のヘンなコードばっかり見てないで、いろいろコードを見たほうがいいと思われ。

19 :
>>14
strlen()使うんだから、char以外は使えないじゃん。

20 :
>>16
文字列複製用のメモリ確保だと思われるから、長さはバイト数でいいんじゃね?

21 :
意味の問題。
mallocの引数は「バイト数」
strlenの返り値は「文字数」

22 :
sizeof(char) == 1バイト

23 :
>>22
保証は無い。(まだそんなマシン動いてるかどうかはともかく)

24 :
>>23
100%保障。
sizeof(char)が1でないコンパイラがあったら捨てたほうがいい。

25 :
一応ANSIならとかつけたほうがいいんでねぇの?
sizeof( char ) != 1の環境は見たこと無いけど・・・

26 :
問題なのはバイトの方!

27 :
>>26
だからcharは1バイトだって。

28 :
>>25
何も書いてない時の ANSI 縛りは、暗黙の了解事項だろ。
そうでないとなんでもありありになっちゃうし。

29 :
まえスレの人は、charが1バイトってくらいは分かったうえで、いろいろ言ってる様な印象だったけど、
ちがう人と交代したのかな?

30 :
牛タンクの容量を割り当てる関数があるとしよう。引数はリットル型だが、実はintのtypedefだ。
箱の中に複数本の牛パックが入っている。
本数を問い合わせる関数があるとしよう。返り値は本数型だが、実はintのtypedefだ。
箱の中の牛パックを開けてタンクに入れようとする。
同じintのtypedefだからといって、
リットル型の引数に、本数型を渡していいものだろうか。
俺はダメだと思うね。
たとえ1本1Lと決まっていても、本数型からリットル型に変換する段は踏むべきだ。

31 :
いちいち
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 :
>>30
strlen()のリターン値は文字数==バイト数で、malloc()引数もバイト数じゃん。

33 :
>>30
強いtypedefのあるD言語をお使いください。

34 :
>>31
> 初心者だって、 ・・・って書くだろ? 
それ、たとえば誰が書いてるの?
職場の先輩とか?

35 :
malloc()の戻り値をcastするやつはバカ

36 :
俺は*sizeof(char)は付けない派だが。(付いてても気になら無いけど)
>>31
これはちょっと全体的に反対。
>#define MALLOC(type, size) ((type)*)malloc(sizeof(type)*(size))
そんな訳の分からないマクロ作るぐらいなら、素直にcalloc使うよ。
>普通はC++だから、文字列クラスを使うだろう。
そんな普通は無いだろ。

37 :
>>36
名前欄消し忘れた・・・。
是非スルー頼む。orz

38 :
>>36
全体的に賛成だがcallocになるのか?ラッパー関数とかじゃなくて?

39 :
> 普通はC++だから
www

40 :
>>32
たまたま 文字数==バイト数 なだけじゃん。

41 :
>>40
「規格上」文字数==バイト数。
たまたまじゃない。

42 :
>>35
Cではキャストは不要だがC++では必要。
まぁ、C++でmallocを使うこと自体がおかしいが。

43 :
>>41
たまたま「規格上」一致する組み合わせ

44 :
>>38
>>31のマクロだと「型と要素数を指定してメモリを獲得する」機能が欲しそうだったんで、
指定の仕方が近いcallocを持ってきただけだよ。
>>1やらの話なら、文字列長渡してメモリのアドレス返すラッパならアリじゃないかなぁ。
個人的には面倒だからやらないけども。

45 :
>>40
たまたまじゃないよ。
あつかってる文字セットが収まる範囲を1バイトにしてるんじゃん。

46 :
ここで文脈を読まずに文字数==バイト数なのはASCIIコードだけだとかいってみる

47 :
>>44
すでに_strdupがあるもんな。
「文字列の尻には\0があるから、+1文字分の領域が必要」
ということに対処するコードは一ヶ所だけにまとめておくべきで、
プログラム全体に散在させるべきではないよね。
それが後で変るかどうかは関係ない。
あちこちにmalloc(strlen(s)+1)と書けばいいと言う人間は、
構造化プログラミングを否定していると思う。

48 :
>>45
牛パック1本が1リットルと決まっているからといって、
リットル数を与えるべきところに本数を与えていいと思うか?

49 :
>>47
malloc(strlen(s) + sizeof(char)) って書くってこと?

50 :
恒久的に一本一リットルなら何の問題もないだろ。

51 :
>>50
恒久的にってのもだけど、論理的にも一文字1バイトだし。

52 :
俺も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 :
>>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 :
論点は、 (1)charのサイズの問題 (2)sizeof(char)を書くか なのかな。
(1)はラッパを書く、(2)は書いたら弊害があるのか? でダメ?

55 :
>>53
strlen()+1だけの関数とか、そんなのつかってるのオタクの職場くらいですよ。

56 :
>>53
壮大な釣り?
>size_t ScanAscizStringLength(const char* s) {
string lengthはどう考えてもstrlen()の戻り値そのままだろ。
stringに形容詞がつくだけで長さが変わるなんて気色悪い。
getStringSize()って名前なら判らんでもないが。
で、malloc(sizeof(char) * stringSize)なら「あ〜あ、一一書いているよ」で済むが、
malloc(CalcRequiredMemoryForString(string))なんて書いていたら「戯け」の一喝だな。
# CalcRequiredMemoryForDoublePrecReal()なんてのも作るのか?

57 :
>>55
ふつう文字列クラス使うよな。
strlenとかstrcatとかstrcpyなんて直接使わないもの。

58 :
>>56
ふつうC++なので、やるとしてもテンプレート関数だな。

59 :
>>57
mallocとか使ってることから、ここはC限定ではないのかな?
>>53
そこまで書くんだったら >>49 程度で済ました方が良いと思う。それと、その関数名だと長すぎて使いたくない。

60 :
>>54の(2)sizeof(char)を書くか
http://www.kouno.jp/home/c_faq/c7.html#8
一般的には、どっちでも良いってよ。

61 :
ポイントとしては、
無知やうっかりミスによってバグを生じさせない
ということ。
+1が必要なことを知らない人もいるし、
+1を書き忘れることもあるし、
sizeとlengthを書き間違えることもある。
じゃぁどうすればいいか。
Cを捨ててC++で文字列クラスを使うべき。

62 :
>>59
C++でもmalloc使う人いるんだよねぇ。
> >>49 程度で済ました方が良いと思う。
strlen(s) + sizeof(char)
これこそ意味不明だねぇ。
1文字分ってことなら、
sizeof(char)
ではなく
sizeof(char)*1
としないとねぇ。
そうするなら
sizeof(char)*(strlen(s)+1)
になるわなぁ。
> その関数名だと長すぎて使いたくない。
いちいち手でタイプする人いるんだよねぇ。
ミスタイプしたりするからコピペが基本よ。

63 :
>>62
長い数式を書かない人なんだね・・・

64 :
>>53
まあ、常識的に考えてこんな関数つかわねーよな。

65 :
>>53とか>>55>>56とか
void *getBufByLen(int length)
{
 return malloc(length + 1);
}
まぁこのぐらいのラッパなら良いんじゃないの?
strlen(str)+1がどのぐらい出てくるかにもよるんだろうけどさ。
どうしても「+1」をソースコードから出来るだけ消したいなら、俺なら
#define LEN2SIZE(x) ((x)+1)
でも作って、LEN2SIZE(strlen(str))で書くか。
したら、今度は副作用がどうとか言われんのかねぇ。

66 :
>>65
そこまでして+1を消すと、かえって読みにくくなるよ。
strlen(s) + 1 と直に書くのがいちばん素直なCのコード。
技巧に走りすぎてもよくない。

67 :
>>66
そうは思うけどさ。
たまに上司の好みで結構色々言われんのよ。
(俺も多分好みで妙なコード書いてるとは思うけど)
んで、そこで激論しても時間無駄だから、
まぁ良いかと思えることは従うことにしてる。
今のところ「+1消せ」は言われたことないけど、
そういう指示が出たらこうするかな、ってぐらいのモン。

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

69 :
>>65
getBufByLenではなくallocBufByLenにしたほうがいいと思う。

70 :
>>62
>C++でもmalloc使う人いるんだよねぇ。
それは酷い。

71 :
ひょっとしてJavaに移植するときとか、そこまで考えてるのか?
Cだけなら sizeof(char)==1 が仕様で定義されてるけど

72 :
乱れる倫理。10歳以下のセミヌード!
http://www11.big.or.jp/~magmell/science/watchfiles/semi01.jpg

73 :
うわ・・本当に脱いでる・・・

74 :
蝉の脱皮だろ
この板では空気を読む必要は無い。

75 :
>>71
#include <stdio.h>
int main()
{
printf("%d\n",sizeof(char));
return 0;
}
をCでコンパイルしてみたか?
C++でもコンパイルしてみたか?

76 :
>>72
これはアブラゼミだね

77 :
>>75
CとC++でsizeof(char)は絶対1なのは仕様で保証してるんだけど・・・

78 :
1バイトは8ビットとは限らないが、charは1バイトと規格で決まっている。
ってことでしょ?

79 :
>>75
もう帰れ無能。

80 :
>>43
Cの規格での「文字」の定義は「1バイトに納まるビット表現」。
規格書ちゃんと嫁。

81 :
>>80
文字っつーかcharな。単に文字とか言うとまた噛み付いてくるで。

82 :
>>81
>単に文字とか言うと
規格に於ける定義の話をしてるんだが。

83 :
>>82
それならきっちり「文字型」といった方が誤解ないよねとか
文字とだけ言うとシングルバイト文字とマルチバイト文字を
ごっちゃにするやつが出てくるから 規格話するなら正確に
みたいあn

84 :
>>75
関係ない話なんだが、
sizeof演算子の結果の型はsize_tだけど、こういう場合はintにキャストしなくていいの?

85 :
>>70
C++だろうとmallocは使えるでしょう?
mallocしたものをdeleteしたりしなければ。

86 :
>>80
charが1バイトなのは当然として、
1を掛けるのを省略して書いて良いのかどうか
という問題だろう。

87 :
>>85
使えるけど、new があるのに
>mallocしたものをdelete
する危険を冒してまで態々使う意味が判らない。
>>86
「省略しちゃいけない」とする理由が
「文字数とバイト数は意味が違うから」であれば、
規格上は「文字」=「1バイト文字」であり
「文字数=バイト数」であるから
「省略しても問題ない」よね?という確認。

88 :
問題は無いね
どうすべきかとなると宗教論争になりそうだ

89 :
>>86
C FAQにあるよ

90 :
つきつめるとCHAR_BITすら意味をなさないからあまり気にするものでもないと思うが

91 :
>>87
> 「文字数=バイト数」であるから
それは数値の一致であって、意味の一致ではない。
あくまでも「1バイト文字」の「文字数」なのだから。
省略してもプログラムは意図した通りに動くが、
プログラムが動けば何だっていいというのは間違い。

92 :
>>91
はあ…
>それは数値の一致であって、意味の一致ではない。
意味の一致だってばさ。頭悪いなあ。
「規格では、strlen() はバイト数を戻す」
これで納得した?

93 :
charやstrlenをハードコーディングしちゃうなら*sizeof(char)を書く意味はほとんど無いと思うなぁ。
>>87
new使ったってその危険はdeleteとdelete[]を間違える危険にかわるだけじゃね?

94 :
なんつーか
みんな暇なの?

95 :
規格では、strlen() はバイト数と等しい値を返す
だろ?

96 :
strlenの返す値の意味がバイト数ではなく文字数だと言いたいんですかね。

97 :
そんなに不安ならコメント書いとこうぜ

98 :
>>96
格納するのに必要なバイト数
ではないのは確かだな。

99 :
>>1
アルファベット=レターと非アルファベット記号=キャラクターとストリングの意味からして、strlenが間違い。

100read 1read
1read 100read
TOP カテ一覧 スレ一覧 2ch元 削除依頼