【結構迷う】C vs. C++【どっちで行こうか】
一般的には「C/C++」とひとまとめにされることの多い両言語ですが、
どちら一方をどっぷりと使っている人にとっては、かなり大きな
壁を感じると思います。
そこで、「C/C++」な人でも「C派」「C++派」に分かれて、それぞれの
観点からどちらの言語がより良いか、議論してみましょう。
主観的、客観的意見なんでも構いません。ただし建設的な議論に
なるよう、理由も添えてお願いします。
ルール
1.Java、C#などの「C/C++」以外は論外。これらについて言及している
レスは無視してください。
2.速い、遅いなどの議論は極力説得力のある根拠、ソース(情報源)
などを提示してください。
3.特定のOS、開発環境を理由に挙げたり、叩いたりしないでください。
たとえば、「Linuxの人は…」や「VC++ってやつは…」などは禁止。
4.標準、準標準のライブラリに関しては、その言語を使う場合常に
ついてまわるので言及をOKとします。
5.どちらか一方しか使ったことのない人は、その旨を述べた上で
意見をお願いします。
6.その他、明らかな煽りや無意味な書き込みも無視でお願いします。
2 :
1:2008/04/06(日) 03:18:23
単純にC拡張として好きだ
1つの意味の処理まとめて{ }ブロックで括って内部で変数寿命完結させるところとか美しい。
それとC++はMFCとか面白いじゃあないか 表向きの効率は旧VBや.netに劣るけれども。
便利なライブラリがC++でしか用意されていない。
5 :
C++:2008/04/06(日) 04:12:38
単純にC++が好き
newは嫌いだけどな
RAII の気持ち良さを知ってしまうと、もう C には戻れない。
string の楽チンさを知ってしまうと、もう C には戻れない。
template の汎用性を知ってしまうと、もう C には戻れない。
抽象プログラミングの威力を知ってしまうと、もう C には戻れない。
C はプログラマを低レベルなバグで悩まさせ、疲れさせる言語だ。
環境的な制約がない限り、迷う必要などない。
7 :
1:2008/04/06(日) 10:38:57
自分は一度、C++に疲れて愛想を尽かそうとしたクチなんですけど、
設計と進化を読んでからC++が大好きになってしまった。
「ポインタがあるのになぜ参照が導入されたか」などの理由を知ると
それがあまりにも必然に思えて、「C++は複雑化しすぎ」とか言われるほど
複雑に見えなくなってきた。C++の各機能の導入経緯を知ってから
自分の思考回路がC++と馴染んだ気がする。
C派の意見としてよく聞くのが、ABI不在による保守の問題とか、
その辺は自分はあまり実感ないです。
それから上記の理由により「複雑すぎて云々」も今や感じません。
あと、Boostにアドビから画像処理ライブラリが追加されるなど、Boostの勢いにも
魅力を感じます。
8 :
デフォルトの名無しさん:2008/04/06(日) 10:40:58
> ポインタがあるのになぜ参照が導入されたか
なんで?
ライブラリ作ったり引っぱってきたりするのに公式なABI仕様がないのはつらいよ。
せめて、同一プラットフォーム上だけでも統一してほしい。
10 :
1:2008/04/06(日) 13:14:10
>>8 ビョーンさんは言語内臓型とユーザ定義型を差別したくなかった
↓
例えば、複素数型でも c = a + b; と書けるようにしたかった
↓
演算子オーバーロード(operator+など)を導入
↓
一般的にユーザ定義型はポインタ渡しの方が効率的
↓
complex *operator+( const comple *a, const complex *b) {...} とすると…
↓
c = &a + &b; と書かなくてはならない
↓
誰もそんなの書きたがらないので、参照を導入(元々&a + &bには別の意味があるとも言っていた)
ちなみに記述方法の問題が出たとたん、すぐに参照を思いついた訳では
ないそうです。友人に相談したとき、その人がポロっと発した
「リファレンス」と言う言葉で閃いたそうです。
>>8 演算子多重定義のため。
値渡しじゃ効率悪いし&x + &yとか見れたもんじゃない。
それに&x + 1とか多重定義できないし。
12 :
デフォルトの名無しさん:2008/04/06(日) 13:17:37
確かに、
Cの人は「演算子のフルセットを提供しなくちゃいけない」という
脅迫観念に駆られる必要がないので、その辺はうらやましく
思うときがある。
加算関数なんてほとんど
void add(vector *dest, const vector *x, const vector *y)
の1パターンだからな。
方法論がシンプルな分、どうやろうか悩むことがほとんどないし。
ポインタ変数そのものをアドレス変更権付きで渡す際に
「ポインタポインタ」という美しくない方法を取ってたのが
「ポインタの参照」でしっくりきた。から参照はなかなか良いと思う
でも内部的にホントは「参照変数」なんて実体はなくて
便宜上そう見せてるだけなんでしょうね、きっと。
Cは文字列の扱いがうんこ過ぎる
C++はADLをはじめとする名前空間とオーバーロードの関係がわからなすぎる
文字列処理する必要のない環境だって山ほどあるんだ。
んなこと言ったら、OS書くときゃdouble、floatはほとんど使うわんだろ。
>んなこと言ったら、OS書くときゃdouble、floatはほとんど使うわんだろ。
プッ(´,_ゝ`)
GLibがないと生きていけだが、他に誰か同じような人ひる?
>>19 OS Xの座標系がfloatなんだがどうすれば良いかな。
いやでも、アプリケーションの高水準なインタフェースと
ドライバの低水準なインタフェースの差を埋めるような部分はOSの仕事としてあるのでは?
どこまでをOSと言うかだけど、標準GUIコントロールとか描くのとかもOSの仕事だと思ってるから、使いまくりだと思うな。
>>14 ライブラリとアプリでコンパイラが違うとマングリング規則が違って使えないだとか、
下手するとコンパイルオプション違うだけで、動かなかったりだとか。
(2番目はCでもありそうだけど)
かつてはC++でバリバリやってたけど、今はC。
stringとかvectorとか便利だとは思うけど、「C++使いの常識」を踏まえて
コードを書かないと、効率が落ちたりするのが気に入らない。
EffectiveC++やEffectiveSTLを読んで初めてC++を使えてるって感じがやだなぁ。他にもいろいろ本読んだけど、
プログラムでやりたい事がなかなか進まずめちゃくちゃフラストレーションがたまった。
STLを勉強したいのか、プログラムを完成させたいのか、自分でも分からなくなるときがあった。
テンプレート使ったときよりコードは美しくないけど、Cの方が変なところに気をつかわず
コードが書けて、作りたいものがはかどる。
小物のツールこそC++で作ってしまうなぁ。
客先納品物の場合は何かと面倒なのでCで書くこともままあるけど。
設計から自分で仕切れる場合は問答無用でC++だな。
>>26 >かつてはC++でバリバリやってたけど
信憑性に難あり。
つか、C++が使える環境でC++を使わない理由などないんだが。
29 :
1:2008/04/07(月) 13:42:13
>>29 私の場合は、ライブラリはextern "C"で作るかソースごと使うか。
毎回毎回CでList構造書くのはつかれたよパトラッシュ
再利用しようとしてvoid*使うけど、型安全じゃなくなるよ
毎回毎回プロジェクト毎に最適なore_string型の実装を考えて
書くのは(ry
>>32 標準のstringを内包して、必要な機能を付けるだけでいいんでない?
C vs C++スレだけど、
なんだかんだでCもC++もだめな気がする今日この頃
C++が非常に実用的で現実的な言語であることを認めた上で個人的な意見としては、
・ここで言われるC++の利点は他の高級言語なら、より良く実装されてる。
逆に言うと、それらの言語から見て、C++の実装は非常に中途半端に見える。
・Cは(一部の例外を除いて)非常にシンプルで明快なシンタックスである。利便性を
元に実装されたC++の拡張はグロテスクだ。
なので、低レベルの処理はCで、高級な処理はC++以外の言語でというのが理想。
38 :
28:2008/04/08(火) 13:21:51
>>29 C++を使いたくないが為の言い訳にしか聞こえないな。
マングリングだのABIだのが仕様上規定されている言語なんざ
そうは多くない。
>>38同意
だいたい、ライブラリをバイナリで落としてそのまま使える気がしない。
というか、それが問題なく使えることってあんのか?
ビルドに苦労することはよくあるけど、それは何の言語でも同じだろ。っていうか
それは言語とは関係ないし。
面白そうなタイトルに惹かれてきますた
C++から C には・・・もう戻れないに一票
>>3,
>>5 に共感そのもの
>>9 そうかな?必要と感じるなら立ち上げたら?
>>13 ちょっと理解できない。オブジェクト指向では
object a, b, c;
add (&c, &a, &b) の表現ではなく
c = a + b; と記述できる処だよね。
add はそのまま operator + で同じような内容だし後は operator = だけでしょ。operator - がいるなら当然 sub も書くことになるんだから工数は何も変わらない。
>>16 というか領域・空間のチェックはしてない。そこがマニアックたる処だと思う。C は好きです。
overload は実行時に都度確定する部分だから細かく気にする人は精神的によくないかもね。
>>26 ばりばりに C++ してたら C には戻れんと思うが・・・
struct , class メンバー使い出したらそれだけでも C++ から C には戻れない。
>>36 中途半端なスタンスがいい。厳格なオブジェクト指向な実装が好きな人はそれを使えばいい。だけど C をカジってた人ならきっと窮屈に感じると思う。それにオブジェクト指向から手続き型には戻れんと思う。
>>40 オーバーロードの解決はコンパイル時だぞ。
オーバーライドとごっちゃにしていないか?
あと、演算子の件はoperator +=も用意するとか、
2つの型が関わる場合に、
operator +(T1 const&, int const&)と
operator +(int const&, T1 const&)のように
いくつも関数を作らないといけないということを言っているのだと思われる。
>>36 >低レベルの処理はCで、高級な処理はC++以外の言語でというのが理想。
俺もこれに一票。
DTrace とか使ってると C++ のマングリングが鬱陶しいし。
vectorとclassがあるって理由だけでC++使う。
Cに比べればstringがある分、文字列処理もましだし(それでもきついけどw)
>>40 > オブジェクト指向では
> object a, b, c;
> add (&c, &a, &b) の表現ではなく
> c = a + b; と記述できる処だよね。
演算子オーバーロードとオブジェクト指向は何の関係もないと思うが。
>>40はいろいろと微妙に分かってない罠。
C なんてもう組み込みとかよほど制限された環境じゃないと使う気しないわ。
>>41 だけど、それは C でも同じでは?
C なら型が違う毎に add1() add2() とするでしょし operator += が必要なら append() とかを書くことになるのでは?
後、メンバー関数が継承される時 virtual な扱いにいつされるかというところがあるとおもう。operator が別扱いではないですよね。
>>44 そうかな。関係ないのだろうか?
オブジェクトにメッセージを送るという感覚、これまでの add(a, b) ではなく独自の struct あるいは class な物にたとえば c = a + b という記述ができることであって、一例として挙げている演算子再定義にこだわり過ぎてない?
で、指摘の通りきっと微妙に判っていないんだとは思う。厳格なオブジェクト指向は触ったことないし神髄は未知の世界です。
>>46 ところが
>>13も言っているが、Cだとわざわざappendなんて用意しないし、
複数の型がからむときも、41のoperator +のように
右辺と左辺が入れ替わっただけの関数なんて用意しない。
C++だってBoost.Operatorsでその点はばっちり解決できるんだけどな。
>>47Boost.Operatorsってメンバ関数以外もやってくれるんだっけ? だとすごいす。
でも、Boost.Iterators使おうとしたとき、マニュアルとヘッダ読みながら何とか
コンパイルに成功したが、あの小一時間あれば自分でイテレータに必要なもの
全部書けるなとおもた。
あの手の実装補助は相当使いこなさないと、効果ないかも。
話逸れたけど、ここにはCマンセーの人はいないの?
>>48 でも、今から手続き型のスタイルにもどるって時代逆行では?
先輩方が手続き型で痛い目を見て、少しでもミス記述が防げるには?…と考えてきたと思うし・・
>>47 ごめん。どうもよくわからない。必要ない物を用意しないのは同じでは。 append が必要ないなら当然 operator += も必要ない。
そもそも operator += じゃなく C スタイルで append で何も不具合はないわけだし(コード書く人の気持ち一つ)
ところでここで C という人は C++ なメンバー関数であったりそういうのが本当にいらないって事を言ってるのだとしたら・・orz
>>49 そりゃそうなんだけど、現実は
Cのライブラリ:add 1つだけ
C++のライブラリ:operator +に+=、++全て勢揃い
となっていうことがなぜか多い。
(もちろんCでappendの実装が困難というわけではない)
Cの方がいいに決まってる
>>48 一度しか使わないなら大抵の小物ライブラリがそうだよね。
何度も使うから効果を発揮するわけで。
ベクトルクラスを作ったとき、演算子を定義して
c = a + b とできるようにしたけど、
一時オブジェクトの生成がオーバーヘッドになって使えなかった。
add( vector &c, const vector &a, const vector &b ) にしてから全体の計算が
10秒から2.5秒まで落ちた。 正確なデータ、根拠じゃないけど速く感じたのは
事実だった。
オーバーロード自体はきらいじゃないけど、こういうときは無理にする必要は
ないよね。冷静に考えると自作クラスに演算子を用意するのって実は
限られている希ガス。(代入演算子はとか除いて)
ちなみに自分はC++派。上の関数をインラインにするだけでさらに速度アップするし。
あと、add_assign() とかも用意した。
お一人様、「式テンプレート→テンプレートメタプログラミング」コースごあんなーい
インライン関数は C でも大抵のコンパイラが対応してるんじゃないかな。
>>54 RVO が利用できるよう、演算結果を初期化で受けると
オーバーヘッドは減らせる。
あるいは c += a + b; みたいに使うとか。
そしてコンパイルする度にうんざりする…
>>54 それって何かが間違ってる。
add() が + () という名前に変わるだけ。
+ という関数名はそのまま使えないから operator でそうしてる。実際の呼び出しに差違が起こるのは・・何かが可笑しい。と思うが。
間違ってないよ。
+ 演算子は仕様上結果を戻り値で返す事しか出来ないからね。
ええとなんだ。ET使えよこの野郎とか煽ればいいのかな
そして
>>13へ戻る。Cだとこんなに単純で済むのに、と。
ほぼスーパーセットとなってる言語と比べてどうすんだよ
いらないと思ったらその機能を使わなければいいだけ
何でも入れれば良いという思想に慣らされてしまっていれば
そう感じてもおかしくはないね
基本C言語
まあ組み込みなので
C 言語にブロックの先頭以外で変数を宣言できる機能を追加すれば何とか我慢できる。
inline 関数の機能がなくても最適化できるのが理想だが、現実的にそれができるコン
パイラやリンカは少ないので inline を追加してほしい。
C99 は C++ との互換性に問題があるから使いたくない。
gccを機能制限しつつ使えばいいじゃん。
C++でそれだけ使って後はCとして書けばいいんじゃないの
>68
すみません。コンパイラは自分で選べないケースもあるんです。
>69
個人的にはそれを主張しているのですが、お客さんが C++ は絶対ダメって言うんです。
その手がありますね。
顧客によっては MISRA-C などのソース検査を要求しますが。
スコープ内での変数宣言こそ簡潔なプログラムへの助け
C 言語用のライブラリを作るとき公開ヘッダー以外を C ではなく C++ で
実装した場合、ライブラリユーザー側のデメリットって何かありますか?
ライブラリ本体がC++だと、コンパイラ毎に
ライブラリのコンパイルが必要になるんじゃなかったっけ
newや例外など、C++用ライブラリを使う場合は>76の通り。
それらを使わなければ、巧く共存できる。
DLL だとスタティックライブラリで実装すれば外のライブラリの
影響を受けないんじゃないかな。.so の仕組みは少し違うのかな。
何でほとんどのオープンソースの C インタフェースのライブラリは
C++ で実装しないのかな。
Linux OS 自体の実装も C とアセンブラだけかな。
昔々隅々まで C++ で作られた BeOS という OS がありました。
今は Palm が買い取った筈だけど…
C++ だと C や他の言語から呼び出すのが面倒だから止めて欲しい。
C++ で実装していてもインタフェースが C のみなら問題ないんじゃない?
extern "C" がウゼーの
C 用のライブラリのヘッダーファイルにも普通 extern "C" が入っているよ。
名前空間、クラススコープ、オーバーロード。
最低でもこの3つが無いとCに戻る気には慣れんなぁ。
オプソのCのコードやOpenGLのコードなんかを見れば分かるけど
手動名前空間で関数名がクソながかったり、関数名に型名が混在したり
名前が汚すぎる。人が用意したコードならともかく自分のコードであんな命名
規則を守りつづける気がしない。
テンプレートよりデストラクタが欲しい。
参照カウントみたいなことを人間の手でやっていたら絶対どこかで間違うはず。
逆にC++の要らないところって何だろう
例外指定くらいな気がする
>>85 あくまで最低ラインだからねー。
テンプレートなら今でも不自由な環境あるじゃん。
そんなかんきょうでも、俺は
>>84が満たされていればC++を選ぶ。
でも、
>>84すら不自由なら流石に手を引くけどな(例:Embedded C++)
ねーよw
92 :
デフォルトの名無しさん:2009/10/11(日) 11:14:06
迷うような場面ではC
使いこなせるはずなのになんか使いこなせないC++
理由よくわかんないけどCのほうが早く作れる気がする
のろわれてんのか?
dll作ろうとするとC++はちょいめんどい
C++は機能や技法が多すぎて、ケースに合った最適な方法がすぐ思いつかなかったり、
最適な組み合わせが閃かなかったりする。
>>94 自分の場合、結局Cでも使える関数のエクスポートに落ち着いちゃう。
クラスのエクスポートも可能だけど
まあこのあたりは言語の話でいいのか微妙だな
所詮拡張機能だし
Cでも無理やりクラスっぽいことはできるけどメンドイね
ハンドルと関数を公開してC++用のヘッダにラッパー書くのが一番簡単かな
99 :
デフォルトの名無しさん:2011/01/11(火) 19:02:40
100
効率に関しては、その反対が真実な場合(つまり、CよりもC++の方が効率を助長する)があることを私は思い切って主張したい。」以下は平均的Cプログラマによって作成され、人が見る典型的なコードだ。
for(i = 0; i < strlen(line); i++)
{
...
doSomethingWith(line);
...
}
そのようなことをするのは非常に非効率だ。ループの外で(特にdoSomethingWith関数がconstでないポインタを取るならば)
コンパイラはstrlenの最適化すら出来ないだろう(コンパイラは、その関数が文字列を変更するかどうか分からないからである)。
確かに、答えは"そのようなことをするな"だ。しかし、Cは初心者プログラマにそのようなコードをするのを助長している。
それが全く自然な考え方であるのだ。
今や、C++での自然な考え方により、同じことをC++ではどのようにするか比べよう。
for(i = 0; i < line.length(); i++)
{
...
doSomethingWith(line);
...
}
これはCバージョンと非常によく似ているが、ずっと効率的だ(std::string::length()はただメンバー変数の値を返し、
呼ばれる度に文字列の長さをカウントする必要が無いからである)。たとえ文字列がループ本体の中で変更されても
効率的であることに注意せよ。
>>102 > for(i = 0; i < strlen(line); i++)
そもそもこれが自然じゃないだろw
先に筋書きありきで、無理矢理こじつけ様とするからこうなる
>>103 そうか?実際けっこう見たことあるよ。
> 確かに、答えは"そのようなことをするな"だ。しかし、Cは初心者プログラマにそのようなコードをするのを助長している。
> それが全く自然な考え方であるのだ。
>>104 性能が重要な箇所で、loop の判定式の中で関数を使うなんて素人だろ
平均的 C++ が書く C のコードはこんなもんなのかもしれんが、
平均的 C プログラマはそんなコードは書かない
>>102 の論理はどう考えても無理筋
>>105 × 平均的 C++ が書く
○ 平均的 C++ プログラマが書く
失敬した。
>>105 だから、素人の話をしてるんだよ。
> しかし、Cは初心者プログラマにそのようなコードをするのを助長している。
>>107 > 以下は平均的Cプログラマによって作成され、
> 以下は平均的Cプログラマによって作成され、
> 以下は平均的Cプログラマによって作成され、
つか、わざわざプロパティアクセスと関数呼び出しを比較するなんて
>>102 は相当 Linus が嫌いなんだろうなw
普通に考えたら
>>102 は無いわ
>>108 あ、そこに引っかかってるのか。「平均的」っていうのは個人の経験で揺れちゃうんで、
確かにそこがおかしく見えることもあるだろうな。
>>109 の「普通」も同様。
template の魅力。チマチマやると効くからなあ。
>>110 > そこに引っかかってるのか
> 個人の経験で振れちゃうんで
ワラタw
今度は「貴方の勘違いです」作戦ですか?
理屈も糞も無いなw
俺は素直さが美徳の世界に戻るわ
>>112 いや、勘違いだなんて言ったつもりはないよ。
筆者にとっては正しくて、あんたにとっては正しくない。それだけのこと。
テンプレートでソースコードと実装の乖離が激しくなるのは確か。
つまり筆者は素人衆のお山の大将だったわけか
っていうか、ほかにフォローするところはないのかね?
>>102 はいちばん突っ込みやすそうなところを晒し上げしただけだろ。
そうは言っても、そのほかにもCの悪い例としてgetsをあげてたり
(getsがセキュアでないのはCプログラマなら常識で、普通使わないし、使われていない)
仮想しているCプログラマのレベルが低すぎる。
いやいや。「 Linus の主張にはほとんど根拠が無く出鱈目である」という点に反論はないのか、と。
C++ PG : 「見てみてー、C++ が C より優れているケースを(無理矢理)見つけたよー!」
C PG : 「そんな糞コード書くかよw」
醤油うこと
>>118 Linusの主張で唯一根拠が無いのが
「C++は多くの平均以下のプログラマが使っている」
って点だが、それすらも
>>101 のリンク先の反論の
あまりのヘボさによって例示されてしまっている。
計らずも証明されてしまったな
>>121 > Linusの主張で唯一根拠が無いのが
リンク先の記事では「まともな根本を持っているのは唯一つである」とされていて、
それは「STLデータコンテナを使えば、一部の古いC++コンパイラがサポートしていない場合がある」という点
だけみたいなんだけど、他の点には根拠があると言えるの?
C++ PG : 「C++ には C の仕様も入ってるから、俺ら C のエキスパートでもあるんスよ」
C PG : 「お前、普段バイクに乗ってる人間が、自転車でも速く走れると思ってるのか?」
>>123 テンプレート、特にBoostでエラーが発生したときの
デバッグが苦痛なのも(何あのエラーメッセージ?)、
C++で良いとされるプログラミングパラダイムがころころ代わるのも
(昔は継承使うのが良いとか言ってませんでしたっけ?)、
事実だろ?
納得しないの荒行に入ってる人を説得するのは至難の業だと思われ
説得出来た所で何の益も無いし
グローバル変数はローカル変数より色んな場所から
アクセスできて高機能、だからグローバル変数を使おう
とか言ってたら頭オカシイと思うだろ?
それと同様に、C++はCの仕様を全て含んでいるから
Cより悪いはずが無い、って主張は愚かすぎる。
言語仕様だって適切に制限されているべきなんだよ。
Obj-CはCの仕様を全て含んでいるから Cより悪いはずが無いけどな。
LinusはLinusでカーネルやデバドラとかそういうの書く場合の経験で
語ってて、突っ込み入れる外野はもっと緩い作業を想定してるのが
モメてる根本だろ?
>>129 カーネルやデバイスドライバだと C++ を使わない理由が出てくると思ってるなら、
何か C++ について勘違いしている可能性が高い。
件の反論にも同様の指摘がある。
> 彼はまた、C++コーダーは"低レベル問題を理解"出来ないと主張する。 ...
どんな理由でそれらに C++ が適さないと思ってるの?
C++ PG : 「C ってアレっスよね、オブジェクト指向とかする時 GObject ってのを使うんですっけ?」
C PG : 「オブジェクト指向的に書きたい時は素直に Java か ObjC を使うだろ・・・」
>>125 それは事実だが、 C で同等のことをより適切なエラーメッセージを得ながら
できるわけじゃないでしょ?(マクロでやればもっとエラーは不可解になる。)
そもそも Linus はそんなこと主張してないし、反論でもそれを否定するような
主張はしていないし、誰もそんな話はしていない。
133 :
132:2011/02/18(金) 09:48:41
あ、ごめん Linus の主張にはあるのか。
> - infinite amounts of pain when they don't work (and anybody who tells me that STL
> and especially Boost are stable and portable is just so full of BS that it's not even funny)
> - inefficient abstracted programming models where two years down the road
忘れて。
C++ PG : 「あ、C ってテンプレート無いんでしたっけw」
C PG : 「テンプレートで頑張るとエラーメッセージが理解不能になるし、コンパイルが劇的に遅くなるって君が教えてくれたんじゃん・・・」
>> 130 使用するスタックサイズとかにまで
気を使いながらカーネル書いてるCプログラマに、
「デストラクタでRAIIすれば資源管理も楽勝っすよw」
なんてレベルのC++プログラマが話しかけてきたら、
あっち行けって言いたくもなるよ。
>>130 レスポンスタイムにシビアな制限のあるデバイスドライバでSTLコンテナ使う場合とか?
コンテナ自体の速度がどうしても間に合ってない→結局自作→なら最初から自作でいいだろ
みたいな流れで。
>>135 なんで RAII がスタックサイズに関係すると思ってるの?
>>136 標準コンテナの何が速度低下に関係するの?
百歩譲って、コンテナの自作が「どうしても間に合わないとき」に
限定されるんならそれだけでも十分役に立ってるじゃないか。
>>138 じゃあLinusは時代遅れの老害だからアホな事ほざいてるだけなの?
>>102 これは、単に、Cで普通に使われる文字列はヌル文字の番兵で終端を表しているだけで
自分の長さを知らないデータ構造なので、
文字列長を知るにはいちいちO(n)のstrlen()を利用する必要があり
それ自体が非効率な仕組みだ、と言えばよかったのにな
まともなCプログラマならそれを知っているから、ループの中でstrlen()を呼んで
いちいちO(n)をO(n^2)に悪化するようなことはしない
もっともいずれにせよstrlen()は必要で、その時点で既に非効率なわけだが
勿論Cで文字列長を自分で保持する構造を書くことは勿論できるけど
C++でも標準ライブラリを捨てていくらでも自分で書けるわけで
C++の標準ライブラリやboostを攻撃するのなら、Cのgets()やstrlen()が
攻撃されるのも理解しなきゃな
「使わなければいい」というのなら、C++のSTLだって、使わなきゃいいだけなんだ
>>137 そりゃ、オブジェクトをスタックに積んで、
スタックが巻き戻るときに自動的に呼ばれるデストラクタで
資源解放するのがRAIIだからだろ。
それとも資源管理を明示的に書くのをサボるためだけに
スマートポインタを使うのか?スマポだって生ポインタよりは
スタック消費するぞ。
>>141 scoped_ptrはきっかり生ポインタと同じだけしか領域を消費しませんよ
もちろん、多機能なshared_ptrならもっとオーバーヘッドがあるけど
やりたいことが単なるRAIIで、スタックに積むかわりなら
scoped_ptrで十分でしょう
>>142 書き込んだときは、スマポ自体のサイズと、
スマポのデストラクタ -> オブジェクトのデストラクタ
の二段階呼び出しのスタック消費の両方を念頭に置いてたんだ。
でも、少なくとも前者は scoped_ptr があるし、
後者も最適化で消せるみたいだ。
完全にこっちの見識不足だった。
>>139 その言い方はちょっと違うな。老害ってやつじゃない。
C を使ってる分にはすごく優秀なプログラマと見て間違いないはず。
>>101 のリンク先の言葉を借りれば、「Cハッカー症候群」 "C-hacker syndrome" 。
症例はこのスレにたくさん挙がっている。
>>140 >自分の長さを知らないデータ構造なので、
>文字列長を知るにはいちいちO(n)のstrlen()を利用する必要があり
>それ自体が非効率な仕組みだ、と言えばよかったのにな
無知でスマソ。
C++ の文字列も結局は内部でひっそりと文字数をカウントしているんだよね?
それは strlen() を使うのと計算量が大幅に異なる様なデータ構造になってるの?
それは strlen() を使うのと計算量が大幅に異なる様なデータ構造になってるの。
具体的にはどういうの?
_M_length
それじゃ分からん
クラスが
Cのノリで直接バッファ操作したりしないからな
>>152 それって結局内部的に計算してるってことだよね?
小学生みたいだな。
きちんと答えてくれないから、どんどん質問のレベルを下げて行ってます
例えばさ、固定幅のバッファを数珠つなぎにして一つの文字列にしてるから
文字数のカウントが速いんだとか、そういった分かり易いシンプルな説明って無いの?
つーか、本気で誰も答えられなくてワラタw
午後の部を待つか・・・
単に文字列長用のスロットがあるだけなら Pascal の文字列と一緒だよね
>>157 string同士の操作はお互いに文字数が分かってるのでカウントしなおさない。
const char* が含まれる場合は1回だけstrlen相当の処理が使われる。
>>160 どうもありがとう。
文字列のコピーや連結の時にショートカットが出来ると言う事かな。
それだけの事であれば、文字列長のカウントがホットスポットになった場合に、
C で同じ様な実装をするのは雑作無い事だよね。
ある文字列の先頭の 5 文字を除いた文字列を関数に渡したいと言った時に、
C ならポインタを 5 文字分だけずらして渡してあげればいいだけだけど、
C++ の文字列では、文字数情報を記憶しないといけないので、わざわざ
substr() みたいな関数呼び出しにしないといけないんだよね?
こっちのオーバーヘッドの方が無駄じゃないの?
const char*を返すc_str()というメンバがあるから、読み取りのみでいいなら
string.c_str() + 5 とかで渡せる。(ちゃんとnullストップになってる。)
挿入したい場合は挿入用のメンバ関数がある。
自分には良く分からない・知らないものを
単に良く分からないから嫌っているってだけのことが
*非常に*多いのがこのスレを見ていても良く分かるね
よく分かっている道具を使うのは間違いじゃないし正しい態度でもあるが、
よく知らないものを知らないくせにdisるのはバカのやることだな
>>162 その関数が C の文字列を受け取る関数ならその通りだけど、
C++ string を受け取る関数なら、やはり何らかの事前処理が
必要になるよね
>>163 俺はこれが気になったから質問してるだけだよ
>これは、単に、Cで普通に使われる文字列はヌル文字の番兵で終端を表しているだけで
>自分の長さを知らないデータ構造なので、
>文字列長を知るにはいちいちO(n)のstrlen()を利用する必要があり
>それ自体が非効率な仕組みだ、と言えばよかったのにな
C++ の文字列って C の文字列を dis れる程、効率的な物
なのか知りたくなってね
>C の文字列を dis れる程、効率的な物なのか
そんな良い物ではないよw
for内でstrlen使っちゃうような、うっかり八兵衛には効率的なのかもしれないが。
>C++ string を受け取る関数なら、やはり何らかの事前処理が
だから挿入用や上書き用のメンバも何種類もある。
何文字目から始める&終わるか引数で渡せる。
Cのポインタみたいなノリで書きたい場合は、イテレータという物もある。
まぁ、substr()のコストを払ってでも足し算オペレータで連結できる魅力に勝てない人もいるわけで。
要は、適材適所なんだからどの方式も一概に否定したもんじゃないさ。
>>166 ありがとう。やっぱりそうなんですね。
C++ が実行効率に神経を注いでるのは聞いていたので、
何かいい仕組みがあるのかもと期待しちゃいました。
>>168 今していたのは C++ と C の文字列の計算量の話
その何種類もあるメンバも内部的に計算してるわけでしょ
そしたらその分の計算量が発生するでしょ
繰り返しになるから、これ以上は説明しませんので、
お願いします・・・
C++ で C っぽく書けるけど、
C で C++ っぽくは書けないお。
C++ だからって string を使わにゃならんわけじゃなし。
C++のsubstr()がO(n)なのはその通り
ただし、
>>168の言っているように、C++では本当にジェネリックなアルゴリズムとして
記述する場合はSTLのようにテンプレートとiteratorが使われる
この場合は本質的に効率はポインタと同等でありながら、データ構造の内部表現を
問わない
charのストリーム、charのリスト、charの配列、stringを全く同じテンプレート関数に
適用できるということだ
Cならアダプタか、別々の実装を書く必要があるだろうな
また、特にstringで受ける必要が無い関数なら、C++であってもconst char *
もよく使われるよ
>>171 文字数のみを考えるなら、こんな感じの構造体と
それを操作する関数を用意してあげれば良いだけ
typedef struct { int len; char str[] } string;
>>170 ポインタ+位置差分の加算等のことを言ってるのなら、
イテレータでポインタライクに操作できるんだって。
先頭の位置は変数(ポインタ)で保持される。
>>173 CではC++と違ってカプセル化によってデータ構造の整合性が常に保たれることを
保障することが難しい
Cでカプセル化したければ、opaqueポインタ経由でユーザにアクセスさせるように
してデータ構造を隠すしかないが、stringクラス的な用途ではそうするのは非効率だ
この辺も、Cでパスカル文字列が採用されなかった理由のひとつだろうと思う
ただの創造だが
>>173 うんそういうこと。でもそれを全ての文字列操作関数に対応させたり、
さらには非標準の文字列操作ライブラリにも広く対応させたり
自分の力だけでやるのは大変でしょ?
そういう標準化、規格化として意味があるわけです。
>>178 だから、関数が「stringで受けるように作ってあれば」
部分文字列を渡したければsubstrを使う必要があり、それがO(n)なのはその通り
だが、C++で関数をそう作る必要はどこにもない
iteratorで受けてもポインタで受けてもいい
要求に応じて適した選択が選べるということ
>>174 C の方が良いと主張したいわけじゃないです。
C++ の文字列の方が優れているという人がいたので、
それは誤解じゃないの? と聞いてみた次第です。。。
>>179 自分で作る関数に付いては、もちろんその場で一番効率が良い実装をするのが
当たり前だと思います
>>180 標準の文字列型として、所有権・寿命の管理を気にしなくても使えるようにするのが主目的だから、
効率だけ見てどっちが優れているかを考えるのは不毛なこと。
その中でも、文字列を変更しない間に繰り返し長さを得る場合には std::string のほうが効率的な
「こともある」と挙げているのが元の記事。はじめから、すべての場合で効率的であると主張して
いたわけじゃない。
まあぶっちゃけ「平均的な」プログラマが、それぞれの言語で「平均的な」コードを
書けば大抵Cのほうが速いだろうけどな
重要な違いが出るかどうかはともかく
ただまあ、明らかにC++のが速いことが分かってるものもいくつかある
qsort()に対するstd::sort()とか
配列には先頭も終端もないし長さを調べる方法もない
と思ったほうが楽なこともある
ないよりはあるほうがいい場合もあるが、すべての場合ではない
それは配列ではなくてポインタだろう
配列ではないが配列のインタフェースかもしれない
速度が必要な内部処理のようなところではcnost char *で、
設定ファイルを読み書きするようなところではstd::stringで、
必要なら外部の正規表現ライブラリでもなんでも使って、
こういう風に選択できるところがC++のいいところなんだってば。
ちょっとしたテキストビューワが必要なときに、テキストエディタで要求されるような
行単位のリスト構造を一一作らないときがすまないようなロートルCプログラマには
理解し難いことなのかもしれないけれど。
そういう時は ObjC を使う
GC もあるし GUI も完備
>>187 Cで書かなきゃならん部分だけCで書いて、
それ意外の部分はshなりPerlなりPythonなりで
書くのがCプログラマなんで、その指摘は的外れかと。
C++プログラマはC++の中だけで機能を選択するが、
Cプログラマは言語の枠を超えて機能を選ぶ。
>>189 なんで C++ プログラマは「shなりPerlなりPythonなり」を使わないと思ってるの?
C++ だって Perl なり Python なりでそうすることはできるけど、
C で 187 みたいなことできるの?
192 :
デフォルトの名無しさん:2011/02/19(土) 20:11:15.88
まぁC++の方が色々できるし便利だけど、道路が多い街が住み安いとは限らないよな。
慣れるまで大変で。
言語の枠というか、型の枠をぶち壊す選択をしやすいのはどっちかというとCだな
要はターミネーターはT-800かT-1000かって話してんの?
日曜の早朝から無駄な煽りご苦労様です~
>>190 C++でCに追加された構文的拡張は、
それらの言語ではより良く(より簡潔に、またはより一貫性のある形で)
実装されているので、それらの言語も使える場合
C++を使う理由は実行速度くらいしかない
(Cと併用できるならそれすら無い)
使用言語が増えれば増えるほどコンパイラの新Ver追ったりライブラリ追ったり
手間は増えると思うんだ。
一つの言語だけを追い掛けてるプログラマも珍しいでしょ
2、3個の言語を組み合わせる程度なら追加の手間はないと思うよ
各コンパイラ、version毎のtemplateの対応状況を
把握する手間に比べれば、どってことないよな。
2、3個がっやっぱ限度なんだな
5,6個も組み合わせる必要ないからな。
Linusの場合C+ASMが確定なので、あと1枠か。
Linusは古参ハッカーなんで、三つ目はPerlじゃないかな。
>>198 え?
>189 にある「Cで書かなきゃならん部分」ってのも実行速度が欲しいところぐらいじゃないの?
他になんかある?あったとしてもC++では書けない、なんてことあるの?
C++ PG : 「C ってアレでしょ、まだバッファオーバーフローする関数とか使ってるんでしょ」
C PG : 「gets() の事ならもうずっと誰も使っていないし、2012 年に予定されている次の仕様で削除される予定だぞ」
>>206 このスレッドを読んできて、それでも「書けるか書けないか」
が争点だと思えるなら理解力が無さすぎる。
CのほぼスーパーセットのC++で書けないなんてことが
あるわけないだろ。
問題点になっているのは、いわば「読みやすさ」。
>>208 なんで C++ で書くと読みやすさが損なわれると思ってるの?
「読みやすさ」の定義は
ロートルの人が読めるかどうかです
そりゃ読めない文字とか知らない言い回しとか使われたら、普通は読みにくいとういうか読めないわな。
>>209 その時々で流行のパラダイム(OOPとか)をサポートする
構文糖が節操無く追加された結果、言語のデザインに一貫性が無い。
一貫性が無いから、構文糖がどのような暗黙的コードを生成するかは
単純に暗記するしかなく、さらに複数の異なる暗黙的コードの相互作用が
様々な罠を張ってて、簡単に自分の足を打ち抜けるようになってる。
ただ罠を避けるためだけの本(Effective C++とか)が必読本の時点で
何かおかしいと感じるべき。
こんな言語が読みやすいというなら、読みやすさは
プログラミング言語の評価基準にならないよ。
C だって自分の首を締める方法は残されてる。しかも不様に。
まあ、確かに C++ は罠が多いけど
ヤバい所は使わずに美味しいところだけ使うこともできる。
C は、できないよね。
無様さでは C++ には勝てないよなあ
純粋仮想関数が = 0 って糞ワラタw
さらに言えば、Cはコードの一部分を読むだけで
そのコードがどう実行されるかが比較的判りやすい言語だ。
もちろんマクロやグローバル変数等を使ってそうじゃなくすることも可能だけど、
そういうコードは「悪いコード」だとする文化がある。
一方、C++はコードをより広いコンテクストに依存させる構文糖
を積極的に追加する上に、どういうコードが良いコードか
(例えば、ある構文糖をどういう場合に「使わない」かについて)
の文化すら存在しないので、あるコードが何をしているか把握するのに
ずっと多くのコードを読まなきゃいけない。
だからC++は読み難いんだよ。
コンパイルも糞遅いしな
>>212 Cだって正しく使おうと思ったら暗記しないといけないことは山ほどある。
未定義動作とか副作用完了点とか。 C FAQ にいろいろ載ってるよね。
> 複数の異なる暗黙的コードの相互作用が様々な罠を張ってて
これは、なんのことだろう?ひとつでも例を挙げてみてもらえないか?
>>215 > もちろんマクロやグローバル変数等を使ってそうじゃなくすることも可能だけど、
> そういうコードは「悪いコード」だとする文化がある。
なんで C++ だとそんなのが受け入れられると思ってるの?
何でなんでって、質問ばっかだなw
議題について根拠も挙げずに断じるような書き込みをすればそうなるだろ。
相手が嫌になって折れるまで質問を続ける気だろうなあ
>>217 例えば、コンストラクタの中から例外を出すと
デストラクタが呼ばれないから、
常にデストラクタが呼ばれる、という前提でプログラムを書くと
リークしちゃう、とか。
じゃあコンストラクタでは例外送出しなきゃいいんじゃね?と思うと
コピーコンストラクタでのエラーは例外じゃなきゃ拾えないし、とか
どんだけ落とし穴掘ってれば気が済むんだよ。
C プログラマは普通で
C++ プログラマは経験の浅いやつって
前提があるみたいだな
相互作用の原因は三つある
継承と例外とコンストラクタだ
>>223 C にしろ C++ にしろ、言語のダメな所が認められないプログラマはまずいよな
それは当然だな
それの説明に妙な前提があるのがおかしいんだよ
>>226 前に挙がっていた例では、C++ を支持している人は C については素人っぽかったよ
>>224 × 相互作用の原因は三つある
○ 俺の良く知らない機能が三つある
把握したところで煩雑な処理が解消されるわけじゃないなら言語の問題だわな。
どっちの言語がどうという訳ではないが。
>>217 Cの副作用完了点について知らないなら、
C++で&&とかの演算子オーバーロードが
何故禁じ手か絶対理解できないな。
しかもショートサーキットの概念は特定の言語に
依存しない一般的なものだけど、&&とかがオーバーロードで
副作用の仕方が変わるのは"たまたま"演算子オーバーロードが
関数に変換されるというC++固有の性質だから。
つーか、流石にその程度なら皆正しく使えてるだろ。
未定義動作、特に整数オーバーフローとかCにも難しい罠が
あるのは否定しない。
>>229 単純な原因から複雑な結果が生じているのだから
原因を良く知らないから悪いとか、原因を良く知れば解決するという問題ではない。
例えばswitchでbreakが書かれていない場合
通常書くものが書かれていない場合はコメントを書く。
そういうパターンを整理すれば良いような気がする。
C++には、何も書かなくても自動的に処理する機能が多いが
その機能を使わないから何も書かなかったのか、
使うから何も書かなかったのか分からない。
>>234 > C++には、何も書かなくても自動的に処理する機能が多いが
具体的に。
>ヤバい所は使わずに美味しいところだけ使うこともできる。
フグかよと
>>233 例えば、仮想関数もデフォルト引数も、共にどうってことない
判りやすい概念だが、C++で両方同時に使うと
仮想関数自体は動的型で呼び出し先が決まるのに、
デフォルト引数は静的型で解決される、という
悪意を疑いたくなる罠が存在する。
これも個々は単純だが、結果が複雑な例だな。
>>237 うーん。個人的にはあたりまえに思うんだけど、慣れちゃってるからなんだろうなー。
もっと酷い罠があるからなあ。
>>235 デフォルトコピーコンストラクタとデストラクタのコンボとか。
あまりにも有名なトラップなんで、嵌るやつもいないかもしれんが。
コンストラクタといえば、explicitではない型変換ができるのもおかしい
そもそも継承のおかげでアップキャストは当たり前で
例外を使えば型を変更しなくてもエラーに関する仕様を変更できる
型とは一体なんだったのか
>>241 > 例外を使えば型を変更しなくてもエラーに関する仕様を変更できる
これどういうこと?
例外云々は知らんが、explicit無し一引数コンストラクタの邪悪さは異常。
デフォルトがユーザ定義型で暗黙的型変換可能って、誰得だよ。
このスレ読んでるとC++使いの俺でも
C++使うのやめようかと思うから困る
>>244 もうC++使ってるんなら手遅れでは
罠が多すぎて習得するのが大変すぎるという話題だからな
>>245 C++0xの右辺値参照が難しすぎて、
俺には理解できる気がしないのだよ。
C++から足を洗ういい機会な気がしてな……
ベター C として使うのが一番だよ。
(うっかり基底クラスの配列に継承クラスを入れてしまいながら)
C++使うなら最低STLは使いたいが、
そうなるとクラスと例外とテンプレートは使うしなー。
実際、C++の機能で取り除けるものが思い浮かばん。
>>245 "Modern move semantics"とかそんな感じの本が
多分出版されるから、大丈夫だよ!
真面目な話、better C としてC++を使うっていうのが
一番メリットが無いと思うわ。
Cと比べて特に生産的というわけでもなく、
C++のグロ文法とABI不在の問題点は引き継ぐとか。
どこがbetterなのかと。
STL便利じゃん。
C++ PG A : 「C++ は better C として使うと便利じゃん」
C++ PG B : 「STL 便利じゃん」
C++ PG C : 「クラス便利じゃん」
C++ PG D : 「テンプレート便利じゃん」
C++ PG E : 「例外便利じゃん」
C++ PG F : 「名前空間便利じゃん」
C PG : 「それもう "better" C じゃなくて C++ じゃん・・・」
D&E読んで信者になれば救われるお
C++ 信者 A : 「私は C++ の全てを理解した本物のプログラマだ!」
C++ 信者 B : 「私は C++ の全てを理解した本物のプログラマだ!」
C++ 信者 C : 「二人のうち少なくとも一人は嘘を付いているな・・・
(C++ の全てを理解出来るのはスッポスッポ先生だけ!)」
コーディングの快感度が大事。
better C ならC99でおk。
C++イラン。
来年には C1x も出るしね
Cの方がマシと言ってるやつらも、それでやるしかないからしぶしぶ使ってるだけだよな。
そうやって無理矢理仲間に引きずり込もうとするなよw
>>258 C++が酷い言語であることは実例付きで
散々述べられてるけど、Cはそうじゃないだろ?
一緒にされては困る。
>>261 bool 無いとか酷い。仮想関数無いとか酷い。名前空間無いとか酷い。
デストラクタ無いとか酷い。テンプレート無いとか酷い。例外無いとか酷い。
そんなものが「C言語のような低レベル言語」に必要だと?
まったく笑えるほど愚かだな。
結局、変態構文好きはC++
そうじゃない場合はC
を使えばOKってことかな
今更 C は苦行でしかないような。
昔から C++ は苦行でしかないような。
C++ は苦行だと感じるけど
C は苦行だと感じないのが不思議
このスレのC++信者は、C++をdisられて
最初はロートルだのなんだのレッテル張って
抵抗していたが、次々と論破されちゃって
涙目って印象だね。
このスレで議論するまでもなく雌雄は決定しているからな
世間に抗ってもあんまり意味は無いよね
JavaだのLLだのの言語処理系の発展が著しい昨今、
それらの言語を実装/拡張するための
「低級言語としての」Cの重要性は全然下がってない。
alternativeが存在しないからな。
一方、C++のCへ追加した機能については、代替手段がいくらでも存在する。
例えばLLならどれを使ってもC++よりは上手くやれる。
つまり「C + 他言語」でC++の代わりは十分勤まる。
それどころか、C++はABI不在、マングリングが腐ってる、
などの理由でCの「低級言語としての」利点を改悪してる。
文法だって罠だらけで腐ってる。
ゆえに他言語と組み合わせて使うなら、C++はCよりも劣る。
さて、ロートルというのは、たぶん新しい言語を覚えたくない人間、
という程度のニュアンスだと思われるが、
果たして本当に新しいものを覚えたくないのはどちらかね?
>>272 > 「低級言語としての」Cの重要性は全然下がってない。
> alternativeが存在しないからな。
低級言語としての C++ は良い alternative
> ゆえに他言語と組み合わせて使うなら、C++はCよりも劣る。
extern "C" すればいっしょですう。
>>272 > 一方、C++のCへ追加した機能については、代替手段がいくらでも存在する。
そりゃそうだが、正直めんどい。
このくらいがめんどくさいと言ってよく名前空間無しでやっていられるものだ
クソ長い関数名を書かなくていいだけでもC++使う意味はあるわな
>>272 ABI界面でextern "C"すりゃいいだけなのに何を言ってるんだか俺にはわからねー
C++使いは他の言語使わないみたいな言い草だけど
boost.pythonとか知らないの?
今流行のV8だの、その上で動くnode.jsだの勿論C++で書かれてるし……
現実的には複数言語を使う場合、インタフェース部分のグルーを書く必要があったり
デバッグやリファクタリングが面倒になったりと面倒もあるから
C++一個で済むならそのほうが楽なこともあるよ
ケースバイケースってやつだね
C+他の言語が普通なら、C++も他の言語の一つとして扱えば良いだけだと思うんだが、
なんでC使いの人は執拗にC++を叩くんでしょうか?それとも俺が知らないだけで、
C++以外の他の言語も攻撃してるんでしょうか?
perl は糞
だれも「文法が罠だらけでクソ」に
反論できてなくてワロスw
>>280 そりゃWindowsとMS-DOSどっちを選ぶかみたいなもんだ
WindowsはMS-DOSにくらべりゃ複雑な糞の山だが
それでもみなWindowsを使ってるんだよ
その例えは正しくないよ。
シンプルなカーネル(C言語)とユーザランド(他言語)ってOSと
何でもカーネルにぶち込む(C++)OSって感じ。
一時期は後者が流行ってたけど(速度的な問題で)
やっぱり保守しやすいのは前者で、最近はそっちに流れてる感じ。
C++は糞の山だけど、関数に長い名前付けたくないから使いますよっと
C PG : 「最近 C++ の影が薄いよなあ・・・」
C PG : 「C++ はスマホの主要開発言語に成れなかったからなあ・・・」
C PG : 「サーバサイドは Java に完敗だし・・・」
C PG : 「ウェブアプリは JavaScript の独壇場だし・・・」
C PG : 「デスクトップアプリは C# や Objective-C の時代だし・・・」
C PG : 「そもそもクライアントアプリはウェブアプリ化が進んで行くだろうし・・・」
C PG : 「Kernel プログラミングも殆どが C と ASM だし・・・」
C PG : 「その内、Pascal みたいになって行くのかな・・・」
C++ PG : 「C++ 0x が完成した暁にはッ!」
C PG : 「(うわ、居たのか)200x 年代は終わっちゃったよ?」
C 使いの人って、どんなコード書いてるの?
C のコードが見たかったら、ネットに沢山あるよ
C++はウンコだが、Cも鼻糞だと思うんだ。
だから他人を巻き込もうとするなってw
>>290 > 本当に信頼性のあるコードを書く方法は、人の典型的な弱さを考慮に入れるシンプルな
> ツールを使うことであって、副作用のあることや、プログラマの無謬性を前提とする漏れのある
> 抽象化を隠している複雑なツールを使うことではない。
こんなの真面目に考えたら C の最適化コンパイラなんて使えないじゃないんじゃないか?
最近は知らないけど、昔はリリースする時は最適化オプションを付けないというのはあったね。
普通は各最適化レベルでコードにどんな変更がされるかを把握した上でコンパイラを使うから、
複雑なツールの内には入らないんじゃないの。
>>293 セマンティクスをシンタックス(型システム等)に写像する行為は
完全には上手くいかない(漏れのある抽象化の例)し、
そのリンク先の主張にはとても同意できない。
>>295 そんなんで正当化できるなら「C++ プログラマはデストラクタ呼び出しや例外によるコードパスを
把握した上で C++ を使うから複雑なツールの内には入らない」って言えるってことにならない?
>>297 デストラクタや例外をコンパイラオプションひとつで
付けたり外したりして問題が起こらないというなら、
その主張を認めよう。
>>298 なんで付けたり外したりできることが関係してくるの?
最適化オプションをつけずにリリースって、どんだけおめでたいんだろ
>>299 お前のような信じられないほどの低能には
決して理解できないよ
裸の王様はじまったな。
Cはポータブルアセンブラとして、ハードウェアの抽象化を実現している。
すくなくとも、Cの規格の範囲内のことをしている限り、
どんな最適化オプションを付けてもCコンパイラはvalidな
コードを生成する(はず)。
しかし、Cの提供する抽象化にも漏れはあって、
OSカーネルなどのハードウェアに近いプログラムを書くときは、
規格の範囲外のことをする必要が出てくる。
そういうとき、確かに複雑な最適化は思わぬ結果をもたらすことがある
(漏れのある抽象化の例)。
そういうとき、大事なのは漏れのある抽象化にどう対処するか、ということ。
Cコンパイラの場合、単純に最適化レベルを下げる(非常に低コスト)ことで
実現できる。
このように、抽象化が漏れたときに簡単に対処できるかどうかは非常に重要で、
例えば簡単にオンオフできるというのは良いデザインだ。
>>303 ありがとう。
で、 C++ 使って特定の機能が「漏れのある抽象化」など問題を起こすようなら使わなけりゃ
いいわけですよ。 extern "C" で C のコードと混ぜてもいいしアセンブリのコードと混ぜてもいい。
これができるんなら C++ を目の敵にする理由は無いと思うんだけどね。
え?簡単じゃない?
はじめから C で全部書くのに比べたらずっと簡単でしょ。
>>304 C++のどの機能は使ってOKで、どの機能は駄目か、という点について
共通となる文化がない。
例えば、俺が自分でC++を使うときに従うルールは、
多分304のそれとは異なっていて、そのため304が俺のコードを読むときは
例えばオペレータオーバーロードを常に疑わなきゃならないし、
任意の関数から例外が飛んでくる可能性を考慮しなければならない。
俺の従うルールなんて判らないんだから。
これは正直しんどいと思うんだが、どうよ。
俺自身は、使い捨てだがLLより速く走る必要のあるコードを
C++で書くことは良くあって、そういう場合はCより楽なのは確か。
でも、この用途はニッチすぎるだろ。
306 :
304:2011/03/02(水) 13:20:57.48
>>305 > これは正直しんどいと思うんだが、どうよ。
C++ ではオペレーターオーバーロードがあって、関数からは例外が飛んでくる。
特に説明の無い限り演算子は組み込み型の定義と類似のものだと読むし、
例外安全を疑うなら変数定義やクラス定義のほうを見て RAII が徹底されているか
確認する。
そういう文化だと認識してるからどうってことない。
> でも、この用途はニッチすぎるだろ。
組み込み機器でLL(?)の類を走らせるのは面倒あるいは不可能。
C++ が最適だよ。
>>306 おいおい、それじゃJoelの言ってるような
副作用の強いC++の機能を使うってことじゃん。
その場合、コードの一部分だけ見ても動作が判らないだろ?
そりゃ読み難いし、「間違ったコードが間違って見える」にも反するよ。
言語を混ぜてもいいのか
RAIIを徹底しなければならないのか
それが問題だ
>>307 > その場合、コードの一部分だけ見ても動作が判らないだろ?
> そりゃ読み難いし、「間違ったコードが間違って見える」にも反するよ。
あなたにとってはそうかもしれませんが、僕にとってはそうではないのです。
C のコードだって、どんな言語で書かれたコードだって、そういうのは無くならないでしょ。
読みやすく、間違ったコードが間違って見えるように書くのは、言語じゃなくてプログラマの
責任によるところのほうが大きいんだよ。
ただ C++ は理不尽な罠が多いってだけだなw
まあ現実的には、ある程度ルールというか空気みたいなものはあるしなあ。
それは会社ごとだったり、開発の規模や種類だったり、
グーグルのコーディングスタイルガイドだったり。
>>306 現場はコンパイラはC++でも
ソースはまんまCのとこばっかじゃん。
なのに「組み込みはC++が最適(キリ」とかwww
でも C++ の安くてうまいとこは使えるじゃん。
>>309 C++で間違ったコードが間違って見えるように書く方法は、
Cの機能だけを使って書くということで、
(なにせ、C++の構文ときたら、実際にやっていることを隠蔽するばかりだからね)
さらにCコンパイラを使うことでC++の忌まわしい機能が
使われていないことをチェックすることができる。
Linusがどっかのメーリングリストで似たようなことを書いてたけど、
なるほど納得だね。
> (なにせ、C++の構文ときたら、実際にやっていることを隠蔽するばかりだからね)
そりゃそうだ。だって隠蔽するためにあるんだから。
間違ったコードすら埋もれてしまうのも必要悪だと思って、
自分はC++を使っている。
>>311 「現場」といって自分のまわりの状況を紹介してくれるのはいいのですが、
それがどこでも同じだと言える根拠は無いですよね?
>>313 > C++で間違ったコードが間違って見えるように書く方法は、
> Cの機能だけを使って書くということで、
なんで他に方法が無いと思ってるの?
C++以外の言語ではどうなるの?
> Linusがどっかのメーリングリストで似たようなことを書いてたけど、
>>99-101
Kernel PG : 「以上、Kernel 開発には C++ は相応しくないという知見が得られた」
C++ PG : 「いやいや。でもそれはお前の個人的な感想、もっと言えば妄想かもしれない
という可能性は完全には排除出来てないんでしょう?」
Kernel PG : 「(また悪魔の証明か)なら、あんたが C++ で書いたら良いんじゃないの、
Linux に匹敵する Kernel をさ。」
Darwin とか C++ 使ってるけど
>>314 清濁合わせ飲む感じでC++を選択するなら、それはそれで良いんじゃね?
「C++が使える環境でC++を使わない理由などない」とか言っちゃうアホに
反論したくなるだけで、勝手に使う分には好きにすればいいさ。
俺にとってのC++は、書くのはCより楽な場合があるけど、
読むのはCより常に面倒であり、かつ
プログラムは読む時間の方が書く時間よりずっと多いので
可能なら選択したくない言語だけど。
>>316 > なんで他に方法が無いと思ってるの?
ある抽象化を実現する(実際にやっていることを隠蔽する)とき、
(1)抽象化が漏れるシチュエーションを減らす
(2)漏れたときの対処が容易
という二点を満たすのが良いデザインだ。
デザインする、という行為を放棄しているC++は、
当然ながら両方とも満たしていない。
なので、C++を使うときは、Cの機能だけ使うほうがマシなのさ。
>>317 悪魔の証明ってのは言い得て妙だな
バグの存在が客観的に証明されるまではテストもデバッグもしない
自分でバグを探すのは自殺点であり得点にならない思ってる
そういう性格の人もいるんだろうな
>>317 悪魔の証明なんて要らないだろ。言語の特性から結果が導き出せることを示せば良いんだよ。
それをしないで決め付けだけを主張するから突っ込まれる。
>>320 > デザインする、という行為を放棄しているC++は、
こういうのが「決め付け」な。
何が「当然ながら」だよ。わらかすな。
で、 C++ 以外の言語はどうなの?
C++ 以上に裏でいろいろやってくれるけど、全部悪い言語なの?
>>323 裏でいろいろやってる内容をCで表現できれば良い
C++の舞台裏はCで表現できないというか実装依存とされあえて表現していない
>>324 どういうことなの?
他の言語も裏でやることは全部実装依存だろ。
たとえばPythonの例外処理機構とC++の例外処理機構とで、
「Cで表現」できるかどうかが違うの?
>>323 C++以外の言語、といっても色々あるだろうが、
C++ほど抽象化が漏れている言語はそうそう無いだろ。
例えば
>>237 の罠なんて、C++が歴史的にCの拡張として実装された、
という文脈をみなければ到底理解できん抽象化の仕方だ。
つまりコンパイラの実装とか、過去の互換性とか、そういう背景を
理解しなければいけないという点で「抽象化が漏れている」。
しかも、それに対する対処方法は「両方同時に使用しない」しかなく、
本当に同時に使用されてないかは対応するコードをチェックしてまわるしかない。
なので「漏れたときの対処が容易」でもない。
で、C++以外の言語だが、少なくとも
>>320 の(1)については
C++よりマシだ。C++のような理不尽な罠が少ないからな。
>>325 仕様と実装が分離している言語は嫌われるということ。
その理由の一つは、抽象化が漏れた時に実装が隠蔽されていると困るから。
あと、スクリプト系の言語においては、例外はそんなに悪くない場合もある。
例外は「間違ったコードが間違って見えるようにする」の規則には反するが、
ちょっとした書き捨てスクリプトなんかは
「逆に考えるんだ。間違ってもいいと考えるんだ」て感じで
適当に書いてもいい場合があるからな。
そういう意味では、C++でも使い捨てスクリプトなら良いんじゃね?
LLと比べて生産性で勝てるかは疑問だが。
ひょっとして使い捨てスクリプト的なプログラムしか書いてない?
>>326 なるほど。それは正しい主張だと思うよ。
ただ、Cとの互換性も欲しいし「パフォーマンスを損なわずに実装すればそうなるわな」と
思っちゃう自分にとっては、そこらへんは飲めちゃう話なんだよね。
C++に実装された機能と同等のことをCでするために(既存あるいは自前の)ライブラリ郡を
使うのと比べたら、「抽象化の漏れ」についてたいした違いは無いだろう、と。
>>329 どう読めばそう取れるんだ?
それに、俺がどんなプログラムを書いてるか解らなくても、
同じような主張をしてるLinusやJoelが
書き捨てスクリプトだけ書いてるわけないくらい解るだろ?
まったくもってアホすぎる。なんて低能なレッテル張りだ。
>>330 抽象化が漏れたときのダメージは、それが(暗黙的な何かを伴うために)
発見しにくいという意味において、はなから抽象化していないよりも深刻だよ。
だからC++と同等のことを(C++のような抽象化を提供しない)Cでしても違いが無い、とは思わん。
ただし、自分が知能に本当に自信があるなら、C++を選んでもいいと思う。
例えば von Neumann が目の前に現れて「C++なんて楽勝www」とか言ったら
「どうぞどうぞ」って言っちゃうよ。
>>334 確かに俺はLinusでもJoelでもない。
ここの書き込みに彼らが関係していないのは確実だろう。
しかし、彼らと似たような主張をしており、
そしてそれ以外の情報が与えられていない状況で、
「使い捨てスクリプトだけ書いている」と推論する妥当な理由が存在するのか?
相手を貶めるレッテル張り以外の何物でもないだろ。
CPGはC++のクソさだけを上げてるが、Cのクソさは気にならないのかね?
寂しいのは分かるが、こっちを巻き込もうとするなってw
>>318 I/O Kit で例外やテンプレート禁止の C++ のサブセットを使ってるだけでしょ
一緒くたにして巻き込みたい気持ちは分かるけど、阿鼻叫喚度では
C++さんにはとてもとても敵いませんわ。頑張ってもムリポ。
隠蔽の多いアセンブラやリンカは捨ててバイナリを直接入力したほうが安全
>>339 一番下のだけ見たけど、そんなのに引っ掛かる様な奴は
どんだけ安全策が施されていたらまともなコードを
書ける様になるんだよw
というかその結論はマジで書いてるの?
>>343 逆に聞きたいけどお前の安全の基準はなんなんだよw
Cが絶対的な安全基準なのか?
>>345 質問に質問をw
まずは
>>339 の一番下のリンクを読んでくれ。
話はそれからでも遅くないさ。
しかもよく読んだら
>>339 の最後の奴は C の罠じゃなくて C++ の罠じゃん・・・
CPP を知らない C++ プログラマにとってはその結論は正しいんだろうね。
それを書いた人だって C で #define を使うなとは言わないでしょ。
なんで一番下しかよまないの?
>>347 そのページだとC++と書いてるが、#defineの危険性や展開時のクセはCでも変わらないだろ。
Cでも複雑にdefineが絡み合ってたら、C++なみにクソなコードになるって。
>>349 きちんと読んであげないと書いた人が可哀相だぞ。
C++並みのコードを書くには何百個 #define すれば良いのやら見当もつかないわ・・・
自分は質問するばかりで、答えてもらったのに返事も出来ない奴は
生え際が消滅する呪いが掛かるってばっちゃが言ってた。
一番下のだけに関してでも、
・マクロであることを意識して展開時にどうなるかを考えなければならない(Cのその他の構文から考えると例外的)
・エラー時に分かりにくい
どちらもC++のテンプレートを叩くときの常套句と重なる気がするんだが。
>>353 言語の中での位置付けを無視すればどんな拡大解釈だって可能さ。
君だって本当に CPP とテンプレートの問題が同レベルだとは思ってないんだろう?
CPP の用途はシンプルな置換が殆どなんだから、テンプレートと一緒にするのは
ちょっと理解出来ない。
>>354 確かに拡大ぎみだとは思うが、知らなければ落とし穴になりうる物なのは確かだと思うんだろ?
>>355 拡大気味なんじゃなくて無理筋を攻めてる感じがするね。
>>353 CでできることをするときにはC++でやった方が罠が小さいのは同意するよね。
"C++よりは"という枕詞無しで、Cは安全とか言っちゃうPGはセンスを疑う。
結婚はしたくないタイプ。
誰が何で同意するのか書かないと話にならんわ・・・
Cプログラマ的にはC++と比較してどうこういう気持ちは無いよなあ
何か色々と残念だなあと思う事はあるけど
結局コードがなきゃね
もう一度書かせてくれ。
Linusの主張(
>>99)で唯一根拠が無いのが
「C++は多くの平均以下のプログラマが使っている」
って点だが、それすらも
>>339 の反論の
あまりのヘボさによって例示されてしまっている。
とりあえず362と設計はしたくない
口喧嘩に勝つことがそんなに重要かねえ
365 :
339:2011/03/03(木) 23:30:28.78
>>362 自分はプログラマでは無い。
だから適切なコードの例示すことはできないが、
339で言いたかったのは、そういう本なり記事なりがあるくらい
なんだから、Cにもクソ差は充分盛り込まれてるんだろうということ。
違うというなら俺よりも著者にお便りでも書いてください。
このスレでは、コード書けない人がプログラミング言語をクソ呼ばわりしちゃう訳か
コードは書けるよ。
良い例が書けないだけで。
そんなんじゃ云い訳にもならんだろ
サンプルコードも書けないし、文献も見つけて来れない奴が、
何であれプログラミング言語をクソ呼ばわり出来るんだ?
失敬
何であれ → 何で
>>365 そういうロジックでいうなら、
紹介してくれたCの本が絶版になってる一方、
Effective C++が必読本&ベストセラーとなってる点で
察してくださいよ。
なんだなんだこのスレは
>>365 そういうロジックでいうなら、
紹介してくれたCの本が絶版になってる一方、
Effective C++が必読本&ベストセラーとなってる点で
察してくださいよ。
373 :
372:2011/03/03(木) 23:44:07.54
連投失礼
とりあえずC0xはクソ
C1xだった
>>339 の内訳
・絶版の書籍
・ウィキのメモ書き
・大半が C 以外の言語にも当て嵌まるコーディング上で避けるべき点のリスト
・C++ の罠
これで彼は何を主張したかったんだろうか・・・
>>372 そりゃ新規でCだけ覚えるヤツがいないからじゃねーの?
Cのみ扱った本って339のに限らず殆ど絶版じゃねーの?
>>377 CのバイブルK&Rを無視すんな。
Cの本=絶版じゃねーよ。
>>378 は、単にプログラム関連の書籍を見た事が無いだけじゃねーの?
C++の罠じゃなくてCの罠に見えるが
>>382 MAXマクロが引数を二回評価しうるて話やろ
C++だとそもそもマクロ使わないけど、Cだとねえ
>>382 3項演算子の?と組み合わせてる例以外はCの罠に見えるが
>>383 >>339どこをどう読んだらそうなるんだよ・・・
しかも、それだってgets()の話と一緒だろ。
Cプログラマには常識レベルの話で騒いでるだけ。
>>385 C++の例だってC++PGには常識なんじゃないの?
>>384 それはCPPを知らない事が前提だろ。筋立てが無理矢理すぎるんだよ。
>>386 常識の範疇で収まるなら云い訳がましい書籍が何冊も出ないだろうさw
罠といってもマクロには名前があるから検索しやすい
問題は、名前のない暗黙の罠をどうやって検索するか
>>365 >339で言いたかったのは、そういう本なり記事なりがあるくらい
結局の所、選んだリンクがマズかったな。
>>333 CでもC++で抽象化されているものと同様のことをしようと思ったらライブラリレベルで抽象化を行うでしょ。
そうしたら同じように気をつける以外避けようの無い抽象化の漏れも出てくるでしょ、って話。
>>392 何か例を挙げてみてくれるか?そうすると話がしやすい。
で、俺が最初に思いついたのは、シグナルとスレッドが両方絡むような
プログラムで、これは確かに罠満載で難しんだけど、
ある意味で「本当に難しいことをしようとしてる」から難しいんであって、
C++の提供する抽象化のように、面倒くさがらずに
明示的に書けば難しくない例(例外の代わりにエラーコードを明示的に書くとか)
と一緒にしたくないな。
394 :
393:2011/03/04(金) 08:49:15.42
>>393 で挙げたのは、
気をつける以外避けようがない罠があるCプログラムの例、のつもり。
このスレの
C++がdisられる → 脊髄反射で質問 → さらにdisられる → C++だけじゃなくCも糞と言い出す → 一緒にすんな → 最初に戻る
のループはちょっと面白いな
シグナルはプロセスを制御する。
プロセスとスレッドが両方絡むのは、.NETとC++が両方絡むようなもの。
C++プログラマでもC++/CLIを素直に受け入れる者は少ない。
しかし敵の敵は味方だというし
C++をdisるくらいならC++/CLIをほめちぎるほうが前向きだ。
>>393 ごめんそれ例外が難しいんじゃなくて393に例外が難しいだけにしか見えない
>>398 例えば、mutexでロックして処理を実行していて(処理が終わればアンロックする)
途中で非同期シグナルで割り込まれた場合とか。
割り込まれた場合、即座に処理を中断することが望まれるけど、
mutexを握ったまま中断されるとデッドロックしてしまう。
(なので、シグナルハンドラから安易にpthread_cond_signalとかを送っちゃヤバい)
かといって、のんびりアンロックするまで処理を中断しないのも困る。みたいな。
まあ例外はなあ。使わんとこもあるし。適材適所じゃねえの。
C だって goto は使えるけど、無茶な使い方はしないでしょ。
goto と例外を直接比べてるわけじゃないよ。念のため。
402 :
400:2011/03/04(金) 14:21:19.51
あー、pthread_cond_signalについては忘れてくれ。
上の例とはちょっと合ってない。
>>399 GC頼みのRAII守らんコードなんてC++で例外使うなら即ゴミ箱行きじゃ
PGごと窓から投げ捨ててしまえ
>>403 例外は書くのが難しいんじゃないんだ。
読むのが(そして、どのコードをゴミ箱に突っ込むべきか)を読み解くのが面倒なんだよ。
なに?例外安全で無いコードを書くやつなんていない?
人間は基本的にミスするものだし、何より
>>339 を読んで
「Cにも罠がある!」とか言っちゃうような底なしの低能どもが
Exceptional C++ に書いてあるような内容をミス無く実行できるはずもないだろ?
メモリ直接いじっちゃう言語が危険じゃないわけないだろ
C++と危険のレベルが次元違いとはいえ、最悪とだけ比較してCが安全と思ってたらヤバイ。
ヨハネスブルグより安全なら大丈夫ってか?
はい
スレタイにある通り、最悪とだけ比較します
>>399 > しかしお前にも、例外を使ったマズいコードと、
> 例外安全な良いコードを簡単に見分けることなどできないはずだ。
>
>
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx リンク先の記事が言っているのは良いコードと悪いコードの見分けではないよ。
Raymond Chen からの最後のコメントにこうある。
> My point is not that it's easier/harder to find mistakes in
> error-based or exception-based code. It's that it's harder to
> **tell the difference** between code where the author thought
> about errors/exceptions and code where the author didn't.
書いた人が処理の失敗をちゃんと意識しているかどうかをコードを見て
判別するのが例外を使った場合はより難しくなる、と言っている。
ただし、これについても疑問の余地が残る。
処理の完了前に副作用を起こしてしまうようなコードを修正するには処理順を
入れ替えるだけだったり、途中の値をローカル変数を使って保留させたり
するんだけど、これは例外を使った場合でも戻り値を使った場合でも同様
だからね。
>>399 > 複数のコードパスを(暗黙的に)生成してしまうコードが
> 難しくないわけがない。
> これは言語仕様を理解できるか否かの問題じゃなく、
> 人間の認知機能の問題だからな。
人間にとって扱うのが難しいほどの数のコードパスを生み出しているのは
使用する処理が持つ失敗の可能性であって、通知~処理方法として例外を選択
したことでそれが増えるわけではない。
通知~処理方法に戻り値+明示的なテストを選択した場合、プログラマの手抜き
などによって本来分かれるべきだったコードパスが暗黙のうちに合流してしまう
ことがある。
例外を批判するプログラマは、しばしばこの暗黙の合流に慣れており、
例外安全の文脈で示される本来あるべきコードパスの数を見て、それを例外が
引き起こす問題だと勘違いしている。
例外が暗黙のうちにコードパスを分けるのに比べて、戻り値を使った場合の
暗黙のコードパスの合流は多くの場合に間違いとなる。この点で例外のほうが
優れており、それゆえに C 以外の言語には多く採用されていて、実際に利用
されている。
>>399 例外にまつわる誤解について、参考リンク。
http://www.boost.org/community/exception_safety.html > 2 Myths and Superstitions
...
> It's almost as though exceptions are viewed as a mysterious attack on
> otherwise correct code, from which we must protect ourselves.
...
> "Exceptions make it more difficult to reason about a program's behavior." ...
これが書かれたのがもう10年前のこと。いい加減にこんな迷信は消えて欲しい
ほしいところなんだけど、まだまだみたいだね。
もうひとつおまけ。
http://www.parashift.com/c++-faq/exceptions.html#faq-17.1 [17.1] What are some ways try / catch / throw can improve software quality?
> By eliminating one of the reasons for if statements.
...
>>408 Raymond Chen はコメント欄で色々突っ込まれたあげく、
最後に「例外はミスを見つけるのが難しいんじゃないんだからね!
コード作者の意図が読みづらいだけなんだからね!」
って意見をちょっと変更しているように見える。
ま、それはいいんだけど。
何でPGは、自分が使わない言語をdisるのでしょうか
>>409 ここではずっと、「読むのが難しい」という話をしてたつもりだった。
なぜ読むのが難しいかと言えば、
例外が throw するコードと catch するコードが同じ画面にあることは
滅多に無く(どこか関数の深いところから飛んでくる)、
しかも = やら + といったオペレータからさえ飛んでくる上に、
変数の型をチェックして型を実装したコードを見つける必要があり、
さらに継承が使われてたらクラス階層をたどる必要があり、
ポリモーフィズムが使われてたら実行時における型が何かを知る必要があり、
すなわちどこからどんな例外が飛んでくるか知るのに
コードの様々な部分を読まなきゃならない。
これが、高々(オーバーロードさえない)関数の戻り値を調べてるコードを読むより
読みやすいというなら、あんたは大嘘つきだ。
>>405 >>406 危険な言語であるCに、さらに罠を大量に追加して
「自分の足を撃つなら、撃つやつが悪い」って突き放してるんだぜ。C++は。
Cの危険さは必要悪だが、C++が容易する便利機能は他の言語で
もっと安全に実装されてるんだから、
そっち使ったほうがいいよ。
そうそう、
>>399 のリンク先を読むのが面倒なひとのために。
次のコードブロックは、例外ベースの正しいコードと間違ったコードを
それぞれ表しています(実際に使われてるコードから抜粋した、らしい)。
(1)
NotifyIcon CreateNotifyIcon()
{
NotifyIcon icon = new NotifyIcon();
icon.Text = "Blah blah blah";
icon.Visible = true;
icon.Icon = new Icon(GetType(), "cool.ico");
return icon;
}
(2)
NotifyIcon CreateNotifyIcon()
{
NotifyIcon icon = new NotifyIcon();
icon.Text = "Blah blah blah";
icon.Icon = new Icon(GetType(), "cool.ico");
icon.Visible = true;
return icon;
}
これはヒドいwww
>>409 > 例外が暗黙のうちにコードパスを分けるのに比べて、戻り値を使った場合の
> 暗黙のコードパスの合流は多くの場合に間違いとなる。
何か例をあげてみてよ。
多くの場合に間違いとなるなら、簡単でしょ?
例外をcatchしたとき、どこからthrowしたか知るのは難しい。
これもコードパスがどこからか合流していることを意味する。
おそらく、同じ「型」の例外ならば合流して良いということにしたいんだろうが
例外のコードパスはグローバルすぎてどうしようもない。
「型」のことしか考えないから、スコープの感覚が退化してるんだろう。
int hoge(){
int ret;
if(( ret = foo() ) != FOO_OK ){
return ret;
}
if(( ret = bar() ) != BAR_OK ){
return ret;
}
if(( ret = baz() ) != BAZ_OK ){
return ret;
}
return HOGE_OK;
}
int caos::Panic::Confusion::Hoge() throw(...){
try{
caos::foo();
caos::bar();
caos::baz();
return caos::Panic::Confusion::hogeReturn_t::HOGE_OK;
}
catch(caos::Foo_Exception &e){ throw caos::Panic::Confusion::hogeException(e); }
catch(caos::Bar_Exception &e){ throw caos::Panic::Confusion::hogeException(e); }
catch(caos::Baz_Exception &e){ throw caos::Panic::Confusion::hogeException(e); }
catch(...){ assert(0);caos::Panic::Confusion::hogeException("UnknownError"); }
}
どっちがわかりやすいかなんて、明らかだろ
0xスレから飛ばされました。以下コピペですが、ここで議論をしたいと思います。
pure C++ vs C/C++で後者にしたほうがいい例を知りたいです。
過去の投稿(↑)はこれから読みます。
=============
普段からpure C++(およびC++0x)しか使ってなくて、困ったことはないのですが、
C言語のほうが短く簡単に書けるようなことってたぶん結構あるんじゃないかと思うのです。
思いつくのを羅列してみると、
- I/O関係(printf,scanf,...)
- マクロ
- 配列初期化
- ポインタ演算
C++0xでかなり改善されているとはいえ(autoとか)、対応するコンパイラがマシンに入ってない場合も多いので、
ちょっとC言語も勉強してみようと思うのですが、みなさんが普段dirtyテクニックとしてCを混在させているものを教えてください。
421 :
419:2011/03/05(土) 13:18:33.29
>>420 いや、普段0xスレしか見てないので、そこに書き込んだのですが、
たしかに、雑談チックな話をはじめる雰囲気でもなかったので・・・。
気軽に答えてくださればありがたいです。
C++に危険な部分があるのは確かだけどさ、
だから使わないってのは極論すぎるような。
使い捨てスクリプト的なプログラムみたいに
それで済む仕事ならいいだろうけど。
>>422 確かに、今すぐ結論を出す必要はない。
Cで書きはじめて途中でC++に変更できる。
逆はできない。
それってまともな設計しないで書き始めてるってことだよね。
オチは見えてるなぁ。
>>424 まともに設計されたモジュールは、実装言語すら情報隠蔽できるのだよ
そういう意味ではC++で書きはじめてもいいけど
C++固有のモジュールシステムは使えない
>>423 Cで書きはじめるなら、
それはC++に変更する意味ないよ。
>>413 > 変数の型をチェックして型を実装したコードを見つける必要があり、
> さらに継承が使われてたらクラス階層をたどる必要があり、
> ポリモーフィズムが使われてたら実行時における型が何かを知る必要があり、
なんのためにそんな実装しだいでどうにでも変わる情報を知る必要があるの?
それは戻り値でのエラー通知でもわからないはずなんだけど、何が違うの?
> これが、高々(オーバーロードさえない)関数の戻り値を調べてるコードを読むより
> 読みやすいというなら、あんたは大嘘つきだ。
あんたの言うような読み方しない。しないでいいと思っている。
そこらじゅうに if が散らばったコードより処理の元々の意図が読みやすいぶん
戻り値+分岐を使ったコードより簡単だと思う。
>>416 array = realloc(array, size);
こんなのとか。
>>417 例外が発生した場合のコードパスは、暗黙のうちに一本に合流しようとする。
これは明示的に catch を書くことででいくつかに分けることができる。
> おそらく、同じ「型」の例外ならば合流して良いということにしたいんだろうが
> 例外のコードパスはグローバルすぎてどうしようもない。
ここの2行目がよくわからない。何に困ってるの?
例外が悪だというなら当然longjumpも悪なんだろ?
そこはどうしてるわけ?
>>431 setjmp/lognjmp はCでも非常に危険なので、それを使わなければ
実現できない場合以外は使われない。
C++では、単純に使うことすら危険すぎる。
C++ だって例外を使わない選択はできるぞ。
そういうプロジェクトも少なくない。
コンパイラによってはオプションまである。
>>435 例外だって積極的には使われないという認識なんだけど。
統計でどうかとかは分からない、イメージ論でしかないが。
少なくても自分の場合は復帰不可能な場合でしかまず使わない。
なんかここで C を擁護してる人の C++ への思い込みが酷すぎる。
C++ が酷いのは同意なんだがw
つーかわざわざ日本人に用途が分かりやすいように"例外"て名前をつけてくれてるのに、
何でもかんでも例外で返すやつがいるのかよと。
>>439 「例外は例外的な場面でだけ使う」とかいうやつか。
そんな基準は主観的なものになってしまって役に立たないよ。
http://www.boost.org/community/error_handling.html > The problem is that one person's ``exceptional'' is another's ``expected'':
> when you really look at the terms carefully, the distinction evaporates and
> you're left with no guideline.
コンストラクタの失敗ならどんな些細な理由でも例外で返す他無い。
>>440 それはほとんど復帰不可能なケースなんじゃないの?
Cならexitするような。
どうでもいいことは無いだろ。
その手の復帰不可能な例外ならmainで一括して拾うか、処理系によっては
拾う必要すらなかったりすると思うんだけど。
例外の危険性って、どこから飛んでる来るか分からない=拾いきれるか問題
という前提条件なんじゃないの。
投げられても拾う必要がないなら除外されるだろ。
例外自体の危険性ははset/longjumpとそれほど変わりなく(むしろ例外の方が安全か)
それが問題になるのは用途だろ。どういう用途で使うか考えずになんで議論できるのか。
>>445 拾う必要があるかどうかはアプリレベルで決めること。ここで言えることは無い。
>>445 だれが拾いきれるかどうかなんて問題にしたの?
そんなの問題にしても catch (...) で終了だよな。
>>428 例外の場合、その関数を呼び出す側に暗黙的にコードパスを追加できるから、
実装しだいでどうにでも変わるとか言ってられないよ。
っていうか、「僕はいいかげんにコード読んでます」とか自己紹介いらないから。
>>434 realloc すらまともに扱えないプログラマが、C++ になったら
まともなプログラムを書けるなんてとても思えない。
素直に C/C++ じゃなく python あたり使ってほしい。
>>450 例外を投げない関数が例外を投げるようになったときの話か?
戻り値にエラーを含まなかった関数が含むようになったときと同じじゃないか?
エラーが無視されないぶん例外のほうがマシじゃないか?
>>441 mallocに失敗するときは殆ど復帰不可能だから、
エラーチェックなんていらないよなwww
>>451 誰もそんなこと瑣末な主張はしていない。
>>416 の望んだとおりの例を挙げただけだろ。
ちゃんとアンカーついてるんだからレス辿れよ。
>>454 勝手に糞コード書いといて、問題起きますよねってアホか。
だいたい、どこが暗黙のコードパスの合流なんだよ。見え見えじゃねーか。
ム板の例のスレでもそうだけど、例外が難しいという主張をするときには、それが
戻り値+分岐だとどう違うのかよく考えてからにしろよ。
>>452 いや、もっと単純に、コードを追跡するのが面倒って主張に対し、
そもそも追跡なんてしないって返されたから、
そりゃやべーでしょって話。
>>457 だったら何のために実装にもぐって追跡なんてするのか教えてくれ。
戻り値でエラー通知されたときにはそれが不要になる理由がわかるようにな。
459 :
457:2011/03/05(土) 21:10:07.19
あと、戻り値の場合はその関数の return を調べれば
(または、時には関数定義の戻り値の型を調べるだけで)
エラーが追加されたか判るけど、
例外の場合、どこまでも遡る必要がある。
460 :
457:2011/03/05(土) 21:13:19.26
さらに言えば、エラーを戻り値で返す関数が
戻り値を処理してなければ、単純にバグを疑うことができる。
一方、例外の場合、catch していないときでも
もっと上のルートで例外処理しているのかもしれず、
バグかどうかの判定にはずっと多くのコードを読む必要がある。
>>453 バカか?
exitするかどうかの為にチェックするんだろ
>>457 お前さんのデバッガには例外時に潜れる機能も付いてないのか?
>>461 冗談に噛み付かれてちょっとビックリ。
しかし真面目な話、exitさえまともにできないときあるよな。
>>463 あまりにセンス無い文だったので冗談だと分かんないからな。
どこら辺がどういう意味の冗談になってるの?
>>459 なんで戻り値の場合は仕様(ドキュメント)が更新されるのが前提なのに
例外だと仕様が更新されないのが前提なの?おかしいだろ?
>>462 実装に潜って追跡する必要が無い、って主張が無理筋だとわかったから
デバッガ使って読みますよ、に変えたんだよね?
>>460 catch してなかったらバグで catch してたらバグじゃない、とか思ってるの?
それ違う。(むしろ逆のことのほうが多い)
実際は、例外使えば「戻り値を処理していない」というような、バグを疑うパターンが
減るってことだろ。いいことじゃないか。
>>464 441が自分で勝手に復帰不可能なエラーか否かを決めてるからさ。
そんなこというなら、malloc失敗はもうOSがクラッシュしてて何しても無駄、とか
なんとでも言えるだろ?
で、お前は例外の痛いところを突かれて、どうでもいいところに噛み付いてるんだよねw
>>466 デバッガ使いこなせてないからってそれはないだろ
>>467 > catch してなかったらバグで catch してたらバグじゃない、とか思ってるの?
> それ違う。(むしろ逆のことのほうが多い)
どういうこと?
>>457 属性throw()もコメント//never throwも使わない人?
>>470 少なくとも C++ の場合、リソース解放やのために catch しているケースでは
RAII で置き換えたほうがよいことが多い。 catch してリソース解放している箇所が
あれば、似たような別の処理で同じようにする必要があり、漏れる可能性が残る。
>>471 例外で投げれる型の制限について、コンパイル時に
チェックしてくれたら良かったのに、とは思うよ。
>>468 それを言うならお前の方が例外なんて使う必要が無いケースで軽々しく例外飛ばしてると
勝手に考えてるんじゃないの?
>>472 エラー処理 = リソース解放、ならそうかもね。
でもデストラクタで可能なエラー処理なんて、たかが知れてると思うの(例外投げれないからな)
呼び出し側が例外安全になってない場合
throwしたらバグ
exitしたらバグじゃない
だからthrowするよりexitする方がいい
>>476 大抵そうだと思うが、可能な限りデストラクタ呼んで欲しい場合はthrowの方がいいんじゃない?
>>474 例外を必要十分なだけ使ってる良いコードと、
なんでもかんでも例外をとばしてる糞コードとが
コードを詳細に追跡すること無く、容易に判定できたらいいのにね。
>>475 そうか。分野によっては catch にエラー処理を書くことは多いのかもしれないな。
個人的な経験の話になっちゃうみたいなんで、「逆のことのほうが多い」は無視して。
C++を攻撃されると、自分が攻撃されてると感じちゃう繊細なお前らへ。
別に、お前らを攻撃してる訳じゃないからね。
C++をちゃんと使いこなしてるなら、それはそれで立派なことだから。
あと、万一C++標準委員会の人間が読んでるなら、
お前らいいかげんにしてください。
人間、皆がお前らみたいに賢くないんです。マジで。
>>478 ・仕様を読む
・throwで検索して何を投げてるのか見る
これだけでも見分けられるかもしれない。
>>482 C++委員会の方々も必要な機能を必要な人だけが使ったらえぇ
と、おっしゃってたからなぁ。
だったら必要ない機能をOFFにする機能を用意しろと
#define NO_TEMPLATE
#define NO_EXCEPTION
#define NO_NAMESPACE
#define NO_INHERITANCE
#define NO_OPERATOR_OVERLOAD
みたいなので全部無効に出来てたらそこそこいい言語になるのになあ
いやいや、規格上は上手く取り外し出来るようになってないだろ今のところ
委員会はそんなこと言うならちゃんと取り外せるように作れと
rttiや例外は無効にできるコンパイラが多い
487はどんだけ無茶言ってんだよw
例外なしでコンストラクタ書かされるならC++使いたくない。
コンストラクタ使わない書き方が普及したらC++使ってもいい。
>>490 コンストラクタで例外を何に使ってるの?
>>490-491 「コンストラクタで例外を投げてはいけない」とか言っちゃう人たちですか?
コンストラクタが戻り値戻せないのがそもそもおかしいんだよなぁ
戻り値受け取る自然な構文がないのはわかるけど、もうこんなんでいいから取れるようにしてくれ
Hoge h(42);
int ret = return<Hoge>;
>>494 失敗の通知なら例外でいいし、副次的な情報なら参照引数でいい。
>>492 例外をOFFにした場合の話なので、コンストラクタの中でもOFFです
errnoでいいじゃん
何がご不満?
ああそうだよ値戻し用の引数でいいじゃん
Hoge(int n, int *ret){
if(なんかエラー){
*ret=1;
return;
}
*ret=0;
}
int ret;
Hoge h(42, &ret);
if(*ret){
return ERROR;
}
なんで今まで気付かなかったんだろう
というかコンストラクタのエラー対処法の議論ってそこらに議論転がってるけど
今までこれ見たことないな
なんでそこまでするほど例外使いたくないの?
if文が好きな前時代の遺物ロートルだろ
>>499 言語仕様でいうと正当なコードだろうけど
ものすごい挑発的に見えるから、大人しくCを使うのがよさそう
>>500 >>501 例外使うのがモダンなコーディングスタイルかというと、
それも疑問。
グーグルのC++コーディング規約は例外を禁止してるだけでなく、
go言語は仕様から例外を外してる(戻り値でのエラー通知を採用)。
>>504 google のスタイルがモダンじゃない
というだけの話だろ。
>>465 C++だと、名前空間、オーバーロード、ポリモーフィズムがあるから
あるメソッドが例外送出するように仕様変更になったとして、
じゃあどこを直せば良いのか、簡単には判らなくないか?
特にオペレータが変更されたとき。
一方、Cならgrepで一発。
>>505 グーグルよりモダンな505さんかっこいーwww
>>509 これはGoogleの講演会に行ったときに聞いた話なんで、信じてもらえなくてもいいんだけど、
Googleが例外を使わないのは、歴史的な事情(過去の例外安全でないコードと混ぜるため)
もあるけど、何よりGoogle の規模だとほぼすべてのコードパスが実行されうるため、
例外機構で見た目がすっきりしても処理を追いにくくなるからだってさ。
まさに、このスレで議論されてるような話だね。正しい主張かどうかはともかく。
510 :
509:2011/03/06(日) 02:18:01.33
>>506 確かにコンパイラの支援がないときついかもな。
関数消してコンパイルしてみりゃ一発ではあるんだが。
>>509 >例外機構で見た目がすっきりしても処理を追いにくくなるからだってさ。
ま、この主張の妥当性はおいておくとして、
それの根拠に
>何よりGoogle の規模だとほぼすべてのコードパスが実行されうるため、
を出すのは愚かだろ?
俺には
「全てのコードパスが実行される ⇒ 処理を追いにくくなる」
は、およそ論理的な主張とは思えない。
あ~やだやだ。google 信者ってこんな奴らばっかなんだよな。
513 :
509:2011/03/06(日) 02:45:44.36
>>512 いや、別にGoogle信者じゃないんだが。
「全てのコードパスが実行される → 暗黙的コードパスも残らず実行される → 暗黙的コードパスは追跡しがたい(が追跡しないわけにいかない)」
こんな感じ。で、メリット(見た目すっきり)とデメリット(追跡しがたい)を秤にかけただけかと。
あんたの推論はステップを飛ばしてる上に、意味の無いレッテル張りをしてる。
>>509 >>513 失敗する可能性があっても、実際に失敗しないかぎり失敗時の安全性は考えなくていい、
って暗に言ってるように聞こえるんだが、正気か?
>>513 お、暗黙的コードパスの追跡とか言い出したな。
458 への回答が無くて気になるんだが、かわりにおねがいできないか?
516 :
509:2011/03/06(日) 03:00:56.87
知らねーよwww
こっちは例外使ってるし。
だから
> 正しい主張かどうかはともかく。
って書いたじゃん。
>>458 >>515 関数fについてエラー処理してるコード辺があったとして。
そしてそのエラー処理が漏れていないかチェックしたいとき。
戻り値:関数fを探して、その関数でリターンしてるところをチェックし、エラー処理のコードと比較
例外:関数fを探して、例外を投げる可能性のある全てをチェックし、エラー処理のコードと比較
になると思う。
どっちが大変かな?
戻り値ベースなら、簡単な検索でかたがつくよ?
そういえば、393とか416の回答はどうなったんだろう?
>>517 仕様は無いのが前提なのか。その時点ですでに破綻気味だな・・・。
で、例外を使っていれば変に catch してるところが無い限り
エラー処理が「漏れる」なんて事は無いんじゃないの?
「漏れる」の意味がよくわかってないだけなのかもしれない。
戻り値で言えば if などによる分岐が無い場合を指してるんだよね?
>>519 例外ベースなら、全ての投げられる型に対して
個別の例外処理を実行する必要がある、というシチュエーションです。
戻り値ベースだと、例えば整数が帰ってきて
それぞれの値に応じてエラー処理を実行します。
少し違うけど >> 418 のような感じでしょうか。
>>519 それと、仕様があっても仕様とコードが対応しているか
調べるときに同様のレビューが入るのでは?
>>520 そんなめんどくせー関数を仕様無しで使えってのがそもそも無理だ。
あと、結果が複数あってそれぞれの動作が別々に決まるようなら、
それはもう「エラー処理」とも少し違う気がする。例外の使える言語でも
戻り値とかで状態を返すべきところでしょ。
>>521 どうも例外を使う場合は具体的な例外の型をすべて仕様として列挙することを想定してる
みたいだけど、そんなことはあんまりしない。(検査例外について言われる問題が関連する)
例外安全性のレベルを示すだけか、例外の型を示すとしても基底クラスをいっこ示す程度。
524 :
523:2011/03/06(日) 04:49:14.94
523 には個人的な願望が混ざってしまった。他のプログラマがこういう認識かどうかはよく知らない。
個人的な願望で言わせてもらえば、例外安全性を示すだけにとどめた上で、例外について何も
書いてなければ強い保証を提供しながら例外を投げるものと解釈するのが楽でいい。
>>456 マジレスすると
例外を使うと周囲から色々なことを期待される。
自分では戻り値+分岐と同じような使い方しかしないつもりなのに
RAIIを期待される。
所謂「驚き最小」のために、その期待を裏切らないことを期待される。
そういうことに振り回されたくないなら
最初から例外は使いませんとかC++は使いませんと宣言しておいたほうがいい
>>503 Hoge(const Hoge &src, int *ret)
を使ってコピーするようにすればいいだけだよな
本来のコピコンは殺しておいて
>>525 エラー処理の方法は自分個人で決めるんでなく、プロジェクトのコーディング規約に従えよ
>>525 だから、なんでそれで C++ は使いませんが含まれるんだよw
おまいさんの願望をさりげなく入れんなw
従え。願望するな。
>>525 RAII は例外だけじゃなくて return や break などに対しても役に立つぞ。
例外なんぞ使わなくても C++ では当然の手段だ。難しい話でも無いしな。
それに従っておけば例外についても問題なくなるんだからおいしい話だぜ。
でも解放失敗しうるリソースにRAII使って解放エラー無視するバカが多すぎて困る
RAIIはGCよりも難しい。
「GCに従えば例外は問題ない」とすればバカでもわかる。
>>531 > でも解放失敗しうるリソースにRAII使って解放エラー無視するバカが多すぎて困る
何か例をあげてみてよ。
多すぎて困るっていうぐらいなら簡単でしょ。
>>533 まず、佐藤。
次に、田中だろ、高橋だろ・・・
>>533 ファイル
ストリーム
データベースコネクション
スレッド
プロセス
ハンドル類
動的ライブラリ
基本的にメモリと一部の排他制御以外の全てだな
RAIIはfreeなりdeleteなりが失敗せず例外も投げないというお約束の上に立脚してることを忘れてはならない
基本はヒープメモリ専用のテクニックであって、万能の処方箋ではない
>>535 >基本はヒープメモリ専用のテクニックであって
そんなこという奴、初めて見たよ。
なら、どうすれば解決できるっていうの?
もしかして「2フェーズ・デストラクション」とか言い出すの?
>>535 いや、だから、実際にその点に問題があって困るコードの例を・・・
>>536 そうだよ
解放に失敗しうるとすれば、それは明示的な解放をせざるを得ない
RAIIに任せっきりなんて使い方は危険極まりない
>>537 たとえばファイル閉じる時にフラッシュしようとしたら失敗したなんて時はエラー放置したらデータ飛ぶだろ?
ロック順とかの関係でロック手放し損なったりしたらデッドロックするだろ?
DB接続切り損なったままほっといたらそのうちDBサーバーのセッション数埋まっちゃうだろ?
それくらいも想像できないからファイルとかにRAII使っちゃうんだな
>>539 逆だろう
基本は明示的な終了処理でちゃんとエラー時の対処をして、
万一解放忘れがあったとき時にエラーは無視してとりあえず解放してもらうためにRAIIがある
リソースリークという最悪を避けるための保険としてはRAIIも有効だと思うよ
だが、その場合デストラクタで解放されるというのは本来はバグだ
頼ってはいけないし、終了処理を自分で呼ぶ義務から逃れることは出来ない
>>540 ファイル書き込み処理の途中で例外が発生してデストラクタでファイルが閉じられるとき、
ファイル閉じのエラーは無視して(ログに記録して済ませる程度で)元の例外だけ伝われば
いいよね。
これはバグじゃないと思うんだ。バグだというのなら、どうすればいいの?って話になるし。
RAIIがどうこうじゃなくて、マルチタスクをちゃんと運用できてないという話なんじゃないの。
どこからそんな話が出てきたんだろう・・・
書き込みが終わるまで待ってから終了するための待機タスクが必要なんだろ?
>>541 ちゃんと状況がわかった上で、その局面ではあえてエラーを無視するという選択をして、
実現方法としてデストラクタに任せるというのなら、まあいいと思う
「とにかくRAIIに任せとけばいいよwww」って連中がそこまで考えてるかどうかが問題
だからさ、例外が出たら
てきとーにRAIIでリソース解放(失敗しても無視)して
てきとーにログ吐いて終了するような
使い捨てスクリプトには、C++もいいもんだよ
豆知識
ロンドン証券取引所(LSE)の証券システムはC++製
継承以外は単純なサーチで済むんじゃないの?
そういうプリプロセスツール作るとか。
あるいは自分でマクロ書いて置き換えて使えば?
C信者
・例外を使いこなせない。継承も使いこなせない。if文大好き
・C++に比べたら、Cは安全だと信じてる
・いまだにemacsやvimを使ってる。IDEは使えない
・実はC++について詳しくない(思い込みで嫌ってる)
C++信者
・なんでもRAII。リソース解放の失敗?なにそれ?
・Cを書かせたら strlen をループの中に書いたり、gets使ったり、reallocでメモリリークさせたりする
・コード読まない。コードより仕様書
・C99やC1xは悪い規格である。C++と互換性がないから
>>550 編集者
・信者に比べたら、中立な編集は正義だと信じてる
・2chは悪いインターネットである。編集しないから
>>511 派生型の仮想関数はそれじゃ見つからなくね?
>>550 両方ともdisってるように見えるが、
C++信者の方がクソプログラムを生産する素養に満ち満ちている件。
あと、このスレでは
> ・実はC++について詳しくない(思い込みで嫌ってる)
は当てはまって無いかと。
安易に構文を追加したため罠だらけで、
コードの可読性はいたずらに低く、
ご自慢の機能(RAII)は安全なプログラムを書く役にはさっぱり立たず、
コンパイラのバージョンが上がると古いオブジェクトファイルと
リンクできなくなることもあり、なのでシステム全体を再コンパイルする必要があるのに
コンパイルは糞遅く、エラーメッセージはカオス。
そんなC++が大好きです。
559 :
デフォルトの名無しさん:2011/03/09(水) 16:06:17.82
結局CとC++、選べるならどっちがいいの?
演算子オーバーロードとかテンプレートとか使うかどうかはともかく
今時クラス化できないって辛すぎないか?
そういう意味では文字通りC++(Cのちょっと高機能)として使うのが一番お得
今時は動的リンクや動的型がないと辛い。
どうしても静的型がいいという保守的な人がC++を使う。
>>560 クラスっぽいことはCだと構造体と委譲でやることになるが、
確かに委譲は書くのが面倒臭いけど、辛すぎるってほどか?
C++使った方が楽だけどね。
しかし
>>250のような理由により、クラス程度ではC++を使う気にならないという。
absがdoubleに対応してるC++はCよりマシ。
だからどんなプログラム書いてんだよw
>>564 ocaml には abs と abs_float があるが
C++ よりはるかにマシだ
includeしないと使えないabsなんて(ry
>>566 スレ違いです
巣に(・∀・)カエレ!!
>>569 確かに C vs C++ のスレに OCaml なんて
子供の喧嘩に親が出てくるような大人げなさだが。
abs 云々なんて言語の良さとは無関係ってことさ。
そしてC++はウンコすぎるってことさ。
>>570 absだけじゃなくてオーバーロードのメリットを言ってるんだろ。そのくらい理解しろ
enumの型チェックが働かないCはクソ。
void *から他のポインタにチェックなしで代入できるCはクソ。
const定数で配列数を指定できないC99はクソ。
名前空間でシンボル名を整理できないCはクソ。
インライン関数が無くて副作用のあるマクロ使いまくりなC99はクソ。
そしてなにより文字列型が無い言語はアプリケーション開発に使えない。
C++は複雑すぎて僕には使いこなせません
という文章にもいろんな書き方があることがわかって有意義なスレだった
終了
C を LL で例えたら・・・
「それは Scheme(~R5RS)!」
「厳選された必要最低限の機能に飛び道具を隠し持ったミニマル言語!!」
Java を LL で例えたら・・・
「それは Python!」
「教育目的に適した理解し易さと、お仕事で使えるパワフルさを兼ね備えた言語!!」
ObjC を LL で例えたら・・・
「それは Ruby!」
「柔軟なオブジェクトシステムと美しいクラスライブラリを持った自由な言語!!」
C++ を LL で例えたら・・・
「それは Perl!」
「かつて一時代を築いたため使用者人口はそれなり。奇麗に書く事も可能らしいよ!!」
>>572 それらの性質が、実際のCプログラミングにおいてどれほどの障害になるのか、
という議論を抜きにただリストアップされても、片手落ちなわけですよ。
それほど強く主張するのだから、いくらでも語れるよね?ぜひ語ってくれ。
>>572 > そしてなにより文字列型が無い言語はアプリケーション開発に使えない。
こんなもんはLLとかと組み合わせてそっちでやる。
(LL自体は内部でCを使って文字列処理を実装してるだろうけど)
>>573 議論自体には有効に反論できず、
相手が低能であるということにして勝利宣言ですかwww
さすがC++使いさんは一味違いますね。
>>572 > const定数で配列数を指定できないC99はクソ。
> インライン関数が無くて副作用のあるマクロ使いまくりなC99はクソ。
どういうこと?
つまりCは組み込み専用で、アプリケーション開発には使えないと言うことかな。
それなら納得。
>>575 void f(enum x)にenum yの値を突っ込んでエラーが出なかったり、
g(x++);とか書いたらマクロで副作用があったり、それがどの程度
問題なのか説明されないとわからないほどC使いはアフォなの?
>>578 言ってる内容が変なので、C90の間違いじゃないの?
>>579 >>550 >・Cを書かせたら strlen をループの中に書いたり、gets使ったり、reallocでメモリリークさせたりする
型チェックがないなら警告すればいい
仕様が不十分なら実装を工夫する
仕様なんて飾り
C使いの駄目なところは、未だにプログラマは間違えないことを前提に
考えている所。暗黙の宣言とか可変個引数とか、生産性・品質は度外視。
計算機使わず手計算でも間違わなければよいとか言ってるのと変わらん。
テストとデバッグが苦手なんですね
分かります
>>579 おやおや、C++使いは副作用があるような危険なマクロに
関数と同じような名前付けちゃうのかい?www
それに、そんな問題は、
>>231 で語られてるC++の問題同様、
ハマるとしたらハマったやつが馬鹿なのさ。
>>582 それ、C++を擁護する台詞のつもりかwww
C++ プログラマのプロファイル(最新版!)
C のコードを書かせたら、
・性能要求がきつい箇所で strlen() をループの判定部分に入れる
・あれだけ使うなと言われているのに、未だに gets() を使い続ける
・平気で realloc() でメモリをリークさせる
・副作用がある事を意識して使うべきマクロに関数と間違う様な名前を付ける
・厳密な型検査があれば通過しない様なコードを無意識に書く
あぶねー、あぶねーw
>>582 >>413 で少し書かれてるようなC++の読みにくさは、
例外に限らずC++コードの全てに適用される。
可読性は度外視。コンパイラがパースできるなら良いと
言ってるのと変わらん。
C++はコンパイラも相当苦労してパースしてるしね
>例外が throw するコードと catch するコードが同じ画面にあることは
>滅多に無く(どこか関数の深いところから飛んでくる)、
同じ画面に無いところが例外の最大のメリットだろ。
>しかも = やら + といったオペレータからさえ飛んでくる上に、
それは不可能では無いが普通はしない。極端な例を出すなよ。
>変数の型をチェックして型を実装したコードを見つける必要があり、
? 意味わからん。例を出してくれ
>さらに継承が使われてたらクラス階層をたどる必要があり、
>ポリモーフィズムが使われてたら実行時における型が何かを知る必要があり、
継承した意味ねーだろ。頼むから継承の基本を理解してほしい。
>すなわちどこからどんな例外が飛んでくるか知るのに
>コードの様々な部分を読まなきゃならない。
例外はcatchしなきゃいけないという考えがJavaドカタ並に間違っている。
>>584 そうだな。まずCプログラマが書いたnkfとかのソース見ると危険なマクロがあるな。
OGRE や OpenSceneGraph みたいなグラフィックライブラリを C オンリーで書こうとしたら地獄も地獄に思えるのだが、
Cプログラマは楽にこなせるの?
>>589 自分で書いたマクロで罠に嵌る奴は居ないだろw
えー、もしかして
>>579 ってそういう前提だったの?
Cプログラマは、子供の喧嘩でもすぐ大人を呼ぶ
子供だけでは危険だと分かってるから
CppUnitなんてのは軟弱みたいな話だし、CプログラマはCオンリーで書けると答えるんじゃないかなあ
C に限界を感じたら LL を混ぜたり、ObjC を使ったり、今なら Vala を選んでも良いカモね
>>582 > 生産性・品質は度外視。
おいおい。笑かすなよ。
このスレにもRAIIがあれば catch なんていらん、なんてやつが
結構いたわけだが(もしかして
>>589もそうかな?)
そんなやつらが品質とか何の冗談だよ。
C++でコーディング規約をガチガチに固めてbetter Cとして使えば良いんじゃね?
例外と継承の規約は結構有名だが
コンストラクタは最低限の処理だけ、という規約がネックになっていると思う
>>しかも = やら + といったオペレータからさえ飛んでくる上に、
>それは不可能では無いが普通はしない。極端な例を出すなよ。
あんたのプログラムではコピーコンストラクタで例外は出ないのか?
例えば、エンコーディング情報付き文字列型を定義したとき、
異なるエンコーディング情報を持つ文字列を + で連結した場合に
例外投げるのは極端な例かい?
>>変数の型をチェックして型を実装したコードを見つける必要があり、
>?意味わからん。例を出してくれ
オブジェクトのメソッド全般。関数名だけでは一意に決まらないからな。
これは普通は問題にならんが、メールとかで patch でやりとりしてるときは
個人的にウザイと感じることがある(patchだけ見ても何の関数呼ぶか判らないから)。
が、これはちょっと難癖付け過ぎかと自分も思う。
>>さらに継承が使われてたらクラス階層をたどる必要があり、
>>ポリモーフィズムが使われてたら実行時における型が何かを知る必要があり、
> 継承した意味ねーだろ。頼むから継承の基本を理解してほしい。
継承の基本とやらを教えて?
それを理解したら、プログラムの挙動を理解したり、
テスト/デバッグしてるときに実行時における型が何かを知る必要はないんだね?
> 例外はcatchしなきゃいけないという考えがJavaドカタ並に間違っている。
詳しく。
>>599 >それは不可能では無いが普通はしない。極端な例を出すなよ。
string同士の + で例外飛ぶよなw。その状態だと末期だが
>>ポリモーフィズムが使われてたら実行時における型が何かを知る必要があり、
>テスト/デバッグしてるときに実行時における型が何かを知る必要はないんだね?
処理を差し替えたくて継承してる奴に対し、呼ばれる関数が
静的に決まらないから読みづらいというのはちょっと噛み合ってない。
でもデバッガでステップインするだけのことがそんなに面倒か?
面倒だよ
いちいちvtbl探し出してポインタを手繰ってなんて…
仮想関数呼び出しは全部vtblのポインタ経由になるから遅いのも大問題だよな
#define MYTHROW(e) throw e(__FILE__,__LINE__)
話が見えん。こういうことやらないて話なのか
Cプログラマって大変なんだな。デバッガでボタンクリックすりゃいいものを、
コンパイラの生成したアセンブリコード追うなんて。
そりゃC++なんて汚くて読めないはずだ。
でもCなら弱いメモリモデルのRISC最適化コードも読めちゃうんだすげー。
>>602 君の話こそ見えないよ。
604 :
599:2011/03/10(木) 02:28:58.26
>>600 オブジェクト指向で興味深いプログラムを書くためには、
異なる型の異なるオブジェクトの相互作用を書く必要が出てくる。
例えば、
x.func(&y)
みたいなコードを考えよう。
ここでポリモーフィズムが使われてる場合、
yに対する副作用のあり方もxの実行時の型によって変化しうる。
継承は、ちゃんと設計できてれば、xの状態遷移については
全ての派生型で問題ないことを保証するだろうが、
yについてはその限りではない。
なので、xがある特定の型のときだけyが例外を投げることはありうるし、
さらに悪い状況では、ある特定の状況で特定の実行型については
x.func(&y) の呼び出し自体がバグ、ということさえありうる。
なので、継承の基本を理解すれば実行時の型を知る必要が無い、
というのは理解できないんだよね。あんたなら解る?
> でもデバッガでステップインするだけのことがそんなに面倒か?
テストするとき、ステートメントカバレッジより
ブランチカバレッジの方が、100%に近づけるのは遥かに難しいよね?
同様に、デバッガで動かしながら実行時の型を網羅していくのは
単純に読むのより、ずっと大変だよ?
デメリットはC++としか比較しないくせに、メリットは他の言語持ち出すのなw
>>606 ・Cは危険な言語である。ただし、低レベルプログラミングのための必要悪である。
・C++は危険な言語である。理由はCと同様である。
・C/C++は他の言語との連携がとりやすい言語である。
・他言語と簡単に連携がとれるのに、C++のような構文拡張は必要なのか?
というのが議論の発端なので、他言語のメリットが出てくるのはしょうがない。
もともと、C単体でC++と勝負してる訳じゃないのよ。
毛がない議論だ
>・他言語と簡単に連携がとれるのに、C++のような構文拡張は必要なのか?
グルーコード書くうえでC++の幾つかの機能は重宝
610 :
デフォルトの名無しさん:2011/03/10(木) 07:26:05.18
Rubyで書こう
>>604 >x.func(&y) の呼び出し自体がバグ、ということさえありうる。
それはyの単体試験で確認しておけばいいのでは?
そのためにyは外部とのインターフェースをpublic/privateで限定し
そのインターフェースが整合しているかどうかだけ確認できれば問題ない。
xの実体がわからないようなxとyの結合コードはその後で試験でしょ。
この時はfuncはステップオーバーする程度でxの実体なんてどうでもいい。
>>611 yの単体試験でそれがバグかどうか確認できるためには、
yの任意のpublicメソッドが任意の順番で呼ばれても全て正しい動作、
というくらい強い条件を満たす必要がある。
613 :
612:2011/03/10(木) 09:10:35.56
さらに、任意のタイミングで、も追加。
>>609 boost::Python は楽だけど、Cython はもっと楽。
結局、グルーコード自体も他言語(この場合はPython)で生成させた方が楽だったり。
615 :
614:2011/03/10(木) 09:30:15.57
でも、その主張の方向性はいいと思う。
Cのマズい点をC++使いが挙げると、どうしても
>>586のリストを
更新する感じになっちゃうんで、むしろC++の良いところを
挙げていく方がいい。
PHPかJacascriptを主流にして、コンパイラの最適化でC/C++なみの速度を出すのがベスト。
いちいち関数の戻り値を受けるのに変数定義するのとか面倒だ。
コンパイル時に判明するだろ。
やはり時代は OCaml か……
なんか話がmyframework with C vs. myframework with C++になってるな
C vs. C++のつもりで書き込むと馬鹿と言われそうだ
いろいろ言語あるのは面倒だ。
C/C++の一つの後継であるPHPかJacascriptに統一して発展させるのがいいよ。
これでGUIや3Dも出来るようにする。
すでに実用されていて過去のソースも沢山あるし。
>>604 > x.func(&y)
これで C++ の問題点を主張しようとしてるの?
C でも func が関数ポインタだったら同じことじゃないの?
あるいは x_func(&x, &y) とか。
>>621 >Exception classes cross subsystem boundaries
C++でしか使えない例外投げてるのに、よく言うよな
共通言語なんとかの例外でも投げればいいんじゃねえの
>>621 例外をcatchしたとき、どこからthrowしたか知るのは難しい。
特に下流で処理しない場合は、上流でパスが合流してしまうのでその傾向は顕著である。
おそらく、同じ「型」の例外ならば合流して良いということにしたいんだろうが、
そんな単純な例外処理ばかりじゃないし、だからといって様々な状況を区別できるよう
型のバリエーションを増やす(そのサイトにある"Using the bits / data ..."の方法)のは
>>517>>520にあるように可読性が下がる。
可読性という点でいえば、
>>460のような問題もある。
あと、そのサイトの"The Java mindset:"の項では、Javaがメモリーリソース以外を
try/finally で処理するのに対し、C++はRAIIで処理するから try/catch ブロックは少なくてすむ
(この辺りが「Javaドカタ」とか
>>589がいいだした理由かな?)と書いてあるけど、
メモリーリソース以外をRAIIで処理することについては
>>535>>538に問題が書いてある。
>>620 >C でも func が関数ポインタだったら同じことじゃないの?
同じことだね。だから、関数ポインタを使わないでも実現可能な処理は
関数ポインタを使わない方が読みやすい。
実際、関数ポインタを乱用するのは悪いコーディングスタイルだ。
>あるいは x_func(&x, &y) とか。
Cではオーバーロードさえないのでx_funcは一意に決まる。
>>623 > 例外をcatchしたとき、どこからthrowしたか知るのは難しい。
fopen() がヌルを返したとき、どのシステムコールが失敗したか知るのは難しいな。
>
>>517>>520にあるように可読性が下がる。
> 可読性という点でいえば、
>>460のような問題もある。
> メモリーリソース以外をRAIIで処理することについては
>>535>>538に問題が書いてある。
すでに全部反論なりなんなりのレスがついてるんだけど、それについてはどう考えてるの?
>>624 じゃぁなんで C++ の仮想関数は「 virtual を乱用するのは悪いコーディングスタイルだ」で
済ませられないの?
あと、 C++ にはオーバーロードがあるけど x_func() の呼び出しは一意に決まるよ。
違いを言うなら、単純な grep だけじゃ定まらないってところだろうね。
>>625 >>460についてる反論は、C++にはRAIIがあるから、というもので
これについては
>>475>>535が再反論になる。
>>517についてる反論は、戻り値で処理するとか、投げる例外の基底型は
たかだか一つとか書いてるけど、たかだか基底型ひとつでは処理しきれない場合がある
というのが
>>623の主張だし、複数の型を用意すべきというのが
>>621の"Using the bits / data ..."の提案。
>>535>>538についてるレスはとても反論とはいえないね。
C++では安全性の低いプログラムしか書かないというならいいけど。
>>626 OK. virtualを乱用するのは悪いコーディングスタイルだ。それでいい。
そうなるとvirtualなんて滅多に使用しないから、
C++の継承なんて全然便利じゃない。使用しないから。
だからCの構造体+委譲+必要最小限の関数ポインタでオブジェクト指向を実現するよ。
(または、動的型の言語とCを組み合わせて使うよ)
>>628 templateで使うときに共通インターフェースがあると便利なんでvirtual無しでも
crass使いますけど。
Cで委譲とか言ってる人は具体的にどうやって実装してるの?
関数ポインタ使わずにできるのそれ?
>>627 RAII は役に立つし、デストラクタでのエラー処理が問題になるなら
明示的な破棄処理と組み合わせて正しく処理にもできる。 (
>>539-545)
> たかだか基底型ひとつでは処理しきれない場合がある
そういう状況だと戻り値でも同じか、例外のほうがいくらかマシな状況にはなってるんじゃないの?
>>628 「最小限の virtual 」でやったほうが楽だし間違いも減るんじゃない?
>>632 あまり使わない処理が構文でサポート(トラップ込みで)されてるよりも
シンプルな言語でやりくりしたい。
そんな好みが尊重されてもいいと思うの。
>>629 templateで総称型やりたいってのは、また別の話じゃ?
>>630 vtable相当のことをやりたかったら関数ポインタ必要。
今はそうじゃない(できるだけvirtual減らす)という話なので、
関数ポインタなんて無くてもできる。
>>634 構文サポート欲しいってのも好みだけどね。
もう少し中身が見える構文にしてくれればいいのにな
仮想関数はhoge.foo()じゃなくてhoge.virtual[foo]()みたいに呼び出すようにすべきだった
>>631 明示的な破棄処理を書けば正しく処理できるのは否定しないよ。
ただ、明示的に書く必要があり、RAIIは保険として使うというのなら
>>467>>472や
>>621の"The Java mindset:"に書いてあるような
RAIIがあればtry/catchを減らせる、というのは成り立たないよ。
>> たかだか基底型ひとつでは処理しきれない場合がある
> そういう状況だと戻り値でも同じか、例外のほうがいくらかマシな状況にはなってるんじゃないの?
そっちが何を比べてどうマシと言っているのか分からないけど、
>>517のような場合
> 戻り値:関数fを探して、その関数でリターンしてるところをチェックし、エラー処理のコードと比較
> 例外:関数fを探して、例外を投げる可能性のある全てをチェックし、エラー処理のコードと比較
の二つなら、前者のほうが圧倒的に楽だと思うよ。
>>604 どうせ実行時の型を無視できないなら動的型付け言語でいいよね。圧倒的に生産的だし。
>>604 >継承は、ちゃんと設計できてれば、xの状態遷移については
>全ての派生型で問題ないことを保証するだろうが、
継承だけじゃなくテンプレートとかも、きちんと設計するのは苦痛だよな。
必要最低限だけ確実に実装すれば、プログラマ同士が満面の笑みでがっちりと
握手出来るのが C や LL の良い所。
ローカルなsubsystemの中で閉じるという感覚がなくなってるな
テンプレートやら何やら発明された瞬間に全世界が変わるのが普通
変化を拒否したら負け
という世界観
>>637 > ただ、明示的に書く必要があり、RAIIは保険として使うというのなら
>
>>467>>472や
>>621の"The Java mindset:"に書いてあるような
> RAIIがあればtry/catchを減らせる、というのは成り立たないよ。
どういうことなの?
たとえば Java で File は finally の中で close() しなければリソース漏れを
起こす可能性があり、 finally を書くために try ブロックが必要になる。
これに対して C++ の std::ofstream は正常フローの最後に close() の
明示的な呼び出しを書いておけば、リソース解放のために例外を catch する
必要は無く、当然 try ブロックも不要になる。これは RAII による恩恵だ。
・・・と思ってるんだけど、何か間違ってる?
>>637 >>517 の問題は(
>>519 で指摘の入っているとおり)関数の仕様が無い状態で
「すべて漏れなく処理」を望んでいる時点ですでに破綻している。
戻り値なら簡単に可能であるかのように書かれているが、ある時点の実装を見て
実際の戻り値を洗い出しても、仕様が無ければ後で追加・変更される可能性が
あり、そうすれば当然漏れが出る。
問題が破綻しないように事前に仕様があるという前提を置けば、戻り値なら
if (result == FOO_ERROR) ... で、例外なら catch (FooError& e) ... で、
同様のコードを書くことになる。
エラーに対してのリアクションが、もっとも典型的な「リソースを解放しながら
処理を中断する」というものであった場合、例外+ RAII のほうが間違いを
起こす可能性が少なく、後で例外が増えても問題は起こらず、こういった点で
マシだと考えている。
エラーに対してのリアクションが↑以外の何か固有の処理で、しかも処理方法が
異なるエラーが複数返ってくるというなら、
>>522 の言うとおりだろう。
>>639 「C や LL」で設計するのと C++ で継承やテンプレートを設計するのと、
何が違って苦痛なの?
「必要最低限だけ確実に実装すれば~」って話も、「C や LL」は
よく知ってるのに C++ はよく知らないプログラマならそうだろうっていう
当然の話じゃないの?
(「よく知ってる」人口の違いを言ってるんなら否定はできない気はする。)
>>643 >「必要最低限だけ確実に実装すれば~」って話も、「C や LL」は
>よく知ってるのに C++ はよく知らないプログラマならそうだろうっていう
>当然の話じゃないの?
どゆこと?
「C と LL と C++ の全てを知っているプログラマは必要最低限以外の実装も
きっちりこなすはずだ」と言いたいの?
>>644 いやぜんぜんちがう。
「必要最低限だけ確実に実装すれば~がっちりと握手出来る」なんてのはソフトでも
ハードでも、ほとんど何にでも言える話で、それが C++ ではそうはいかないとなると、
「必要最低限」を示した文書が読めないとかそういう話なのかな、と。
テンプレートライブラリが引数に対して明示する要求(「コンセプト」と呼ばれるもの)は
慣れてないと何が書いてあるのかさっぱりわからない、とか。
↓こんなやつね。
http://www.sgi.com/tech/stl/InputIterator.html
>>645 C や LL では「必要最低限」は文書で示す物ではないからね。
そこまでしないと使えない言語を使うのは苦痛だな。
>>646 別にコンセプト使わなきゃ C++ 使えないわけじゃないし、
似たようなことを C でマクロ使ってやろうとすれば同じようなことになるし、
やっぱり
>>639 の真意はわからない。
>>647 C++ はちゃんと設計すれば問題無いと言う人間が居たり、
C++ でも設計しないでプログラムを書けると言う人間が居たり、
話がコロコロ変わって大変ですね。
>>648 どっちも言語問わず当然成り立つ話なんから、誰もそんなことわざわざ言わないと思うよ。
そうだな。多分、このスレだけなんだろうな。
このスレを上から順に読んで行けば君にも分かると思うよ
>>648 それは開放閉鎖原則といって
継承を正当化するためのキャッチフレーズのようなものらしい
>>641 こういう理解度でもC++が使えるのは、C++の利点といえるのだろうか?
また裸の王様はじまったな。
>>641 >>657 その例では、例外が投げられたとき呼び出されてるのは正常系のcloseじゃなく
デストラクタだよ。ofstreamはデストラクタでcloseしてくれる。
でも、デストラクタではファイルクローズに失敗したときに出来ることは殆ど無い。例外投げれないし。
実際、ofstreamはデストラクタでは失敗を無視する。
なので、ちゃんとリソース解放の失敗まで含めて安全なプログラムするなら
RAIIじゃ駄目なときがある。駄目な場合の例は
>>535
>>642 RAIIでは十分じゃない場合が多々ある(
>>535)ということが書かれているのに、
それでもRAIIのほうが間違いを起こす可能性が少ないというならば、
ちゃんと理由を書いてほしい。
>>642 >>521でも指摘されてるけど、コードと仕様が対応しているかチェックする必要があるよね。
だから仕様はあるという前提でいいかと。
> 問題が破綻しないように事前に仕様があるという前提を置けば、戻り値なら
> if (result == FOO_ERROR) ... で、例外なら catch (FooError& e) ... で、
> 同様のコードを書くことになる。
ここで話題にされてるのは、書く難しさではなく読む難しさだよ?
仕様に記述されていない例外が本当に投げられない
(例外仕様を使うならstd::unexpected()が呼び出されない)
ということを確信するためにはいったいどれほどのコードを読む必要があるのか。
って書いてから気がついたけど
> エラーに対してのリアクションが↑以外の何か固有の処理で、しかも処理方法が
> 異なるエラーが複数返ってくるというなら、
>>522 の言うとおりだろう。
ってあるから、もしかしたら持ってる見解は同じなのかもしれない。
でも、それってそんなに特殊な例かな?
>>621のリンク先ではそういう処理を
例外で扱う話がFAQで載ってるんだけど。
>>658 > 正常フローの最後に close() の明示的な呼び出しを書いておけば
って書いてあるのに読み飛ばしてる?
>>661 詳しく。
こっちは open() ~ close() の間のどこかで例外が投げられたケースを考えてた。
>>660 > でも、それってそんなに特殊な例かな?
>>621のリンク先ではそういう処理を
> 例外で扱う話がFAQで載ってるんだけど。
どこのこと言ってるの?よくわからない。
「このエラーのときはこうする」ってのがいくつか決まってることはあるだろうと思うけど、
その場合はハナから列挙されてない例外について考慮する必要はないだろう。
「漏れなく」があるとしたら型は関係なくて「ここでは例外などで処理を中断しては
いけない」という話になるんだろうけど、それなら catch (...) すれば(してあれば)いい
わけで。これはいろんな戻り値を返す関数での「その他のエラー」ってやつに対応する
ことになる。
特定の場所で全部の例外を漏れなく catch なんて仕様は稀だと思うけど、こればっかりは
言い切れないからなぁ。やっぱり例を示してもらうのがいいんだろうね。
仮に、投げる例外を列挙した仕様が先に確定してしまっていたのなら、例外仕様を使うか、
あるいは関数の実装全体を catch (...) で囲うかしてあればよくて、そうじゃなければ漏れてる。
(こんなコード書かせる仕様に文句を付けたいところだというのはお忘れなく)
>>662 もちろんずっとそのケースを想定してるわけなんだけど、
伝わらないようだから具体的なコードを書いてみようと思う。
template<typename T>
void save_to_file(char const* filename, T const& obj)
{
std::ofstream file(filename);
file.exceptions(std::ios::badbit | std::ios::failbit);
file << obj;
file.close();
}
このコードで、 file << obj で何かに失敗して例外が飛ぶと仮定しても
リソース漏れは起こらずその例外は呼び出し元に伝えられる。
逆に file << obj が成功して file.close() が何かに失敗し場合、
file.close() から std::ios::failure (あるいはその派生型)が例外として
伝えられ、それがそのまま呼び出し元に伝えられていく。
665 :
664:2011/03/11(金) 11:21:40.58
念のため先に言っておくけど、 file << obj が失敗したときにさらに file の
デストラクタで close() か何か失敗したときの話は
>>541 ね。
>>663 > どこのこと言ってるの?よくわからない。
"Using the bits / data within ..."の銀行サブシステムの三つの例外の話。
>>665 ファイル自体に問題があって書き込み失敗したのなら
>>541だけど、
file << obj が内部で文字列のエンコーディング変換に失敗とかして
データの一部が破損しちゃった場合、
それで例外が投げられたのならファイルクローズの失敗には対処したいよ。
>>663 > 仮に、投げる例外を列挙した仕様が先に確定してしまっていたのなら、例外仕様を使うか、
列挙した仕様が先にないのなら、仕様があれば例外コードが読みやすいって話はなんなの?
それに例外仕様は投げられる可能性のある型をコンパイル時にチェックしてくれるわけじゃない。
コメントとあんまり変わらん。
あと、catch(...)は万能だけど、そこ通ったら普通はバグじゃない?
もしバグじゃないなら、あんたとは分野が違うってことで納得する。
>>663 > 「漏れなく」があるとしたら型は関係なくて
どうしてそうなる?詳しく。
>>658 ファイルcloseのエラーはリソース解放の失敗を意味するわけじゃないよ。
バグで間違ったハンドル渡してるとかのケースは別として。
>>669 write や fflush の失敗かもしれないって?知ってるって。
C++プログラマは、ただ単にC++のユーザベース・コードベースを増やしたいから
better C などと甘言を弄してCプログラマをC++へ引き込もうとしてる。
そんな安い態度が見え見えなので、Cプログラマは嫌悪を示している。
>>663 > 特定の場所で全部の例外を漏れなく catch なんて仕様は稀だと思うけど、こればっかりは
> 言い切れないからなぁ。やっぱり例を示してもらうのがいいんだろうね。
>>621のリンク先の subsystem in a banking app. の例でもいいんだけどさ。
subsystem を呼び出すとき、呼び出した場所の近傍でそいつが投げる例外を
漏れなく処理するのは普通だよ。
そんなのはシステム境界面で処理しないと発散してしまう。
>>664 おめえ、データベースのセッション中になんかエラーがあったら
セッション切断し損なっても無視するっていってんの?
おめえの方法だとそういうことになるんだけど。
OSSのCプロジェクトでは、日夜こういう会話が(主にメーリングリストで)繰り広げられているという……
C++ PG「なんでC使ってるんすか?C++理解できないんすか?www」
C PG 「何でってCで十分だからだけど」
C++ PG「C++理解できないんすねwwwロートルwww」
C PG 「(うぜぇ……)で、何の用ですか?」
C++ PG「パッチ書いてあげましたよ。もちろんC++でwww」
しかし平均的C++プログラマは
>>586なので、パッチはゴミである。
C PG 「……全然使い物にならないんだけど」
C++ PG「は?C++なのにダメなわけないじゃないすか!C++ですよ!?」
C PG 「そういう問題じゃ……」
C++ PG「やっぱりロートルはダメだなー!C++が理解できないなんて!!」
C PG 「もう帰ってくれ……」
こうやってCプログラマはC++を嫌っていくのである。
Cマ可哀想!
>>666 > file << obj が内部で文字列のエンコーディング変換に失敗とかして
> データの一部が破損しちゃった場合、
> それで例外が投げられたのならファイルクローズの失敗には対処したいよ。
「対処」って、具体的にどうしたいの?
「エンコーディング変換に失敗」を捨てて「ファイルクローズの失敗」を通知
するの?それとも両方の情報をどうにかして混ぜたエラー(戻り値のビット和
とか例外オブジェクトの入れ子とか)を通知するの?それ以外?
・・・こういう聞き返しが要らないように念押して
>>541 を挙げてたん
だけどなー。残念。
>>675 「なんかエラー」と「セッション切断し損なった」との2つのエラーについて、
無視しないとしたらどうしたいのか、つまり
>>678 と同様のことを聞きたい。
あと、具体的にどのデータベース API を想定しているのか示してもらえると
話がわかりやすいんで、できればおねがい。
>>666 > "Using the bits / data within ..."の銀行サブシステムの三つの例外の話。
んー?これが「エラーに対してのリアクションが何か固有の処理で、しかも
処理方法が異なるエラーが複数返ってくる」という例なの?
そこで挙げてる三つの種類の例外がひとつの関数から飛んでくるなんて話には
なってないし、それを一箇所で全部 catch しないといけない、なんて話にも
なってないよ?
例外オブジェクトの区別にはオブジェクト内のデータじゃなくて型を使うべし、
っていう話でしょ。
それに、関数呼び出しに対してそこから投げられる例外を逐一 catch する
ようなやり方は "The return-codes mindset" として否定してるし。
まぁ元々の「それってそんなに特殊な例かな?」については、わりとよくある
だろうと思ってるから、深く突っ込む必要はなさそうだけどね。
そういうときは戻り値を使って分岐したほうがいいだろうと思う。で、たぶん
それらは「エラー」とは呼ばない。
>>667 > 列挙した仕様が先にないのなら、仕様があれば例外コードが読みやすいって話はなんなの?
仕様があるときの話を聞かれてるのか、ないときの話を聞かれてるのか、よく
わかんない。書き込みミスってない?
「~って話」をアンカーで指してもらえるとたぶんわかる。
> それに例外仕様は投げられる可能性のある型をコンパイル時にチェックしてくれるわけじゃない。
> コメントとあんまり変わらん。
そうだね。残念だね。でも動作は明確に変わるよ。それが望ましいことは
少ないんだけど。
例外仕様の動作を受けれるという前提なら、とりあえず仕様に列挙された例外と
コード中の例外仕様に記載された例外を見比べれば対応は明確だ、という話ね。
前提があまり成り立たないだろうとは思ってる。
> あと、catch(...)は万能だけど、そこ通ったら普通はバグじゃない?
C やアセンブリやそのほか例外を想定していない何かの API と C++ との境界
では必要になる。すべての例外を catch するのが正しいので、バグじゃない。
>>668 「漏れなく」ってところでは catch (...) が必要になるし、それが書いてあれば
仕様どおり漏れなく catch されていることは明確だから。
これで話がつかないなら「漏れなく」の意味が何か違うのかもね。
>>670 std::fcloseやstd::fstream::~fstreamは確実に解放を成功させるから、POSIXのcloseみたいに
エラーコードを見て適宜繰り返し呼ぶ必要はないのよ
>>681 > だから仕様はあるという前提でいいかと。
って書いてるよ?
とうか、そっちが勝手に仕様が無い前提の話をしてるだけじゃない?
質問者がそんなこと言い出したことは一回も無いよ?(あったらポインタ示して?)
仕様とコードを一致させるためコードレビューが必要とは言ってたけど。
もしかして、質問者は仕様もろくにないような開発をしているんだ、
という印象操作のつもり?
>>678 このアホはC++でうまく扱えないケースは扱わなくていい、ということにしたいのか?
もちろん両方通知する。
変換に失敗した文字列に関する情報と、成功した文字列が正確にファイルへ
書き込み完了したかどうかは独立の問題だからだ。
そしてお前はアホだからデータベースはうまく扱えない
>>675
>>682 あんたは
>>673のような書き込みを見ても、それでもサブシステムから投げられる
例外を漏れなく処理する、というのをcatch(...)で受け取ることだと思うんだ?
ほんと、分野が違うわ。
>>683 そうだね。そのファイルストリームに対して出来ることは何も無いね。
でも、誤解する人もいないだろうけど、ストリームが解放されることと
期待した結果が得られる(ファイルクローズ成功)ことは別。
ここでリソース解放の失敗と言ってるのは、明らかに後者のこと。
そしてそのストリームに対してできることが無いことは、
アプリケーションにやることが無いことを意味しない。
なんか話がズレてるような。
RAIIはリソース解放処理を簡潔にし解放に関するバグを根絶する為の
手法なのであってI/Oエラー対応は全然別の話。
>>685 んー。聞きたいことがはっきりとはわかってないんだけど、
「投げる例外型を列挙した仕様が無い場合、
例外ベースの処理は読むのがむずかしいのではないか?」
という話かな?
例外型の列挙が無くても、処理が失敗するかどうか(つまり例外が発生するかどうか)と
失敗した場合の状態(例外安全性のレベル)についての仕様があれば、多くの処理では
あまり問題なかったりする。
(個人的にこう思ってるけど、このことについて強い自信があるわけじゃない。
問題のあるケースがあれば知りたいと思ってる。)
この考えの元では、新しく書くコードでも例外発生時の動作として問題になるのは、
変に catch して例外を握りつぶしたり意味の違う例外にしてしまわないこと(例外中立の維持)と、
例外発生時の状態を不正にしないこと(例外安全性の維持)の2点になる。
前者は catch してるところを見れば明らかで、後者は RAII の徹底ができているかを
見ればいい。後者について副作用の順序を確認するのは簡単とは言えないけど、
それは例外特有の話ではなく、戻り値でもそれ以外のエラー通知方法でも同じこと。
>>686 > 変換に失敗した文字列に関する情報と、成功した文字列が正確にファイルへ
> 書き込み完了したかどうかは独立の問題だからだ。
いや、だから、その2つを個別に両方通知するべきなのは当然で、みんなわかってる。
問題にしてるのは、書き込み途中に何か問題が発生して、処理を中断してその問題を
伝えようとしてたら、さらにファイルのクローズに失敗した場合。
この場合はファイルへの書き込みは全部終わってないんだから、クローズの失敗を
大きく扱う必要は無くて、デストラクタを使って(ログの出力程度で済ませて)も問題ないよね、
って話。
データベースの話も同様に考えてる。
>>679
>>688 もしかしてcatch節で後処理すること知らない人?
>>686 問題のケースは↓の (1) になると思うんですが、
ここでどうするべきだという話なんでしょうか?
template<typename T>
void save_to_file(char const* filename, T const& obj)
{
std::ofstream file(filename);
file.exceptions(std::ios::badbit | std::ios::failbit);
try
{
file << obj;
file.close();
}
catch (std::exception& e1)
{
if (file.is_open())
{
try { file.close(); }
catch (std::exception& e2)
{
// ... (1)
}
}
throw;
}
}
>>688 ofstreamが管理している資源はストリームだけであり、確実にファイルに書き込む責任という資源は所有していない
OO的、RAII的に言えばリソース解放というのは所有している資源の解放というのは明らか
>>641がなんて書いていようが関係無い
>>689 まったくそのとおり。
だから、RAIIを使えばtry/catchブロックを減らせる、というのはナンセンスと主張してる。
リソース解放に伴うエラー(I/Oエラーなど)の対応は別にしなきゃならんのだから。
>>693 なんでそうなる?
そうじゃなくて、catch節で後処理しようぜって主張だよ。
>>641はそうじゃないだろ?
>>695 うん。それならそれでいいんだ。というより、あなたの主張は全面的に正しいと思う。
>>690 サブシステムの例外をそれを呼び出した関数で処理しない場合、
呼び出した関数を呼び出す関数群、その関数群を呼び出す関数群、
などなどに例外が伝搬してしまうから。
どんな例外を投げるのかはサブシステムの機能の一部なわけで、
それが伝搬してしまうのはモジュール化が壊れてる。
モジュール化を高めるために、上に例外を再送する場合でも、
一度キャッチして自らのシステムの例外として再定義した方が良い。
実際、システム境界面で処理しない場合に、サブシステムが変更になって投げる例外が変更/増減した場合、
変更箇所がグローバルになってすごい困ると思うんだけど、どうだろうか?
>>680 > そこで挙げてる三つの種類の例外がひとつの関数から飛んでくるなんて話には
> なってないし、それを一箇所で全部 catch しないといけない、なんて話にも
> なってないよ?
リンク先の該当箇所は「エラーを通知される側が、複数種類のエラーから
個々のエラーを区別する方法」を論じてる。
この時点で、一つの関数から複数種類のエラーが通知されるケースを
想定してることは明らかだ。
なぜなら1関数1エラーの場合に「通知される側がエラーを区別できない」なんて状況は、
真面目に論じるに値しないからだ(あんたにはそうじゃないかもしれないが)。
> それに、関数呼び出しに対してそこから投げられる例外を逐一 catch する
> ようなやり方は "The return-codes mindset" として否定してるし。
だれもそんなことは主張してない。
ただ、
>>673>>697 のように、漏れなく例外を catch するケースはあって、
その場合に著しく読み難いと主張してる。
>>691 それは複数の"logically distinct kinds of errors"が単一の関数から投げられるケースは考えないって言ってるんだよね?
それはもういいって。
そんな単純なケースなら確かに例外はうまくいくんだろうが、それは
>>621のFAQで挙げられてる銀行の例とは違う。
>>692 ファイルへの書き込みは(壊れた文字列以外)全部終わってて、それで壊れた文字列と
クローズ失敗をそれぞれどうするかってケースだよ。
しょーもない例で悪いが、webをクロールしてデータを集めて、それをUTF-8変換して
ファイルに保存する場合(壊れた文字列は変換せずにまとめて別ファイルに保存)とか。
まあ、所詮作られた例なんで何とでも言えるけど、両方同時に扱うケースなど無い、なんて
ちょっと強弁しすぎだろう。
>>694 別パーティションのファイルへ書き込んだり、NFS使ってるならローカルのファイルへ書き込んだり。
あとさー、ファイルの例はあんまり深刻さが理解できないかもだけど、
データベースのセッション生殺しはヤバすぎるって(だってプログラムは切断したつもりなんでしょ?)。
それじゃすぐセッション埋まっちゃうよ。
C++の開発プロジェクトでは、日夜こういう会話が(主に会議室で)繰り広げられているという……
顧客 「ファイルを保存する際は、エンコーディングのエラーと書き込み完了の両方を必ずチェックしてください」
C++ PG「できません」
顧客 「え、何故ですか?」
C++ PG「RAIIではどちらか片方の例外しかキャッチできませんから。そんなことも分からないんですか?(ため息)」
顧客 「(うぜぇ……)じゃあRAII以外でやってください」
C++ PG「は?RAIIで出来ないなら仕様が悪いんですよ。仕様を変えてください」
顧客 「何でですか!?それ全然理由になってないですよ」
C++ PG「C++が理解できない無知な顧客は困るなー!わがままばっかりで!」
顧客 「……もう帰ります」
こうしてC++の業界シェアはJavaやLLに奪われていくのだった。
>>699 >
>>694 > 別パーティションのファイルへ書き込んだり、NFS使ってるならローカルのファイルへ書き込んだり。
さすがにそれはないだろ。ファイル名ひとつ受け取った関数のやることじゃない。
エラーを受け取ったアプリケーション側がそういう対処をするならわかるけどさ。
どうやって2つのエラーを同時に両方返すのか、って話が聞いてみたいな。
個人的に、そんな状況を報告してくるAPIにはお目にかかったことが無いんで。
個人的に興味のあるところを抜粋した最近の流れ。
例外使うとコード読むのが難しくなるよ。
↓
catchしすぎだから難しいんだよ。
RAII使えばほとんどcatchしなくていいよ。
↓
RAIIはリソース解放のエラーを扱えないから、やっぱりcatchが要るよ。
↓
RAIIと明示的な解放処理と組み合わせればcatchしなくていいんだよ。
↓
失敗が重なったときに片方しか伝わらないから、やっぱりcatchが要るよ。
↓
いまここ
>>701 二つの例外型を多重継承した型を投げれば良いじゃん。
いちいち型を定義するのは面倒だけど、エラーというセマンティクスを
型というシンタックスへ写像するってのは、そういうことだからね。
>>704 それができれば簡単なんだけど、元の例外をstd::exception&で受けてたら無理なんじゃないの?
たとえば
>>694 のコードだと file << obj からどんな例外が飛んでくるかわからないわけで。
で、例外だと多重継承できれば呼び出し元の期待にはそのまま答えられそうなんだけど、戻り値のときはどうするもんなの?
706 :
704:2011/03/14(月) 13:16:19.25
もとの
>>694のコードで出来ないのは知ってるよ。それはそっちを変更すべき。
っていうか、こっちはC++が嫌いなんだよ。どうやるかなんてこっちに聞くなよ。
こっちは対処する必要があるケースを言ってるだけ。
戻り値のときは、エラーの種別を知りたいだけなら整数型でビットフラグを使う。
もっと情報が必要なときは、情報を保持した構造体を返す。
>>704で書いた多重継承っぽいことがやりたいなら構造体+委譲で。
構造体をそのまま返すか、構造体のポインタを返すか、構造体のポインタを引数で渡すかは状況によりけり。
>>706 > こっちは対処する必要があるケースを言ってるだけ。
「RAII使えばほとんどcatchしなくていい」に対して、ひとつでも catch が必要な
ケースを挙げれば否定できるような流れになってるのは何なの?
そんなのレアケースでしかなくて、レアケースには専用の処理で対処できるん
だから、「ほとんどcatchしなくていい」を否定する意味ないでしょ。
「RAII使えばほとんどcatchしなくていい」と「RAIIだけでは済まないケースがある」とが
両方成り立つ可能性は無いと思ってるの?
>>706 ありがとう。
なるほど、ビットフラグに、戻り値用の構造体か。
やっぱり自分では見たことないわ。
業務でやってるとけっこうあるのかね。
>>707 >>695の言い方を借りれば、RAIIはそもそも失敗の可能性があるリソースは管理していない。
だから
>>641のような方法は、「一度例外が発生したら、それ以後はファイル等のリソースは管理しない」と宣言してるわけよ。
なのに管理できてるみたいな主張しているわけで、そりゃ否定されるだろ。
あと、既に例としてファイルとデータベースと二つあがってるよ?
さらに言えば、安全性度外視の使い捨てスクリプトならRAII大活躍だから。
だからRAIIは役に立つよ。うん。
らいー
Java7 の try-with-resource は Throwable.getSuppressed() に close() からの例外が詰められるらしいぞ。
やったね。
http://d.hatena.ne.jp/irof/20110227/p1 > 「もう片方の例外が消えてしまう!ありえない!これだから最近の若いもんは…」なんて方のために、Throwable.getSuppressed() があります。
やはりC++はウンコすぎることが確定してしまったな
一応、C++0xにもnested_exceptionというのがあって、
>>694の(1)のとこでは、書き込みできなかった例外とクローズできなかった例外をまとめてthrowできる。
Throwable.getSuppressedに相当するのがnested_exception::nested_ptrなんだけど、
getSuppressedは配列を返し、nested_ptrは1個のオブジェクトしか返さない点は異なっている。
>>716 C++0x の nested_exception は Throwable でいう getCause() のほう。 getSuppressed() とは意味が違う。
>>710 > 管理できてるみたいな主張しているわけで
これ、どのレスのことなの?
正しいとされてる
>>695 と否定されてる
>>641 の違いがよくわかんない。
原発の組み込みってCで書いてるんだろ?
FORTRAN
>>718 大雑把にいうと、
>>641はRAIIでtry/catchを減らせる(置き換えられる)と主張してる。
一方、
>>695は単純にRAIIとはどういうものかを説明してる。
C++は罠だらけな上に、ユーザが安全でないコードを作ることを助長してる。
Cもな。
C の方が少ないけどね。
C++ は罠が多いかわりに便利な部分も多い。
C++使ってる人は、他の言語使ったりせんの?
んなわけないだろ。
>>726 何使ってるのん?
どういうときにC++と使い分ける?
>>727 sh, python, javascript, lua, ...
作るものや環境によって使い分ける。
・・・っていうあたりまえの答えにしかならないに決まってるんだから、
ほんとうは何を聞きたいのかよくわからんのだけど。
C++の在り様は適材適所という概念とは遠いところにあるので
そういう質問が出るのも無理なかろう。
意味不明だなぁ。
Cとの互換性を維持しながら抽象プログラミングも可能にし、
また様々なパラダイムを分け隔てなく構文サポートするという
デザイン上の決定のため、C++は壮絶なまでの糞言語へと成り下がってしまった。
そんなC++を好んで使うような人間が他の言語を使う理由って何だろう?
他の言語と比べるとC++のあまりの糞さに我慢できなくならない?
>>731 OSのない環境用のプログラミング言語としてはCかC++ぐらいしか選択肢の無いことが多い。
で、Cに比べてのいろいろなメリットがデメリットを上回れば使うことになるだろう。
メリットについてはこのスレの頭からいくつも書かれてるから、拾い読みしていくといい。
>>731 そりゃC++使ったことのない人間には分からんだろうねぇ。
C++使ったことあるからこそ、C++が嫌いになるという可能性は考えないのか
>>734 アマチュアならそれも許されもするが、プロはダメだ
>>734 Cの細々とした面倒さを経験していれば、
Cに戻る気にはならない。
C++の危なさは全然飲める。
>>737 ・C++はCよりも読み難い
・プログラムは書くのより読む方が難しく、また読む時間の方が長い
これらの意見についてはどう思う?
読みやすく簡潔なコードを書けない738がかわいそうだと思う。
>>738 人の書いたのをいじくる保守奴隷はC
新規のプロジェクト中心なクリエイティブやつはC++
>>739 >>740 C++の最低さのみならず、C++プログラマの圧倒的な低能さ
までもが余すところ無く示されたこのスレで、
一体何の冗談だよwww
> 6.その他、明らかな煽りや無意味な書き込みも無視でお願いします。
プログラマ割合や募集でC/C++と一緒くたになってるのを
みると、お察しくださいだと思うんだがなぁ。
C++プログラマが低能なのは否定できない(このスレ見れば一目瞭然w)からって
Cプログラマも仲間にしようとするなよ。
低能なのはお前等だけだってwww
優れたプログラマは、良いシステム/良いデザインといったものに対する洞察と志向を持つものである。
そのため、適度なシンプルさ、適切な抽象化、直交性の高い規則などを好むのは
その人が優れたプログラマである良い兆候である。
一方、C++のような、場当たり的に構文が追加され、つぎはぎだらけの醜悪な文法は
良いデザインといったものから遠く隔てられている。
このようなグロテスクな文法を好む人間は、システムやデザインの良さに対する洞察力が
根本的に欠けているため、優れたプログラマである可能性は限りなく低い。
おそらく、スパゲティプログラムが何故悪いのかさえ、彼らは本当の意味では理解できないだろう。
CPU論争をちょっと思い出すな。
RISCの方がシンプルで整然としていて直交性が高いと持てはやす人たちが
その昔いたが、どこに消えたのやら。
>>740 × 人の書いたのをいじくる保守奴隷はC
○ 長く保守される良いプログラムはC
× 新規のプロジェクト中心なクリエイティブやつはC++
○ 書き捨てスクリプトはC++
748 :
745:2011/03/21(月) 20:38:47.08
そうそう、745はC++プログラマをこき下ろすのは主題じゃなかった。
言いたいことは、C++を好んで使う人間は優れたプログラマの可能性は低く、
典型的には
>>586のようなプログラマなので、
彼らを自分のプロジェクトから排除するという目的のためだけに
Cを選んだとしても、それは十分に合理的であるということ。
>>748 恐らくLinusの引用だと思うんですが、C以外も使うプログラマが
Cを好むとは今一思えない。仕方がなく使ってるだけで。
メインフレームをVM言語やLLにしましょうとか言われた場合は受け入れるんですか?
>>749 え?Cは好きだし、(悪い部分もあるけど)総体としては全然悪くないと思うよ。
システムプログラミング用の言語としても、LLやVM言語を拡張するための
言語としても、適度にシンプルで扱いやすい。
でも、例えばPythonで要求が満たせるならそっち使うよ。だって楽じゃん。
751 :
750:2011/03/22(火) 07:44:28.52
むしろこっちが質問したいよ。
C++以外も使うプログラマがC++を好む理由は何?ってね。
>>752 エラーの処理については、C++例外を使った方が可読性が低い、とこのスレで議論されてる。
初期化と解放については、そんなものが本当にプログラミングにおいて重要な問題なのか疑問だ。
C++では例外がある上にfinallyが無いから解放はややこしい問題たりえるが、Cでは全然難しくない。
標準で便利なコンテナが提供されていないのはCの欠点だ、というのは認めざるを得ないね。
GLibとかの実装があるし、リストくらいなら自分で簡単に実装できるから不便は感じないけど、標準であるのは便利だ。
最後に、全体的な主張である(と思われる)Cで書くと冗長であるという点については、
その代わりがC++の漏れのある抽象化というならごめん被る。
C++の「漏れのある抽象化」ってのを問題にしてる人(一人?)は、
そのほか諸々の「漏れのある抽象化」は問題にしないの?
C以下にも利便性を優先して受け入れてる抽象化が山ほど積み重なってると思うんだけど。
CPUキャッシュとかメモリアクセス速度とかタスクとかネットワークとか電源とか。
なんでCとC++との間の違いだけことさらに問題になるの?
C++が提供する抽象化は、その他の言語ではもっと良い形で提供されてるから。
あと、C++の漏れのある抽象化の弊害については
このスレで議論されてるけど、Cのそれは述べられてない。
何の理由も無く一緒にされても困る。
>>738 >・C++はCよりも読み難い
そうは思わない。
同等レベル。
>・プログラムは書くのより読む方が難しく、また読む時間の方が長い
読みにくいコードは、どっちにしろ
読みにくい。
とくにC++だから読みにくいとは思わない。
テンプレートや例外は、使うべき範囲で
使うので、問題にはならない。
>>745 C++の全仕様を使い切る必要はない。
自分が正しく使える部分のみを使え。
つぎはぎかもしれないが、うまく
使えば問題にはならない。
>>751 必要充分だから。
また、ターゲットのリソース的に
他に選択肢がないから。
多少の罠があるくらいは不問。
>>753 漏れがあって何がダメなの?
潔癖症なの?死ぬの?
機能が多すぎるからダメって言うのは、スマフォよりガラケー、ガラケーより高齢者ケーが
良いと言っちゃう人なのかな?
だいたい40代後半ぐらいから上の世代はC++に不慣れなのでJavaとかC++のOOにめっぽう弱い
というか取り組もうとすらしなかった世代
まさか今の20代でC++否定とかないわな
>例えばPythonで要求が満たせるならそっち使うよ。だって楽じゃん。
じゃあやっぱり仕方がなくC使ってるだけじゃん。
>>762>>764 だからさ、何かを主張するなら根拠を示そうぜ。
ちなみに、C++とC++プログラマのウンコっぷりはこのスレ参照。
>>763 お前は低能過ぎて適材適所って概念が理解できないのね。
道具を工夫して上手く使う技術が無いのがCPG
このスレ参照(キリッ
C++とC++プログラマはウンコ(ソースはこのスレ
>>755 昔々、アセンブラからCに移行しようとしていた若者たちは、当時の
ベテランプログラマから「Cは遅い」だの「メモリ使用量がわかりにくい」だの
たいそう言われたものさ。
>>766 別にCと適当なLLなりVM言語なり組み合わせれば良いじゃん?
それも道具を上手く使うって範疇に入るだろ?
>>769 アセンブラと、レジスタやスタックを抽象化したCでは記述できる対象が違う。
Cではアセンブラの代わりにはならないし、その逆もしかり。
あとさ、
>>728 がPython使うって書いてたけど、C++とどうやって使い分けてんの?
そういった言語使っててC++の醜悪さと生産性の低さは気にならないの?
このスレのC++使いは、自分はろくに思考もせずに安易に質問するくせに、
他人の質問はスルーするから困る。
773 :
772:2011/03/23(水) 07:46:22.82
ああ、そうだった。
C++使いは
>>745だから、C++が醜くても気にしないんだったね。
忘れて。
CPGって参照使いたくなったり継承使いたくなったり演算子の関数のオーバーロード使いたくなったりすること、全くないの?
これらすらも使いこなせないから手を出さないの?
それともCオンリーでがりがり書いてるの?
>>771 Cと、OOやテンプレートを使えるC++では記述できる対象が違う。
C++ではCの代わりにはならないし、その逆もしかり。
>>772 Cの面倒さと生産性の低さは気にならないの?
>>774 参照はconst参照のみなら、あってもいい。それ以外の参照は邪魔だ。
継承については
>>628。時々使うが構文サポートなんていらん。動的型付け言語でもないのに実行時の型を強く意識する必要がある。
演算子オーバーロードは可読性が下がるからマジでいらん。
最近はPythonを良く使ってる。
>>775 C++は構文糖を追加してるだけ。しかもキモイ。
Cでしか書けないところはCで、それ以外はLLで良い。
>>776 >>738 あとさ、Pythonなりと簡単に組み合わせられるって言ってるじゃん。
そこ無視して何言ってんの?アホなの?
Cで無理矢理我流にOOしたソースが読みやすいわけがないバカでもわかるだろそんな事
実務したことない趣味グラマかCでOOとか言ってるのって
実務レベルで見ると、ここの自称Cプログラマ、C++プログラマ、両方の言うことが胡散臭いからな。
>>781 信じられないだろ?C++信者の発言のまとめなんだぜ、それ
>>782 Juha Nieminen なんていう国際的馬鹿のことなんてどうでも良いわ。
誰が連れてきたんだよこんなカス
Cやってて例外が欲しい時がある
で、C++にすると、finallyがないことに気付く
Cにも例外が欲しい、C++にもfinallyが欲しい
Cにもメタプログラミング用の機能が欲しい時がある。
C++のtemplateのように、うっかりチューリング完全でしたみたいなやつじゃなくて
最初からメタプログラミング用にデザインされたやつを。
メタプログラミングは、通常の変数に入らない第二級オブジェクトをプログラムする。
おれは第二級オブジェクトが欲しいとは思わない。
第二級オブジェクトって何?
オブジェクトをプログラムするって?
例外と rtti は要らね。
クラス、スマポとテンプレートは無いと死ぬ。
あと C++0x の細々とした機能がはやく欲しいな。
これができれば C でもいいや。
>>787 他人のことばかり語って
自分は語られる対象になれない
かわいそうなオブジェクトのことです
>>777 > 演算子オーバーロードは可読性が下がるからマジでいらん。
それって可読性を下げるだけの使い方しかできない、キミの落ち度でしょ。
使い処を間違えてる自分を責めれば?
>>790 道具の使い方は、使う人じゃなくて使われる状況で決まるんじゃないか
逆に、状況と無関係に「正しい使い方」が決まるようなものは道具ですらない
アレなプログラマしか居ないなら、
C を選択してしまうかもしれない。
実際に、そう選択したことはあった。
数年前だけどね。
そんな状況では C でも悲惨だけどな。。。
>>755 「良い」の基準が違うだけじゃないかなぁ。
オーバーヘッドを抑えるだとかCコンパイラ・リンカとの親和性を保つだとか、
そういうC++のミッションを無視すればそりゃ他の言語より出来が悪く見えるかもしれないけどさ。
「C++の漏れのある抽象化の弊害」ってのが何のことを言ってるのかはっきり
わからないけど、Cのstrlenやreallocの誤用は当てはまらないっていうんでしょ?
結局自分が知ってるかどうか、自然に感じるかどうかっていう基準でしかないんじゃないの?
「Cをマスターした俺をおどろかせるような抽象化の漏れは有害だ」っていう。
抽象化「詳細を知る必要はない」
漏れのある抽象化「ただちに詳細を知る必要はない」
Cの、
ライブラリ関数がマクロか関数か決まってないとか、
memsetでポインタや不動小数点数を0埋めしても0にならないとか、
ctype関数にcharの値を渡しちゃダメとか、
コンパイルエラーにならないconstとか、
可変長引数での暗黙の型変換とか、
setjmpのガチガチの利用制限とか、
そういう諸々の(実装や歴史を知らないと納得できないような)罠については
理不尽だと言わないの?何が違うの?
そういう例を挙げると「C++プログラマがCを使うと危険な例」にされるんだよな。
ほんと、どうかしてるぜ。
>>791 つまり、悪いのは状況であって、自分ではないとw
>>796 > ctype関数にcharの値を渡しちゃダメとか、
> コンパイルエラーにならないconstとか、
どういうこと?
> 可変長引数での暗黙の型変換とか、
どういうこと?
shortもintになるけどlongはintにならない。
sizeof(long) == sizeof(int)の人は要注意。
803s/の人/に慣れている人/
>>801>>802 それが罠と言う人は、それで問題おきるような使い方してるのか。
>>796の
> ライブラリ関数がマクロか関数か決まってないとか、
も含めて、そういうのが問題になる使い方の例を示してほしいな。
>>796 > memsetでポインタや不動小数点数を0埋めしても0にならないとか、
わざわざmemsetって名前が付いてるのに、メモリのゼロクリアじゃなくて
数値をゼロにすると思っちゃうの?なんで?
罠っていうのはさ、例えばC++でmemsetをうっかりplain old data型以外に
適用すると未定義動作になっちゃうとか、そういうのだと思うよ。
>>790>>798 ひとつの記号がコンテクストに応じて色んな振る舞いをするっていうのは、
すごく読み辛いんじゃないかな。
Cでも、staticが状況に応じて色んな意味を持つのはうざいでしょ?
言語仕様で定義されてる振舞いだけでも、記号の多義性はうっとうしいのに
ユーザが勝手に定義できるとか、うざすぎでしょ。
>>801 関数の定義域が0からUCHAR_MAXまでの正整数とEOFのみってだけだよね?
関数が、ある型の一部の定義域のみで値を持つことって普通にあると思うけど。
>>796 それらのリストには、確かにCの抽象化の漏れと言えるものも含まれてる。
しかし、ライブラリ関数は「嫌なら使わなくていい」し「使われてるかどうか簡単に調べられる」し
「正しく使うのが難しいなら、使いやすいラッパーを用意する」ことも出来る。
つまり
>>320でいうなら「漏れたときの対処が容易」だから、そんなに問題じゃない。
演算子オーバーロードを問題にするのも言いがかりレベルの話だと思うけどね。
好きに定義できるからといって、可読性が落ちるような使い方をするやつは
いないだろと。
<<と>>だけは変な使われ方することがあるかもしれないが。
>>810 いるよ
可読性は落ちるが短く書けるとか、リスクはあるが低コストとか
すべてはトレードオフ
確かに、ソースが重要だな。
仕様書のどこにも書かれていない、現場のソースが重要。
仕様書だけをソースに、ctypeが云々というのも言いがかりだろう。
>>812 あなた、boostを初めてみたときの「なんじゃこりゃ!?」
って驚きを忘れてしまったのよ……
>>809 > しかし、ライブラリ関数は「嫌なら使わなくていい」し「使われてるかどうか簡単に調べられる」し
> 「正しく使うのが難しいなら、使いやすいラッパーを用意する」ことも出来る。
C++の問題点として挙げられているもののうち、これらにあたらないと思ってるのはどれ?
どれも同じことだと思うんだけど。
・デフォルト引数+仮想関数
・C++例外
・演算子オーバーロード
結局は問題の量と得られるメリットとのトレードオフなのに、
「Cを選ぶ理由は無い」とか「C++を好んで使う人間は優れたプログラマの可能性は低い」とか
極端なことを言い切っちゃうから不毛な議論の種になるんでしょ。
いいかげんに学習しなきゃ。
>>815 それら三つとも、「使われてるかどうか簡単に調べられる」がイマイチかなー。
どれも「定義してる側」を見れば分かるんだけど、「使用してる側」を見ても分からないんだよね。
検索性もイマイチだし。
あとC++例外は「嫌なら使わなくていい」も難しい。
標準ライブラリをごっそり諦める必要があるからね。あとコンストラクタのエラーをどうするかとか。
最後に「使いやすいラッパーを用意する」も何かピンとこない感じ。
だってそれらの機能自体がシンタックスシュガーという「ラッパー」だからね。
でも、結局は
>>816でFAだわ。皆好きなの使え。
>>816 トレードオフは、単純なモデルで行き詰まった場合にのみ許される複雑なモデル。
Cで行き詰まらない限り、C++で複雑なトレードオフを考えるメリットはない。
>>818 Cを選択することにはトレードオフが無いかのような発言だな。
なんで
>>816のすぐ後にそんな書き込みができちゃうのか不思議だわ。
>>818 トレードオフは、選択肢のあるモデルで行き詰まった場合にのみ許される複雑なモデル。
Cではただ機能が不足しているので、C++からわざわざトレードオフを考えるメリットはない。
>>820 C++の機能から、トレードオフで必要な機能を選択したらCになった。
通常は、GCを使うか使わないかの単純な二択。
C++を含めると、数種類のスマポが選択肢に加わる。
Boehm GC さんを忘れないで。
>>816が的確なことを言ってしまったから、学習不足な偏見の塊が
騒ぎ始めたよ。
演算子オーバーロードに関して。一つの記号に複数の意味があるのを否定するなら、
文字列の連結に+を使う言語や&を使う言語はどんなもんかね。
只並べるだけで連結できる言語(awk)もあるが、正直却って読み難いぞ。
>>825 ユーザーが自由に多重定義するのとは違うから、統制がとれている。
ちなみに、連想配列があればユーザー定義型もいらないってのが動的言語の魅力。
>>825 文字列の連結に+を使うのは、+記号なのに加法(交換法則)を満たさないから
実はあんまり良い定義じゃないと思う。
>>826が言うように統制が取れてるから
そういうものかと受け入れられるけど。
なるほど。じゃぁ、ドキュメント化とコードレビューとで統制が取れればなんとか許容かな。
まぁでも、統制が取れない馬鹿はCでもFILE*をフラグに転用したりするから同じことって気もするけど。
>>818,820
「行き詰らない限り」と言っても、
>>752-753 にあるように配列以上の高級なデータ構造を
扱おうとしたら機能の不足によりわりとすぐ行き詰まったりして、あまり稀でもない。
>>829 その高級なデータ構造に動的な型付けをするなら、C++は使わない。
結局、静的型か動的型かで対立しているのだと思う。
>>828 仕事なら統制取れるからC++は許容できる。チームの面子にもよるけど。
オープンソースだとC++は辛い。統制とり辛いし、基本patchでのやり取りだし、
それに
>>676みたいなの本当に在るんだぜ。
>>829 すぐ行き詰まるから、逆にLL等と組み合わせるときに
どこまでCで書くか悩むことが少ないというメリット(?)もある。
>>828 > まぁでも、統制が取れない馬鹿はCでもFILE*をフラグに転用したりするから同じことって気もするけど。
いくらなんでも、そりゃねーよwww
>>829 型チェックが弱くなる欠点があるけど、それを許容できれば
Cでもリストやハッシュくらいなら問題なく使えるけどね。
別にfor文でリストをイテレートするくらい、書き難くも読み難くもないだろう?
>>828 FILE*をフラグに転用したりするほどの馬鹿が
C++で演算子オーバーロード使ったらどうなるのっと
Linux原理主義者の言ってることは
要するに彼らには必然的にマルチプラットフォームであらゆる環境への対応が必要で
道路が整備されていないところで自動車を使うのは危険だ馬車を使うのが最も良い選択だ
馬車でも馬を交換しながら走れば車と同じように走ることはできる
と言ってるようなもん
C :ナイフ。切れ味は良い。缶切りや栓抜きの代わりもできるが、専用器具の方が使い勝手が良い。
C++ :十得ナイフ。ただし全部の刃が専用ナイフと同等の大きさ。通常の人間の手には大きすぎ使い難い。
>>837 何も問題ない。C++は神の言語だからどれほどの馬鹿が使っても
問題が起こらないように設計されてる。
実際にC++使いは馬鹿ばかりだが何の問題も起こってない。
>>832 本当にいたんだってばw
main()が延々と1000行位続く中で、先頭のほうでFILE*を使ってファイル読み込みが終了。その後でフラグとしての余生をw
記憶に間違いなければこんな感じ。
--
#include<stdio.h>
//他、色々使ってなくても色々インクルード
main(int argc, char**argv)
{
FILE*fp;
//その他有象無象の変数群が100行ほど
if(!(fp=fopen(argv[1],"r"))) exit(-1);
//ファイル(確かcsv)読み込み処理が200行ほど
fclose(fp);
if(func()<0)fp=0;//この関数もトンデモだった気がする
//なんかの(演算)処理が400行ほど
if(!fp)
{
//更になんかの処理(出力向けの文字列加工だったか)が200行ほど
}
//結果の出力に100行ほど
}
>>821 わらた。
でも個人的には、クラスやテンプレートが
ないと、ウンザリしちゃうんですが。
>>827 気持ちはわからんでもないけど、
合理的な主張ではないと思う。
一般的に受け入れられる表記なら、
統制とやらにかかわらず受け入れる
べき。だいたいわかりやすくなれば
いんじゃね。
>>843 変数に型のない言語も、一般的に受け入れられているよ
受け入れちゃいなよ
>逆にLL等と組み合わせるときにどこまでCで書くか悩むことが少ない
これを読むと、結局Cにも高等アセンブラ以上の価値は無いってことなんだろうか。
C++には何の価値もないけどね
いや、低能プログラマ判別装置としての役割があるか
847 :
843:2011/03/30(水) 09:32:14.51
>>844 受け入れてる。最近はPerlばっかり。
ただそういうのが使えない環境は
やっぱりあって、そこではC++を
使いたい。オレは。
>>847 その環境がもっと有名になれば、C++の評価も上がるんじゃね
PerlやC#は、OSの環境を前面に押し出して成功したんだろ
不便な環境が有名になるのを願うって後ろ向き過ぎるだろ
なんで動的言語が使えない環境=不便な環境なんて思っちゃうのかねぇ。
>>849 じゃないけど、世間では
動的言語 = 性能が出ない代わりに便利だから普及している
という認識が一般的だと思ってたわ
>>850 ばーか。
動的言語も使えるけどC++を選ぶってならともかく、
使えないからC++を選ぶっていうんだから、不便だろ。
C++ PG「CとLLの組み合わせには敵わないから、LLが使えない不便な環境が流行ってくれぇ!」
ちっちゃい組み込み機器なんかが有名になるのを願うのは後ろ向きとは言わないんじゃないかね?
スマートフォンとか、もうVM言語が載るくらい十分に高性能になっちゃったからねぇ
もっとしょぼい環境が流行ってくれないとC++使いは困っちゃうね
いや、別に流行らなくても困らない。
ほっといてもC++の人気は落ち続けてるんだから
こんなスレで苛めなくても良いのに
Roomba のソフトウェアは Common Lisp のサブセットで書かれているという話もあるし、
リソースの限られた環境向けのプログラムが C/C++ じゃないといけないという事も
無いんじゃないの。
たかが掃除機にすらGC付きの言語が載る時代なんだなぁ
C++とVBのシェアがC#に奪われてるって書いてるね。
グラフを見てもC++の人気は下がってるね。
C++ってほんとに落ち目だね。
新しい言語を覚えることも出来ず、やっと覚えたC++にしがみついてる低能は哀れだねぇ
C++なんてUnixにおいては所詮one of themに過ぎないし、
Windowsではメイン開発言語の座をC#に奪われてしまい、
OS Xではそもそも相手にされていない。
いまさらC++を選ぶ理由なんてないな。
> OS Xではそもそも相手にされていない。
意味不明。
触るなよ
> 6.その他、明らかな煽りや無意味な書き込みも無視でお願いします。
もしかして
>>860はテーブルの矢印だけみて
「C++の人気は上がってる!」って喜んじゃって
嬉々としてリンク張っちゃったのかな?
ちょっとでも英語読めれば、全然逆のこと書いてあるの分かったのにね。
>>864 MacはObjective-Cがメインでしょ
そ、そうだね。C#すごいね
人気で一喜一憂とかw
アニオタかよ
>>867 お前には分からんだろうが、速度が必要な所にはSTLとか使うし。
Objective-Cで速度稼ぐためにIMPを使うのではなくSTL使っちゃうなんて
本当に低能C++使いは新しいこと覚えるの苦手なんだね。
ほれ見ろ元気になっちゃったじゃないか。
> 6.その他、明らかな煽りや無意味な書き込みも無視でお願いします。
もういっこ。
> 1.Java、C#などの「C/C++」以外は論外。これらについて言及している
> レスは無視してください。
>>871 お前には分からんだろうが、NSArray や CFArray は std::vector の代わりにはならないww
>>872 C++に関連した事象を述べてるだけだよ。
>>873 そりゃそーだ。だからライブラリの受け渡しするときは、
いちいちstd::vectorをNSArrayに変換しなきゃいけないよね。面倒くさいね。
あと、Objective-CとC++はそれぞれ独自の例外処理を持ってるけど、
混ぜて使うと簡単にリソースリーク起こすよね。
だから混ざらないようにtry/catchの嵐になるね。馬鹿だね。
>>875 > std::vectorをNSArrayに変換
馬鹿丸出し。
もはやC++使いは理由を述べて反論することも出来ないwww
語れば語るほど低能さを露呈するからwww
std::vectorをNSArrayに変換www
try/catchの嵐www
879 :
デフォルトの名無しさん:2011/04/01(金) 20:08:43.20
CとC++はどっちから勉強したらいいんですか?
用途はDLL作成とコマンドラインツールが主です
>>879 その用途ならどっちでもいいんじゃね?
このスレでは論争ごっこして遊んでるけど、CもC++も十分実用的な言語だから。
プログラミング初心者ならC++は少し難しいかもなぁ。
C++は低能専用言語なんで、それでも良ければ
C++は低脳には使えません
883 :
デフォルトの名無しさん:2011/04/01(金) 21:10:45.24
何故C++は難しいのですか?
C++の文法は罠だらけだから。
罠を避ける方法を学ぶためだけに最低でもEffective C++を読む必要があるから。
>>883 1から作った言語ではなくCの上位互換を強く意識しているために
落とし穴だらけになった
しかも完全上位互換じゃないし
対極的な言語としてはC#があり、JavaをSunに訴えられたM$が
リベンジを誓って1から作ったために言語としてはほぼ完璧な構造を持つ
対してJavaは建て増しに次ぐ建て増しで次第にガタガタに崩れて来ている
OOP自体が、建て増しに次ぐ建て増しを推奨していた時期があった
C++は既にPL/Iの規模を超えてるよな
C++がC#に取って代わられつつあるというのは分かるが
Cはもうファーム用言語だな
俺はC++はよく分からないけど、機会あれば使ってみたいよ
そっか、俺はファームを書いてたんだ!
で、ファームって何?
>>883 難しかったら「難しいから採用されないんだ」って言えるでしょ
891 :
デフォルトの名無しさん:2011/04/01(金) 23:54:18.06
C++はあの秀丸エディタの開発で使われてますよ
C++はあのLLVMの開発で使われてますよ
C++はあのGCCの開発で使われてますよ
有名処って LLVM, V8, OpenJDK, Firefox, Inkscape, WebKit と OOo くらいかな
後なんかある?
コンシューマゲームとか。
イギリスのオンライントレード?だったかがC++
Darwin
ゲームの?
ゲームと言えば Quake III は C なんだな
ライブラリを入れると膨大になるので自立して動くプログラムだけ。
Linux, *BSD, Apache, MySQL, Perl, Python, Ruby, Blender, Quake III, etc.
この辺りは全部 C かな。中で一部 C++ を使っている物もあるけど。
>>897 Mac OS X の Kernel 部分の事を言いたいなら、実装言語は C でしょ。
> Mac OS X の Kernel 部分の事を言いたいなら、実装言語は C でしょ。
やたら C ということにしたいようだが、どの部分のこと言ってんの?
>>894 金融系は OCaml とか何でもアリだからな
このスレ読んで分かりました
C++使いは低能じゃなくて無能なんですね
>>897 Darwin というか MACH/BSD は C と ASM だぞ
>>902 何故ろくに知りもしないことに口を挟むのか
C バケツでウラン
C++ 汚染水溜まりに新聞紙
ワロタw
残念ながらC++はオワコン
matzがtwitterでC++をdisっとる
>要するに「私は大クラス主義に慣れていて、
>Java/C++プログラムで細かいクラスがたくさんあると
>把握しきれない」という自分の能力の限界の暴露に過ぎないのです
歳とったら無理って結論だろ
>>914 低能には謙遜とか皮肉って理解できないのかな?
>>894 > WebKit, Firefox
に加え Chromium も C++ か。
FFmpeg は C(しかもC99)だね
フーリエ変換や物理挙動のコアライブラリーみたいな数式的なものを書くときはCで十分だし、むしろ巨大関数として一気に書いてしまった方が作りやすいってのもある。
HTMLパーサーのような巨大なシステムとしての構造を書くなら、C++みたいにクラスを使える言語の方が整理しやすくて作りやすいと思う。
ブラウザーがC++で、FFmpegがCなんてのは、まさに象徴的な気がする。
Gimp も C
>>916 >Chromium も C++ か。
Chromium は超巨大プロジェクトだから何とも言えない。
C++ が多いのは WebKit や V8 がベースだから当たり前。
% du -sh chromium
3.6G chromium
% find chromium -type f | wc -l
237588
% find . -name '*.cpp' | wc -l
8091
% find . -name '*.cc' | wc -l
7687
% find . -name '*.c' | wc -l
5891
% find . -name '*.py' | wc -l
5174
% find . -name '*.js' | wc -l
4220
% find . -name '*.idl' | wc -l
2427
% find . -name '*.mm' | wc -l
1138
% find . -name '*.m' | wc -l
303
NaCl は大体 C だね
% du -sh native_client
264M native_client
% find native_client -name '*.c' | wc -l
504
% find native_client -name '*.cc' | wc -l
260
% find native_client -name '*.py' | wc -l
113
このスレでC++を推してる人はソース読まないから
各プロジェクトで実際にどの程度C++が使われてるかなんて知らないよ
このスレでCを推してる人はソース読んでるから
各プロジェクトで実際にどの程度Cが使われてるか完全に把握してるよ
>>918 >フーリエ変換や物理挙動のコアライブラリーみたいな数式的なものを書くときはCで十分だし、むしろ巨大関数として一気に書いてしまった方が作りやすいってのもある。
これもC++で書いた方がいろいろメリットがあると思うが。
巨大関数のすべての変数を冒頭で宣言するのは面倒。
面倒なだけならいいが、最初に宣言して後から初期値を設定しなくてはいけない状況では
意味的に定数でも変数にしなくてはいけないから、バグの温床になる。
const変数をif文やfor文の中で宣言できないのは、正直つらい。
別に巨大関数なんてCでも滅多に書かないわけだが、そんな理由ならC99で十分なわけですよ。
あと、C99では標準でrestrictがあるのでasm無しで最適化効かせられる。
>>924 >巨大関数のすべての変数を冒頭で宣言するのは面倒。
規格上も、10年以上前からそんな事をする必要は無いんだが。
そそ。巨大関数を書く奴に限って関数先頭で宣言したがる。
で、そんな奴はC++で書かせてもやっぱり関数先頭で全部宣言してしまう。
共通処理クラスをわざとそれでは使いにくいように設計してやったら、
そのクラスの宣言だけ途中に書いて、それ以外はやっぱり関数先頭で宣言していた。
存外、>924も実はその口かも知れず。
フーリエはともかく、物理挙動みたいに現実の概念を
プログラムで表現する場合はCよりC++の方が遥かに
適していると思うが。
>>924 >最初に宣言して後から初期値を設定しなくてはいけない状況では
初期値を設定出来る所で宣言すれば良いじゃん
いつの時代の人ですか?
>>929 Simulaの後継であるC++はオブジェクト指向的な
シミュレーションがCより得意と言いたいのかな?
それはそうかもね。
でもさ、計算速度が必要なときは
きちんと効率よく解ける方程式を導出して解くので
オブジェクト指向とか関係ないんだよね。
計算速度が必要ないならC++である必要も無いしね。
>>924 こういうレベルの理解度でCの代わりにC++使ってる人多いんだろうなぁ
restrictや可変長配列などのCのメリットを説明するならまだわかるのだが、
「Cで十分」という説明はCのメリットがありませんと言ってる
ようなものだ。
C++使いからしたら、敢えて機能制限の多いCを選ぶ必要は無い
不思議な理屈だなあ
言ってるような物だと無理矢理断定しても、言ってない物は言ってないんだぜ
C++ な人はソースコードを確認しない人とか、規格を確認しない人ばかりなの?
そんなんだと、断定口調で書き込んだ所で説得力は無いよね
C使いは
>>934みたいに人とのコミュニケーションができない
知障ばかりなのね
俺はむしろ気軽に他人を知障と呼んじゃう人が心配だわ。。。
>>935 C++はソースの可読性がクソだし、規格をちゃんと把握するのも困難だ。
ソースや規格を確認しないような人だからC++を好むのかもしれん。
>>933 それは確かに感じた。
C使いが、Cが必要だと理由を言わず、ただ単にC++が不要だと言っている。
これでは、C++を使えない自分に対する言い訳を言っているようにしか聞こえない。
もしくは10年、20年以上前の記憶でしか、C++を見ていないとか。
いつの時代の人ですか?
>>939 >いつの時代の人ですか?
何だ気にしてたのかw
皮肉は事実に裏付けされていないと意味ないよ。
どう考えても、大規模なソース書く上で、C++の方が可読性がいい。
「どう考えても」は理由の説明じゃないよ
どう考えたのかを具体的に書かないとネ
>>938 Perl と C++ は可読性が低い言語の二大巨頭だな
一時期大きな人気を獲得して、その後、後発に追い抜かれたという点でも似ている
スパゲッティプログラムってあるだろ。C言語はそれになる。
C++はクラスなどを使うことで各機能を分割して作成できる。
それに標準機能がC言語より多いからコードの短縮にもなる。
C++ の可読性が低いなら C っぽく書けばいいじゃない
C++ の全ての機能を使う必要はないのよ
C++ PG が書く C が汚くなるのは、このスレから想像が付くよな
C が悪いんじゃなくて、ただ C を知らないというだけの話だが
>>945 C++ で C っぽく書くなら C で書いた方がマシ。
C++ の機能を充分に使えず、C とも互換性が無いコードなんて誰も読みたくないわ。
スパゲッティプログラムとは。
処理の流れや構造を把握しにくく、修正や機能の追加が困難なプログラム。
麺が複雑に絡み合い数本の麺を引っ張り出そうとしても全体がついてくる、スパゲッティに例えたのがこの言葉である。
http://e-words.jp/w/E382B9E38391E382B2E38383E38386E382A3E38397E383ADE382B0E383A9E383A0.html オブジェクト指向プログラミング - Wikipedia
背景
オブジェクト指向という考え方が生まれた背景には大規模なソフトウェアが書かれるようになってきたということが挙げられる。
コードが複雑化してゆくにつれソフトウェア開発コストが上昇し1960年代にはsoftware crisisといったようなことも危惧されるようになってきた。
そこでソフトウェアの再利用、部品化といったようなことを意識した仕組みの開発や開発工程の体系化などが行われるようになった。
このような流れの中で、プログラムコードについては手続きや関数といった仕組みを基礎に整理され、
その構成単位を部品化を推進する仕組みが提唱され構造化プログラミングとしてまとめあげられた。
しかしデータについては限られた種類の基本データ型の値という低レベルの抽象化から抜け出せなかった。
そこでインスタンスを整理して管理する仕組み(例えばクラスとその継承など)まで
考慮して生まれたのがオブジェクトという概念である。
C++の創始者は論理美の追求よりも現用としての実用性を重視した。
そのためC++の再定義した「オブジェクト指向」はこれらの問題を全てクリアにし、
既存言語の拡張としてオブジェクト指向機能を実装できることでブレイクスルーを迎え急速に普及する。
大規模なソフトウェア開発のためのC++言語。
可読性、保守性が落ちたらC++を使う意味が無い。
可読性が落ちるっていうやつは、上手く使えてないだけだろ。
どんな機能を備えた言語だろうと、スパゲッティコードを書くプログラマは
いとも簡単に汚いコードを書いてのける物だぜ。
オブジェクト指向に万能感を抱く時代は90年代で終わりを告げたと思っていたが・・・
>>949 もっと扱い易くて可読性を損なわない言語があるから
わざわざ C++ を採用する理由も無いんだろう
>>947 今更、素の C なんかで書きたくないわ。
C との互換性を気にしなきゃならんとか理由があるなら別だけどね。
>>952 中途半端な C++ で書く方が理解に苦しむわ。
Better C は絵に描いた餅。
>>952 今更、C++ というのも十分微妙なんだがな・・・
>>952 C99オススメ。食わず嫌いなら。
Cの構造体やファイルスコープなどのモジュール化機能は原始的だけど、
LinuxやFFmpegくらいの規模のプログラムなら問題なく組めるわけで、
しかもコードスペニットが局所的コンテキストにのみ依存する
シンプルな構文のため(書き手によっては)可読性も高い。
まあ、巨大なプロジェクトだとC単体じゃ辛いけど、
その規模だと他言語と組み合わせたらいいと思うわけよ。
>>951 CもC++もイマイチだが。CよりかC++はわかりやすいってだけ。
他言語との比較はしてないんだろ。
C++がCより分かり易いとは到底思えんな
string a,b,c;でc=a+b;など。
ポインタのポインタ使わずに参照やクラスで置き換えられること。
スパゲッティコード減らせること。
>>953 Better C 悪くないけどなあ。どこまでが Better C なのかは微妙なとこだけど。
>>954 それは同感。
>>955 プレステの頃は C でも書いたけどねえ。 C はもうやだ。
まあ結局何を作るかによるんだろうなあ。
みんな何作ってるのよ?
おいらはコンシューマゲームとか。
ツール類は Python とかだねー。
>>958 便利な機能を積み上げて行ったら、全体として汚くなってしまったのが C++ だと思うわ
スパゲッティコードは C++ でも量産可能
STL開発に必要な機能を付け加えていったのがC++。
STLの構想が先にあり、実現のためにC++が作られた。
STLのアーキテクチャの多くはアレクサンドル・ステパノフによって作られた。
1979年に彼はジェネリックプログラミングの初期アイデアを練り始めソフトウェア開発に革命をもたらす可能性を探究し始めた。
ジェネリックプログラミングの一部は1971年にデイビッド・マッサーにより開発されて提唱されていたが特定のソフトウェア開発の分野に限定されたものであった。
ステパノフはジェネリックプログラミングの大きな可能性に気づきゼネラル・エレクトリックの仲間たちに、ジェネリックプログラミングがソフトウェア開発の広範囲に渡る基礎として研究されるべきだということを説得した。
当時はジェネリックプログラミングを実際にサポートしているプログラミング言語がまだなかった。
Standard Template Library - Wikipedia
今頃 STL の歴史のおベンキョですか
コードも規格も読まないし、
C++の良さも自分じゃ説明できない(理由の無い断定のみ)から
Wikipediaのコピペくらいしか出来ないのさ
>>958 スパゲティコードを減らせるどころか、
言語仕様がスパゲティになってるだろwww
> 理由の無い断定のみ
>>939 > C使いが、Cが必要だと理由を言わず、ただ単にC++が不要だと言っている。
C はシステムプログラミングや他言語の拡張に有用であり、必要。
C++でも同じことは出来るが、コード片が持つ意味に影響を与える範囲が
(比較的限定されてるCに比べ)あまりにも広く、そのコード片の持つ意味を理解するのに
大量のコードに目を通す必要があり、端的に言って可読性が低い。
だからC++は不要。
> これでは、C++を使えない自分に対する言い訳を言っているようにしか聞こえない。
他者が書いてるものを理解しようとしないから、自分が聞きたいようにしか聞こえないんだよ。
>>967 ネタだと思うけど、なんかもう病的だよな。
>>959 >Better C 悪くないけどなあ。
貴方はどんな時に Better C を使うの?
一人で書くなら気兼ねせずに C++ の機能を余す所無く使えば良いでしょ。
チームで書くなら C++ 使いにとっても C 使いにとってもストレスフルな
コーディングルールを採用する事は疑問だなあ。
そもそも、どこで線引きをするかで余計な調整作業が発生するし。
嫌がる C 使いに無理矢理 C++ を押し付ける時くらいしか役に立たない
気がする。
どっちが好みでも構わないけど、どちらでも平均以上のコードが書けると助かるね。
不満を承知でもその条件下で最良のコーディングができるのが、良いプログラマだと思う。
こんだけ、グダグダ言われるようだと、
>>967は仕事で使いたくないな。
たとえ、すごいC使いだとしても。
ま、そもそも採用しないけどね。
>>970 少なくとも、このスレのC++ PGはまともにCは書けないよ。
C++を書かせてもリソースリーク起きまくりのコード書くよ。
> 理由の無い断定のみ
>>969 まあ、どこまでが Better C なのかってのが微妙なとこなんだけど。
> 一人で書くなら気兼ねせずに C++ の機能を余す所無く使えば良いでしょ。
そこまではする必要がないというか、そこまでできる環境なら LL に逃げられたりするし、
そこまですると、それこそ C++ 否定派の人が言うように、ややこしい問題が発生しがちだから。
> チームで書くなら C++ 使いにとっても C 使いにとってもストレスフルな
幸いなことに C 使いは切り捨てられるので。
それと、あまり潤沢な環境でなかったりもすると、落とし所が大体見えてたりするから、
そんなに厳密にコーディングルールという形で強制しないで済む場合も多い。
もちろん阿呆が要ると破綻するけど、それはそういう人間が入った時点で負けで、
どんなに決め事をしてもおかしくなるから。
(とはいえ決まりごとが無くていいわけではないけど)
まあ、ちょっと特殊な環境なのかもしれない。
とりあえず
>>973(
>>959)がC嫌いなのは分かった。
でも、何で嫌いなのかは良く分からんなー。
多分、Cには無いがC++にある機能の何かを必要としてるんだよね?
あまり厳密なコーディング規約は必要なかったみたいだけど、
C++のこの機能だけは必須、みたいなのってあるの?
ちなみに当方、数値計算を生業にしてるためrestrict修飾子にはお世話になってます。
これで新規にFortranを書くことは無くなったから。
あとC++0xの右辺値参照には注目してる。これがあれば行列演算メインの計算はC++でやるかも。
>>973 >幸いなことに C 使いは切り捨てられるので。
それは Better C じゃなくて、単に制限を強めた C++ でしょ。
C PG からしたら何にも Better じゃない。
わざわざ C の名前を騙る理由がよく分からんなあ。
ある程度規模が大きくなると class は欲しくなりますし、
(そりゃ class が無くても書けるけど、それ言ったらアセンブラだっていいわけだし)
template もマクロよりマトモな面は多々あるし。
(酷い面も多々あるけど)
C++ は、機能もありますが、現実的な現場の共通認識として必要なのかも。
だから、このあたりは実際に作ってるものによるんだと思います。
C の資産が膨大に残ってて、 C が主流の現場で C++ 使うんだーなんて
言い張るのは、そりゃ阿呆というか不幸だと思いますし。
右辺値参照はどうなんでしょうかね。ちゃんと調べてないし詳しくないので、あれですが、
STL なんかはパフォーマンス的な底上げにはなるのでしょうけど、
行列演算が速くなったりするんでしょうか。
小さな行列演算が書きやすく速くなるならいいなあ。
えっと、誰か
>>970 と一緒に仕事がしたいってお願いしたの?
>>976 行列演算 C=A+B を(オペレータオーバーロードで)計算したとき、これまでは
(1)テンポラリ行列Dを確保してA+Bの結果を格納(2)Cの領域解放(3)DをCへコピー(4)Dを解放
って無駄な処理をしてたけど、右辺値参照があればDとCのswapのような処理が書けて
(3)(4)のような無駄が無くなるという話(間違って理解してなければ)。
一度確保したメモリを使い回すような貧乏臭い処理も必要なんで、
これまで関数でやってた計算の全てをオペレータオーバーロードで置き換えられないだろうけど、
ちょっと期待しているわけです。
Better C 改め C++ の subset が良いという人は Embedded C++ で
アプリを書けと言われたら納得するのかしらん。
>>976 なんだか主張がふわふわしている。
おそらくCが嫌いなんじゃなくて、C使いが嫌いなんだな。
C使いを排除するための方便としてのC++。
1. C++ でないと実現が困難な事
2. C があれば C++ は必要無い事
3. C++ でも C でもやり辛い事
1 に該当する分野ってそんなに無いからなあ...
最近は 3 が多い希ガス.
C が無くなれば 2 に該当する分野は C++ で
独占出来るから、Better C とか色々考える罠.
そんなのが上手く行くとは思えんけど...
>C++ でも C でもやり辛い事
デバイスドライバーとか埋め込み系はC/C++の独壇場だろ。
C/C++はもはや特殊用途限定の言語。
今時アプリケーションをCで書くとか時代錯誤な認識でいるなら
出家した方がいい。
SQLiteやFFmpegのような、ライブラリとしての用途も兼ねる
アプリケーションは今でもCだよ。
でも、これも一種の埋め込み系かな。
>>982 君は Haiku OS でも使ってるのかな?
それともユーザモードも入れての話?
カーネルモジュールは C の独壇場だよ。C++ の出番は無し。
頑張っても IOKit の Embedded C++ 止まり。
Embedded だから、テンプレートも名前空間も使えない。
実現できることは同じだから表現力で差別化を図るC++
どうせ同じなら表現力に無駄な投資をしないC
C++は文学