X



sizeof(char)が必ず1でも、省略すべきではない
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
垢版 |
2007/08/19(日) 20:06:26
malloc(sizeof(char)*(strlen(s)+1))
ではなく
malloc(strlen(s)+1)
と書くような糞コードばかり見て育った、
悪しき慣習を引きずった人は引退すべし
0006デフォルトの名無しさん
垢版 |
2007/08/19(日) 20:15:45
>>1 
こういうのが孤軍奮闘して、単に議論がダラダラと続いているだけなのに、最終的には
「宗教論争」と言い出して「どちらでもいい」ということにしてしまうんだよなぁ。

2chの片隅で、そんなことをしても、なにがどうなるってわけでもないんだけど、
弱い人は、精神防衛せずにはいられないんだろうなぁ。
0007デフォルトの名無しさん
垢版 |
2007/08/19(日) 20:17:16
>>5
それもいいかもね。
ただ、charとワイド文字の切り替えを意識してるコードだって知らない人がみたら、意図をつかみにくいかも。
0008デフォルトの名無しさん
垢版 |
2007/08/19(日) 20:25:17
>>7
切り替えがなくとも、
sの指す先の型を人間が手作業で書くのは良くないので、
ミス防止のためには、コンパイラに仕事させたほうがいいと思う。
0010デフォルトの名無しさん
垢版 |
2007/08/19(日) 20:28:27
複数箇所に
malloc(strlen(s)+1)
のようなコードを書くこと自体が間違い。

最低でも関数でラップすべきだし、
C++ならstd::basic_stringを使うべきだろう。
0013デフォルトの名無しさん
垢版 |
2007/08/19(日) 20:51:41
ちんちんが臭いんです><
0016デフォルトの名無しさん
垢版 |
2007/08/19(日) 21:35:30
そもそも strlen はcharの文字列の長さを求める関数であって
多バイト文字の文字数を求めるなら strlen を使っちゃダメだろ。
0018デフォルトの名無しさん
垢版 |
2007/08/19(日) 22:04:24
>>14
ええ? malloc()のラッパーって話じゃなくて、malloc(strlen(s)+1)のラッパーってことだよね?
職場のヘンなコードばっかり見てないで、いろいろコードを見たほうがいいと思われ。

0025デフォルトの名無しさん
垢版 |
2007/08/19(日) 23:01:36
一応ANSIならとかつけたほうがいいんでねぇの?
sizeof( char ) != 1の環境は見たこと無いけど・・・
0028デフォルトの名無しさん
垢版 |
2007/08/19(日) 23:10:32
>>25
何も書いてない時の ANSI 縛りは、暗黙の了解事項だろ。

そうでないとなんでもありありになっちゃうし。
0029デフォルトの名無しさん
垢版 |
2007/08/19(日) 23:13:32
まえスレの人は、charが1バイトってくらいは分かったうえで、いろいろ言ってる様な印象だったけど、
ちがう人と交代したのかな?
0030デフォルトの名無しさん
垢版 |
2007/08/19(日) 23:13:51
牛乳タンクの容量を割り当てる関数があるとしよう。引数はリットル型だが、実はintのtypedefだ。

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

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

俺はダメだと思うね。
たとえ1本1Lと決まっていても、本数型からリットル型に変換する段は踏むべきだ。
0031デフォルトの名無しさん
垢版 |
2007/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とかやってるから、
つまらないバグやセキュリティホールを作り込んでしまうんだよ。
0036前スレ980
垢版 |
2007/08/19(日) 23:33:02
俺は*sizeof(char)は付けない派だが。(付いてても気になら無いけど)

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

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

>普通はC++だから、文字列クラスを使うだろう。
そんな普通は無いだろ。
0044デフォルトの名無しさん
垢版 |
2007/08/20(月) 00:16:28
>>38
>>31のマクロだと「型と要素数を指定してメモリを獲得する」機能が欲しそうだったんで、
指定の仕方が近いcallocを持ってきただけだよ。

>>1やらの話なら、文字列長渡してメモリのアドレス返すラッパならアリじゃないかなぁ。
個人的には面倒だからやらないけども。
0047デフォルトの名無しさん
垢版 |
2007/08/20(月) 00:23:18
>>44
すでに_strdupがあるもんな。

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

あちこちにmalloc(strlen(s)+1)と書けばいいと言う人間は、
構造化プログラミングを否定していると思う。
0048デフォルトの名無しさん
垢版 |
2007/08/20(月) 00:24:19
>>45
牛乳パック1本が1リットルと決まっているからといって、
リットル数を与えるべきところに本数を与えていいと思うか?
00525
垢版 |
2007/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のサイズを掛けている-部分だと思うよ。
0053デフォルトの名無しさん
垢版 |
2007/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)) ;
と書けるようになるっしょ。
0054デフォルトの名無しさん
垢版 |
2007/08/20(月) 00:47:20
論点は、 (1)charのサイズの問題 (2)sizeof(char)を書くか なのかな。

(1)はラッパを書く、(2)は書いたら弊害があるのか? でダメ?
0056デフォルトの名無しさん
垢版 |
2007/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()なんてのも作るのか?
0059デフォルトの名無しさん
垢版 |
2007/08/20(月) 01:06:54
>>57
mallocとか使ってることから、ここはC限定ではないのかな?

>>53
そこまで書くんだったら >>49 程度で済ました方が良いと思う。それと、その関数名だと長すぎて使いたくない。
0061デフォルトの名無しさん
垢版 |
2007/08/20(月) 01:09:02
ポイントとしては、
無知やうっかりミスによってバグを生じさせない
ということ。

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

じゃぁどうすればいいか。
Cを捨ててC++で文字列クラスを使うべき。
0062デフォルトの名無しさん
垢版 |
2007/08/20(月) 01:13:01
>>59
C++でもmalloc使う人いるんだよねぇ。

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

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

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

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

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

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

0065デフォルトの名無しさん
垢版 |
2007/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))で書くか。
したら、今度は副作用がどうとか言われんのかねぇ。
0066デフォルトの名無しさん
垢版 |
2007/08/20(月) 01:29:49
>>65
そこまでして+1を消すと、かえって読みにくくなるよ。
strlen(s) + 1 と直に書くのがいちばん素直なCのコード。
技巧に走りすぎてもよくない。
0067デフォルトの名無しさん
垢版 |
2007/08/20(月) 01:38:58
>>66
そうは思うけどさ。
たまに上司の好みで結構色々言われんのよ。
(俺も多分好みで妙なコード書いてるとは思うけど)

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

今のところ「+1消せ」は言われたことないけど、
そういう指示が出たらこうするかな、ってぐらいのモン。
006859
垢版 |
2007/08/20(月) 01:42:50
>>62
ごもっともです。

ところで、もともとの質問主の環境は VC++6.0 みたいですね。
素直にC++の文字列クラスを使うのがいいのかな...
0071デフォルトの名無しさん
垢版 |
2007/08/20(月) 11:39:01
ひょっとしてJavaに移植するときとか、そこまで考えてるのか?
Cだけなら sizeof(char)==1 が仕様で定義されてるけど
0072デフォルトの名無しさん
垢版 |
2007/08/20(月) 11:47:13
乱れる倫理。10歳以下のセミヌード!
http://www11.big.or.jp/~magmell/science/watchfiles/semi01.jpg
0075デフォルトの名無しさん
垢版 |
2007/08/20(月) 11:52:25
>>71

#include <stdio.h>

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

}

をCでコンパイルしてみたか?
C++でもコンパイルしてみたか?
0078デフォルトの名無しさん
垢版 |
2007/08/20(月) 13:19:39
1バイトは8ビットとは限らないが、charは1バイトと規格で決まっている。
ってことでしょ?
0083デフォルトの名無しさん
垢版 |
2007/08/20(月) 14:25:58
>>82
それならきっちり「文字型」といった方が誤解ないよねとか
文字とだけ言うとシングルバイト文字とマルチバイト文字を
ごっちゃにするやつが出てくるから 規格話するなら正確に
みたいあn
0084デフォルトの名無しさん
垢版 |
2007/08/20(月) 14:40:08
>>75
関係ない話なんだが、
sizeof演算子の結果の型はsize_tだけど、こういう場合はintにキャストしなくていいの?
0086デフォルトの名無しさん
垢版 |
2007/08/20(月) 15:12:41
>>80
charが1バイトなのは当然として、
1を掛けるのを省略して書いて良いのかどうか
という問題だろう。

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

>>86
「省略しちゃいけない」とする理由が
「文字数とバイト数は意味が違うから」であれば、
規格上は「文字」=「1バイト文字」であり
「文字数=バイト数」であるから
「省略しても問題ない」よね?という確認。
0091デフォルトの名無しさん
垢版 |
2007/08/20(月) 15:45:13
>>87
> 「文字数=バイト数」であるから

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

省略してもプログラムは意図した通りに動くが、
プログラムが動けば何だっていいというのは間違い。
0092デフォルトの名無しさん
垢版 |
2007/08/20(月) 15:54:11
>>91
はあ…
>それは数値の一致であって、意味の一致ではない。
意味の一致だってばさ。頭悪いなあ。
「規格では、strlen() はバイト数を戻す」
これで納得した?
0093デフォルトの名無しさん
垢版 |
2007/08/20(月) 16:06:54
charやstrlenをハードコーディングしちゃうなら*sizeof(char)を書く意味はほとんど無いと思うなぁ。

>>87
new使ったってその危険はdeleteとdelete[]を間違える危険にかわるだけじゃね?
0099デフォルトの名無しさん
垢版 |
2007/08/20(月) 17:09:30
>>1
アルファベット=レターと非アルファベット記号=キャラクターとストリングの意味からして、strlenが間違い。
0100デフォルトの名無しさん
垢版 |
2007/08/20(月) 17:39:16
外人は文字が2バイトかもしれないなんて考えてないから、
strlenという関数名なんだろ。
0103デフォルトの名無しさん
垢版 |
2007/08/20(月) 18:01:54
>>84
整数型の暗黙の変換ルールがあるから問題ない。
ただ、size_tは符号無しだから、
intに変換されることで情報が失われるかも分からんね。
0107デフォルトの名無しさん
垢版 |
2007/08/20(月) 18:23:09
>>100
記号一つに2バイトなんて無意味だし不可能。
strlenが誕生した時代は数バイトのメモリが数万円。
0112デフォルトの名無しさん
垢版 |
2007/08/20(月) 18:44:08
>>108
PDP-11は、メモリ64KB程度搭載で、1万ドルくらいだったそうだな。
当時の為替レートからすると、360万円か。

数バイト数万円は違うが、数Kバイト数万円くらいだな。
0115デフォルトの名無しさん
垢版 |
2007/08/20(月) 18:53:46
>>1
#defineで定義しておけ。
0119デフォルトの名無しさん
垢版 |
2007/08/20(月) 19:03:27
>>84
キャストするべき。
size_tがintと同じサイズである保証は全くない。
sizeof(int) == sizeof(long)の環境に限定するなら、省略するのもありかも試練が。
0130デフォルトの名無しさん
垢版 |
2007/08/20(月) 23:37:29
>>129
Cにおいてsizeof(char)=1は仕様だが、
1バイトが8ビットなのは仕様ではない。
0132デフォルトの名無しさん
垢版 |
2007/08/21(火) 00:19:55
ここの人達が、同じプロジェクトに放り込まれたら、
どうなるんだろう...
C FAQ は理解しやすくなる「かも」とかいてあるけど、
逆に意図が分からなくて困惑する人もいるかも。
0133デフォルトの名無しさん
垢版 |
2007/08/21(火) 00:22:53
同じプロジェクトに入ったら個人レベルでソースファイルを分割し
他人が担当しているソースファイルは一切見ないようにすればOK。
レビューとかあれば、同じ信念をもち曲げないメンバーでする。

そんなプロジェクトやだなぁw
0134デフォルトの名無しさん
垢版 |
2007/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ビットの環境て使うべきでない、
とかそういう意見をお持ちの方?
0136デフォルトの名無しさん
垢版 |
2007/08/21(火) 07:54:41
マロック・ストラレン
0138デフォルトの名無しさん
垢版 |
2007/08/21(火) 10:44:54
>>137
C++ のクラスをWin32とWinCEで使いまわす俺には必須だぜ!

ところで、>>129 がどこに突っ込んでるのかが知りたい。
UTF-16の1文字は2バイトとは限らないし
2オクテットとも限らないわけだが。
0151デフォルトの名無しさん
垢版 |
2007/08/21(火) 22:00:31
コンパイラは省略しません。そういう意味では無駄にコストが発生します。
# 勿論、コンパイルのね。
0155デフォルトの名無しさん
垢版 |
2007/08/21(火) 23:24:28
意味はあっても価値はない。ってところかしら?
価値が無いからと言って、消して良いのか?
でも最適化でけされるよ。
消されなかったら実行時のコストだな。
じゃあ、今、消しておこう。
0156デフォルトの名無しさん
垢版 |
2007/08/22(水) 02:04:18
消してしまったsizeof(char)を復元する必要が出てきたときに
莫大なエネルギーが消費されるからそのままにしておいたほうがいいお。

仕事でスパゲッティコードをリファクタリングしたときに、
元のコードをコメントで残しとけとか言われて非常に苦労した覚えがあるお。
0158デフォルトの名無しさん
垢版 |
2007/08/22(水) 02:23:23
>>156
>復元する必要が出て来たとき。
上の方で誰か書いてたけど、ラッパー関数にするか、マクロにするかして、
一度に変えられる様にしておけば良い。
復元してもどうせ1だからそのまま使う訳じゃないだろう。
0167デフォルトの名無しさん
垢版 |
2007/08/23(木) 20:54:00
もうねmallocなんてあちこちで書いてちゃだめなんだよ。
ラッパーとか言うのも違うな。
構造化だよ。オブジェクトを作る段でだけ利用するんだ。
そもそもC++の偉い人がnewなんてすばらしい関数を
用意してくれているんだから、new使えよ。
0168デフォルトの名無しさん
垢版 |
2007/08/23(木) 21:34:07
Dの偉い人が動的配列なんてすばらしい機能を
用意してくれているんだから、動的配列使えよ。
0172デフォルトの名無しさん
垢版 |
2007/08/24(金) 00:32:18
newだって寿命管理はプログラマがやらなきゃいけないわけで、
mallocと同じように、
考えて使うところを狭めないと、
収拾が付かなくなる。
0180デフォルトの名無しさん
垢版 |
2007/08/24(金) 20:52:42
文法的にも、プログラム的にも、省略するのは間違いではない。
だが、
プログラムを人間が読んで理解する上では、省略しないほうがよい。
0181デフォルトの名無しさん
垢版 |
2007/08/24(金) 22:22:15
>180みたいな人間に合わせるために、省略しない方がいい。
>180みたいな人間が見ることがないコードなら、遠慮することなく省略していい。
0182デフォルトの名無しさん
垢版 |
2007/08/25(土) 00:29:12
>>180
そもそも理解の妨げにならない、という話をしてるんじゃないのか。
0185デフォルトの名無しさん
垢版 |
2007/08/25(土) 11:05:48
書く目的が、、、
(1).人間が理解しやすい、と言うなら、
「無くても理解できる。」、「無駄なコードに見える」
(2).char -> wchar_t や処理系固有の文字型に変更する可能性のためなら、
strlen はchar専用、またsizeof(char)と直接書くのも適切ではない。より汎用的に書くべき。
また#if などで、文全体を置き換えるとすれば、(1).より、無くても良い。
必要な型の場合のみ書く。
(3).その処理系はsizeof(char)自体が、1ではない。
このスレの前提「必ず1でも」に一致しないので、除外する。
0191デフォルトの名無しさん
垢版 |
2007/08/25(土) 15:29:12
>>185
汎用的に書くからには、それで正しく動作するように書き、テストもすべきだ。
見かけ倒しで実際にはダメなんてのは迷惑。
だから、charでしか正しく動作しないのであれば、charで書いておくべきだ。
0196デフォルトの名無しさん
垢版 |
2007/08/26(日) 14:29:20
なんかchar型のサイズが1バイトって前提の話になってるけど
C++だとcharのサイズって1(単位なし)だよな。
で、各型のサイズはcharのサイズの整数倍であることが保証されている。

でも1=1バイトかどうかは環境依存だよな?
#あくまで企画上の話なので実際にcharのサイズが1バイトじゃない環境出せとかいうのはなしね。
0197デフォルトの名無しさん
垢版 |
2007/08/26(日) 14:37:23
>>196
1バイトが8ビットであることも決まっていない。
CHAR_BITは8以上となっているから、1バイト=7ビットでは規格合致できないけど。
0198デフォルトの名無しさん
垢版 |
2007/08/26(日) 14:58:19
>>196
C、C++は 絶対何があってもsizeof(char)は1バイト
と規格で定めてる。
それ以外の環境はありえないし存在しない。

1バイトが8ビットかどうかはこのスレでは論じていない。
0199デフォルトの名無しさん
垢版 |
2007/08/26(日) 15:02:07
>>197
とりあえず、規格上のサイズ指定に使われている単位と
環境上で実際にサイズ指定に使われている単位って違うよなってことを
指摘したかっただけなんだ。

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

あと、バイトの出自ってIBMの内部呼称でbit octetからきてると思ったんだが
今はなんかビット数に関して不問にするみたいなのってあるのかな?
0200デフォルトの名無しさん
垢版 |
2007/08/26(日) 15:12:09
>>199
そういうこと。外から見てcharが2オクテットだったとしても、
CHAR_BIT == 16にして、sizeof (char) == 1にすれば規格合致できる。

いずれにせよ、198の言うとおりこのスレで話すようなことではないけどな。
0201デフォルトの名無しさん
垢版 |
2007/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に渡すときはそれを
使ってバイトサイズに変換しろっていうまとめをするとすれ違いにならないかな?
0202デフォルトの名無しさん
垢版 |
2007/08/26(日) 15:48:12
マルチバイトを扱うなら文字列関係は普通ライブラリ化する
不都合が発生してもそこだけ修正するので1の件は重要じゃない
反対にmalloc散らばりまくりの汚い実装なら
17文字余計にタイプすると人件費にして2円位になるから
わざわざ強要してもとコストがかさむだけでメリットがない
0206デフォルトの名無しさん
垢版 |
2007/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;
0210デフォルトの名無しさん
垢版 |
2007/08/26(日) 16:25:29
>>201後半
それはない。
そうだとすると、malloc(2)の返すポインタが
要素数2つのchar配列として使えないという意味になるではないか。

mallocが使う単位もまた、sizeofと同じ。
0212201
垢版 |
2007/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とした環境依存。
実用上同じでないと使い勝手が悪いというのならそれには同意。
0213デフォルトの名無しさん
垢版 |
2007/08/26(日) 16:43:08
C99ではsizeofの結果はバイト数ってことになってるな。

> sizeof 演算子の結果は、そのオペランドの大きさ(バイト数)とする。
0214デフォルトの名無しさん
垢版 |
2007/08/26(日) 16:44:00
>>212
The sizeof operator yields the number of bytes in the object representation of its operand.

ってわけえ、sizeofはバイト数を返します
0216デフォルトの名無しさん
垢版 |
2007/08/26(日) 16:51:06
sizeof()の返り値はバイト数
malloc()の引数はバイト数

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

バイト数なら、そのまま+1してmallocの引数に渡すのはOKだが、
文字数なら、sizeof(char)を掛けないと、バイト数にはならないよね。
0219デフォルトの名無しさん
垢版 |
2007/08/26(日) 17:03:15
strlenの引数は char* だから文字数=バイト数と考えてよいのでは?
それとも漢字が混じるとそれも1文字として扱われるだろうか?
だとしたら、sizeof(char)掛けてもバイト数にはならないよね。
0221デフォルトの名無しさん
垢版 |
2007/08/26(日) 17:05:29
それは数値の一致であって、意味の一致ではない。
あくまでも「1バイト文字」の「文字数」なのだから。

省略してもプログラムは意図した通りに動くが、
プログラムが動けば何だっていいというのは間違い。
0222デフォルトの名無しさん
垢版 |
2007/08/26(日) 17:15:13
仕様上キャラクタ=バイトです。
たまたま文字を意味するときだけ
わかりやすくキャラクタと表記します。
そのため、byte という型はありません。

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

>>215
ごめん。
俺の疑問は俺の誤解だったということで解決したから、次のネタはないの。。。
単発と言うことで許して。
0231デフォルトの名無しさん
垢版 |
2007/08/27(月) 01:09:02
お前ら、こんな下らない話で、よくここまでスレを伸ばしたなぁ。

いまどきmallocとstrlenを散在させるようなコードを書くほうがオカシイ。
strlenなんて使うか? ふつー。
0233デフォルトの名無しさん
垢版 |
2007/08/27(月) 01:23:27
>>231
話がループしてるからいくらでも伸びる気がする。
ところで、
「散在させる」ってのはどこから出てきた?
strlenを使わないなら何を使う?(あくまでCだとして)
sizeof(char)を省略すべきでない?
0234!= 231
垢版 |
2007/08/27(月) 01:25:34
ここでstrlen_sだなんて言ってみるテスト
0235デフォルトの名無しさん
垢版 |
2007/08/27(月) 01:28:31
>>231
くだらないからこそだろう

まさにこれこそが 「自転車置場の議論」 ってやつだな
0236デフォルトの名無しさん
垢版 |
2007/08/27(月) 01:35:19
>>233
マクロ、ライブラリ、クラスの中で使うのではなく、
ベタベタと書くコードの中で使う = 散在させる

ぶっちゃけ、適切に局在化されていれば、
多少マズいコードだろうと直せるので、
このスレで話しているようなことは、
どーでもよくなるんですよ。
0237デフォルトの名無しさん
垢版 |
2007/08/27(月) 01:39:54
そうだ、マルチバイト文字が存在するからいけないんだ!
今日から、みんな、英語で生活!
それで全員ハッピーだ!
0239233
垢版 |
2007/08/27(月) 02:01:15
>>236
「散在させる」はスレの流れから読み取ったわけじゃないのね。

俺も同じ考えだけど、ちょっと論点がずれてる気がする。
「局在化」とか、「直せる」とかはこのスレには関係ないな。
局在化したその場所で「省略するかしないか」ってことが問われてる。
まあ、そこで、「どーでもよい」ってのが答えなんだろうけど。
0240デフォルトの名無しさん
垢版 |
2007/08/27(月) 04:21:09
ここで新たな判断基準を持ち込んでみる。

どちらが適切だと思うか主張する場合に、年収も書くこと。
年収の多い人のやり方が、すなわち、より成功に近い。
0243デフォルトの名無しさん
垢版 |
2007/08/27(月) 09:28:33
>>231
C言語なら「普通」strlenを使うと思う。

NULL終端までのバイト数を取得する関数なんて作るのは、
まぁライブラリの標準関数が使えないプロジェクトぐらいじゃないの?
0249デフォルトの名無しさん
垢版 |
2007/08/27(月) 17:23:02
struct {
size_t bufferLen ;
size_t validLen ;
char szBuffer[1] ;
} ;
とかの構造体を使って、バッファの長さや有効長を管理したらいいじゃないか。
szBuffer[1]と言いながら、実際にはヒープから長い領域を貰うのは気持ちわるいかもしれないが。
0253デフォルトの名無しさん
垢版 |
2007/08/27(月) 20:09:30
>>245
fgetsで文字列を読み込んだり、コマンドライン引数を受け取ったりした際に
得られた文字列長を調べるための、strlenより高速で信頼性のある方法を教えてくれまいか?
0256デフォルトの名無しさん
垢版 |
2007/08/27(月) 21:29:46
>>253
まず、得られた文字列の長さを調べる必要が、本当にあるのかな。
次に、何かにつけてfgetsするのかな。
0264デフォルトの名無しさん
垢版 |
2007/08/27(月) 21:55:18
基本的に、
気やすくstrlenやstrcpyを使わない
ってだけで、かなり速くなるし、安全性も高まる。
0265デフォルトの名無しさん
垢版 |
2007/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') { なんたら }
}
0267デフォルトの名無しさん
垢版 |
2007/08/27(月) 22:07:14
>>264
strlen,strcpyの安全性が低く感じるのは、呼び出し元の安全性が低いから。
速くなるってのは、一度取った長さを変数に入れておくとかってレベルの話かな?
いずれにしろ、これらに限らず「安易に使わない」って意味では同意できる。
0268デフォルトの名無しさん
垢版 |
2007/08/27(月) 22:25:48
>>267
> strlen,strcpyの安全性が低く感じるのは、呼び出し元の安全性が低いから。

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

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

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

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

0269デフォルトの名無しさん
垢版 |
2007/08/27(月) 22:28:11
安易に使わないってどゆこと?

必要だから使うんじゃないか。代替手段があるというのか?
0271デフォルトの名無しさん
垢版 |
2007/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ぐらい普通に使うと思うんだけどねぇ。
0272デフォルトの名無しさん
垢版 |
2007/08/27(月) 22:32:33
なんかボーっとしてる間に、えらいスレ進んでてびっくりだ。
253と271とコレ以外は俺じゃないんで一応。
0277デフォルトの名無しさん
垢版 |
2007/08/27(月) 22:55:12
>>273
>>243に対して>>245だったから、strlenを全否定してるように見えたんで、
「まぁ使うんじゃないの?」ぐらいの感じで書いただけだよ。

ループ内とかで同じ文字列に対して何度もstrlen呼んだりとか
そういうのは無駄だと思うよ。
0278デフォルトの名無しさん
垢版 |
2007/08/28(火) 22:18:22
結論は出ましたか。
0281デフォルトの名無しさん
垢版 |
2007/08/28(火) 23:30:57
adobePの新作期待age
0282デフォルトの名無しさん
垢版 |
2007/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でないならわかるが
0294デフォルトの名無しさん
垢版 |
2007/08/29(水) 21:26:11
exit(0);
0299デフォルトの名無しさん
垢版 |
2007/08/30(木) 19:28:14
おもしろいことに、関心と一般の議論の大きさは、
機能の重要性と反比例していることが多い。
その理由は、大きな機能より小さな機能のほうが明確な意見を持ちやすく、
流行のような、一時的な関心を引きやすいからだ。
〜〜Bjarne Stroustrup『C++の設計と進化』
0300デフォルトの名無しさん
垢版 |
2007/08/30(木) 22:41:51
>>299
そして、プログラムとは、小さな機能を集めて大きな機能を実現していく。
だから、小さな機能を議論することは、最終的に大きな機能
そして、重大な機能を議論することにつながるのである。
0302デフォルトの名無しさん
垢版 |
2007/08/31(金) 00:56:46
ttp://msdn2.microsoft.com/ja-jp/library/xa1a1a6z(VS.80).aspx

世界一巨大なソフトウェア会社のコーディング例では、
len = _vscprintf( format, args ) // _vscprintf doesn't count
+ 1; // terminating '\0'
buffer = malloc( len * sizeof(char) );
のように、sizeof(char)を省略していない。
0304デフォルトの名無しさん
垢版 |
2007/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);
はダメだろう。

意味として間違ってる!
0307デフォルトの名無しさん
垢版 |
2007/08/31(金) 02:23:04
演習3のプログラムも酷い。

例とはいえ、freeしないのは、どうかと。
それに、stdio.hしか#includeしてないぞ!!!
0308デフォルトの名無しさん
垢版 |
2007/08/31(金) 02:37:23
>>303のURLのソースを見ると、スタイルシート"masato.css"を使ってる。

ttp://www.kumamoto-u.ac.jp/
のトップページでmasatoを検索すると、
ttp://www.syst.cs.kumamoto-u.ac.jp/~masato/pe2/index.html
がヒットする。似たようなセンスの問題が。

ttp://www.syst.cs.kumamoto-u.ac.jp/~masato/pe2/02/index.html
の問題4は、>>303の演習3と似てる。

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

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

熊本大学だいじょうぶか?
こんな質の低い教育やってちゃイカんぞ。
0310デフォルトの名無しさん
垢版 |
2007/08/31(金) 04:12:25
ttp://www.syst.cs.kumamoto-u.ac.jp/~masato/pe2/02/index.html
> 問題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;
> }
0311デフォルトの名無しさん
垢版 |
2007/08/31(金) 04:12:51
>
> 1. 「配列aとmallocで確保された領域bの違いは,
> 静的に確保されるメモリ領域と,
> __に確保されるメモリ領域という違いがある.」
> __に入る適切な言葉を以下から選びなさい.
>
> a.愛ゆえ
> b.俺的
> c.仮想的
> d.動的
>
> 2. b[2]の型は何ですか?


0313デフォルトの名無しさん
垢版 |
2007/08/31(金) 04:16:42
さらに、for文の書き方が酷い。

同一行に書くのなら {} を省いても構わないが、
別の行に書くのなら {} は省くべきではないのに。
0315デフォルトの名無しさん
垢版 |
2007/08/31(金) 09:32:49
>>302
そういうことやってるから細かいバグが残ったりなかなか取れなかったり
するんだろ。しっかりしろといいたい。
0316デフォルトの名無しさん
垢版 |
2007/08/31(金) 09:37:52
そうだな。

+1を人間がコーディングしていたら、+1し忘れて、バッファオーバーフローするわな。
0317デフォルトの名無しさん
垢版 |
2007/08/31(金) 10:12:40
世界一安定してる会社のコーディングスタイルならともかく、バグだらけの会社のそれを例に出されてもな
0320デフォルトの名無しさん
垢版 |
2007/08/31(金) 13:30:54
>>302
ほんと、あそこのサンプルコードってゴミばっかりだよな。

>>313
お前の推奨するスタイルなんかどーでもいいわけだが。
0322デフォルトの名無しさん
垢版 |
2007/08/31(金) 15:41:38
>>321
酷すぎるww
その前にあるNULL代入も意味無いしw
constもキャストもないからコンパイルも通らんだろうなw
0324デフォルトの名無しさん
垢版 |
2007/08/31(金) 16:31:06
>>321
あれだな、
1.まず鍋を用意します。
2.次に鍋を投げ捨てます。
3.そして既に作っておいたカップラーメンを食べます。
みたいな感じか。

それにしても僅か8行でツッコミ所満載な上に
メモリリークのおまけ付きとか流石マイクロソフトだな。
0327デフォルトの名無しさん
垢版 |
2007/08/31(金) 17:10:02
strcpyしたかったのかな。"Hello world!"で12文字だからnew char[12]じゃ足りないけど。
str.CopyChars(str.GetBuffer(), "Hello world!", 12); と書いとけばいいのにw
0335デフォルトの名無しさん
垢版 |
2007/09/01(土) 11:25:14
// 動的に確保した領域のポインタをpszSrcに代入
pszSrc= new char(12);
// newに成功した場合
if(pszSrc)
// 動的に確保した領域を無視して、文字列リテラルのポインタをpszSrcに保存
// 動的に確保した領域はリークする
pszSrc= "Hello world!";

C言語しか分からんけど、newをmallocに読み替えるとこんなところ。
C++だと文字列リテラルの代入は、なんかstrcpyみたいな動きすんのか?
0336デフォルトの名無しさん
垢版 |
2007/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)。
0341デフォルトの名無しさん
垢版 |
2007/09/03(月) 04:22:12
mallocが失敗する可能性は考慮しないのか?
つーか、mallocってNULL以外が返ったとしても
実はメモリ確保に成功したかどうか不明だという
おそろしいバグがあるんだがLinuxって怖いよな
0342デフォルトの名無しさん
垢版 |
2007/09/03(月) 08:06:28
mallocやnewが失敗する状況って、かなりヤバいよね。

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

だから、mallocやnewに失敗した時点で、OSから再インストールするハメになるわけで、
成功したかどうかチェックし、失敗したことがわかったところで、ろくに対処できないなら、
開き直って、mallocやnewをラップして、失敗したらexitしてしまい、
ラップしたものを使う側は、失敗することはないものとしてコードを書いてしまうのもアリかと。
0343デフォルトの名無しさん
垢版 |
2007/09/03(月) 09:14:15
>だから、mallocやnewに失敗した時点で、OSから再インストールするハメになるわけで、
おいおい、普通はrebootで充分だろ。

実際Gnomeなんか使っていると、malloc()に失敗する頃には事実上操作不能になっているから、
諦めてとっととexit()ってのはありだと思う。
私の仕事関係では、常駐型アプリケーションの起動は基本的にスクリプトから行ない、
アプリケーションが異常終了したときには可能ならそのアプリケーションを再起動するようにしている。
0344デフォルトの名無しさん
垢版 |
2007/09/03(月) 09:42:29
>>343
rebootで十分という保証があれば、ね。

OSの上で走るすべてのプログラムが、
設定やデータをファイルに書く時、
一貫性を保てるように書いてくれればいいが、
そうでないと、
不正で壊れたファイルを読むことになり、
こまったことになってしまう。
0345デフォルトの名無しさん
垢版 |
2007/09/03(月) 13:09:01
OSからとかねぇよw
書き込み中の電源断でさえジャーナルファイルシステムなら通常問題無いのに、
メモリ確保失敗くらいで整合性取れなくなるとかw

基幹システムなどなら、ソフトウェアとして既に品質に問題有りだし、
個人PCやグループサーバーレベルで再インストは潔癖過ぎだろ。
0346デフォルトの名無しさん
垢版 |
2007/09/03(月) 13:13:01
1GiBのメモリ確保しようとして失敗したって状況なら、
メモリ確保失敗したとユーザに通知したり、
そのために数KiBのメモリを確保したりしようとしてもいいと思う。
0347デフォルトの名無しさん
垢版 |
2007/09/03(月) 13:32:25
>>345
ファイルシステムのレベルで問題がなくても、ファイルの中身のレベルでは問題だよ。

ファイルの中身までトランザクションやジャーナルでやっていれば大丈夫だが、
そうでないプログラムの場合、ファイルの中身の一貫性が失われてしまう。
0348デフォルトの名無しさん
垢版 |
2007/09/03(月) 13:56:19
>>347
>そうでないプログラムの場合、ファイルの中身の一貫性
345の下2行の通り。
重要なシステムなら論外、DBMSなどで一貫性の確保は必須だし、
それでも抜けた異常はバックアップからリカバリさせる。
OSからとかダウンタイム長すぎだろ。

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

ユーティリティか何かがhttpd.conf壊したって、
OSどころかapacheから入れなおす馬鹿は居ないだろ。
0349デフォルトの名無しさん
垢版 |
2007/09/03(月) 16:41:48
>ユーティリティか何かがhttpd.conf壊したって、
>OSどころかapacheから入れなおす馬鹿は居ないだろ。
見たことあるな。
俺はこれをWindows病と名づけた。
0351デフォルトの名無しさん
垢版 |
2007/09/03(月) 20:36:44
ネトゲのクライアントは、たまにWindowsの設定やらシステムファイルやらをぶち壊す奴が居る
0353デフォルトの名無しさん
垢版 |
2007/09/03(月) 21:53:13
しばらく前、幻想三国志2っちゅーゲームでアホほど再起動かかってOSが不安定になった。
再起動の原因がメモリリークと気付くのが遅すぎた・・・。

HDDがガリガリ鳴り出したらセーブして再起動とか、
偽典女神転生を思い出して懐かしかった。
0354デフォルトの名無しさん
垢版 |
2007/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);

これくらいは抽象化するだろ?お前らどうやってる?
0355デフォルトの名無しさん
垢版 |
2007/09/03(月) 23:21:41
>文字数→バイト数として扱いたい意図
ここは自明だろーがよ
というのが反対派の意見だと思う。

a++; // 1を足す
っていうコメントを読まされるような感じ というか
0357デフォルトの名無しさん
垢版 |
2007/09/03(月) 23:49:03
まぁ、俺も現実的にはC++使うな。
だけどC++使うからこそ観念的に省略しないんだけどな。

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

文字列操作と言いながら型を強く意識するのは、やはりスマートとは思えないよ。
0359デフォルトの名無しさん
垢版 |
2007/09/04(火) 00:00:44
>>357
ぶっちゃけ未対応ソフトの多バイト文字対応をするときは
charをwchar_tに機械変換♥ なんて絶対しないから
もうその辺はすごい勢いでどうでもいい話だと思う。
0360デフォルトの名無しさん
垢版 |
2007/09/04(火) 00:11:32
そもそも文字型が独立しておらず、charやunsigned charが
整数型の1つである(JavaやC#でいうbyteにあたる型)という時点から
もう文字とバイトをごっちゃにするのは始まっている。

だから俺は文字 == バイトを甘んじて受け入れ、sizeof (char)を使わない。
0361デフォルトの名無しさん
垢版 |
2007/09/04(火) 00:15:20
機械変換とかじゃなくて、テンプレート関数の話な。
allocator((Tr::getlen(s)+1) * Tr::char_size);
みたいな感じで実装して、型はコンパイル時に決まる。

ちょっとした関数を総称化すると、
自分が自明だとか本質的だと思っていたものが、
そうでもないと気付かされるって話。
0363デフォルトの名無しさん
垢版 |
2007/09/04(火) 00:28:46
>>360
文字とバイトがごっちゃというのは整理出来ていないから。

文字は文字集合として独立していて、バイトも文字集合とは関係無い。
その2つを繋いで、バイト列の上で文字を表現するルールがエンコーディング。
概念が頭の中で分かれていれば、unsinedだとかSJIS, UTF-8やらがあってもごっちゃにはならないはず。
0364デフォルトの名無しさん
垢版 |
2007/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 を入れるとか、
場合によってはハードコーディングとか、もう見てられない。

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

それで登録日時(時分秒が有る)とかを検索する処理でも同じソース使って馬鹿がって結果になってた。
0368デフォルトの名無しさん
垢版 |
2007/09/04(火) 00:52:32
>>363
文字とバイトがごっちゃというのは俺に言っているのか?
俺は、CとC++が文字とバイトをごっちゃに扱っていると言ったつもりだ。
だから俺にそんなこと言われても、お門違い。
0369デフォルトの名無しさん
垢版 |
2007/09/04(火) 01:04:36
wchar.hなど有るし、文字とバイトをごっちゃに扱ってるようには思えないが・・・
それにchar==文字でなく、char*==nul終端文字ストリームというのがあったから
SJISなどをそれなりに扱えて来たわけだし。
0370デフォルトの名無しさん
垢版 |
2007/09/04(火) 01:20:30
ちなみに、java,C#などは文字型が本当の意味で独立してるわけじゃなく、
単に内部のエンコードを割り切ってUTF-16に統一してるだけ。
昔、C言語がasciiで十分と考えたように。

その利便性はもちろん大きいけど、その代償としてUTF-8などを読み書きするとき
エンコード変換のオーバーヘッドを受け入れている。
※よほど巨大なファイルでない限り対したオーバーヘッドじゃないけど。
0371デフォルトの名無しさん
垢版 |
2007/09/04(火) 01:27:26
UTF-16もサロゲートペアを考えるとchar==1文字とならない。
Unicode領域で固定バイトが出来るのはUTF-32だけ。
でもascii1文字に4byteも使うことと、
サロゲートペアの文字があまり重要でないことからUTF-32で扱っているシステムは少ない。

未来の言語のcharは32bitかもしれない。
0372デフォルトの名無しさん
垢版 |
2007/09/04(火) 02:46:39
おれは>>355と同じように考える。
>>357,>>361で抽象化とか総称化とかって話がでてるけど、
そのようなケースになったときは、そう書けばいい。

しかし、このスレでは‘sizeof(char)’は抽象化されてない。
あくまで、>>1の記述に的を絞って考えたらやっぱり冗長かなーと。。。
0373デフォルトの名無しさん
垢版 |
2007/09/04(火) 02:49:51
>>354
> char*    strmalloc(int len){return len<0?NULL:malloc((len+1)*sizeof(char   ));}

len=0のときにNULLにしてしまうのは、ちょっと馴染みがないんだが。
0377373
垢版 |
2007/09/04(火) 03:40:49
ごめん、寝ぼけてた。
真と偽を逆に見てた。
0378デフォルトの名無しさん
垢版 |
2007/09/04(火) 07:21:37
>>375
あ、確かに、size_tだな。size_tってunsignedって保証あるんだったっけ?
\0を入れられない、len==-1(len+1が0に)でNULL以外が帰ると都合が悪いので負の数を弾いてた。
0379デフォルトの名無しさん
垢版 |
2007/09/04(火) 07:48:25
>>369
例えばmemsetなどのmem〜関数がごっちゃにしている例。

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

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

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

>>371
D言語はUTF-32も扱える
0381デフォルトの名無しさん
垢版 |
2007/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ならまだいいけど、
構造体やクラス化されると他ライブラリとの互換性がね・・・。
0385デフォルトの名無しさん
垢版 |
2007/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スカラ値単位に区切ってくれる!
}
0387デフォルトの名無しさん
垢版 |
2007/09/04(火) 21:54:37
string は const(char)[] のaliasだから、ただのUTF-8シーケンスなのです。
だから、長さは6なのです。
0388デフォルトの名無しさん
垢版 |
2007/09/04(火) 21:59:16
Dはちょっと見ないあいだにますます変な機能が追加されてんだな

const(char)[] って何だよw
0389デフォルトの名無しさん
垢版 |
2007/09/06(木) 07:48:16
D言語って、そんなに悪くないと思うよ。
同じことをC++でベタベタとコードを書いたり、
可読性の酷くわるいマクロや、テンプレートを駆使しすぎるよりは。
0391デフォルトの名無しさん
垢版 |
2007/09/06(木) 23:49:44
デーげんごっていつのまにかたいへんなことになってんだな
0392デフォルトの名無しさん
垢版 |
2007/09/14(金) 20:35:08
さすがに、みんな飽きたな。
次のネタを検討しようか。

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

ってのはどうよ。

Cの標準化の人達は、なんで、print を用意しなかったのかな。
putsとカブっているとはいえ、引数1つのprintfが氾濫するよりはマシだろうに。
0396デフォルトの名無しさん
垢版 |
2007/09/14(金) 21:37:40
>>393
よくあるprintfの酷い使い方。

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

一行ずつ別々にprintfを呼ぶなら、putsでもいいんじゃないか。
0397デフォルトの名無しさん
垢版 |
2007/09/14(金) 21:39:13
>>395
そんな変な最適化をするコンパイラなんて捨ててしまえ。

そういうのに慣れていると、
printf("私のコードは100%safeです。\n") ;
なんていう恐ろしいことをやる馬鹿が出てくるんだよ。
0398デフォルトの名無しさん
垢版 |
2007/09/14(金) 21:42:51
puts, gets, putchar, getchar, printf, scanfまるごとなくしてしまえ。
f版でいいよ。

gets, putsとfgets, fputsは微妙に挙動が違うのが癪だが。
0400デフォルトの名無しさん
垢版 |
2007/09/14(金) 22:35:27
gccが最適化するからprintfを変な使い方をしてもいい、というのは間違いだと思う。
すでに書かれてしまった膨大なコードのために、変態な最適化をしてくれるのだと思う。
0401デフォルトの名無しさん
垢版 |
2007/09/14(金) 22:37:51

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

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

gccがprintfの引数を見て最適化してくれればバグが顕在化しないが、
最適化しない環境に持っていけばバグが顕在化してしまう。
0405デフォルトの名無しさん
垢版 |
2007/09/15(土) 00:54:17
>>401
俺は何でもかんでもprintf使う方だけど、コレは無いなぁ・・・。

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


puts、fputsなんてここ5年ぐらい使ってない。
対話なCUI作るときは(滅多に作らないけど)cursesなことが多いし、
ログ出力は定型で吐くラッパ作ることが多いし、
出力部分をgrepするのに、いちいち正規表現やなんかで色々指定するのダルい。
0406401
垢版 |
2007/09/15(土) 01:53:37
>>405
そのまさかをやる人間が少なくないのですよ。

printfに渡す文字列に対してサニタイジングを行うべし
なんて真顔で言う人間までいる。
0408デフォルトの名無しさん
垢版 |
2007/09/17(月) 16:14:37
>>400
一般論だが、
想定外の変なデータにあわせてプログラムを書き換えるというのは
たいていあとでほころびが出たりしますよな。
0411デフォルトの名無しさん
垢版 |
2007/09/18(火) 01:10:15
かつては、printfをどこかで使ってるなら出力は全部printfにしたほうが、
さらにもう一つputs関数がリンクされてしまうよりも
実行ファイルが小さくなるという効能があったのではないかと思う。
0413デフォルトの名無しさん
垢版 |
2007/09/18(火) 01:42:07
そもそもputsとfputsの挙動が違うのがな
今日の言語設計者は気持ち悪くて、そんなことできないと思う。
0414デフォルトの名無しさん
垢版 |
2007/09/18(火) 03:22:46
しょうがない。

もとはと言えば64KB程度のメモリで動いていたマシンのOSと、OSの上で動くプログラムを書くとき、
メモリを節約するために共通コードを関数としてライブラリ化したような代物だから。
0415デフォルトの名無しさん
垢版 |
2007/09/29(土) 23:17:00
ところで、sizeof(char)=sizeof(short)=sizeof(int)=2っていう設定のトンデモコンパイラがあるらしい。
一応、C言語の規格上これは間違っていない。(型のサイズは決められてないからね。)
0420デフォルトの名無しさん
垢版 |
2007/09/30(日) 15:02:18
>>415
「だから sizeof(char) は省略すべきではない」という主張?...でもなさそうだな。
このスレタイは「必ず1でも」って条件付きだから関係ないよね。
0422デフォルトの名無しさん
垢版 |
2007/09/30(日) 16:21:03
数学で毎回全ての問題の全ての数字に (注意:これは10進数)
みたいな但し書きをかかれるようなものだろ。
0427デフォルトの名無しさん
垢版 |
2007/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.
0429デフォルトの名無しさん
垢版 |
2007/10/13(土) 20:00:42
>>415
> ところで、sizeof(char)=sizeof(short)=sizeof(int)=2っていう設定のトンデモコンパイラがあるらしい。
> 一応、C言語の規格上これは間違っていない。(型のサイズは決められてないからね。)

それどこが出してる?
製品名と会社のweb siteのどちらかでいいから教えて
0431デフォルトの名無しさん
垢版 |
2008/01/21(月) 00:49:50
未だにsizeof(char)を書いてる人っているの?
0433デフォルトの名無しさん
垢版 |
2008/01/21(月) 19:55:24
Cプログラマの為に、ポイントをまとめたドキュメントを販売しています。
プロのプログラマでもあまりにレベルが低い人が多すぎます。
そんな人に限って、自分のレベルの低さを自覚していない、、、

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

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

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

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

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

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

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

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

興味がある方はどうか、下のサイトをみてみてください。
http://mori.eco.to/
0434デフォルトの名無しさん
垢版 |
2008/01/21(月) 20:09:56
>コンピュータの専門学校に入学、在学中に情報系の国家試験である、基本情報処理技術者、ソフトウエア開発を取得。
専卒かよ。
0439デフォルトの名無しさん
垢版 |
2008/03/21(金) 00:22:32
>>435
おいおい、ブラクラではなかったぞ。

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

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

BASIC時代のPRINTをそのまま引きずった、
printf("Hello, world\n");
なんてのが平然と書かれている本を見るたびに、
こんなので勉強したら無駄な時間を食うのは当然だなと思うし。
0440デフォルトの名無しさん
垢版 |
2008/03/21(金) 02:42:30
>>439
Hello,worldは基本中の初歩であって
これをバカにする理由が思い当たらないんだが
0442デフォルトの名無しさん
垢版 |
2008/03/21(金) 03:12:25
そんなことを言い出したらフォーマット文字列の中に
足がすくんじゃって何も書けなくなってしまうわけだが
0443デフォルトの名無しさん
垢版 |
2008/03/21(金) 03:17:33
正統派の基本を馬鹿にするのは新しいまがいものを売るときの基本
結局同じことの繰り返しになるわけだが
0444デフォルトの名無しさん
垢版 |
2008/03/21(金) 03:35:57
30年間でほとんど進歩してないな。

マイクロソフトの新しいバージョンのVisual C++が出る度に、まっさきに、
Visual C++ バージョンほげほげ対応 という冠を付けた本が出るのだが、
いまだに本編は相変わらず昔のままで、付録的に
コンソールで cc hoge.c とやってコンパイルするのと同等のことをやる方法を
ちょろっと書いているだけで、Visual C++のデバッガの使い方を説明せず、
変数の値をprintfを埋め込んで標準出力に出して確認することを第一に教えている。
0445デフォルトの名無しさん
垢版 |
2008/03/21(金) 03:39:09
>>442
それが正しい。

printfの第一引数が書式化文字列であるとういことを初手から叩き込むべき。
printf("%s\n", "hello, world!");
これくらい、わざとらしくやってもいいくらいだ。

そうでもしないと、↓みたいなことをやるマヌケが出てくるからな。
void print_message(const char *p)
{
printf(p);
}

0447デフォルトの名無しさん
垢版 |
2008/03/21(金) 17:00:16
入門書の何が問題かというと、「ポインタがわかりません」なんて人を今だに量産していること。
しかも、そこに書かれていることが、次の段階の本で否定されていたりする。
0448デフォルトの名無しさん
垢版 |
2008/03/21(金) 21:15:11
>>439
どうやって文字列が表示されるのかを勉強している身としてはとてもバカにできない内容なんだが、
どういう内容を載せるべきだと言ってるのか教えて欲しいな。
0449デフォルトの名無しさん
垢版 |
2008/03/21(金) 22:15:53
printfは、C言語の仕様の一部ではあるものの、ライブラリの一関数に過ぎない。
printfやscanfの使い方は、ライブラリのマニュアルを読めばわかることであって、
入門書で解説すべきなのは、それらの使い方ではなく、
マニュアルを読めばわかるようになるための必要な前提知識である。

ってなことを頭の片隅に置いて聞いて欲しい。

hello, worldのサンプルなんだけど、なんかC言語っぽくないんだよね。
短くてエッセンスが凝縮されているサンプルが思いつかないんだけどさ。

>>448
> どうやって文字列が表示されるのかを勉強している

C言語とはあまり関係ないなぁ。
ライブラリがOSのシステムコールを呼んで、あとはOSが処理してる。
0452デフォルトの名無しさん
垢版 |
2008/03/23(日) 03:37:29
>>445
という以前に、フォーマット文中に誤った引数が指定できて、しかも
その間違いがコンパイラでも内部処理でも検知できないっていう
printfの仕様上の欠陥があるわけで、そもそもprintfを使うことそれ自体が
NGだという話になるんじゃないの?
0453デフォルトの名無しさん
垢版 |
2008/03/23(日) 04:14:43
それを言いはじめたら、標準ライブラリの多くの文字列がらみの関数がNGになるよ。
たとえばstrcpyがバッファオーバーランしうる、とか。

そもそも、
今さらC言語を使わないといけない、しかも、習得するプログラミング言語の最初がC言語でなければならない
っていう状況に閉じ込められた時点で、その人は終わっていると思う。
0461デフォルトの名無しさん
垢版 |
2008/03/24(月) 21:13:13
>>460
そうだよ。
だから、Cを使うということはそのあたりの危険性と利便性をトレードオフする
考え方をもたないと駄目です。
やたら安全性をどうこう言っててもprintf使うだけでもう台無しです。
0467デフォルトの名無しさん
垢版 |
2008/03/24(月) 22:59:48
間違えることのでき、なおかつ、それを機械的に検出できない箇所の数が、道具によって変る

っていう話しなんだよ。
0468デフォルトの名無しさん
垢版 |
2008/03/24(月) 23:18:09
たんによくあるセキュリティ的な話でそ。
Java で間違ったものを toString() しても機械が気付くわけでもなし。
0469デフォルトの名無しさん
垢版 |
2008/03/24(月) 23:46:10
>>468
セキュリティに限らず、いかにバグの入り込む余地を減らすか、ってこと。
余地が少なければ、バグの有無を確認するための工数が減るわけよ。
0470デフォルトの名無しさん
垢版 |
2008/03/24(月) 23:55:12
まあ、コンパイル時にチェックできるところはやるのは当然として、
実行時のチェックは性能とのトレードオフもあるから、Cは今ぐらい
で丁度いいと思う。
0471デフォルトの名無しさん
垢版 |
2008/03/24(月) 23:59:58
いろいろチェックしたらJavaと同じことをやることになって、Javaよりも遅くなったりしてね。
0473デフォルトの名無しさん
垢版 |
2008/03/25(火) 15:13:05
>>469
まだわかってないな。

>バグの入り込む余地を減らすか
という観点では、printf が他の関数等よりもバグ発生契機が多いとは言えないだろう、
と言ってるわけ。もちろんセキュリティに関しては全く別だよ。

実際 gcc は printf("name=%s, qty=%d\n", qty, name) に warning だしてくれるけど、
Java は WriteLine( "name="+qty.toString()+"qty="+name) をスルーする。
printf でチェックが必要なら他のどの方法でもやはりチェックが必要。

漏れは LISP 使いだし出力は全て内部構造のままS式で出すよ、という人は別だけど。
0474デフォルトの名無しさん
垢版 |
2008/03/25(火) 15:27:34
>>473
printfに限った話ではないし。

int height ;
int weight ;
中略
height = weight ;
こういうのを機械的に検出できるかどうかは、
微々たる事ではあるが、
ソフトウェアの規模が大きくなってくると重要よ。
0475デフォルトの名無しさん
垢版 |
2008/03/25(火) 15:49:47
>>474
だからそれが printf とどう関係するんだよ、という話。
「限った話ではない」ではなく、全く関係のない独立した話ですよ。

>>469なんか、まるで printf の仕様がバグ発生契機を増やすかのように
さぞもっともらしいことを書いているが、ではどの処理系でどう書けば引数の
取り違えによるバグを避けられるかは一切提示していない。

>>474に至っては、printf の仕様の問題点については一切語らずに、
「に限った話ではない」との一言で、あたかもprintfに他の同等の処理よりも
多くの問題点があるかのようにほのめかしている。

printf に問題があるなら、プログラマなんだからもっとストレートフォワードに
この処理系のこういう書式化指定法ならバグが減る、と実例を出して批判して。
0477デフォルトの名無しさん
垢版 |
2008/03/25(火) 16:46:28
>>475
仮にprintfが他よりバグ発生契機が多いとは言えないとして、
それで一体お前は何を主張したいんだ?

printfフェチ?
0480デフォルトの名無しさん
垢版 |
2008/03/25(火) 18:27:14
>>475
引数の順序などを取り違える
ことと、
書式化指定文字列での型指定を間違える
ことを分けて考えようぜ。
0481デフォルトの名無しさん
垢版 |
2008/03/25(火) 22:31:54
>>474
どうでもいいけど、

> int height ;
> int weight ;
> 中略
> height = weight ;
> こういうのを機械的に検出できるかどうかは、

これは一体何が言いたいんだ?
0486デフォルトの名無しさん
垢版 |
2008/03/26(水) 09:10:16
高さを表わすint型の値と重さを表わすint型の値は、
型は同じだけれども、値の意味が違う。

だから、
height = weight ;
のような代入は、
C言語の言語仕様的には間違っていないが、
プログラムの意味的には間違っている。

それを機械的に検出できないとは言ってない。
工夫して検出可能にすることもできる。

工夫して検出可能にするか、
あるいは、
小細工せず検出不可能のままにするかは、
自由だ。

ただ、ソフトウェアの規模が大きくなってくると、
「人間が注意してコーディングして、しっかりテストすればいいんだ」
なんて言ってられなくなるので、
機械的に検出できるものは検出しよう、ということになるわけ。
0487デフォルトの名無しさん
垢版 |
2008/03/26(水) 09:28:17
>>486
そのプログラムの「意味」というのには、
 ソースが英語で書かれてる
というのが大前提としてあるよね。

仮に、heightが横幅でweightが縦幅を意味する言語があったら、
そのプログラムの「意味」は全く正しいということになる。
0488474
垢版 |
2008/03/26(水) 09:55:54
>>487
このスレを読み書きしている人で、
heightとweightが英語だと理解しなかった人がいたら、
手をあげて欲しい。
そういう人がいたなら、次からは何か改善するよ。
0490474
垢版 |
2008/03/26(水) 10:25:44
例がわかりやすいように、わざと豪快に間違ったコード片を書いた。

ここまで豪快なミスは少ないだろうが、このタイプのミスをしたことの
ある人はいるでしょう?
0493デフォルトの名無しさん
垢版 |
2008/03/26(水) 10:41:07
>>488
例えば、heightをheiと省略したらその「意味」は通じなくなるし、
他にもhaightとミスタイプしたら通じなくなる。
0494デフォルトの名無しさん
垢版 |
2008/03/26(水) 10:43:10
>>491
そりゃデバッグが足りなかっただけで、
それを言語仕様のせいにするのはちゃんちゃらおかしいだろw
0496474
垢版 |
2008/03/26(水) 11:34:13
>>492
>>493
貴方達が人工知能的なアプローチしか頭にないのは、わかった。
俺らはtypedefを使ってコーディングして、それを機械的にチェックする。
0498デフォルトの名無しさん
垢版 |
2008/03/26(水) 13:11:47
機械的ってのはコンパイラが検出という意味ではないのか。

TypedWidth redBoxWidth;
TypedHeight redBoxHeight;
  :
TypedWidth blueBoxWidth = redBoxHeight;
TypedWidth GreenBoxWidth = (redBoxWidth + redBoxHeight) / 2

とかコンパイルエラーになったら途方に暮れるもんな。

幅と高さは、型を分ける必要は感じないな。
熱量と体積とか、加速度と質量とかなら、型を分けて演算や代入に制限を加えるのは望ましいと思う。
0500デフォルトの名無しさん
垢版 |
2008/03/26(水) 15:59:06
>>496
>474に出てくる変数はすべてint型ですが?
少なくとも、今の話題にtypedefは関係ないよね。
それはまた別の話。

>>497
というかさ、コンパイラにプログラムの意味を解釈させるというのは、全く現実的な話じゃないわけさ。
プログラマの意図する「意味」とコンパイラの意図する「意味」の整合性を保つのがどれだけ大変かわかってるの?
テストを行う方が圧倒的に簡単だし、
そもそも俺には「コンパイラに意味を解釈させれば論理エラーが減る」
という考え方の方がよっぽどデバッグを大変にすると思うんだよね。

>>499
そこで質問なんだが、なぜ重さを高さに代入してはいけないの?
BMI指数なんかは、体重/身長^2 で計算するんだがこれは論理エラーなのか?
超体重理論の公式が、高さ=重さ*2.5 だった場合はどうなんだ?
他にも、例えば Tundere = Deredere はエラーになるのか?
Yandere = Tundere の場合はどうなのか?
0501デフォルトの名無しさん
垢版 |
2008/03/26(水) 17:07:34
>>500
>BMI指数なんかは、体重/身長^2 で計算するんだがこれは論理エラーなのか?
BMI指数の次元が 重さ/長さ^2 であるってだけのことだなぁ。

>超体重理論の公式が、高さ=重さ*2.5 だった場合はどうなんだ?
それはきっと次元を持つ比例定数が省略されてるな。(超体重理論って何?)
PV=nRTのRみたいな。
0503デフォルトの名無しさん
垢版 |
2008/03/26(水) 17:19:45
>>501
例えば、PV=nRT で V=1, nR=1 なら簡略化して P=T と書けるよね。
つまり、pressure = temperature、圧力 = 気温 となるわけだ。
これは正しいんだよな?

そこで何度も同じ事を聞いて申し訳ないんだが・・・
なぜ height = weight が絶対に間違いだと言い切れるんだ?
どうして重さを高さに代入するのが「論理エラー」になるんだ?
比例定数1が隠されてる可能性は絶対にないと言い切れるのか?
0504デフォルトの名無しさん
垢版 |
2008/03/26(水) 17:27:12
仮にheight = weightが正しい(意図してそうする)のであれば、
型でいうところのキャストみたいに、明示すればいいということだと思う。
0505デフォルトの名無しさん
垢版 |
2008/03/26(水) 17:57:12
前提を隠されて「圧力 = 気温」と言われたら、間違ってるとしか言えない。
間違いと言われたくないなら前提を隠さないでくれ。
0507474
垢版 |
2008/03/26(水) 18:55:09
>>500
> 少なくとも、今の話題にtypedefは関係ないよね。

いや関係ある。

1. 引数の型が違う → 型をチェックすれば、検出できる間違いがある
2. 引数の型は同じだが、値に互換性がない → 値の互換性をチェックすれば、検出できる間違いがある
3. 引数の型が同じで、値にも互換性があるが、変数を取り違えている → お手上げ

こういう3段階があるものの、基本的には同一の問題だろう。

> コンパイラにプログラムの意味を解釈させるというのは、全く現実的な話じゃないわけさ。

その通り。俺に対して反論してる人が現実的ではない話を持ち出してるだけだぞ。
なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。

> BMI指数なんかは、体重/身長^2 で計算するんだがこれは論理エラーなのか?

そういう計算をする関数は数が限られているのだから、
それが意図したものであれば、慎重にチェックの対象から外せばいい。
0508474
垢版 |
2008/03/26(水) 19:05:52
>>503
> 例えば、PV=nRT で V=1, nR=1 なら簡略化して P=T と書けるよね。

そこでスレタイ。1だからといって省略すべきではない。

そして、間違える余地を減らすためにも、
PをV、n、R、Tから求める関数を作って必ず使うようにすべき。
関数を使う以上、引数には1を渡すしかあるまい。

いまどきのコンパイラはinline展開してくれるからP=Tと同じ結果になろう。

> なぜ height = weight が絶対に間違いだと言い切れるんだ?

なぜなら、間違ってheight = weightと書いたという例だから。


>>506
色々とバグで痛い目を見ると、考え方が変ってくるかもよ。
0509デフォルトの名無しさん
垢版 |
2008/03/26(水) 19:45:35
>>507
型が同じか違うかで、この問題の解答が全く変わってくる。
「基本的には同一の問題」というのはダウトだろう。
実際、>>507の1,2,3で間違い検出の可能性が全く違っているし。

> なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。
>
>>474 を見たら、「コンパイラによる意味解釈」ということしか思いつかないのだけど。。。
他に>>474の解釈があるなら是非教えて欲しい。
「型が同じでも違っても基本的には同一の問題だから、型チェックでどうにかする」
みたいな詭弁は無しの方向で頼む

> それが意図したものであれば、慎重にチェックの対象から外せばいい。
>
チェックの対象から外すというけど、そもそもそのチェックって一体どうやってやるんだい?
型チェックなら、古の言語Cでもすでにやってし、
なによりそれでで解決がつくなら、>>474でint型しか出さなかった理由がわからない。
確認するけど、型チェックは大前提としあって、
他にも意味論を持ち出せばさらにバグが減らせるという主張でいいんだよね?
0510デフォルトの名無しさん
垢版 |
2008/03/26(水) 19:47:23
> そこでスレタイ。1だからといって省略すべきではない。
>
仮に sizeof(char) が省略すべきでないとしても、省略することは常に可能。
つまり、1は常に省略される可能性があるし、それは常に正しくあるべき。
というか、1をかけるかどうかで意味が変わってきたら、
「だから○○は使えねえんだよw」 (○○には好きな言語やライブラリ名をどうぞ)
とか言われそうなんだけど

> なぜなら、間違ってheight = weightと書いたという例だから。
>
たしかに>474はそれを間違いだと知ってるかもしれない。
でも、少なくとも俺にはそれが分からなかったし、もっと言えばコンパイラにはなんのことやらチンプンカンプンだろう。
なのでコンパイラにそれが間違いだと教える必要があるのだけど、それは一体どうやってやるの?
0511デフォルトの名無しさん
垢版 |
2008/03/26(水) 19:59:24
省略すべきでないのは型の使い分け・型変換の明示だろう。*1なんかいらない。
charとかstrlenとかをハードコーディングしちゃうのではね。
0512498
垢版 |
2008/03/27(木) 14:19:26
素で間違えてた。眼鏡買ってくる。

>474とそのフォロワーが何人かいるのだとおもうが、

>509
多分フォロワーは、(現実的に可能なら)型を分けるべきという議論をしていると思う。
>474は、>496でtypedefでも機械的にチェックできると言ってるが、フォロワーは同意しないかもしれない。

圧力と気温を別の型として扱う型システムが手に届くところにあったら >509 も使うでしょ?
今は自前で定義するもの大変だし定番ライブラリも無いしね。
0513デフォルトの名無しさん
垢版 |
2008/03/27(木) 16:10:03
関数をハードコーディング?
0514474
垢版 |
2008/03/27(木) 22:48:04
>>509
変数の取り間違い、という同一の問題です。
段階0として、人間が目を皿にして探す、ってのを入れてもいいよ。

> >>474 を見たら、「コンパイラによる意味解釈」ということしか思いつかないのだけど。。。
> そもそもそのチェックって一体どうやってやるんだい?

LINTの類いを使っていないと、それしか思いつかないのかもしれないね。

> >>474でint型しか出さなかった理由がわからない。

C言語のtypedefはtypedefしてたってintはintだよ。

> 確認するけど、型チェックは大前提としあって、
> 他にも意味論を持ち出せばさらにバグが減らせるという主張でいいんだよね?

「意味論」なんて持ち出してないぞ。
0515デフォルトの名無しさん
垢版 |
2008/03/27(木) 22:57:35
>>510
> つまり、1は常に省略される可能性があるし、それは常に正しくあるべき。

省略したらバグるべきだとは主張してませんが?

してもしなくても動作は変らないけど、
プログラムを読んだ人間に意図がわかるようにするために省略すべきではないのよ。

> 少なくとも俺にはそれが分からなかった

例や文章が不適切でゴメンね。
でも、今までの話で分かったでしょ?

> なのでコンパイラにそれが間違いだと教える必要があるのだけど、それは一体どうやってやるの?

機械的に検出するためには、機械的に検出できるようにコーディングするのよ。
コンパイル時にエラーになるだけが、検出ではないよ。

>>513
charやwchar_tを直に書かず、マクロやテンプレートによって切り換え可能にすることに対して、
それらを直に書くことをハードコーディングというのだろう。
0516474
垢版 |
2008/03/27(木) 22:57:56
おう、515は名前欄かきわすれた。
0517デフォルトの名無しさん
垢版 |
2008/03/28(金) 00:02:37
>プログラムを読んだ人間に意図がわかるようにするために省略すべきではないのよ。
それは常識が共有できている時しか成り立たない。
変なコードが書いてあったら書いた奴に意図を聞きたくなる。

そしてスレタイ。*sizeof(char) を書くべき派といらない派は、この点において常識を共有できていない。
0521デフォルトの名無しさん
垢版 |
2008/03/28(金) 19:25:44
>>514
> LINTの類いを使っていないと、それしか思いつかないのかもしれないね。
>
LINTでどうやって間違いを検出するのかというと・・・
C言語ならforとかwhileとかを「キーワード」という特別な扱いにして
その周辺の文法や、他にもよくありがちな構文上の間違いが無いか検証するわけね。
話を戻すとつまり、weightとかheightや他の英単語をキーワードとして扱うということ?

> C言語のtypedefはtypedefしてたってintはintだよ。
>
>>474で重要なのは、weightとheightが「同じ型である」ということなわけ。
同一の型の代入を、「変数名が間違っている」という理由でどうやってエラーにするの?
と何度も聞いているのだけど。

> でも、今までの話で分かったでしょ?
>
ぜんぜん分からないのだけど。。。
>>474は一体何が問題なのか? というところから分からない
0522デフォルトの名無しさん
垢版 |
2008/03/28(金) 19:41:51
>>515
> 機械的に検出するためには、機械的に検出できるようにコーディングするのよ。
> コンパイル時にエラーになるだけが、検出ではないよ。
>
間違いを検出するのは、コンパイル時ではないということ???
あなたの主張が全く見えないので、以下で確認させて欲しい。

問1) >>474は具体的にどこが間違っているのか?
1、weightとheightが同じ型であるところが間違っている。これらは型を分けるべき
2、(同じ型であっても)名前が間違っているのは明らかだから、代入したらエラーがでるべき。
3、その他

問2) あなたのいう「機械的に検出」とは具体的にどのような方法で行うのか?
1、weightとheightの型を分ける
2、weightやheightや他の英単語をキーワードとして登録し、その使われ方をチェックする
3、コンパイラや他の何か(例えばLINTやリンカなど)に意味解析をさせる
4、その他

問3) >>474の間違いを検出するフェーズは具体的にどこか?
1、コンパイルの開始前(いわゆるLINT)
2、字句解析時
3、構文解析時
4、構文木を作った後の独自のエラーチェック時
5、コード生成時
6、実行時
7、その他
0523474
垢版 |
2008/03/28(金) 22:06:15
>>521
> weightとかheightや他の英単語をキーワードとして扱うということ?

No.

> 同一の型の代入を、「変数名が間違っている」という理由でどうやってエラーにするの?

さぁ。
それはあなたが言い出したことなのだから、自分で考えてくださいな。

>>522
> 間違いを検出するのは、コンパイル時ではないということ???

コンパイル時に限らない。

> 問1)

3

> 問2)

4

> 問3)

7
0527デフォルトの名無しさん
垢版 |
2008/03/28(金) 23:18:40
そもそも変数名にheightやweightってつけるのは、人の目から見て意味のある名称にして
人間が間違えないようにするため。
それを機械的にって根本的におかしいだろ。
0531デフォルトの名無しさん
垢版 |
2008/03/29(土) 23:11:22
世の中には、

mallocしたものをfreeするとバグの原因になるからfreeしないほうがいい
どうせプロセスが終了するときに解放されるのだから

なんて言う人もいるのですよ。
0534デフォルトの名無しさん
垢版 |
2008/03/30(日) 16:27:19
ていうかmallocするとバグの元になるから
そもそもなるべくmallocしないで済む設計にするのがいいよ
0538デフォルトの名無しさん
垢版 |
2008/03/30(日) 21:53:52
> なんで明らかにダメな方向に誤解して、その誤解の上でしか成りたたない反論をするんだろ。
0542デフォルトの名無しさん
垢版 |
2008/06/12(木) 07:39:29
typedef int WEIGHT;
typedef int HEIGHT;

WEIGHT weight;
HEIGHT height;

height = weight; // warning: 型の異なる代入ですというコンパイラは存在するのか
0545デフォルトの名無しさん
垢版 |
2008/06/15(日) 00:44:21
>>543
そう言う問題じゃなくて、POD であることはわかってるけど、
プログラマが別の型と定義したんだから、 警告するようにすれば
身長 × 体重 なんてしてしまうバグを減らせると言うことなんだ
ろう。

>>542
言語は違うけど、Pascal とか Ada はそう言う型を定義できる。
現状の枠内でやろうとするなら、>>544 の方法がいいと思う。
0550デフォルトの名無しさん
垢版 |
2008/09/18(木) 07:56:04
独自の拡張にメリットを見い出せないからこそBOOST(ライブラリ)やD(派生言語)でstrong typedefを実現しているのだけれど
>>547
間抜けだという理由をどうぞ
さぞかし説得力のある解説をして下さるのだろう

単純に既存のC/C++処理系の拡張としてtypedef警告が実装されていたら
WindowsやOpenGLのプログラムなんてやってられないと思うのだがね
0556デフォルトの名無しさん
垢版 |
2008/10/20(月) 09:05:31
馬鹿な>1っているもんだな
0559デフォルトの名無しさん
垢版 |
2009/09/02(水) 02:43:32
いいえいいえ
0561デフォルトの名無しさん
垢版 |
2009/09/04(金) 00:55:35
strncpy(str1, str2, str2 - strrchr(str2, '.'))
みたいな場合でも、
strncpy(str1, str2, sizeof(char) * (str2 - strrchr(str2, '.')))
とか書かなきゃならんか?

アホらし。
0562デフォルトの名無しさん
垢版 |
2009/09/04(金) 02:02:02
>>561
いやそこはだめだろ。memcpyではあるまいし。
wchar_t版でもなんでもそこでsizeofをかける必要はないぞ。
0564デフォルトの名無しさん
垢版 |
2009/09/04(金) 07:29:42
sizeof(char)をかけるのではなく,
sizeof(char)で割らなきゃいけないところか?
普段Cでマルチバイトとか使ってないんでよくわからん。
0565デフォルトの名無しさん
垢版 |
2009/09/04(金) 11:26:20
str2 - strrchr(str2, '.') の結果は「文字数」だが
strncpy の第3引数もまた「文字数」(バイト数ではない) だからな。
0569デフォルトの名無しさん
垢版 |
2011/11/24(木) 21:22:09.71
もう4年も前なのか
0572デフォルトの名無しさん
垢版 |
2011/11/29(火) 13:44:44.78
>>570
すげぇ
これにコンパイル通るのか・・・こえぇなぁ
これやっちゃったあとってもうcharは復活する手段無し?
0580デフォルトの名無しさん
垢版 |
2012/09/05(水) 19:13:46.94
sizeof(char)と書いてあればテンプレート化の際に
sizeof(T)に置換し易い

シンタックスでセマンティクスを表せるなら
それを使った方が人にも機械にも認識しやすいコードになる
0581デフォルトの名無しさん
垢版 |
2012/09/05(水) 19:57:02.45
charが常に1バイトなことを理解できてなかった奴が
無理やりあとからこじつけてるようにしか見えないな
0582デフォルトの名無しさん
垢版 |
2012/09/06(木) 10:45:40.63
1バイト単位で処理したいときがどうしても出るから、
charが1バイトじゃなくなったら、どうすんの?ってかんじだなw
(char *)にキャストしてクリクリとポインタ進める動きが大事だろ。
0590デフォルトの名無しさん
垢版 |
2014/02/26(水) 21:48:50.86
charが1でない環境でコンパイルされる可能性のあるときだけ気をつければよい
0591デフォルトの名無しさん
垢版 |
2014/02/28(金) 09:37:27.66
>>1の理論によると、sizeof(long)も4と書いてはいけないことになる。
ありえない。
0593デフォルトの名無しさん
垢版 |
2014/03/01(土) 09:06:38.21
自分しかコンパイルしなくて
しかもそのコンパイルする環境でlongが4ならそれでいいだろ
いちいちsizeof関数が実行されないぶん高速化されるわけだし
0597デフォルトの名無しさん
垢版 |
2014/03/02(日) 17:49:41.62
何のサイズかはどうでもいいんだよ
必要なサイズが確保されていればそれでいい
0598デフォルトの名無しさん
垢版 |
2014/03/04(火) 21:16:10.83
何?
C言語ってアセンブラまで見なきゃいけないの?
0599デフォルトの名無しさん
垢版 |
2014/03/04(火) 22:09:37.32
いけないのです。
実用的にCを使うならアセンブラは必修です。
0602デフォルトの名無しさん
垢版 |
2014/03/06(木) 17:46:11.78
めんどくさ
0603デフォルトの名無しさん
垢版 |
2014/03/08(土) 20:56:19.16
アセンブラできる俺かっけー!したいだけにしか見えない
0604デフォルトの名無しさん
垢版 |
2014/03/08(土) 21:15:37.05
ANSI/ISO/JISでは、sizeof( char )は1、と定義されているけど
俺は標準規格がいつ変更になってもいいように
sizeof( char ) は書くようにしている。
0606,,・´∀`・,,)っ-○○○
垢版 |
2014/03/08(土) 21:44:58.40
wchar_tがあるからcharのサイズが変わることは無いしかえる必要性も無い
逆に変えちゃうと1バイトを表すプリミティブ型がほかに無くなってしまう。
(新しい規格にはbyte_tとかあったっけ?)

むしろサイズが変わったときのことを考えるなら
charをそのまま使わずtypedefして使えって思うけどw
0607デフォルトの名無しさん
垢版 |
2014/03/08(土) 21:47:09.16
> 逆に変えちゃうと1バイトを表すプリミティブ型がほかに無くなってしまう。

そうそうれ。おれはそれが理由で安心して省略してる。
0608デフォルトの名無しさん
垢版 |
2014/03/08(土) 21:50:55.80
へーダンゴちゃんは物知りだねえ。
0610,,・´∀`・,,)っ-○○○
垢版 |
2014/03/08(土) 22:06:22.14
大丈夫だよ
C#のコードをそのままCに持ってきてもたいがい
コンパイルすら通る見込みはないから
0611デフォルトの名無しさん
垢版 |
2014/03/10(月) 23:23:15.92
>>606
int iSize = strlen( pName );
char* pBuf = (char*)malloc( iSize+1 );
strcpy( pBuf, pName );
で、もし sizeof( char ) が1じゃなくなったら
メモリを壊すだろ
0612,,・´∀`・,,)っ-○○○
垢版 |
2014/03/11(火) 00:07:57.69
> で、もし sizeof( char ) が1じゃなくなったら


これはありえない仮定を持ち出すという詭弁だな

なぜcharのサイズを変える必要があるのか
wchar_tを用意したからcharのサイズは今のままでいい
という発想が欠落した無能人間乙としか
0613,,・´∀`・,,)っ-○○○
垢版 |
2014/03/11(火) 00:10:44.17
大体にstrlen + malloc + strcpyじゃなくてstrdup使えば1行ですむだろ
そんな無駄なコードを得意げに書くから実力がつかないんだよ

てかいくらバカでもstrncpy使うわ
0616,,・´∀`・,,)っ-○○○
垢版 |
2014/03/11(火) 08:19:22.80
何がダメかって書いておくわ

1.ドヤ顔で言う割りにmallocがNULLを返したときの処理を考慮してない
(strdupはメモリ確保失敗時点でコピー操作を止めてくれる)

2.strcpyはいちど走査するまでソース文字列の終端がわからない。
なので、1バイトコピーするごとに終端文字判定が必要になる。
(あるいは、また内部でstrlenですか?)

strncpyというよりはmemcpyが一番無駄がないのかな。
コピー終端がわかっているので、終端までの間は大きなワードサイズでの
コピー操作を行うことができる
(x86ならmovntdqで16バイトずつコピーするのが最速ですよ)





で、そもそもchar配列のサイズのことを考慮するのであれば
   sizeof (char)
ではなく、
   sizeof hoge_str[0]
じゃないとダメだろ?
単体のcharのサイズとchar配列の1要素のパディングサイズが将来にわたって
同じである保障がどこにある?

結論:お前らのクソ宗教は不完全
0617デフォルトの名無しさん
垢版 |
2014/03/11(火) 12:45:37.33
>>,,・´∀`・,,)っ-○○○

メモリーの破壊例として
やっつけで書いたと思われるサンプルコードにそこまで噛み付くとは
マジで必死だな
m9(^Д^)プギャー

俺はお前と同類と思われたくないからsizeof(char)を省略しないことにする
0618,,・´∀`・,,)っ-○○○
垢版 |
2014/03/11(火) 19:44:41.10
↑お前は同一人物か同レベルのアホだと自分で証明してるわけだが。

sizeof (char)を別に書こうが書くまいがどっちでもいい
そんなことで無駄な時間を費やすなというだけで

書かなきゃいけない理由の説明が不適格だと指摘してるだけだよ


> で、もし sizeof( char ) が1じゃなくなったら

このDQNな仮定の致命的な欠陥の理由をもう一つだけ指摘しよう
charのサイズが変わってしまうと、ASCIIやUTF-8など8ビット単位のエンコードの
テキストを読み書きしてるプログラムがほぼ全滅してしまうわな。

これはsizeof(char)を入れれば解決という話ではない
sizeof(char) == 2になるとfgetcで2文字分入ってきてしまう。
もともとASCII文字列の1文字を1データとしてマッピングできる型としてchar型が
あるわけでそれ以上でもそれ以下でもない。

charのサイズは変わるかもしれないものではなく「変えてはいけない」のが
C/C++の仕様であって、おそらく地球上のどこにも存在しない
標準規格を守らないコンパイラの挙動を考慮しろなんてヴァカな話はない。
0619デフォルトの名無しさん
垢版 |
2014/03/11(火) 20:37:02.31
そもそも >>1 * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char)
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char)をはじめとする sizeof (char)を
書く派の言い分が総じておかしいのは「省略する」という考え方そのものよ。
本質的に必要のない式を付加してるだけにすぎないのに。

タイプ量が増えるしコードが長くなって幅をとったり行が長くなるだけで
何一つメリットがない。
むしろわざわざ * sizeof(char) をつけてる人のコードの品質こそ逆に俺は
信用しないことにしている。
仕様を理解せずに書いてる可能性が高いってことだからな。

WindowsでUnicode APIベースのプログラム書いててもASCIIデータは扱うし
Unicode移植時にcharの操作を機械的にすべてwchar_tに置換すればいい
って発想もたいがい危い。

とりあえず規格で決まってるcharのサイズが変更される確率は限りなく0 *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) * sizeof (char) *
sizeof (char) * sizeof (char) * sizeof (char) に等しいことは確定的に明らか。
0621,,・´∀`・,,)っ-○○○
垢版 |
2014/03/11(火) 22:38:20.94
そんなしょっちゅうstrlenやらなきゃいけないコード書くならヒープ領域自体に
サイズを格納して管理しようぜ。

typedef char* OreoreString;
#define OreoreStringSize(buf) (*(uint32_t*)(buf-4))
#define OreoreStringRewriteSize(buf, newSize) (*(uint32_t*)(buf-4) = newSize)

OreoreString OreoreStringAlloc(size_t n) {
  char* buf = malloc(n + 4);
  if (!buf) return NULL;
  *((uint32_t*)buf) = n;
  return buf + 4;
}
void OreoreStringFree(OreoreString buf) {
  free(buf - 4);
}
OreoreString OreoreStringDuplicate(OreoreString src) {
  int size = OreoreStringSize(src);
  char* cpy = malloc(size + 4);
  if (cpy) memcpy(cpy, src-4, size);
  return cpy;
}

こんなコードをだいがくいちねんせいくらいに書いたことがあったが
なにげにMacのCoreFoundationの文字列がこれに近いデータ構造に
なってるんだよな。
NULL終端つけておけば普通のC文字列関数も使えるし。
0624 ◆0uxK91AxII
垢版 |
2014/03/12(水) 01:09:58.95ID:yJrX5exL
>>621
sizeof (uint32_t)が4より大きくなったらどうするんだ!!1!
0626,,・´∀`・,,)っ
垢版 |
2014/03/12(水) 02:20:54.98ID:DWO9DKRE
>>624
名前通りのサイズにならないデータ型ってある意味面白いなwwww
typedefの意味なすwwww
stdint.hの定義がおかしいトンデモ処理系で正常に動くことなんてプログラマが
保障する必要ないよね。

たしかにBSTRも確かにPASCAL文字列+C文字列のハイブリッド的な実装だ。
個人的に文字列処理でCは使いたくない。C++の煩雑さもたいがいだけど。
0629,,・´∀`・,,)っ
垢版 |
2014/03/12(水) 19:27:22.15ID:DWO9DKRE
628 * sizeof(char) * sizeof(char) * sizeof(char) * sizeof(char) * sizeof(char)
が「省略」とかあほなことを言ってますよ
0630,,・´∀`・,,)っ
垢版 |
2014/03/12(水) 19:33:34.10ID:DWO9DKRE
もしsizeof(char)をかけなければいけないと主張してる奴の
トンデモ加減が理解できないならプログラマの才能ないよ

仕様の意味を深く理解せずにプログラム書いてる奴のコードの品質なんて
総じて低い。
0631デフォルトの名無しさん
垢版 |
2014/03/12(水) 21:06:01.62ID:4AbABLKQ
>>628
痛いのは省略派じゃないぞ。例えば>629-630のことなら
そもそも省略なんて言っちゃうのがどうかしているんだぞ派とでも言うべきだw
0632,,・´∀`・,,)っ
垢版 |
2014/03/12(水) 21:16:24.57ID:DWO9DKRE
switch (n) {
case(1): 〜
case(2): 〜
case(3): 〜
}
return(0);
とかわざわざ括弧をつける奴とか

for (i = 0; i < I_MAX; i++) {
  for (j = 0; j < J_MAX; j++) {
     for (k = 0; k < K_MAX; k++) {
        /* 何かしらの処理 */
        if (cond) {
          break_flag = 1;
break;
        }
     }
     if (flag) break;
  }
  if (flag) break;
}

↑みたいな、gotoを使ったほうがよっぽどきれいに書けるコードを平気で書く奴とか
(そもそもK&Rでも多重ループを抜けるときにgotoを使うのはむしろ推奨されている)

もっと強烈な奴だと
#define then
#define begin {
#define end }
みたいなマクロを定義して「PASCAL風だ!」とドヤ顔する奴とか
このスレの1とその同意者みたいな、意味も無く式に sizeof (char) を掛ける奴とか
みんな、頭弱いんですよ。
0634,,・´∀`・,,)っ-○○○
垢版 |
2014/03/12(水) 21:45:07.65ID:DWO9DKRE
お前ら知ってる?

for (int i = 0; i < array.size(); i++)



for (int i = 0 * sizeof(char); i * sizeof(char) < array.size() * sizeof (char); i += 1 * sizeof (char))

の省略表現なんだぜ。


整数型をとる関数の返り値でreturn 1; とかやってるのも
実は return 1 * sizeof (char); を省略したものなのだ。
省略が嫌いな人はちゃんと書くように心がけよう。



極論だけど、「省略」という概念を勝手に作り出すというのはこういうことなんだよ。
0636,,・´∀`・,,)っ-○○○
垢版 |
2014/03/12(水) 22:17:04.10ID:DWO9DKRE
sizeof(char)を使うべきと主張してる例として出てくるコードが
strdup()の車輪の再発明しかないという現実に絶望したのだ
0637デフォルトの名無しさん
垢版 |
2014/03/12(水) 22:33:15.30ID:UhWwNHPB
別にsizeof(char)いいと思うけどなぁ
ほんの少しだけ柔軟
別にめんどいなら1書くしなー
というかこういう話は規約レベルであって個人なら適当でええんでないの
0638デフォルトの名無しさん
垢版 |
2014/03/12(水) 22:36:20.03ID:YzPuo2JA
そういうヤカラは
if (isfoo(a) == TRUE)
と書いて満足げだったりするからタチ悪い。
0639,,・´∀`・,,)っ-○○○
垢版 |
2014/03/12(水) 23:35:55.62ID:DWO9DKRE
>>637
本来必要の無い冗長な式ととわかった上で「別にいい」というのなら
何も反論はない。好みの問題だからな。
書くべき理由も無いし書いたらダメという理由もない。

書かないことを「省略」という概念で捉えるバカは救いようが無い。
sizeof (char)を掛けるのが害悪なのではなく
言語の基本的な仕様すら正しく理解せずにコードを書く人間が
バグの根源なのだ。
0640デフォルトの名無しさん
垢版 |
2014/03/13(木) 11:53:41.67ID:f8T+x/4U
strlen()は引数のアドレスから'\0'のアドレスまでの差分を返す関数だから
>>1のような例の場合には仮にcharが2バイトになろうが4バイトになろうが無意味だな
0642,,・´∀`・,,)っ-○○○
垢版 |
2014/03/13(木) 19:16:45.68ID:0x0bjcUd
だからさ何度も言ってることだけど
charが2バイト以上になったらテキストファイルをメモリマッピングして
読み書きしてるプログラムがほぼ全滅するじゃん。

絶対あってはいけないことを仮定し、それに対するなんの解決にもならない
オレオレ解決策を提示するのは野暮だね。
0643デフォルトの名無しさん
垢版 |
2014/04/30(水) 04:09:09.95ID:OAq57yR0
名前欄のところにAA使うヤツってイタいのしか居ないのか?

uy
,,・´∀`・,,)っ-○○○

それとも、技術力が低いところと粘着質なところをみると同一人物か?
0644デフォルトの名無しさん
垢版 |
2014/04/30(水) 04:34:13.99ID:lAD+rioe
>>643
uyと顔文字だったら技術力は桁違いだぞ。それが読み取れないとしたら、余程読解力が足らないんじゃないか?
0645デフォルトの名無しさん
垢版 |
2014/04/30(水) 11:10:13.40ID:4gXDKzV2
ぷろぐらまには観察力も必要
好き・嫌いだけで思考停止する奴は向いてない
0651デフォルトの名無しさん
垢版 |
2014/11/04(火) 04:16:52.73ID:9XcfLbNC
>>637
0654デフォルトの名無しさん
垢版 |
2016/03/29(火) 10:13:01.80ID:/c8bAcK4
サッカーブッシュ日本代表日程ぷあたん(しゅっちょうまいくろ教育長交代)春文執行40代売上差額シュガーチョコ
https://www.youtube.com/watch?v=NDq1QoJY0nY宇ドナルドアナリストパワーストーンコーチングとしまえん
サッカーブッシュ日本代表日程古本屋よしたけしゅっちょうちょこしゅがー
ディーラー税務署天才開発者死亡詰みヨミドクターマイクロサービス不足
サッカーブッシュ日本代表日程ぷあたんシフト光金さかい強制バイト人権侵害問題
春分資源執行ニューヨーク低原価ぼったステーキソルトレイク福岡横浜新橋奴隷課金パチシフト強制バイト問題新潟米センター生残
コスメ24チャリティー隠れ40代生活保護プレイボーイバイトレードいたりあん接待問題
マスコミKARDローンケーオーサービス不足婚活パーティー寄付金執行原発ビジネス
FBIチャイニーズタイホテル売上事務所ガチャ決算ガチャキャンペーン(販売報道陣過激派組織向携帯最新情報提供終了
校長発言細心注意ノートン産廃エラー(著作権クレーム中国反応融資高額教育費)(中国捕鯨団体40代社員サッカーコメント
高額入学金ヤフウ新橋大学ヤフウ新橋理事長FX経費 おじや50代資産ガリバズフィード40代エリート
0657デフォルトの名無しさん
垢版 |
2018/05/23(水) 21:10:29.59ID:Au5e7VGg
僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方
役に立つかもしれません
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』

EVRSR
0658デフォルトの名無しさん
垢版 |
2018/07/05(木) 00:46:51.44ID:RfoszcD2
J7V
0661デフォルトの名無しさん
垢版 |
2021/11/22(月) 05:30:11.46ID:BgcNaRYw
sizeof char8_t ならok
0662デフォルトの名無しさん
垢版 |
2021/11/24(水) 19:05:27.71ID:eedqR6oi
char、intなんて使うな
s8,u8,s16,u16...と定義しておけば移植上の問題も解決しここのchar符号つきだったっけ?などと悩む必要もなくなる
0667デフォルトの名無しさん
垢版 |
2021/12/19(日) 12:24:11.57ID:n0pWJPWX
いつのスレだこれw

charが1バイト以外なんてきいたことないんだけど現実にあるのか?
memalloc(tcslen(s)+1)とかc#ならなんてならわかるけど
0669デフォルトの名無しさん
垢版 |
2021/12/19(日) 13:10:48.61ID:n0pWJPWX
どこであるの?
16ってことはユニコードなんだろうけどstrlenやcharが16で扱われるなら、普通の8bit文字はどういう型や関数になるの?
0671デフォルトの名無しさん
垢版 |
2022/01/01(土) 14:55:46.21ID:Je/lt7i4
そいつもcharは1バイトだしsizeof(char)=1だしmallocも誤作動しない
1バイトが16ビットという変態なだけみたいだな
0673デフォルトの名無しさん
垢版 |
2022/01/02(日) 11:53:10.96ID:qIxMJbVw
通信系で8ビットデータをcharに1バイトずつ入れるか2バイトずつパックして入れるか
の2通りを用意しなきゃならないのが面倒だった

charのサイズよりも
それ意外の特殊な構造の方がよっぽど大変だった
0677デフォルトの名無しさん
垢版 |
2022/01/02(日) 16:29:30.40ID:MzGzgg2X
C2000を使って開発してた時も当然1バイトは8ビットとして会話してた
そうじゃないと会話が成り立たない
0679デフォルトの名無しさん
垢版 |
2022/01/02(日) 21:29:09.83ID:T/GE+9gk
[迷信] 1バイトは8ビット
https://www.kijineko.co.jp/%e8%bf%b7%e4%bf%a1-1%e3%83%90%e3%82%a4%e3%83%88%e3%81%af8%e3%83%93%e3%83%83%e3%83%88/

2008年にIEC 80000-13:2008で1バイトは8ビットと定義されたのですが、C言語やC++では、その後の規格(C17やC++20など)でも1バイトのビット数は処理系定義のままになっています。

では、C言語やC++における1バイトは実際に何ビットになっているかというと、<limits.h>ヘッダで定義されるCHAR_BITマクロがそれを表しています。CHAR_BITマクロは少なくとも8以上に定義されることが保証されています。すなわち、1バイトが9ビットであったり、16ビットであったり、64ビットであったとしても、規格上は何ら問題ありませんし、そうした処理系が実際に存在します。
0681デフォルトの名無しさん
垢版 |
2022/01/02(日) 23:57:28.41ID:MzGzgg2X
ストレージの容量
メインメモリの容量
データ通信速度
データ通信量
全てこれで統一されている

コンパイラが何であれ
0682デフォルトの名無しさん
垢版 |
2022/01/03(月) 03:49:39.60ID:b0ADrG90
そんな一般論は中学生以上ならだれでも知ってるんだよ
そういう一般論でプログラミングして問題起きないのかってスレなんだよ
そして問題ありって具体例が挙げられたというのになぜそんなにかたくなに・・・
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況