C++相談室 part148
レス数が1000を超えています。これ以上書き込みはできません。
gotoの話でもするか? それともマクロ? ハード絡みのところなんか俺的にはオモロイが 前スレ999だけと循環してないよ
仮想アドレス使ったら必ずページフォルトするわけじゃない
MMUの仕組みわかってる? こらこら、前スレ999は俺だぞ
なりすましすんなカス >>7
999へのレスって意味ね
文脈で理解してほしいところだが
で循環論法でないことわかった? 環境を限定しないならこれ以上続けても無駄
全ての環境を知ってるヤツでない限り struct AutoDeleteFile {
const WCHAR *m_file;
AutoDeleteFile(const WCHAR *file) : m_file(file) { }
~AutoDeleteFile()
{ DeleteFileW(m_file); }
}; それではおじいちゃんのaddress談義
続きをどうぞ ともかく最初に思ってることがあって
要は荒らしてやろうと
今回は結構うまくいった方かな
この前は
「std::deque には begin() end() clear() があるのに
std::queue と std::stack にそれらが無いのは何故?
有ったほうが便利なのでは?」
って質問で大分いい感じにスレを流した
そら、有ったほうが便利に違いないし、無いことに合理的な理由など無いわけだから荒れる
そういう、荒れそうなネタ考えるのに毎回結構頭使う
ただ、ちょっと前の goto のやつ、あれはダメ
初心者がワーワー騒いでるだけで、ほとんどのベテラン連中は静観してたと思う
俺の狙いはそれじゃない
あと、妹大好きです でも、もともと主張がおかしかったから、釣りだったのはホントじゃないの。 釣りっていうかただの構ってちゃんな。何か深い考えがあるというわけでもないし。 釣りじゃなかったら相当痛い人だし。
釣りならちょっと痛い人で済むよ。 ところで僕は自分の職業の板ってまったく見ないんだけど。
ここは職業プログラマが多いの? わしも見ない
あそこは仕事のグチを書きこむとこやん
こっちは言語仕様のグチを書きこむとこや break break;
bresk break break;
break continue;
こんな書き方ができたら嬉しい? ネアンデルタール人はホモサピエンスの基底クラスであったか。
ネアンデルタール人のDNA、アフリカの現生人類からも検出 新研究
https://www.cnn.co.jp/fringe/35148770.html
2020.01.31 Fri posted at 13:15 JST 多重ループを抜ける方法
ループに名前は名前を考えるのがイヤ
break [数字] は数えるのがイヤ
関数を分けてreturn はもっとイヤ
変数を使ってbreakで抜けるのは論外
でもgotoはなんとなくイヤ
全ての要望に答えたのが >>32 バカの要望を聞いてさらにロクでもない方向に行ってしまうっていう
わかりやすい例を提供してくれてありがとう。 ん?
皮肉のつもりで書いたんだけど
真面目な書き込みととらえられるとは思わなかった あえて説明してるところで恥ずかしいことになってる奴w >>37
おれはおもしろいアイデアと思う
他に考えるとしたら
やはり名前があった方が変更に強いと思うのでその線でいくと
大抵ループにはイテレータやカウンタが紐づいてるから
それを使って
for (auto& x : なんとか) {
for (auto& y : なんとか) {
.break x;
}
}
とかどうだろ?
for以外で使えないしforでも宣言空だとだめだけど
頻繁に使うわけじゃないだろうから妥協できるかなと while(){} や do{}while(); で使えないので却下 for(int x = 0; i < ... )
{
int y = 0;
LOOP:
a[x][y]...
++y;
if(...){ break; /*多重ループ脱出*/ }
goto LOOP;
} >>37
何個の break を書くのか、と break の後に書く数字は? で
結局のところ同じように数えなきゃならないでしょ。 >>32はcontinueを混ぜられるのが面白いけど、やるならこうだな。
break n;
continue n; こういうしょーもないシンタックスの話って馬鹿でもしやすいのが盛り上がる理由なんだろうな。 特定の言語のスレ
シンタックスを語らずに何を語る? break 9;
を数えたく無いとか言ってたヤツがいたけど
そういう時は素直にgotoを使えば良い >>55
C++ ではオブジェクトの寿命の管理と辻褄を合わせなきゃならないんだから full continuation は無理だぞ。 ループに名前を付け、その名前で離脱や継続を行う。
ループA { 途中で送信してしまった。面倒だから書き直さないが、
breakやcontinueはキーワードが紛らわしいのでPerlのlastとnextを拝借する。
last ループA; とか next ループA; みたいな感じ。 gcc5ぐらいから一気にgcc10にしたらエラー表示とかデフォルトの警告とか色々変わっててわろた >>61
まあね。だけどgotoはフリーダムすぎて良くないでしょ。 いや全然そう思わない
gotoで何か不都合がある? >>52
コンパイラ毎の最適化における癖とか、例外の実装についての差異なんかも語ってもいいんだぞ。 >>63
goto は自由すぎるけども、ループを何段階も一気に抜けたいとかいう状況がすでにだいぶん自由だと思うぞ。
そういう状況が生まれたらもう駄目なんだよ。
ごちゃごちゃとした使い分けを考えるよりおとなしく goto した方が「そこが悪い」ってのが目立って良い。 一番使いたいのは2段break
行列や画像など2次元構造では当たり前のように2重ループになる
2重ループを抜けたい状況は設計が悪い
と思う感覚が全く理解できない 構造化を壊さないことを保証した仕組みで脱出したいってことでしょ 2次元構造の2個のループを抜ける為に
非常に関連のある2個のループを別関数に分ける
この方が設計が悪い
というのがおれの感覚 >>67
gotoは悪、多重ループは悪、みたいなどこかで聞いたルールを杓子定規に常に遵守すべき絶対ルールのように考える人が少なからずいるんだろうね。声が大きいだけかもしれないけど。 gotoの利用にコンパイラの補佐があればよかったのに 中カッコ、変数の有効範囲含め
スコープ内に飛び込むジャンプを一切禁止、前方のみと決めれば
なかなか直観的でわかりやすいキーワード
だとおもうのに 一切禁止とか言うから
それが絶対だと初心者が思って思考停止する
この典型がgoto
使った方が良い時は使う
再帰も生ポもグローバル変数も多重継承も多重ループも >>67
ここでワイが「悪い」って言ってるのは使うなとか別の方法がとれるとかいうほどの強い意味じゃなくてさ、
気を付けなきゃならないポイントとして目立ってもらわなきゃ困るって程度の意味。
だけど、日常的にそこら中でそういうポイントがあるのならやっぱり悪いとは思うけど……。 二重ループの脱出は
[&]{
for(){
for(){
return;
}
}}();
で結論出たはずだが 関数オブジェクトはまともなコンパイラならインライン展開される 贅沢言いすぎだね
素のPascalなんてreturnすら無いからね
もはやどうやってプログラムを書いたらいいか分からないレベル Pascalは完璧な構造化言語を目指したから
入口と出口を常に一つずつにするというポリシーがあって
それゆえreturnが無いんだよね
returnがあると出口があちこちに散らばるので
構造化じゃない、汚い、という考え
なお、breakは有るもよう [&]{
try{
for(){
for(){
throw 0;
}
}catch(...){}
}}(); 抽象的なレベルで考えたら break は
「残りの文が if 式で囲まれていると見なして暗黙のフラグを設定する (そのフラグは暗黙にループの終了条件でもある)」
とも考えられるから、構文糖だといえば構造化は壊れていない。
だけどなぁ、プログラムは人が書くものだし、人にとってどう見えるかも大事なんだよな。
そこらへんは見方によってどうとでも理屈を付けられてしまう。 [&]{
try{
for(){
for(){
throw 2;
}
}
}catch(int d)
{printf("%d段階ジャンプしたお¥n",d);}
}(); >>82
break 2 も gotoでループを抜けるのも同じ >>83
それは最悪
throw 3; って書いてもチェックされないし >>67
3重ループは? 4重ループは? なんで2だけなの? [&]{
try{
for(){
for(){
throw "リレミト";
}
}
}catch(const char*s)
{printf("%sの呪文を唱えた¥n",s);}
}(); >>87
答えられないならレスしないで下さい
ウザいだけです for () {
for () {
goto done;
}
}
done:
どう考えてもこちらのほうが綺麗 >>90
だな
必要になったことを変に偽装する悪癖を治すべき病人多すぎ ほんまになぁ。
そんな簡単なことをラベル付き break だのなんだのって面倒なだけとしか思えぬ。
もう構造化は破綻してるんだからおとなしく goto しとけよな! >>89
日本語が不得意みたいなので英語で説明しますね
Double loop frequently appears to treat a two dimension structure such as matrix or image data,
so "break from double loop"is used by programmers related mathematical or visual product.
>>67 states that is good reason and s not always bad design. >>93
意味わかんね
なんでそんなことするの?
アホだから? それともバカだから? >>94
It's purely kindness for non-Japanese speaker. Did you not like it? >>92
構造化的には
breakも途中でreturnもgotoでループを抜けるのも同じだよ Пожалуйста, говорите по-японски. なんだロシア人か
Я не понимаю >>67, потому что я не понимаю японский? >>96
同じだからそれ以上に新しい文法を持ち込んでもそれほど綺麗にならんって! ということを言いたい。 >>96
gotoは正しく使えばという但し書きがつくでしょ
そこをなんとかしたいという話だと思ってる
それが論点だとするとgoto使えというのは解にならない >>102
正しく使う前提なのは当たり前
なんでgotoだと正しく使わない前提になるのか不思議 危ない操作はできないようにしようってのが言語の進化だからな
それ無視して、安全に使うのが前提とか、正しく使うのが前提とか、それ言っちゃね
なんかおかしな方向へ行くよね >>104
構造化プログラミングの概念は知ってるんだよね? gotoを正しくしか使えないように改良したのがreturn、break、continue
ってことも忘れずに >>104
構造化プログラミングでは使わない制御構造を
使うべきでない理由が構造化プログラミングって論法に
抜け出せない枠があるとは思わないの?
>>108
continueだけ、それで正解なんだが
他はみんな間違ってるよ 見てください皆さん、ID:BhmlSyWc ← ひどいですよ
まず何言ってるか分からない
このレベルはきついな >>106
どの辺からgotoが危ない操作だと思うの? まあ1万行ある関数の中で、5千行目ぐらいにgotoがあって、ラベルが関数の先頭付近にあるとか、それに近いのは見たことあるが、あれはどう考えてもgotoの悪い例だからな
包丁で味噌汁食ってるようなもん >>110
きつくて気の毒だな
不勉強なやつは自業自得なので同情はしない >>112
1万行か・・・これ↓より重症だなw
http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.10.4.html 不定値や無限ループの危険はgotoに限ったことじゃないし
ループを抜けるgotoには関係ない話
goto特有の危険な場面
何を心配してるんだろう
酸っぱいブドウ? gotoはどこへ飛ぶか分からないから読みにくいんだよ
前に飛ぶのか、後ろに飛ぶのか、それすら分からない
飛び先を分かりやすく改良したのがreturn、break、continue
それぞれ飛び先が決まっているから追うのが楽
その英知が分からんっていうならreturn、break、continueを使わずに
全部gotoでやれば?って話 どこに飛ぶかわかる名前にするってのが普通の発想
意味でも構造でも文章でも好きな名前を付けられる
関数も変数も名前空間も全てそう >>117
飛び先じゃなく飛ぶこと自体の問題なんだがw つまりはそういう話で、追いやすいように飛び先を制限したいよねーってのが根底に有って
(当然そういうのが念頭にあってreturn,break,continueは生まれたわけで、前例に倣いたい所)
それでブロックに名前を付けるだのbreak 2だのって書き込んでいる人がいるわけで
gotoでいいんじゃね?っていうなら、return,break,continueもgotoでいいんじゃね?
むしろforやwhileもgotoでいいんじゃね?gotoを正しく使えばいいんだろ?ってなる 構造化プログラミング知らずにgotoいきって使うのはさすがにやばい >>122
どうなっていれば「追いやすい」のかを
まず明らかにしようぜ
俺ルールでもいいし
広く認知されているルールでもいいし 巻数はどこに飛ぶか分からないが、必ず元に戻ってくる(のが基本)
行きっぱなしというか、ただのジャンプのgotoやらbreakやらとは違うのだよ
関数のコールは入口と出口が一つになってて非常に構造化されてる好例
こういうところ分からないってのはセンスないよ 使い所でgotoが使えないのはセンス無い
使い所でgptoを使わないのはコードが見にくい
使い所でgotoを使わないのは危険なコード
goto否定派にレベルを合わせた主張をするとこんな感じ 本心では誰もgotoは否定していないんじゃないかな
今は多段breakの機能が無いんだからgotoを使えばいいだろう
しかし、もしgotoを使わないで済む多段breakの新機能があったのなら
それを使ったほうがいいだろうし
じゃーその新機能はどんなものが考えられるか?って遊びだろ?
ブロックに名前付けるだとかbreak nだとかは 多段breakは考えた奴は脳味噌が糞すぐる…
ループの深さを変えたとたんにバグるじゃん?
ループの深さは金輪際変えないとか
ループの深さを変えるとき必ずループ全体を机上確認するとかだったら
gotoでも逝けるじゃん?? ああ、そうだな
break 2だとfor文が3重になったときにバグるな
個人的には面白いと思ったが 画像処理とかで2重ループ良く書くけど、最近2段階breakしたくなった記憶がないな
実は要らないんじゃね まーC++がプリプロセッサを殺すために進化しているのと同様
Cはgotoを殺すために進化したともいえるわけで
たとえば、関数、for、return、などなど、制御構造にかかわるほとんどの物が
gotoを殺すために有るといってもよい
だから、もっとgotoを殺すにはどうすればよいか、考えるのは自然な発想かと
C++でもテンプレートなどで出来ないことはプリプロセッサでしなければならないし
ただ、同じことがテンプレートとかで出来るならそのほうが良いだろうし
もっとプリプロセッサを殺すためにはどういう機能を追加すればよいか考えるのは自然な事だろう
同じ同じ goto とか break とか continue とか、他の言語(javaとか)でもいろいろ小手先的に弄られているけれども、それに何の意味があるのかいつも不思議におもいますね
C/C++ の goto とかはどう頑張っても関数の中でだけしか跳べないのだから、BASIC の GOTO ほどにはスパゲッティ状態を招けないのではと考えます
無論、その関数が異様にデカければ別ですが、そんなデカい関数を書くほうが問題であって goto が問題なのではないかと ループを抜ける為にだけ使われる変数を使ったループ抜け
世の中にはたくさんこういうコードがある
たくさんのコードを見る機会がある人なら
たくさん見たことがあるはず
gotoネガティブキャンペーンのせいだよ >>136
gotoが使わないで済むように進化してくのは期待している。
ただ現状として、多重ループを抜ける場合みたいにgotoを使うのがシンプルで分かりやすいならば、毛嫌いしたり盲目的に原則振りかざすよりgoto使えばいいだけのことだと思うよ。 >>138
お前ほんとに病気だな
多重ループ脱出でgotoが簡潔なのはみなわかってる
でもgotoは自由度が高すぎて構造を壊す可能性があるわけ
だから改善するとしたら何があるかという話をしてるだけであって
別にgoto禁止とかの話はしてない
好きなだけ使ってろよ
あと構造化プログラミングぐらい知っとけ for () {
break label;
} label;
for () {
for () {
break label1
} label2;
} label1;
こういう風にfor文のお尻にラベルを付けられるようにすれば局所化したgoto風のbreakが使えるのでは for () {
goto label;
} label:;
for () {
for () {
goto label1;
} label2:;
} label1:; Pythonはループにラベルをつける手が使えた
と思った(幻覚でなければ またgotoの話になってんのかよ。。
だからいっそ禁止にと思ったが、それよりもさらにクソな構文の提案が出てたり。。
想定を超えた馬鹿どもばっかりじゃねーか。 ただ、凝りに凝った複雑怪奇なテンプレートより
シンプルに作ったマクロの方が読みやすいって事例も当然あるだろうよ
てか、わりと、最近、残念ながらその傾向が・・・で、C++が嫌われる理由にも・・・
だからgotoを殺すのも上手くやらないとむしろ酷くなる
そこが腕の振るいどころで面白い部分でもあるし、言語作ってる連中もそんなことで頭いっぱい
変なゲーム性が有って、逆にそれがまたダメな部分でもあって
あと、妹大好き 多段breakの使用頻度がそれほど多くないことを加味すれば
break n;方式が妥当だろうね
これだと2重ループを3重ループに書き換えたときにバグる、とか
意味不明なことを言ってる奴もいるが
それは1重ループをbreakで抜けてたのを2重ループに書き換えたらバグった
と言ってるのと同じであって、当たり前の話だし、今でも同じことだ
break n;が一番シンプルで妥当だと思うね breakの後にマジックナンバーを書くのが気に入らない
定数には意味のわかる名前を付けたい ただし、break n;のnの部分が変数でもOKとかなってたらかなりウザいが
そこはnは定数と定めたいね、でもC++の場合は定数と言っても・・・
複雑にしようと思えばいくらでも複雑にできるわなー
普通に使う分には問題ないかと
明日からbreak n;が入っても、たぶん誰も困らないし、混乱も起きないだろう
割のいい賭けだし、俺はアリだと思うね breakとbreak nが同じとか意味不明な主張をなさる御仁がいらっしゃるが
じゃあcontinueがcontinue nになったらどんな地獄が発生するか
考えてみたら良い 別にcontinue n;
全然ありでしょ
これと同等の事を、何か別の方法でやるよりスマート
for(;;){
bool do_continue = false;
for(;;){
if(...){ do_continue = true; break;}
}
if( do_continue ){ continue; }
}
↓
for(;;){
for(;;){
if(...){ continue 2; }
}
} do {
do {
...
if (cond) {
continue 2;
}
} while (副作用の有る式1);
} while (副作用の有る式2);
とから? break nなんてやるくらいならbreak label で抜けるループを明示的に指定したいな
↓
ループにラベルをつけるとして、先頭では見づらくて邪魔だな
↓
ループの末尾にラベルを付ければ見やすいけど、それだとlabelついたループを抜けると言うよりlabelの指す位置へのジャンプだな
↓
なんだgotoでいいじゃん
個人的には breakto label という記法でループ出口に書いたラベルに飛べるとするのが分かりやすいと思うけど、こんなことに新しい予約語を導入するくらいならgotoで十分だと思う。 break nが良いとか言ってる椰子は
ついでに行番号も復活してほしいと思っているに違いナス do{
do{
if(...) goto NEXT;
}while(...);
NEXT;
}while(...);
と等価だろう
要はこういうgotoを置き換えるために作られたのが
continueなのだから、そのルールに従うのが普通だろうね
もしくはgoto使わずにフラグでやっても、どのみち内側のループの条件式は実行されないわけで
do{
bool do_continue = false;
do{
if(...){ do_continue = true; break; }
}while(...);
if(do_continue) continue;
}while(...);
これ以外の解釈ってのは難しい そういう機能要望みたいなのここでやる意味ある?
C++Slackでやった方がよくない? ,,-―--、
|:::::::::::::;;;ノ
|::::::::::( 」 <もう構造化は破綻してるんだからおとなしく goto しとけよな!
ノノノ ヽ_l
,,-┴―┴- 、 ∩_
/,|┌-[]─┐| \ ( ノ
/ ヽ| | バ | '、/\ / /
/ `./| | カ | |\ /
\ ヽ| lゝ | | \__/
\ |  ̄ ̄ ̄ |
⊂|______|
|l_l i l_l |
| ┬ | >>149
break n なんて間抜けの極みだと思いますね
java にはラベル付き break が存在して、ほとんど goto です https://www.sejuku.net/blog/20100 >>136
Cはgoto殺すために進化してねえよ
Cのgotoが関数外に飛べないのはスタック巻戻しのような仕掛けが複雑になりすぎるからで
構造化プログラミングで否定されるからという理由ではない
構造化プログラミングで否定される制御構造を持たないことにするなら
breakやlongjmpは存在できないはずだ 結論が先にあって理由が後付けだから支離滅裂、一貫性の欠片もない事を書く
もはや宗教 ほんと、宗教だね
洗脳されてるやつは強固に思考停止していて
何を言おうが馬の耳に念仏だ >>159
根底がわかってねえやつが多いからだよ
古典的な基本がわかってねえやつは若造と爺のどっちに多いだろうね
頓珍漢なことを書いて袋叩きにされたからって逆恨みする精神性なやつはどっちに多いだろうね break labelでいいんじゃね
gotoと同じだが、labelがbreak的な位置にない場合コンパイルエラーになれば良い gotoは便利なswitchだからね。
便利すぎるわこれ。
これからも積極的に使っていこうと思います。 さすがにgotoでジャンプテーブル化の最適化までやる処理系は
まれだと思う アドレス直接指定なのに、テーブル必要ないんじゃないの。
テーブル必要ない分、switchより有利なんじゃないかと思いました。 (条件分岐無しの素のgotoだけでどうやってswitchの便利な代替品にするつもりなのやら… 頑張ってひねり出した!!
けどウンコにしか見えない。
納得できるものを頼む。 >>175
お前が何をいってるのか、何を考えてるのか理解できないのに、お前を納得させられる奴なんていないぞw お尻にラベルつけて break ラベル; がいいとか言ってる奴は構造化の意味がわかってなさ過ぎ
ラベルは飛び先じゃなくてループに付けて break ラベル; でそのループから抜けるんだよ
なので break ラベル が使える言語はたいていループの頭にラベルをつけるようになってる
あと break レベル数 とか言ってる老害は早く滅びろ 名前使うならこんな感じか
void main(){
auto scope1 {
for(;;){
for(){
break scope1;
}
}
} >>176
俺自身何を言っているのかよくわからないのだが。 もしくは、forの直後
void main(){
for(;;)scope1{
for(;;){
break scope1;
}
}
} ループの先頭にラベルを書くくらいなら
gotoの方が分かりやすい あの、スレとは全然関係ないんだけど。
Boostでデバッグとリリース判別するマクロってありますか?
イテレータを1億回ほど回すのでデバッグだけテストを迂回したいんですが。 NDEBUGを知らなかったからです。
おまえらおせーよ。 NDEBUGってISO/IEC9899やん
おまえさんがboostっていうから
レスポンス鈍かったんだよ 今の一重ループを抜けるときの普通のbreakにはラベルを付けないのに
多重ループを抜けるためのbreakにはラベルが無いと読みにくくなるっていう
発想というか対称性というか整合性というか必然性が全く見えないんだが
今ラベル無しの一重breakで誰も発狂することもなく普通に使えているのに
多重breakになった瞬間にラベルが無きゃダメってなるのはなんか弱い
同じことを二回書いたけども
ラベル無しでも別に普通に読めるでしょ、今まで読めてるんだから
大体ラベル付けるんならgotoと手間自体は変わりないしな 下方向にだけ飛べるgoto相当機能があればgotoは要らなくなるんじゃない? >>190は、Cにgoto <label>とbreakがあるのになぜCはbreak nを設けるところまで踏み込まなかったのか、とか
break <n>で即値<n>に行き当たったコード閲覧者が行き先を知るために何をせねばならないかとか、
考えた方が良いので
は… >>190
break nを勧めている人?
対象が1段なのと複数段とでは大きなギャップがあるでしょ。単純に対称性があると言えるものではないと思う。
ラベルつけるならgotoと手間が変わらないというのは同意。ただ、重要なのは手間が減ることではなく、複数段のループの外に出ることが明示されることだから、gotoと意味が混同されず同じ程度の手間でできる記法があるならそれは嬉しい。 現実のC++について話せ
ここで新機能の導入について議論しても無駄だ
フォーラムでやれ 手間が減ることは重要だよ
ラベル名を考える手間をかけて良いならgotoで良い 大体だよ、多重ループはbreakで抜けれないので、仕方なくgoto使うときの
そのgotoを使う都合で必要になった、そのラベルをだよ
じゃーブロックにラベルをつけましょう、ってなんでそーなんだよ
元々のbreakにはラベルなんかねーのに
breakにラベルが無くて混乱したやつ居るか?
ご飯が無いからパンを食べてた状況なのに
すり替わってパンありきになって、パンが無きゃ話にならないとか言い出す始末
別にパン(ラベル)なんかなくても、ご飯があるならご飯食べろよ
ラヘルラベルって、そのラベルがどこ由来か考えてみろよ、gotoだろ?
もう一度言うが、もともとのbreakにはラベルなんかないし、それでみんな普通に過ごせてるし、混乱も起きてない
ただ、gotoで抜けるためには文法上/機能上ラベルが必要だったねってだけで、そこに着目しても仕方がない
本質的には無くても別に困らない ソースコードチェック目的でプログラム読むとき、gotoが出てきたら
そのgotoの使用方法が問題ないものなのか、いちいちチェックしないといけない。
breakならループ抜けるという意図が明白なので、チェックしなくてよい。 そんなに名前が無いと発狂するんならもうgoto使えば?って思うし
なんなら関数化して正式に名前付ければって思うし
そこまでしたくないってときにbreak nが便利なわけだ
やりたいことは「多重ループから抜けたい」であって
「名前を付けたい」ではない!! 関数コールも問題のないコールかどうかチェックしないといけないから
使わない方が良い それならもうポインタもグローバル変数もマルチスレッドも大量のチェックが必要だから使ってはいけないってことで >>199
私と認識が似ていますね
>>137
>goto とか break とか continue とか、他の言語(javaとか)でもいろいろ小手先的に弄られているけれども、それに何の意味があるのかいつも不思議におもいますね
>>164
java にはラベル付き break が存在して、ほとんど goto です https://www.sejuku.net/blog/20100 現行のC/C++にはgoto <label>がある一方、break <n>は無い
もしbreak <n>の追加がgoto <label>の実装より難しかったからやらなかったのだとしたら、
break <n>の飛び先がgoto <label>の飛び先より簡単にワカルから優れているという主張は根拠を失う
break <n>はわかりにくいか、さもなくばgoto <label>と同等なんである >>201
現実ありえないのは重々承知したうえで書くけど
100重ループを脱出するとき数を数えたくないだろうなって思うじゃん
ほかにも3重ループとかで2ndと3rdのループから共通の脱出先ラベルにもできるわけじゃん
文法を拡張する前提ならそこまで想定すべきだと思うね
粗野な即値の数字じゃなくて意味ごとに名前をつけられるようにしてきたのが
プログラミング言語の進化の歴史なのでおれは自然だと思うよ
というかそういう観点からラベル付きbreakというのは他の言語にはあるわけで
で今話してるのはもっと書きやすく読みやすくできないかというトピックでしょ
break Nは使えるだろうけど洗練されてない感じ break [n] はラベル名を考えなくて良い利点がある
使えるなら使いたい
ラベル名を考える必要があるならgotoで良い
ループの先頭で名前を付けるのはgotoより見づらいから使わない break n とか言ってる奴は何故か>>150をスルーしてて笑うわ 他の人は「マジックナンバー」だと思わなかったからでは。 foobarやhogeを超える人気なダミー文字列を考えたほうがよほど建設的だぞ、君たち。 break 5; //C
GOTO 5 : REM BASIC マジックナンバーがイヤなら
break break; 関数で置き換える
引数がめんどうならラムダで置き換える
returnが多重breakの代わりになる >>214
多重ループを単一関数に書くって前提だね >引数がめんどうならラムダで置き換える ←New!
これは場合による
for (i=0; i<INT_MAX; i++) {
for (j=0; j<INT_MAX; j++) {
(何がしかの処理)
}
}
を
for (i=0; i<INT_MAX; i++) {
for (j=0; j<INT_MAX; j++) {
((何がしかの処理)を行うラムダ式fを定義)
f();
}
}
とするのではご利益が無いが、
((何がしかの処理)を行うラムダ式fを定義)
for (i=0; i<INT_MAX; i++) {
for (j=0; j<INT_MAX; j++) {
f();
}
}
とするのではラムダ式定義時点でループ内の変数を参照できないから場合によっては詰む
結局f()は引数がぞろぞろ並ばねばならない >>217
左様
それがラムダ式を適用して解決づべき適切な場合である(キリ ジーオーティーオーというスペルでなければ
制御構造はそのままでいいと言うクソ論法 スレとはあまり関係ないんだけど、nodiscard属性を無視するにはどうしたらいいですか? 変数で受けといてその変数をガン無視すればいいんじゃないの
未使用変数の警告出るだろうけど >>210
お前の言う「他の人」はマジックナンバーの意味わかってないってことか?
このスレ見てたらありえなくもないかと思えてきたわw あと三日くらいしたらお前より出来るようになってるから。 >>208
昔のBASICは、行番号を勝手に付けてくれていたのでgotoでもラベル名を考えなくて済んだのでとても便利だった。 >>226
なお、アセンブラでは行番号がなかったのでラベル名を考える必要があったが、
意味のあるラベル名を考え出すのは大変だったので、分かり易い場所以外は、
多くの人が、lab1: lab2: lab3: のような連番を使う傾向があった。 >>226
>昔のBASICは、行番号を勝手に
auto 文だったかな… すまん俺の聞き方が悪かったのかもしれん
最近プログラミングの勉強始めて、各言語の用途とか調べたんだけど、ここでも一応聞いてみたかったの
何を作ってるって言うより、どんな開発に携わってるかっていうのを聞きたかった 検索はstd::setやstd::unorderd_setより速いけど、挿入が一桁遅い。
静的構築が速いというので、それもやってみたけど、2/3くらいにしかならなかった。 初学者的な質問です、よろしくお願いいたします。
バイナリーファイルを
std::fstream f;
f.open(filename, std::ios::in | std::ios::out | std::ios::binary);
でオープンし、同一ファイルのオープン中に
f.read(), f.seekg() でガンガン読むと同時に
f.write(), f.seekp() でガンガン書き込む
を試しているのですが、seekg(), tellg() と seekp() tellp() は名前は別でもあるにもかかわらず、実はファイルポインタの実体は両者で同一なのでは?
という疑いが発生しました。つまり、seekg()/tellg() と seekp()/tellp() とは独立でない、と推測しています
@この解釈で正しいですか?
Aこういうのは、C++ iostream レファレンスのどこを見て洞察するべきなのでしょうか?
実際のお題は相変わらずエラトステネスのふるいです https://ideone.com/6Ww9nq >>231,233
私は今のところエラトステネスの篩にご執心、という体たらくです… エラトステネスのふるいで
なんでファイルのリードが必要? >>244
結構昔から
http://www.asahi-net.or.jp/~KC2H-MSM/pbsb/pbsbm006.htm
にとても興味を持っていたのです、二つの隣り合った素数の差を「素数のギャップ」と呼ぶことにしたとき、
『素数のギャップが取りうる値の頻度。はじめは2、4が多いが、そのうち、6の方が多くなる。』
『6がチャンピオンの座を降りるのはいつか。』
『少なくとも 10^14 以下では6がトップであり、それ以降、いつ、6以外の数がトップになるかは、知られていない。』
10^14 までの数であっても全部、篩としてメモリに載せられないので、さてどうしたものかと思案中です、最終的には年スパンでずっと計算させ続けるのに耐えられるようにしたい、と その問題だけなら
2次キャッシュに収まるくらいに分けてふるえば速い
間隔も大して大きくならないので
ヒストグラムはオンメモリで済む
スレッドも簡単に分割出来るので
論理コア数と同じだけスレッドを作って回す >>246
コメントありがとうございます
>間隔も大して大きくならないのでヒストグラムはオンメモリで済む
確かに 10^10 まででも最大 354 というのには驚きました、案外密に分布しているんですね
>2次キャッシュに収まるくらいに分けてふるえば速い
constexpr unsigned int windowSize_Default = 30 * 5000000; はでかすぎ、ですか
いただいたアイディアは、どれも私には難易度が高いのですが、ぼちぼち書いていきます… AVXレジスタを使って小さな素数の倍数を消して
ビット命令で大きな素数の倍数を消す
大きな素数の倍数は210ずつ処理する
昔素数の数を数えるプログラムを書いたことがあって
記憶に残ってる範囲ではこんな感じ >>229
100 WIDTH 80,25:CONSOLE 0,25,0,1:SCREEN 1:CLS 3
110 XXX
120 XXX
130 IF XXX = XXX GOTO 110
のようなもので、最初に入れるときは自分で行番号も手で打つのが基本ではありました。
115 YYY と入れると、110と120の間に行が挿入されると言う仕組みです。
それだと9個以上は挿入できなくなるので RENUM 命令を使うと行番号を自動的に
振り直すことができました。その場合、GOTOやGOSUBの行番号も連動して変わる
仕組みです。 >>248
コメントありがとうございます!
>大きな素数の倍数は210ずつ処理する
私は、2*3*5 = 30 でわりと満足していましたが、2*3*5*7=210 まで拡張されたのですか!?うーむ… >>249
mon に入って、プログラムタイトルのコメントの行番号を手打ちで全部 0 にする、とか…
どうでもいい話でごめんなさい… 素数は、6n ± 1 か。
6n + 1, 6n + 5 だけ
6n + 3 は、3の倍数だから、素数じゃない A = 6n + 1, B = 6n + 5 とすると、
AA の並びなら、差は6
AB なら、4
BA なら、2
BB なら、6
A,B になる確率がランダムとすると、6 になる確率が2倍! >>242
たぶんこの一文。
> A joint file position is maintained for both the input sequence and the output sequence.
N3337 だと 27.9.1.1 の第 3 段落にある。
あくまでも std::basic_filebuf ではそうなってるってだけなので、
ストリームバッファ全般に言えるわけではなくて、
独立した位置情報を持つようなものも作れないわけではない。
FILE の fseek のラッピングとして実装することを想定したんじゃないかなぁ。 >>250
ビット命令が48個続くだけ
それほど大変じゃない
今だともっと良い命令があるかも >>254
コメントありがとうございます。いまいちよくわかっていない iostream. の全体像を掴めるよう、いただいたヒントも頼りに潜ってみます
>FILE の fseek のラッピングとして実装することを想定したんじゃないかなぁ。
fseek() が 64bit オフセットならいいのですが
あるいは win32api::SetEndOfFile() のような、オフセットを指定して trunc する方法があればいいのですが
>>242 のバイナリファイルは単に uint64_t な素数を突っ込んでいるものですが、ある日末尾が中途半端にちょん切れてしまったのです… >>256
それファイルに書く必要ある?
仮想メモリ頼りにメモリでやれば? >>256
巨大なファイルにちょくちょくシークしながらアクセスするなら
メモリマップトファイルを使った方が楽やで。 >>256
ググってみたら iostream まわりの継承関係を表した図がすぐ見つかったわ。
https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp10_IO.html
だけど継承関係の他にストリームがバッファとロケールを所有しているという関係もあるのが分かり難いかも。
cpprefjp の rdbuf の項目を見たらストリームのバッファを入れ替える例が載ってる。
https://cpprefjp.github.io/reference/ios/basic_ios/rdbuf.html
本当に「入出力」を司っているのはバッファであって、
ストリームはそれに書式化の機能をかぶせている感じ。 >>257
それはダメでした。win7, 16GB、素数の大きさが10^11 程度でスラッシングが発生して win7 では使い物になりません
GIMPS cli のように、普段は意識することなく3年くらいかけて計算するようにしたいです
>>258
着々と容量が増加するファイルに対して mmap は使えるのですか?win32api::CreateFileMapping では mmap を確立した後にファイルサイズを増やしてはいけない制限がありました >>260
そんな制限があるんか。
連続した巨大なメモリを予約しておいて、
適当な大きさに区切ってファイルにマッピングすればええで。
ファイルを複数に分けることになるけど、
見かけ上は巨大なメモリとして扱えるし、
容量が増加する都度に新しいファイルを作って割り当てればええ。
というやり方を思いついたので具体的に出来るんかいなと思って調べてみたら
MapViewOfFileEx の最後の要素でアドレスを指定する機能がある。
VirtualAlloc で予約した範囲は MapViewOfFileEx で使えないので、
どうやって空いているメモリ空間を探せばええんやろと思ったら
VirtualAlloc で予約した直後に VirtualFree をつこうたらええんやて。
https://stackoverflow.com/questions/12121843/mapviewoffileex-valid-lpbaseaddress
なんという泥臭い方法や……。
てなわけで、若干の面倒くさい手順が要るけどそれっぽいことは出来る。
この手順をいい感じに抽象化するクラスを作ったら色々と使えそうやな。
期待してるで! 普通にAPIで巨大ファイル作れてるけど
CreateFile / WriteFile 最初からどでかいファイルを作る余裕があるならその方が簡単ではあるわな。
どんくらいデカいのがいるんや?
せいぜい数十ギガとかそんなもんやろ?
ケチらんと行くっちゅうのもアリや。 CreateFile
WriteFile
ReadFile
SetFilePointerEx
SetEndOfFile こんな感じ?
.... 0101 0000 0100 0101 0001 0100 0101 0110 STLコンテナ (仮にvとする) のサイズの分だけfor文を回したいってときに
for(int i=0; i<v.size(); i++)
と書くことが多いんだが、v.size()はintじゃないので警告が出る。
警告を一つ残らず潰したいタチだから毎回こういうのはintにキャストしてるんだが、キャストのコストってどんなもんなんだろ。
「大したことないからOK」って立場と「そもそもv.size()が毎回呼ばれてる時点でナンセンスだから改善すべき」って立場と「その警告は無視しなさい」って立場などがあると思うが、皆はどうしてる?
逆順にしたいことなどがよくあるので、範囲for文を使えってのは今回はナシで。
特定の環境、コードでのテストはできるが、一般論として、あるいは皆さんのスタンスとしてはどうですか。 コンパイルの警告のためだけだから
実行時コストは0じゃね 手でタイプするコストうんぬん言うなら
マクロで #define LEN(s) ((int)s.size()) >>267
最も正統派なのはこうかな?
for(decltype(v)::size_type i=0; i<v.size(); i++)
常識的に考えてコンテナの size_type が std::size_t より大きいことはあまりない (大抵は等しい) と思うので、面倒なときは std::size_t を使う。
本当に上限が限られていてその上限が変更されることがあり得ないほどそのプログラムにとって
本質的なものだと判断すれば int でいいやってこともあるといえばあるだろうし、
同じようなパターンが何度も現れるならアダプタを作った上で範囲forというのも考えられる。
状況によるでしょ。 int i = 0; と書かずに size_t i = 0; と書くのはどうだい?
v.size() が本当に size_t を返すか、という問題はあるが。
for (decltype(v.size()) i = 0; i < v.size(); i++)
と書くこともできるね。
i の型が int でないと不味いのかも知れんけど。 >>267
コスト(性能)最優先か
見やすさ最優先か
タイプ数最優先か
次第
キャストのコストって言うけど
intとv.size()のサイズが違えば
どのみち型変換する
コンテナ使うような場所でこんな微妙なコストを気にしてもしょうがないし
>>270は面倒
(業務外だと)私は警告放置が多い
警告を消したい場合はsize_tにするか
コンパイラの設定を変えるか
業務で集団でのコーディングの場合は
他の部分を見て空気を読む for(unsigned int i=0, len=v.size(); i<len; i++)
これもよく見るか >>269
template <typename T> inline auto len(T s) { return s.size(); } >>274
その形が一番、速度的には良い。
forの第二式は毎回評価されるが、v.size()の部分をコンパイラが自動的に最適化するのは非常に難しい場合があるから。 v.size()の値が、ループ内で変化しない「ループ定数」であると判断するのは
コンパイラにとってはものすごく難しい場合がある。
ループ定数であると判断された場合にのみ、>>274のような最適化が行われる可能性が出てくるが、判定できなければループするたびに毎回評価されてしまうのでループの実行速度が遅くなってしまう。 >>283
本人だけが開発していて、記憶力が優れていて絶対に使い方を間違いなければ特に問題ないと思うが、使い方を間違うと危険なことがある。
エラーも出ずに変な動作をしてしまうことがある。
でもそれさえ気を付けていれば特に問題ないとも言える。 >>269
マクロで書く場合、
#define LEN(_s_) ((int)((_s_).size()))
と書いたほうが良い。
特に、s や _s_ を()で囲むのは必須。
sを_s_と書くのは、ミスタイプがあった場合の備え。
例えば、マクロの仮引数にsと書いているのに、マクロの定義部分をtと
書き間違えていて、かつ、マクロを使う場所に t という変数がたまたま使われて
いたとすれば、エラーにならないのに間違った動作をしてしまう。
_s_と書いていれば、_s_という変数は絶対に使われないのでこの心配がない。
そのため、マクロの引数は伝統的に、_s_などのように書くことが推奨されている。 >>280
適してるかどうかはともかく
>>269は解決にはなってる
>>276は解決になってない 皆さんありがとうごさいます。
結構難しいですね。
>>274
> for(unsigned int i=0, len=v.size(); i<len; i++)
これは
for(int i=0, len=(int)v.size(); i<len; i++)
としても性能上そう変わらないですよね?
ループ変数はintであってほしいと思うので、これが自分には向いているように思いました。 キャスト一回って機械語4つくらいじゃあないの?
そこまでシビアってのは競技プログラミングか脳手術ロボットでも作ってんの? 糞コンパイラまで考えてパフォーマンスを考えると>>288だけど
そもそもコンテナ経由でアクセスする時点でそんな事は誤差
そのループに非常に時間がかかるなら
ループ全体で最適化しないと >>290
同じBIT数やBIT数が少なくなる場合の整数型から整数型へのcastは、マシン語では0命令(命令が出力されない)。
高級言語では違う型でもマシン語レベルでは変わらないため。
BIT数が多くなる場合には、x86の場合は、movzx や movsx が使われる。 >>292
実際には、最適化が上手く行かないことも多いので差が出てくることは多い。 >>293
つまり、符号無しや符号付の区別はマシン語ではないので C/C++言語で
castしても高級言語レベルでの意味が変わるだけでマシン語レベルでは
何の命令も増えることはない。 素直にrange-based-for
これが出てきたことの影響のでかさがわかってないやつ多すぎ
禿4にはfor_eachを使う前にもっと適した関数を探せとあるが
本当にそうか自分の頭で考えろ 普通のコンパイラなら
コンパイル単位内の関数は一緒に最適化するので
.size() の中で値を返してるだけなら
ループの外に追い出してくれる
ターゲットがPCなら気にするな
それよりv[i]の方が重い 未だindexループよりrange-basedのほうが早い処理系がない件
>>298
v[i]が重いってどんなstlコンテナだよ >>267
>警告を一つ残らず潰したいタチだから
ここまでは同感です
>毎回こういうのはintにキャストしてるんだが、
私なら int i を unsigned int i にしますが templete<typename T>auto LEN(const T& v)->signed T{return (signed T)v;} とりあえず大きい方に合わせとけば間違いないんだからsize_tでいいじゃん
そのvの要素が将来に渡って21億個を超えない保証がどこにある? >>300
整数のキャストに比べればはるかに重い
そのレベルを気にするなら生ポ >>304
vectorだと生ポと変わらんでしょ
もちろん最適化前提で >>300
range-basedはiterator
c++のiteratorはindexが速くなる連続アドレスのコンテナならpointerと同じコンパイル結果になる
indexアクセスがpointerより遅くないなら、それはコンパイラの最適化のお陰 >>306
生ポと変わらなきゃ良いんだけど
変わるんだよ
VisualStudioやチープなコンパイラだと
いずれにしろここから先は
具体的な環境とループ回数やループの中身全体で考えないと意味がない
なんせ1クロックレベルのことを気にしてるようなので
実はメモリアクセスが支配的で
他の最適化は全く意味がないとか SIMD命令 / DSP命令 / スレッド分け / GPU
他のループと合わせる / ループを分ける
ループアンロール
依存性の削減 / 式変形
アルゴリズムの改善
キャッシュ化 / テーブル化
いろんな最適化がある ところで元々の質問の >>267 は整数の型が合わないのどのくらい気にする?
っていうのを「一般論として」聞いてるので、これに対しての選択肢を派閥系統樹形式にしてみた
├→ きちんと合わせる派
│ ├→ その環境で合ってれば良いよ派 (移植性は気にしない派)
│ ├→ コンパイラの警告は潰す派
│ │ ├→ 理解しなくてもキャストで合わせるので十分派
│ │ └→ 警告される箇所は仕様の詳細を調べる派
│ └→ size_t とか size_type とか使え派 (言語仕様原理主義派)
├→ 問題がなければ気にしない派
│ ├→ 問題に気づかない派 (鈍感派)
│ ├→ 実行コストに敏感派
│ │ ├→ 最適化はあてにする派 (モダン開発環境派)
│ │ └→ 最適化はあてになんないよ派
│ │ ├→ 低レイヤ派
│ │ ├→ 老害派
│ │ ├→ 諦め派
│ │ └→ ベータ開発環境追いかけ派
│ └→ 状況と程度による派 (柔軟派)
└→ えっ、それって駄目だったん? 派
├→ 初心者派
└→ 無知派 >>278
業務外だと、とは書いてあるけど一応突っ込んでおくと
もしそれがコンパイラの警告レベルを下げるとか小さい型へのキャストの警告を無くすとかなら
それはバッドノウハウだよ、真似しないように じゃあ俺、えっ、それって駄目だったん? 派でお願いします。 >>311
わし、こうみえて「警告される箇所は仕様の詳細を調べる派」や
その上で、問題なければ「状況と程度による派 (柔軟派)」に再度ブランチする派 Boostは警告を無視する派、GoogleはMicrosoftの問題なので修正する予定はない派。
ってことは、警告だしっぱなしで構わないって事では? 目grepが難しいので、警告は消すしかないんだけど。 変数の大きさが変わると同じ値のビット表現が変わるのはしんどいので、符号が一番右端にあったほうが良かったんじゃないの。
右端ならビット表現が変わらない。 型違い面倒だからautoにしても警告出るから何でやおもたらi=0でintだったでござる派 HTMLにしろコンパイラにしろ、Microsoft案のほうが合理的と思うけどな。
規格は政治だよね。 >>302
signed Tはできねえぞ
std::make_signed_t<T>にしないと > コンパイラの警告は潰す派
キャストつーか、#pragmaを使ったりもするね
もち、規格票で自分が悪いのかコンパイラのお節介かはっきりさせてからだけど 基本的にはsize_tとかsize_typeとか使え派
面倒でもちゃんとやった方が後のテストや検証は楽なんだよ
まあ無理だったり異様に面倒だったりする場合も現実的にはあるからそこは仕方ないけど i は int にしたいって言ってるんだから
ここの型をsize()に合わせたら
キャストが他に移るだけ >>298
vがグローバルなオブジェクトである場合や、ヒープから確保されたオブジェクトの参照型である場合、コンパイラには v.size() がループ定数であるかどうかを判定するのは難しいことが多い。
このスレでもグローバルに確保された構造体型のメンバを参照する場合、最適化され無い事が指摘されていたが、それと同じことが原因。
C/C++ではポインタや参照があるのでグローバル変数やグローバルなオブジェクトのメンバ変数が変化しないことをコンパイラが見極めるのが難しい。 for(auto i=v.size()+1; 0<len; --i)
for(auto i : my_range(v.size()) reverse_iterator first(v.end()), last(v.begin());
for_each(first, last, [](auto& x) { cout << x; }); 64bit/32bitまたぎできるソース汎用性を考えれば、負の数が必要ないなら size_tを使うのが最善でしょ。 size_tはunsignedなのがうざい
c言語初心者が決めただろこれ ポインタ + size_t == ポインタ
ポインタ - ポインタ == ptrdiff_t
おかしいね >>326
仮に毎回アクセスしたとしてもv[i]の方が重い
毎回アドレスを計算して毎回メモリアクセスするわけで ばかでかいループをたくさん作るなら
性能を心配した方が良い
中身にもよるが、ほぼメモリアクセス時間になりかねない
帯域の無駄遣い
ループをまとめるとか細切れにするとか
キャッシュを有効に使う処理にしないと
キャストのコストとか完全に誤差 8086時代の苦しみを知っている人なら
リニアでないポインタやインデックスが
どんなにウザいものかよく知っている
64bit空間なら64bitを使っとけって悪いこと言わないから ループの中身も知らないで良く言うね
int変換必須なら問題点の場所を移動させただけ 今日日4GB越えとかWindowsNT4.0サービスパックですか、と。 納品したときに
コンパイルで警告出るんですが消してって言われて
それ無視して良い警告ですよって言っても
理解してもらえなかった派 あと警告が出ないからと言って
正しく動くと保証されている訳でもなんでもないのに >>342
それはお前が悪い
そんなんで納品するな 客先と同じビルド環境で警告対応しないのは落ち度だね。次の仕事なくなるでしょ。 >>333
BYTE v[数値];
のような生配列の場合、ループの中のv[i]は、最適化が効いてものすごく効率の良いコードになることが多い。
この場合、vがグローバルに確保されたオブジェクトや参照型であったとしても最適化には余り悪影響はない。
vがstd::vector 型の場合で、かつ、vがグローバル・オブジェクトや、参照型の場合は、コンパイラはv[i]を上手く最適化できないかもしれない。 >>346
すまん。
後半部分は勘違いかもしれない。 >>346
VCはvectorでも生ポインタに近い最適化はしてくれてるみたいだぞ 客や同僚から使えないプログラマ認定されていることに気づけず独りよがりな考えに凝り固まる人いるよね・・・
かわいそうではあるけど、かかわりたくないタイプの人。 標準ライブラリのコンテナのイテレータを sizeof で見ればわかるが、ほとんどの場合で void* と同じ大きさ。
要するにポインタ一個分の情報しかないし、実際ポインタが入ってるし、ポインタの操作になってる。
しいて言えば操作がメンバ関数経由になる分のコストはあるといえばあるけど、
それくらいのインライン展開はするのが普通でしょ。
vector の場合だと領域が連続する保証があるのでインライン展開だけでイテレータはポインタと同じになる。
VC のコンテナだとデバッグモードではイテレータが少し大きい (のと範囲チェックとかする) ってなことらしいんだが、
処理系をインストールしてないから試してない。 >>349
おまえがきちんとした仕様を提案できないで投げっぱにしてるからそんなことになってんじゃないの? >>340
64bit空間で64bit以外のインデックスを使うべきループの中身とやらを書かないあんたが悪い
書けないんじゃないのか? intだとたったの2G要素でオーバーフローして無限ループになるのが怖い イテレータよりポインタのほうが速いよ。
ホントだよ。
いまベンチとってるから。
偶然だけど。 >>351
「無視して良い警告」とか勝手に判断する困ったPGにきちんと仕様を提案しても無駄でしょ。解雇するわ。 unsigned だと
for(unsigned i = s.size(); --i >= 0; ){...}
みたいなので警告出るんだっけ 警告で指摘された問題点に対処もせずに、キャストやらで無理やり消す位なら、出たまま放置の方が100倍マシ ヒープ作るとき、マイナスの値は空きノードのリンクリストに使ったりするので、その手の比較は多発する。 うーん、近頃はちょっとした作法レベルのところまで警告として口出しすることがあるからなぁ。
完全に規格に沿って書いてるわ! ってときにはイラッとすることもある。
個別に警告オプションを設定するのも面倒くせぇし、直してしまう方が手っ取り早かったりもするんだけど、
何がなんでも警告をゼロにしろって言われたら警告レベルを低くする対処をしちゃうかも。 仕事ではやってんなら手を抜くなぼけ
pragmaとかでなんとでもなるだろ 従来cppcheckなどの静的解析ツールが出していた警告をコンパイラも出すようになってくれたのは良い動き。
親切なコンパイラに感謝して警告箇所の修正をやればいい。
修正に工数がかかることが懸念されるなら、依頼主にその旨を伝えればいい。 >>360
すごい偉そうにしてるけど大丈夫?>>327
;0<len; って··· >>360
俺はプログラミングについては趣味者だから実務のことは知らんのだわ。
すまんな。
しかしな、必要以上の品質にするくらいなら手抜きで安くしろって言う客の方が多いと思うぞ。
必要より下になったらあかんのでそこを制御していい感じの
手抜き具合にするのが難しいわけだが、そこを上手くやるのが
手抜きしないことよりもプロに必要な資質じゃね?
手抜きしないよりも適切に手を抜く、どうやって手抜きするか知っていることが大事だ。
仕事は経済的に割に合う形でしか継続できないんだからさ。
そりゃあいつも十全な仕事が出来る時間的・経済的余裕があるならうれしいが、
現実はそうではないだろ。 >>366
何言ってんだ?
手抜きしたいからこそ、コンパイラの警告に素直に従うんだぞ。 DirectX関連使ってるとenumよりenum classを優先しますという警告出るんだけど、ライブラリ変えるわけにもいかなく、どう対応するのが正解なんだろ? そもそも警告って規格で定められている訳でもなく、コンパイラが独自の基準で勝手に出してくる物だからね
mutableは悪だってconst付いてない変数全てに警告出すコンパイラとか出てきたらどうするんだろう >>370
議論のための議論とか、言いがかりのような仮定の話に、いちいち付き合わないことが重要。 >>371
変な作法が追加されることなんて良くあるんだぞ。
今じゃ gcc や clang で -Wall オプションを付けたら
a || b && c
みたいな式にすら警告が出る。
優先順位を間違えやすいとこだから括弧で明示した方が良いんだと!
演算子の優先順位くらい把握しとるわ!
こんなの警告されるようになると想像したことあったか?
他の演算子でも同様の警告を出すようになることくらいはあるかもしれんぞ?
確かに >>370 は極端な例ではあるが、ようわからんところでしょうもない警告が出るようになる
かもしれんという懸念は無い話ではないぞ。 >>374
趣味でしかやってない人の意見なんて無視しろ、というが私の回答です。 >>379
ゲームのチートツールとか。
汎用的な便利なツールは色々とあるけど、個別のソフトをいじるには行き届かないこともあるので。
念のため言っとくけど買い切りの RPG かフリーゲームだけ。 ネットゲームはやってないよ。
ちなみにそのツールは公開してない。
その他に作った有用そうなものは公開してるんで、身バレするから言えない。 >>380
そうなんですか。
ずいぶん詳しいのに仕事じゃないというから不思議に思ってました。 つまり、はちみつ某は、なんの思い入れもない他人のソースを読まされる身になった経験が少ないわけか。 アルゴリズム考えるときは、図を必ず書くと思うんだけど、皆さんは何を使ってますか?
いまは紙と鉛筆使ってるんだけど、探すの大変だから、ソフトに変えたい。 >>382
せやな。
そんなわけで、他人のバイナリを見る機会はあるけどソースはそれほどでもって感じかも。
結果的に読まなきゃならないことはあるけど、所詮は趣味だから嫌になったらいつでも止められるし、急がなくてもいいし。
プレッシャーに晒されながらクソみたいなソースを読むってことはない。 C++なんざ仕事で嫌々書かされるだけの言語だと思ったけど
趣味で使っちゃう子もおるんやな >>383
曖昧なところから思考を整理するなら紙と鉛筆でいいと思うけど、
それなりに書式の整ったようにするなら PlantUML とか。
GUI で自由にってことなら Dynamic Draw くらいが手頃かもしれない。 完全な趣味目的でC++を触る変態はそうそういないと思う。 >>386
禿1読んで信者になった変態もおるんやで >>386
ゲームのチートとかするために
既存のプロセスに割り込んだりする処理を書こうと思うと C か C++ くらいしかまともな選択肢なくね?
C で足りるなら C で済ませることもあるけど、もうちょっと高級なことがしたくなったら C++
ってのは妥当な選択肢というか、唯一解でしょ。
まあ近頃は Rust にも興味があるけど……。 カッコつけろって人
付ける付けないの基準はコンパイラの警告?
完全に優先順位を覚えてる人から見ると
カッコが多いと見にくいんだよ
a == 0 || b != 0
a * b + 1
*a[i]
*a++
こんなのにカッコつけてたら
えっ?何か意味があるの?って考えてしまう > えっ?何か意味があるの?
いや、「あーまた面倒くさいやつ来やがった」だよ 優先順位を完全に把握しているなら機能的には意味のない括弧だと理解しているんだろうが
そのうえで疑問に思った「意味」って、どんなものを想定しているんだろう。
「優先順位を完全に把握していない人が間違えないように」くらいの意味しか思いつかないが。 (a + b + c) + (d + e)
同じ型の整数5個を足すのにこんなカッコが付いてたらどう思う? >>393と言ってる趣旨が違ってないか?
実際に>>397みたいなコードを見たことがあるの? 同じ印象だって話
ちなみに、
わざわざ>>397のようなカッコを付ける時はある 協業できない人があれこれC++について論じるのは害でしかない。 まずプログラム言語っての読み書きする人間のためにあるって大前提忘れてるか自覚してないやつ多いな >>399
マイナスが混ざっているならわからんでもないが、>>393で言っている優先順位の話とは関係ないように思うが? 見やすいかどうかは主観なので、他人や未来の自分が読んで誤解しないようにすることが肝でしょ。
まさか、「数値リテラルの桁区切り文字」にまでかみついたりしないよね?
https://cpprefjp.github.io/lang/cpp14/digit_separators.html 主観で見やすい表記にする
その為にコンパイラの警告を無視したり切ったりする
何も問題無い >>374
> >>371
> 変な作法が追加されることなんて良くあるんだぞ。
> 今じゃ gcc や clang で -Wall オプションを付けたら
> a || b && c
> みたいな式にすら警告が出る。
> 優先順位を間違えやすいとこだから括弧で明示した方が良いんだと!
> 演算子の優先順位くらい把握しとるわ!
把握してても間違えやすいからだと思うね
実際にはa,b,cには比較演算子を使った式が入ることが多いだろう
そうするとけっこうな長さになったりする
で全体の構造が見えにくくなる
そりゃ書いてる真っ最中は問題ないさ
しかし後から読んだときにすぐ理解できなかったり、手を加えるときに間違えたりする
warningを出すべきかは議論の余地があると思うけど、
出すべきと考える理由はわかる それはエディタの機能でかっこを表示したら良いのでは。 主観は重要だろう。
重要でないなら全部アセンブラで書けや。
客観的には最も性能の出る言語だぞ。 &,|とか&&,||は*,+の関係と同じだから括弧つける方が冗長で分かりづらくなると思うんだが 一度書いた四則演算の数式を書き換えることはほとんどないけど、bool論理演算は頻繁に書き換えるでしょ。 数式を遅延評価するオブジェクトを作れば
演算子のオーバーロードで演算子の優先順位を変えられるも同然 テクニックの限りを尽くしてbetter C++を実現したら良い プロなら抽象的な質問には回答しないでしょ。時間泥棒にあう。
「もっと具体的に書いてくれ」と逆質問する義理がないならなおのこと。 自分の職業の板には一切いかないから、ここも職業プログラマはいないと思う。
ここに書き込む意味が無いと思うんだよな。 職業プログラマって?
仕事でソフト作るし、客先に納入したりもするけどプログラマではないな たとえば、外科医が匿名の掲示板で効果的な治療法について話し合ったりしないでしょ。
治療法について話し合ってる人は患者だ。
だから、ここにもプログラマはいないはず。 プロの対義語はアマ。素人の対義語は玄人。
今時点のこのスレの回答者が素人同然の低いレベルであることは、否定できない。
例えば一週間後は違うかもしれない。もっともまともな回答者がこのスレに常駐するようになるかもしれない。 >>374
-Wallとは別に「お節介は一切禁止」というオプション欲しいね >>374はわかるけど
>>393, >>397で警告出すコンパイラとか見たこと無い 私も見たことは無い
でも他の演算子でも同じこと
1u << n+1
こんなのは良く使う
いちいちカッコを付けた方が分かりにくい カッコを付けろって結局警告が出るから付けろってことで
見やすさとか無視した意見が多い
if ((a==(b + 1))||(a==(b + 2)))
こんな感じに書くヤツがいるんだよ実際 警告の出方がコンパイラによって違うわけで
特定のコンパイラの警告に対応するということなら
#pragma使うのと同じだね >>426
それはつけた方がいいだろ。
見づらいのはスペースの使い方に問題がある。 えっ?
まじで言ってる?
if (a == b+1 || a == b+2)
これだと一瞬で理読める
俺が特殊? >>428
演算子の優先順位くらい勉強しておけよ
手間かけさせんな >>366
手抜きがどうこうと最もらしいこと言ってるけど
>>359で言ってるのは「警告に対処するのが面倒くさい」ってことだろ?
仕事で手を抜くべき場所とそうでない場所、みたいな次元の話じゃない
あと警告レベルは最大にしたりすると標準ライブラリにすら警告出るけど、標準より下げるのは良くない
そういうこと平気でやってると必ず後で本格的に面倒くさい原因不明のバグが頻発する 256倍バグを出しても256倍早く潰したら
問題無くね? if( a == (b+1) || a == (b+2) )
これくらい書いてもバチ当たらんだろ。
しょうもないことでドヤってる馬鹿が開発では一番有害。 >>433
256倍もバグ出すような奴と仕事したくない >>435
先方も256倍遅い奴と仕事したくないと思うてはるで じゃあ次は
bool b;
// 略
if (b == true)
の話でもする?w
俺はこれが一番のキチガイ記法だと思ってる 勢いあまってこれも否定しちゃう
BOOL b;
if (b == TRUE) >>439
b==-1が成立することが有るのはウィンドーズのバグ if (a = b+1 || a == b+2)
こう書いたとき気づきづらい
手間をかけるのはそれ自体だけでなくいろいろ見る機会になる >>438
if(a != true){
return true;
} else {
return false;
}
みたいなコード見たときは流石に絶句したわw >>441
それはまた別な話
ところで>>374は
if(a = b){
みたいなコードに対する警告も不要と言うんだろうか? >>441
学習が足りてないだけ
括弧なんて要らん
理解できるレベルまで進化しろ原始人 >>440
で、 if (b) と書いちゃっても自分のバグじゃなくてWindowsのバグと主張する >>445
C/C++ では、b が「非0」、つまり「0 以外」だとすべて真(true) と考えるのが伝統。
なお、余計に混乱を招くだけかもしれないが、
数学的には、b == true とは、単なる数として完全一致であることを調べる演算子ではなく、集合的に、b ∈ {非0} であるかどうかを調べる演算子だとみなすことも出来る。
ところが、C/C++ では、== 演算子は単なる数としての一致を調べる演算子で、
かつ、TRUE は通常 1 にマクロ定義されているので、
b == true が、b が完全に 1 に一致しているかどうかを調べる演算子になっている。
なので、if (b) と書く方が正しく、if ( b == TRUE ) と書くのは間違い。 >C/C++ では、b が「非0」、つまり「0 以外」だとすべて真(true) と考えるのが伝統。
名前が紛らわしいがBOOLは真偽二値じゃないんだからそれは関係ない。
TRUEかどうか判定する必要があるなら if (b) は明らかに間違い。 回避して使うかどうかとは無関係にバグはバグじゃわ; >>439はジョークのつもりだったが、実際に勢い余った人が2人も現れるとはw >>442
なにその想像を超えたキチガイ
>>449
アンタの親切心が何人かの明日を救ったねw プログラミングはアートやからな
狂気もまた創造の源泉、 >>442,450
対話デバッグでaに応じて実行をブレークしたかった人が残したデバッグの痕跡だろうね。
ソースを他人に公開する際にはブレークポイントの情報はなくなるから、他人には意味不明だけど。 >>451
狂気じゃなくて修正の積み重ね。少しづつ修正していると大ポカに気づけない。
だからこそ親切なコンパイラの警告に従う謙虚さが大切になる。 >>452
そっち?
a != true
じゃなくて? BOOL b に対して、正しくはこう :
if ( b ) // 良い
if ( b != 0 ) // 良い
if ( b == TRUE ) // 駄目 graphvizは主要なLinuxの標準リポジトリに入ってるから助かる >>403
浮動小数点数なら桁落ちとか気にしてんのかなーとか勘繰る >>403
整数の場合だと、括弧を付けてある部分に何らかのまとまった意味があるのかも知れない。
数学や物理学では、計算を減らすために式変形していくが、最終的な式は元々の意味が分からなくなってしまうことがある。
その場合には括弧で囲ったくらいで意味が分かり易くなることは少ない。
しかし、そのケースの場合は、括弧で括ると何か意味が分かり易くなると考えた間ロウ製がある。 >>455
>if ( b == TRUE ) // 駄目
-1をTRUE扱いしたくないのであればこれが唯一正しい MSDNの書き間違いかもしれないが、Win32 APIの一部にも「成功時はTRUEを返す」という
仕様の関数があるんだよな。 >>461
そもそも、-1 は TRUE 扱いすると言うのが C/C++ の伝統や文化。
-1 と TRUE を分けて扱うのは、特殊な独自仕様。
>>462
Win32 API の一部どころか、ハンドル値を返す以外のほとんど全ての関数が、
成功すれば TRUE を返す。 おいおい、#define TRUE 1のTRUEと真(true)の区別がぐちゃぐちゃだぞ。
BOOLを返すWin32 APIの多くは「成功時はFALSE(0)以外の値を返す」という仕様になっている。 C++にはtrueがあるので積極的に使っていこうと思います。 >>464
なるほど確かに Win32 の BOOL LineTo(HDC hdc, int nXEnd, int nYEnd)の 戻り値は、
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
のように、成功時には 1 や TRUE ではなく、「非0」を返すと書いてある。 キャッシュかキャッシュでないかで速度が変わる。
これは驚き。 ○ if(b) if(!b)
○ if(b == FALSE) if(b != FALSE)
× if(b == TRUE) if(b != TRUE)
WinAPI使いには常識だと思ってたんだが そういうのをみんなで共有しましょうって事で、たらこさんが2chを作ったんですよ。 >>470
常識というか思い込み。
大半のFALSE/FALSE以外を返す関数なら上で良いが、>>462のようにTRUEを返すなら当然
TRUEと比較しなきゃ正しくない。 本当にそんなのあるの?
戻り値BOOLでFALSE(0)とTRUE(1)以外の値をTRUEと違う意味を表現するために意図的に返す奴があるってこと?
具体例どうぞ >>446
>C/C++ では、b が「非0」、つまり「0 以外」だとすべて真(true) と考えるのが伝統。
>if ( b == TRUE ) と書くのは間違い。
それは b の型が int だったら、そのとおりだけれども、>>438 をみるかぎり bool b なんでしょう?
はっ!これが老害というやつですか… >>473
GetMessage という基本的な API からして変則的だから…… >>462に書いたMSDNのは単にドキュメントの間違いという可能性もあるけどね。
それとは別に、TRUE/FALSe以外に-1を返すAPIがあるのは有名だろう。
いずれにしても仕様をちゃんと確認してそれに従った扱いをすべきで、思い込みは禁物ってこと。 >>475
GetMessage の返却値の場合は一応は TRUE の特殊な場合として -1 の状況もある
って感じだから TRUE とは別の場合を意味する第三の状況というわけではないな。 >>466
bool も式にまざるといつのまにか int に暗黙に型変換されちゃったりして、
やっぱりこう、あまりしっかり区別されてる気がしねぇなあと思うことも多いよ。
Windows API で使われている BOOL よりはかなりマシではあるけど。 GetMessage()が-1を返したときはエラーなんじゃわ; 「WM_QUITでない」という条件における真(0以外)の中の特殊な場合(エラー)に-1ってことなのね
理屈はわからんでもないけど変なの
本当はそんなのの戻り値に「BOOL」なんていうtypedefを使うのがそもそもおかしいんだけどWinAPIだから仕方ないな 今なら適当なフレームワークをかぶせて使うもんだと思う。
素でメッセージの処理とか面倒くさすぎるし。 klocworkがboolメンバ変数にportingがどうのって言ってくるのがうざい >>474
やっぱQZってとんでもなくバカだな
>>439からの流れ読めよ。BOOLについて会話されてるぜ 正の型の値と負の型の値を比較する場合、ビット幅の大きいほうの型に変換されてから比較されるんですかね? >>472
いや。TRUE は、必ず if 式で真と判定されるので、if (b == TRUE) としなくても
if (b) で絶対十分であることは補償されている。
むしろ、if (b == TRUE) と書くのはバグの原因になるので駄目だと言われている。 なんというか、TRUE は、処理系ごとに変化する値ではなく、C/C++ においては、標準的には必ず 1 に #define されている。
一応分かり易さのために TRUE と書いているだけで、TRUEが2になったりする事は考える必要はない。
ただし、逆に、高速化のために 1 ではなく、非0の値を返してたまたまの値、
例えば、12 とかを返してくる関数が有りえる。
その場合、うっかり間違って if ( b == TRUE ) などと書いてしまっていたら
大変なことになるので、意味的に TRUE を返す場合には、
if ( b ) または、if ( b != 0 ) と書く方が安全だと考えられている。 非常に古い時代に、TRUE を -1 と定義していた処理系もあったかもしれないが、
現在の C/C++ では、1 に定義するのが基本とされている。
b == TRUE という判定の仕方は、C/C++ の言語仕様から考えれば推奨されない。 >>492-493
言語仕様にある true を避けているのだから、
その環境においては標準と異なる事情があるのだと察するべきじゃないの。
まあそういうことがあったらもっと別の名前を付けるべきだとは思うけど。
C/C++ はその性質上、様々なシステムの仲立ちをする機会があるし、
いろんな事情に左右される。
TRUE を 1 と定義する機会が多いのは確かだろうし、
そのときの習慣が確立されてもいるのもわかってるけど、
それが当たり前かっつーとそうとも言えんのじゃないかな。 趣味人だとかいってるがハチミツ餃子はたまに良い事いうから困る >>494
TRUE が 1 以外に定義されていても、TRUE の値は、if 文では真と解釈されることだけは保障されているので、if (b) は問題ない。
逆に BOOL b の場合、b が非0であるが、TRUE のマクロ値とは異なった値になっている場合がないとは保障はされない。
なので、if ( b == TRUE ) だと、TRUE ではないが b に真とみなせる値が入っている場合にすり抜けてしまう恐れがあり、重大バグの原因となる。 >>495
ハチミツじゃなくてはちみつな。
>>496
それが真偽値だというのが思い込みで、
実際には様々な可能性が有り得るってことだよ。
普通はこうだからこうみたいな話じゃなくて、
少なくとも言語仕様に無いのはわかってるんだから、
その環境でどうなってるかくらい確認したれやという話。
>>497
私は >>493 からあくまで現代の話だと読み取ったのでそのつもりで返答してるけど、
C/C++ のコードは長期的に使われやすいので現代という範囲の認識に齟齬はあるかもしれん。 WindowsAPIはC++限定じゃなくCを主軸に捉えてるだろ
クラスとか一切無いしマクロだらけだし
そもそもboolが無かったってのはそういうことやろ >>462
> MSDNの書き間違いかもしれないが、Win32 APIの一部にも「成功時はTRUEを返す」という
> 仕様の関数があるんだよな。
具体的にどれ? >>493
TRUEが-1というと昔のBASICにそういうのあったね
だがその時代すでにCも存在していた >>496
何回ループしてるんだよ。
真(truthy)であることが要求されているなら if (b) だし、TRUEであることが要求されるなら
if (b == TRUE) だ。それを取り違えることがバグだ。 まあ失敗時はFALSE、とも書いてあるから、こう書くのが正解!
bRet32 = MakeSureDirectoryPathExists("C:\\tmp");
if (bRet == TRUE) {
// 成功すた
...
} else if (bRet == FALSE) {{
// 失敗すた
...
} else {
assert(0);
} あと>>461は、>>455の三択で選ぶならif (b == TRUE)だが
正しくは↓こう書くべき
bRet = GetMessage(...);
if (b == -1) {
// エラー1が発生すた、
....
} else if (bRet == FALSE) {
// エラー2が発生すた、
....
} else if (bRet = TRUE) {
// 成功すた、
...
} else {
assert(0);
}
つまり出題者>>455の知識と想像力の欠如が諸悪の根源 訂正orz
誤: bRet
正: bRet32
>>509訂正、
誤: {{
正: {
>>510訂正
誤: bRet = TRUE
正: bRet32 == TRUE C89にboolがないことに拒否反応を起こす頭の固い奴に迎合して作られたboolでないBOOL 先にWindowsがシステムコールとしての素朴な要請からbool型の実装型を定義して、
その後コンパイラメーカーがbool型の実装を別の方式にし出すよりは
よっぽどマシやったろうが!
個人的にはBOOLは好きだがな
TRUE/FALSEを表すのに4バイトも使うところが
いかにもリッチなOSっぽく、使っていてリッチな気分になれる >>510
> } else if (bRet == FALSE) {
> // エラー2が発生すた、
> ....
エラーじゃないぞ
人の知識とか想像力とか言う前に自分の知識を見直せよw といっても成功していないのだからエラー扱いで差し支えないなのでは… >>510
GetMessageのマニュアルをちゃんと読めクソ雑魚
エラーの時は-1、WM_QUITの時はFALSE(0)を返すが、それ以外の時は「nonzeroを返す」としか言ってない
nonzeroというのはたくさんの値の集合であって、その判定をある特定の値と==で行うことはTRUEが1だろうと他の値だろうと完全な間違いだ
つまりお前のその糞プログラムは完全にバグっているし、お前がバカにしてる>>455らが言った通りの間違いをそのままやらかしてる クソ雑魚>>510はマニュアルを読まない可能性があるので、マニュアルの使用例貼っておきますね
GetMessageがFALSE(0)返したときの何がエラーだって?笑わせんなカス
TRUE以外ならassertで落としていいなんてどこに書いてある?勝手な妄想すんなゴミ
BOOL bRet;
while( (bRet = GetMessage( &msg, hWnd, 0, 0 )) != 0)
{
if (bRet == -1)
{
// handle the error and possibly exit
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} >>519
>TRUE以外ならassertで落としていいなんてどこに書いてある?
それはこちらが聞きたい;
何を見てそう思ったのか? >>519
変数いらねーから
for(;;)
switch(GetMessage(&msg, hWnd, 0, 0))
{
default:
TranslateMessage(&msg);
DispatchMessage(&msg);
break;
case 0:
return int(msg.wParam);
case -1:
throw std::system_error(std::error_code(int(GetLastError()), std::system_category()), "GetMessage");
} while(GetMessage( &msg, hWnd, 0, 0 ) >0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} とオモタがわかった
GetMessage()は WM_QUIT以外を受け取ったとき非0を返す、としか書かれていないから
bRet32 == TRUEでは正しい判定にならないのねん
使ったのがスゲー昔なので忘れていたが、そのときは多分>>519式に書いたから安心してホスイ しょうもない事で攻撃的になるやつなんなの
いつも吹いてしまうw >>506
BASIC というか、古の言語にはビット演算と論理演算の区別がないものが結構あった。
全てのビットが立った状態 (-1) を真ということにしておけば
ビット演算用の AND, OR, NOT がそのまま論理演算のそれとして使える。
昔はこれが気の利いた方法だったんだろう。 #define FALSE 0 ← 正しい
#define TRUE 1 ← 間違い くず! 0点!! 出入り禁止!!!
#define TRUE (!0) ← 正しい
if(b) ← 正しい
if(b != FALSE) ← 正しい
if(b == TRUE) ← 間違い くず! 0点!! 出入り禁止!!! >if(b != FALSE) ← 正しい
これこそ糞コード 意味的にboolなら
if (a)
if (!a)
で判断すべきだと思う if (a == TRUE)
if (a == TRUE == TRUE)
if (a == TRUE == TRUE == TRUE) もともと>>438と>>439を混同すんなという話なんだが、混同してる奴が次から次へと湧いて出てくるw >>528
#define TRUE (!0) ← 正しい
C/C++ では、!0 は、必ず1 になることが仕様化されているので、仕様に準拠している
処理系ではこれは必ず、
#define TRUE 1
と書くのと同じになるので、敢えて (!0) と書く意味は無い。 boolだろうがBOOLだろうがYESNOだろうが
意味がboolであればboolと同じ扱い >>529
糞コードだが
> if(b == TRUE) ← 間違い くず! 0点!! 出入り禁止!!!
より1億倍マシ >>528
1がイヤなら0もイヤだろう
#define FALSE (0!=0)
としないと >>537
マシとか言う以前にそもそも動作が違うんだが。
bがTRUEと一致するかどうか判断するのに他にどういう書き方をするというんだろう? 普通はTRUEかFALSEしか入ってないんだよ
それ以外が入ってる可能性があるなら
普通TRUEがどうかの判断だけじゃダメじゃないか? switch (b){
case FALSE:
...
case TRUE:
...
case ???
...
default
...
}
これで >>539
それは難しくいえば数学の集合論の話になる。
{0} と {非0} の二つの集合が有り、
if の条件式では、前者が偽、後者が真と評価される。
TRUEはどんな処理系であれ、必ず後者の集合の要素(元)になっていることだけは
保障されている。
なので、if ( b != 0 ) や、if (b) は正しいが、
if (b == TRUE) は絶対駄目、ということになる。 >>543
BOOLなのに
1と2を区別したい事があるんだってさ if ( b == TRUE ) は、この条件式自体の動作は問題ないが、
b が TRUE ではないが、真である何らかの値を持っていたときに破綻してしまう。
BOOL b と書いた場合、本人が書いたプログラムでは b は、必ず
TRUE か FALSE の二値に限って書くことになろうが、往々にして、
APIなどでは、「真」の意味で「非0」の値を返してくること関数が含まれて
しまっている。
だから、勘違いや混乱が起き易い。
そのため、if ( b == TRUE ) というのは、絶対にやめておいたほうが良い書き方
となる。 TRUE/FALSE以外を想定するなら
時と場合による
TRUE/FALSEしか想定しないなら
if (b) / if (!b)
と書くべき 昔VB6からWinAPI呼ぶときの注意点として本で読んだ気がする
それboolじゃないよね?とは思った >>545
じゃあ聞いてみよう。
bがTRUEと一致するかどうか判断する必要がある場合はどう書く? >>546
排中律が成り立たないからFALSEでないことはTRUEを意味しない。
成功した場合にTRUE、失敗した場合にFALSEを返すという関数がある場合、成功したかどうかは
FALSEでないことではなくTRUEと一致するかどうかで判断しなければならない。 >>548
架空のケースについてのお答えは差し控える
つか糞コードかどうかはともかく>>509の方はMSDNの記述に準拠したコードという意味では
非の打ち所が無い(何かあってもMSDNのせいにできる >>539
> bがTRUEと一致するかどうか判断する
それ自体がまずい(ことが多い)と指摘されてることにそろそろ気づこうよ… >>552
>>514見ているのにいまだにそんなこと言っているのはなんでだろう intの取り得る値の集合に対し、TRUEの定義が-93でありかつそれ以外は偽と解釈をせよと仕様に書いてあったら
さすがに(b == TRUE)とか(b != TRUE)書くことを現実の選択肢として考慮せざるおえない
もちろんそんな仕様が糞だが、仕様なのだからしようが無い
数学の本質は自由性にある、 FALSEは定数
TRUEは範囲で観測によって収束する
適性に乏しいやつには厳しいよな 集合B={FALSE=0,TRUE=1} の場合 !FALSE=TRUE だが
B'={FALSE=0,TRUE1=1,TRUE2=2,TRUE3=3} の場合
!FALSE={TRUE1,TRUE2,TRUE3} となる
しかし TRUE={TRUE1,TRUE2,TRUE3} と定義すると
B''={FALSE=0,TRUE} となり、同型B≡B'が示されるため、B'をboolとみなすことは可能である
ただし、比較演算子は集合として同値であるのか、集合に含まれるのかを示さなければならない
b⊂B'(≡B) のとき、 b=FALSE は一意だが、b=TRUE は b=1∩b=2∩b=3 を示す 数学関係ないのに数学ネタでひっぱってるヤツがいるな
IDは違うけど同じ人?
数学関係ないから >>553
>>514の話なら>> 509だし、そうでないAPIもたくさんあるから
> それ自体がまずい(ことが多い)と指摘
されてるんだが、まじでわかってないのか?
引っ込みつかなくなってるだけだと思ってたが… 訂正
b=1∩b=2∩b=3
→b=1∪b=2∪b=3 グローバル領域にインスタンスを作って、初期化はmain()の中でしたいとします。
で、初期化に必要な情報はmain()の中で初めて分かるとします。
こういうときってそのクラスのコンストラクタとしては何もしないものを作っておいて、初期化用の関数を別途用意するというのが普通ですか?
インスタンスの宣言だけしておいてコンストラクタは後で呼ぶなんてできないですよね? >>561
逆に不思議だわ。
「成功時に0以外の値を返す」と「成功時にTRUEを返す」は違うということがなんで理解できないのか。 >>566
どこから違うことを理解してないと思った?
思い込み激しすぎw GetGlyphOutline などで文字画像を取り出そうとすると、フォントが持ってない文字は代わりの文字を出力してくる。
(例えば、昔の毛筆フォントでは「(はしご高)」などはMSゴシックになる。)
これを抑制したいので、そのフォントがグリフデータを持っているかどうか、調べる方法はありますでしょうか? >>571
違いを理解しているなら>>566の後者はまさに>>539だということも理解できそうなもんだが。 >>574
ここよりwindows apiのスレのがいいんじゃないかな >>576
もしかして(ことが多い)っていう意味もわかってないのか? win32は変な仕様多いからAPIの仕様確認しないと罠にはまる 多い方に合わせろって話でもないだろう。
>>568の通りそれぞれの仕様に合わせて適切に扱えってこと。 GetModuleFileNameとか仕様作った奴のセンスを疑う >>580
誰も多い方に合わせろなんて言ってないのに…
単にそういうケースが多いって言うだけの話であることも説明しないとわからんのかな?w なら問題ないケースもあることを理解してるわけだ。だとすると>>552で指摘してたのはなんだろうと。 >>584
えっ?
まだ(ことが多い)ってわざわざ書いてる意味がわからんのか?
まともな奴と会話してる時ならいちいち書かないんだが、ネット掲示板なのでわけわからん奴に絡まれないようにわざわざ書いたのに想定外の低能さんなの? >>585
つまり>>552は、まずい場合もあるしそうでない場合もあるという意味のない指摘なわけだ。
ようやく>>539に戻れたな。
>>537
マシとか言う以前にそもそも動作が違うんだが。
bがTRUEと一致するかどうか判断するのに他にどういう書き方をするというんだろう? bがTRUEと一致する条件の話はしてなくて
boolに対するif文をどう書くかの話だろ
APIの使い方なら他スレでやって 余所でやれって、APIと言語仕様のズレの話だろ
正しい理解はどのようなものかという興味は
スレ違いじゃねえぞ APIの正しい理解ならAPIのドキュメントを見れば良いのでは?
もともとのboolの話とは全く関係ないですね >>586
> つまり>>552は、まずい場合もあるしそうでない場合もあるという意味のない指摘なわけだ。
お前には意味ないのかもな…
必死になりすぎw >>533に書いたが、boolじゃなくてBOOLの話をしているのになぜかboolと混同する人が boolの話題でbool以外を語るのはこんな感じ
内部的に固定小数点なfloatライブラリもあるぞ
内部的にvectorなmapライブラリもあるぞ BOOLも同じ
意味的なBOOLが前提
それ以外は特殊事情 >>590
意味のあるなしは主観だからいいとして、結局これ理解できたかな?
>>537
マシとか言う以前にそもそも動作が違うんだが。
bがTRUEと一致するかどうか判断するのに他にどういう書き方をするというんだろう? >>594
>>552
低能は一度指摘されたことを何度も繰り返すw boolができるまでは
if (!!b)
こういうイディオムもありましてね >>576を理解しているなら
>bがTRUEと一致するかどうか判断するのに他にどういう書き方をするというんだろう?
このような判断がが必要な場合があることも理解しているはずだろうが、
結局この質問には答えられない(答えたくない)ようだな。 goto、マクロ、BOOL
全部C言語の範疇なんだよなw
おじさんがんばりすぎ つか真理値の型であるbool型および
真理値の型としての名前を与えられたBOOL型の議論が
Win32 APIの仕様という現実に汚染されてぐちゃらけてますな
TRUEに幅が有る、なんていうおかしいことを言い出す香具師まで出る始末、! >>487
え?話の発端は >>438 でしょう?
>>439 は >>438 の bool を BOOL にすげ替えたミスリードでしょう?
>>491
もう一度いいますが、
>if (b == TRUE) と書くのはバグの原因になる
のは b の型が int であれば、確かにそういえますが、b の型が bool ならばなんの問題もなにのでは?
https://ideone.com/aL3agg
前提条件を全然考慮せず、条件反射的に
>if (b == TRUE) と書くのはバグの原因になる
と判断するのは老害的発想と私は断定しますね 一般論として、APIの呼び出しが成功しました、という情報にはそれ以上幅も糞も無い(成功した要因など知っても無駄
から、成功=TRUE、失敗=FALSEとする割付の下では、TRUEこそ単一値として規定されるべきブツに他ならない
よって、一般論としては b == TRUEは言うほど糞ではないはずであった、 まあエラー要因を複数種類返したい、ということなら
成功判定は b == SUCCEEDEDでSUCCEEDEDでなかったらエラーコードが入っている、という
INTかDWORD返しがストレートやったがな!(成功時非0を返す、とか言われるよりは if( b == TRUE ) って、結局 if( b ) ってことだろ。 >>555
ヘッダファイルの中で TRUE の値が -93 に #define で定義されていたとしても、C/C++ の仕様だと、0だけが偽で、0以外は真であることだけはANSI Cで決まっているので、それはない。 つまり、
#define TRUE (-93)
はANSI Cの規格上非合法だからそれはない >>548
その場合で、かつ、b が TRUE に一致するもの以外を除去したいなら
if ( b == TRUE ) と書く以外には無い。
しかし、Win32 API の仕様でも、そのようなことを判定する必要があることはない
ように通常、作られている。
何人かが指摘しているように、FALSE との判定は良いのだ。
TRUE との判定はまずい。 gotoといいBOOLといい、闇が深いな
裾野が広がれば、底辺は底なしカヨ、 【IT】不動の人気を誇る「Python」、評価が二分される「Java」「JavaScript」
https://egg.5ch.net/test/read.cgi/bizplus/1581244420/
>JavaScript、Java、Python、「C++」「C」が特に多くの人に習得されたプログラミング言語だった C++11規格でJavaやC#の優位性がかなり失われた気がするわ。 >>614
というか、JSやJavaは、ちゃんと学んだ人も多いだろうが、
Pythonを実際に使ったことのある人はかなり少数派だと思う。 >>617
Javaは、GUIも出来たしブラウザ上でも動いたし、他に代わるものがなかったので
それしか選択肢がなかったために実際に使った人は多かったはず。
JSも、HTMLを使おうとした際にそれしか動的言語は無かったから同様。
一方で、Pythonに関しては、似たようなものは他にたくさんあるし、
自分以外の人に使ってもらうにも実行環境のインストールが必要だし、
Javaと違って互換性にも問題あるので使いにくい。 >>618
つまり、Pythonの評価が高いのは、前評判だけで実際に使った人が少ないから。 ごちゃごちゃいうよりまずはいっぺんオッPythonで
そこそこの規模のプログラム(最低1000行以上)かいてみりゃわかる
はっきりいってクソだよ
あんなもんで巨大なプログラムはとても書けたもんじゃない 自分で1000行も書かなくても、どこかの誰かが書いてくれたライブラリを呼び出せば
望んだ仕事をやってくれるって部分がPythonの好まれる理由じゃないのん?
C++を使う人は、Pythonの流行を裏から支えてる感じで。 pythonで1000行くらいで根をあげてるようじゃ
どんなコード見ても文句言い出すだろ。。仕事にならんわ。 インデントをきっちり合わせないといけないので、Cの適当なインデントにうんざりしてる人にはむしろ合うかもしれない
でも関数やブロックが大きくなると、同一階層を探すのがつらくなるので、適切なブロック、関数分けが必須になる
いずれにしても、神経質な人には合ってるのかもしれない 機械学習ならpythonほぼ必須なんだが
いまだにやったことないとか
ロートルなのを白状してるようなもん pythonがいいとは思わないけど、perlがクソすぎるので相対的にマシだから流行ってる
それ以上の理由はないと思う perlの代替っていつの時代の話だよ
お前完全に取り残されてるぞ Pythonは、スマホで動かすのは難しいらしい。
少なくともスクリプト言語として動かすのは困難。
デスクトップマシンですら、
・互換性の問題がある。Ver 2系と Ver 3系で大幅に異なると聞いた。
・Windowsですらどの処理系が標準か不明。
・GUIがちゃんとまともに使えるかどうか不明。 >>630
Pythonのせいではなく、Perlのようなスクリプト言語がそもそも使えないという
スマホの限界だとは思う。
スマホでも使えることは使えても、IDEのような専用環境だけで使えるだけでは
本来のスクリプト言語としては使い物にならない。
このスマホの時代に Perl, Python, Ruby は合わないかも。 iOS, Android 共通にスクリプト的なことをやりたいなら、もう、スクリプト言語は諦めて、
C++で書いておいて iOSではSwift とリンクし、Androidでは、JNIを使ってJavaから
呼び出すほうがずっと簡単。
なお、AndroidならシェルスクリプトがPythonなんかより遥かに簡単に使える。 >>625
- 括弧などに従って自動でインデントが付く
- 手動 (あるいは半自動) でインデントの位置を合わせる
これの二択だったら前者の方が「きっちり」してると思うわ。
まあインデントの付け方にいくつかの選択肢がある点はやりづらい面も
あるかもしれんが、自由度と統一性は両立できないもんだしな。
Python はいじったことないからよう知らんけど、 (インデントで構造を表す系統の文法である) Haskell を書くのはつらかった。
Haskell ではインデントと改行の替わりに波括弧とセミコロンも使えるけど、Python にそういうのないの? pythonをswift, javaなんかと比較してる人は
隔離された世界で誰にも使われないアプリを細々と作ってる感じがするわw
学習系を含むデータ解析のツールとして環境が優れてるからpythonが人気なんだよ
c++でテンプレートいじってるよりビッグデータ解析してビジネス提案できる方がはるかに収入高い >>633
ブロック開始終了記号とインデントを両方組み合わせたものが一番分かり易くて間違いにくい。
インデントだけでやると、個人的には見間違いそうで神経をすり減らすので辛い。 研究者が使うのにPythonは良い選択なんじゃないの。
事務作業にVBAが良い選択なのと同様に。 今さらですが、そもそもWin32のFALSEって、0であることは保証されてるんですか?
BOOL b = FALSE;
if (b)
{
ここに来ないことは保証されてるんですか?
} >>639
まともな C/C++ では、FALSE はどんな処理系でも 0 であることが保障される。 >>639
規格書のようなレベルで規定されているかどうかは知らないけど、公式ドキュメントの至るところで
FALSEは0である前提で書かれているものが見つかるから、そこを疑う必要はないと思う。
>>640
FALSEはWindows SDKの定義であってC/C++とは直接関係ないんだが。 >>640
現実にはそうだってのならわかるが、質問は保証があるかどうかなんだから、根拠を添えろよ。
少なくとも現状の WinDef.h では FALSE は 0 、 TRUE は 1 と定義されているのはわかったし、
常識的に考えればこれが変更されることはないが、
私はマイクロソフトのドキュメントからこれを裏付けるような文言を見つけられなかった。
BOOL が int であることは発見できた。
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
should be TRUE or FALSE って書いてあるのにこれに反するような API があるのはアレだよな……。 システムハンガリアンもそうだけど明白な違反が堂々と放置されているからなあ >>642 >>643
[根拠]
数学的に以下の根拠となる:
1. FALSE は、if ( FALSE ) とすると、偽として処理されることは絶対に保障される。
2. if (x) で x が偽として評価されるのは、ANSI C も、古い C でも必ず 0 という1つの値のみであり、他の値はすべて真と評価される。
1, 2 を両方成り立たせるためには、FALSE は必ず 0 でなければならないことが
証明される。 数学が大事です。
今の場合、仕様書に書いてなくても、数学的に考えれば絶対であることが証明できます。 昨日の奴かw
BOOLとboolは別物だということが結局最後まで理解できなかったんだな。 >>645
頭が悪いとか話が通じないってよく言われない?
言われる度に相手の方が間違ってると思ってるだろうけど、話が通じてないのはお前が自分の間違いを認識できてないからだぞw このスレには、失礼ですが、はちみつさんも含め、数学に弱い人が多いようです。 >>649
いや、むしろ逆に現実では天才と呼ばれています。 仕様書にすべては書いてなくても、数学で考えれば絶対であることが証明できる事柄があるのです。
今回のもその一例です。 ああ、荒らしに来ただけか。
まぜっかえすにしてももうちょっとマシなこと言えよ。 失礼ですが、はちみつ氏は、C++の仕様には詳しいですが、それ以外は結構間違っています。 >>656
ここでの君の書き込みだけで判断すると
君が間違ってる可能性が高い >>1
私は、東大数学科の人とは意見が一致することが多いです。
よく考えてみてください。
もし分からないようなら、多分、あたなは東大数学科ではないか、レベルが落ちてしまったと思われます。 まとめるとこう。
1. BOOL型およびTRUE/FALSEは真偽値として用いるために*Windowsで独自に定義*されたものだが
厳密には真偽値と振る舞いが異なる
2. 具体的には、FALSEでなれければTRUE、TRUEでなければFALSE、という排中律が成り立たない
3. 排中律が成り立たない以上、FALSEとの比較、TRUEとの比較はそれぞれ意味がある ここは、学歴も実績も嘘を付けてしまうので参考になりません。
東大数学科と言うのもたぶんデタラメでしょう。 排中律君も数学君と同じ人かと思った
違うのかな?
普通の言葉で書こうよ
書けるでしょ >>664
TRUE を持つ内では皆が共通に論じられるほど広く知られたもののひとつだからでしょ。
反例としてはひとつあれば充分。
ちなみに「TRUE と比較するべきではない」に対する反例ね。
true であれ TRUE であれ、それと == で比較するのが罠になりやすいっつーのは
罠になりやすい部分として有名すぎて逆によく知られている常識だが、
絶対不変の定理みたいに言い始めたやつがいたから変なことになってるんだよ。
現実はそんな綺麗なもんじゃねーよっていうのに Windows はうってつけだろ? BOOLはWindows APIでしか使わないと思ってるから話が通じないんだな
数学君はなぜ話が通じない?
BOOLがTRUE, FALSE, UNKNOWN, ERROR
からなる集合だったら? >>664
>>639からの流れで、あくまでWin32APIの中でのFALSEの話をしているからだろう BOOLは非常に広い環境で使われていて
その多くはTRUE/FALSEの2値を示す型として使われる
こういう普通の環境では
if (b) / if (!b)
で判断するのが最良
そうではない特殊な環境(Windows APIなど)は
個々のAPI別に語らないと意味が無い Wimdows APIに限定した話ならここですべきではない
他へ つまり、Windowsで>>439のように書いていたのをWindowsのBOOLを知らずに否定しちゃう人、
というネタそのものを体現してくれたわけだな。 BOOLについて議論するならどのBOOLか限定しないと
enum BOOL {TRUE,FALSE};
みたいなのかもしれないし
負論理の入出力ポート読み書きする値だとかで順番も重要だったりして >>671
何が「つまり」だか
Windows APIが色々と特殊なのは知ってるよ
Windows 2.0から組んでるし
特殊事情はあくまで特殊事情 そもそも、特殊じゃない「普通の環境」のBOOLって何ぞ?
typedef bool BOOL; とかw https://ideone.com/T9gWWT
こうなるので、負の型にキャストするのが良いんですかね? 標準にはboolと_Boolしかないんだからそれ以外はどこぞの馬の骨が好き勝手に決めただけの独自定義
そのライブラリのマニュアル熟読しろでこの話は終わり >>675
そうなんだけど
C言語スレでやれ
じじくさい話ばっかりでうんざりするわ じゃあboolに戻すけど
if (b == true)
これ書く異常者は一定数おるわな >>680
私には正常な書き方に思えますよ
その書き方のどこが異常なのでしょうか? if (b) で済むのを
if (b == true) と書くのは
if (b == true == true) と書く異常者と同じ
きりねえって話 bool b;
if (b == true) // コードスメルではあるがバグではない
BOOL b;
if (b == TRUE) // 正しいか正しくないかは状況による >>685
C++スレでC++以外の言語という「つまんないこと」でイキってんのおまえだろ おまえみたいの「いちびり」って言うんだけど意味わかる?w >>682
バグにならなければ問題ないのでは?
>if (b == true == true)
とは私も書きませんが、だからといって異常だとは思わない
というか、あなたの「異常」の定義が異常なのでは? >>688
いちびり、とは、あなた、関西人ですなぁ >>689
正常と異常の境をおまえさんはどこだと思っている? >>674
Windowsしか知らないの?
世界が狭い
非常に多くの環境でBOOLを使う >>690
ああ、おまえほんまは関西人ちゃうなw
俺もほんまの関西人ちゃうけどなw >>692
大文字のBOOLを使う「非常に多くの環境」とは? >531や>>682が異常とは思えないって
まじかQZ >>692
その定義を出してみなよ。
標準の仕様じゃないんだからその環境ごとの特殊な定義であることは変わらんだろ。 >>697
その返しは口喧嘩に負けた小学生みたいだから、ちゃんと相手の質問に答えなよ もう自分で何を言っているのかわからなくなっているんだろうな。
BOOLやTRUEの定義が環境によって異なる場合があると認めた時点で
if (b == TRUE)
これが正しいと言えるかどうかはその定義次第だということになるのに。 俺の狭い経験だと
BOOLはintで、TRUEは1、FALSEは0
しか見たことないけど、他の定義の環境ってあるのかな? windef.hのFALSEが-1とかに変更されたら、既存のソースは崩壊だろうな typedef unsigned BOOL:1;
ならまだ救いがあった
なんでint型にしてんだろうな >>705
それは BitField みたいだけど、構造体メンバ以外で使えるようになったんだっけ? もしかしたら、Rubyが、0をtrueと解釈してしまうことから変なことを思ってる
人がいるのかもしれないが、C/C++においては、言語仕様的に条件式で偽と
解釈されるのは、古くから、唯一、整数の 0 しかないなかったので、言語仕様が
修正されない限り TRUE が 0 以外の値にマクロ定義されることは絶対に無い。 あれ?
もしかして私・・また同じ日を繰り返してる・・?? >>708
スマン:
誤:修正されない限り TRUE が 0 以外の値にマクロ定義されることは絶対に無い。
正:修正されない限り FALSE が 0 以外の値にマクロ定義されることは絶対に無い。 >>681
if(b)で十分なのにif(b==true)と書くのはif((a==b)==true)と書くのと同じで冗長なんだよ
これがすぐに理解できないなら論理を簡潔にする能力が欠如してるのでプログラミングの才能はないね >>712
しかも、b は、少なくとも見かけ上は int 型ではなく、BOOL 型だし。
それに他の言語の場合、if の条件式に入れられるのは唯一 bool 型の
場合があり、一番 if の条件式に入れ易い型。 >>713
他の言語の場合、例えば x, y が整数型の場合、
x == y
とした結果の型が bool 型。
そして、if の条件式に入れられるのは bool 型のみだったりする。
だから、もともと b が bool 型なのに、敢えて b == true と判定して
また bool 型に「直して」しまうのはとても奇妙な感じになる。
その文化との兼ね合いから、C/C++ でも、b が BOOL 型の場合は、
if (b) とするのが美しく見える。 MISRA-C でも、if( 変数 )で、変数が実質的にブール型の場合は、これでOK
int a = ( 5 < 10 );
printf( "%d", a ); /* 1 */
if( 5 < 10 ) と、if( a ) は同じ意味。
a は、実質的にブール型 bool型が存在しない時代に何故bool型になるのか >>695
異常を「コンパイラがコンパイルできない」と定義していますから >>712
コンパイルが通るんだったら異常ではないのでは? >>712
>論理を簡潔にする能力が欠如してる
簡潔すぎてわかりにくいのも困りますね、プログラミングはまず他人への分かりやすさを優先するべきでは? 簡潔過ぎて分かりにくいって何?
if (b) で分かりにくいなら
変数名が適切でないとかそもそも分かりにくい作りとか
他に問題があるんじゃないの? もしかして
if (a ==b)
よりも
if ( (a == b) == true )
の方が見やすいとかいっちゃう? そりゃ
if (a == 42)
よりも
if (a == 42 == true)
のほうが見やすいし
if (a == 42 == true != false)
のほうがさらに見やすいのが異常者 カッコも付けないと見にくいよな
if (((a == 42) == true) != false) QZは変なこだわりに固執するやつだから、一般的な感覚とか常識とかについて議論しようとしてもそもそも議論が噛み合わないし、スレを無駄に汚すだけ if (true == true == true == b == true)
if (true == b == true == b == true)
int *p = &*&*(int *)&*&*&*&*&*(int *)&a; ようちえんじがかんじをつかわないでってぐずってるのとおなじだね 異常とは、普通じゃないことだよ
少数派のこと
if (b == true == true) は明らかに異常
if (b == true) はたまに見るけど、まぁ異常かな boolやBOOLでない変数abcをif(a==b==c)と書きたい事はある。 if(b==true)
はifのなかには比較入れないとダメだと思っているんじゃね
そう言う言語もあるし 「rust が c++ を超えた!! 神!!」みたいな記事をよく見ますけど、今後c++がrustから学んでもっと良くなることって期待して良いですよね?
rustに勉強のコストを割くか迷っています >>731
片山はQZほど馬鹿ではない
まず国籍が違う なぜ
if (a == true)
と書くやつがでてくるのか
それは条件式に食わせるためには比較演算子で値から「真偽値」に変える必要があると
思っていてそれがboolと同値と理解していないからだろ
だからそういうやつは
if (a == 42 == true)
とは書かない
この例はむしろboolを理解してるやつからしか出てこない発想
やつらはいったん「真偽値」になればあとは論理演算子でつなげると理解している
ある意味、条件式を作るときのイディオムに馬鹿正直に従っているわけで別に
異常だと騒ぐほどひどくはない
別の見方をすればboolを特別視しないで書いてるわけで、
冗長にはなるが共通のフォーマットで書ききるってことはほかでもあることだ
そう思えばやっぱりひどくはない
実際おれは特別読みにくいとは感じないし、この無駄は最適化で消える
何かの機会にこれ冗長だよねと教えてやるぐらいで十分 冗長な書き方をする人の真意なんて測りようもないし理由が一つに決められるわけもないだろう。
想像するだけ無駄。 >>715
そう書くべきだしそれが普通ってことはわかってんだって。
自分で書く分にはそう書くよ。
でも、他者が書いたコードを読むときや利用するときは
> 変数が実質的にブール型の場合は
っていう前提を確信できない場合がある。
整数型で真偽値の代用にすることがある C/C++ では
型で判断できないことがあるから罠だよねって話をしてるんだよ。
真っ当なデザインではない場合があるから思い込まずにちゃんと確認しようねってこと。 > この例はむしろboolを理解してるやつからしか出てこない発想
そりゃそうだ
ifの制御式は比較でなければならないと言い張るやつへの皮肉なわけで operator =(BOOL value){
if(value==0){
return FALSE;
else if(value==1||value==2||...){
} >>596
あったあった
今はわざわざそれ使う理由忘れた Cだとそれで必ず0か1になるからTRUEと比較しても大丈夫!っていうクソみたいなバッドノウハウ operator ==(BOOL value){
if(this->value == 0){
if(this->value == value){
return TRUE;
}
}
else{
if(value==1||value==2||...){
return TRUE;
}
}
} >>743
そもそもTRUEと比較する必要はないしWindowsから出てきたイディオムでもないと思うが。
どちらかというとtruthyな値からtrueを得るイディオムとして使われているような。
よく見かけるのはJavaScriptとか。 リターン式から返却値の型を推定させる場合にはautoが必要だ >>725
あなたのいう「一般的」というものが、実はそれほど一般的ではなかった、という可能性はありませんかね?
というか、まずあなたのいう「一般的」をあなたの言葉で定義するべきでしょう
あなたに定義できますか? 単語の意味は辞書引けよ
APIの仕様はヘルプ読め、と同様だな
なんで個人が定義するんだよ true と比較したけりゃすればいいじゃないの。
そのプロジェクト内で一貫したポリシーがあるのならそれでいいよ。 コード規約「if(bool)はif(bool==true)と書かなければならない」
やだよ、そんな規約ww
規約決めるまでに紛糾してプロジェクト始められねぇよw explicit operator boolだとラムダとかの戻り値強制したいときそうなっちゃわない?
value() && true か value() || false
static_cast<bool>(value())は好きじゃない 意味的にboolの型であればboolにキャスト
そうじゃないなら意味通りにboolに変換 >>258
mmap を確かめています、なんだかすごく時間がかかってしまいました…
ideone はファイルを作らせてくれないみたいですね… https://ideone.com/zXFtEY
fd と fd に紐付いた mmap をつくっておいて、
@fd 側にデータを追加すれば mmap でも見えるのですが、
Ammap 側からデータを追加しても fd は増量しないようですね
今は cygwin で見てますが、ちゃんと linux をいれて確かめるつもりです… I/Oの遅さの陰に隠れてたけど。
ストリームよりSSDのほうが速いよって時代になって困る。 >>743
ああなるほど
if(TRUE == !!b) のことか
if(!!b) は javascript の方だろ ! は見づらいから私は not と書くことにしてる。 一応、alternative tokensに規定はあるが
使う奴の心は #define BEGIN { なんてやるやつと同質だね Cにも_Boolがなきゃヤダジタしてたやつとか
マジそういう言語へ行ったきり帰ってくるなって感じ
で結局BOOL < 0みたいなオカシイことが起き出す原因を作りやがる C と C++ で解釈が違うのに結果として動作は同じみたいなのがたまにあってすげーなって思う。 >>770-771
if 文の条件式を見てて思い出した。
C だと条件式の評価結果を 0 と比較するというルール
C++ だとブールに変換するというルール。
まあ整数をブールに変換する規則は結局のところ 0 と等しいかどうかなんで
ちょっと回りくどくなってるだけなんだけど、
そういう違いがあっても互換性が維持されるというのがどこかで検証されてるんだろうと思うと、
手間かかってんなぁという感想が浮かんだ。
他にも列挙定数の型が C と C++ では違うとか……。
私が把握してるのはそんくらいだけど、
探せばもっとあるんじゃないかな。 >>766
>if(TRUE == !!b) のことか
さすがにこんな意味のない書き方が人の目につくほど蔓延りはしないだろう。おそらく>>743の妄想。
!!b は、bool型(と、しばしばオーバーロード)を備えた言語で非bool型の値bをbool型に変換するテクニックだろ。 そういうゴミみたいな自己満テクニック()が積もり積もって誰も触れないスパゲティモンスターになっちまうんだよ
b!=0でも(bool)bでもいいからやるべきことを直接表現しろ (bool)b
はCへの移植の可能性があるならやっちゃダメ >>776
何で?
ISO/IEC 9899:2011 (E)
7.18 Boolean type and values <stdbool.h>
1 The header <stdbool.h> defines four macros.
2 The macro
bool
expands to _Bool. typedef char bool;
の可能性があるから Cに移植する可能性があるならC++の機能を使っちゃダメなのは当たり前だよなぁ
C++スレで言うことではないと思うが >>779
問題点はそこじゃない
移植時にコンパイラが問題点を見つけられないのが問題 コンパイラが問題点を見つけられない例は他に山ほどあるが
だからといってわざわざ増やさなくても良い Cに移植する可能性が無いならどうでも良い
ちなみにキャストで警告が出る環境もある >>778
マクロとtypedefが被った場合どうなるか解ってる? >>733
Rustを少し見てみたけど、書き方が全くC/C++とは違っていて、
全く異なる文化圏の言語になれた人が設計した臭がした。
これがC/C++の代替になるとは考えにくい。
はっきり行って、これを使えといわれると辛い。 個人的には Rust は好感触。
型システムは ML 系言語で実績があるものを基礎にしてることもあって、C++ のグダグダな歴史を背負ったものよりはまとも。
ML 系はやっぱり高級路線の言語だし、インデントでブロックを表す系統なのがしんどいけど、
Rust は上手く低レイヤ用 (としても使えるよう) に着地させてるし、 C 風の外観を踏襲してもいる。
C++ が Rust から取り入れられるものはそんなに多くないと思う。
C++ は良くも悪くも互換性についてかなり強い要求があるので、
Rust 的な、カッチリと保護された仕組みを後付けするのはどう考えても無理。
C++ が Rust を参考にすることは間違いなくあるとは思うが、
全体の思想がまるで違うので限定的な範囲でしか取り入れられない。
もし取り入れらたらそれは C++ の新機能として新しく学ぶので十分でしょ。
Rust を学ぶのは間違いなく有用ではあるけども、
Rust の知見が C++ に取り入れられる可能性がありそうだからという理由ならそんなに意味ない。 C++の配列は長さの情報を持ってないってことになってるけど
長さを与えなくてもdelete[]できるんだから、メモリのどこかにその情報はあるよね?
なんでその情報をプログラマが利用できないようになってるの? rustがかっちり保護してくれるとか低レイヤー向けとか馬鹿ほど信じてるよね。
ありゃ帯に短し襷に長しの典型言語だわ。 >>792
実際、Rustは、Cを簡単にするのではなく、Cを難しくしてしまっていて、Cのポインタが理解できない or 難しく感じる人には、Rustの特徴の核心たる所有権、借用などの部分はちんぷんかんぷんだと思う。 >>793
Cの問題点を取り除いたと言うより、ほとんど全てのプログラミング言語が暗黙のうちに用いている代入の概念をなるべく使わないようにして変数束縛などの全く異なる独自概念を用いようとしている。
しかし、これは、手続き型言語と関数言語の違いに匹敵するくらいのプログラミングの概念の変更になってしまうため、手続き型言語の中で改良された次世代言語と言うものではなくなってしまっているとも言える。 RustはC++なら簡単にできることをものすごく回りくどく書かないとコンパイル通らない感じだからとてもつらい >>790
RustがC++に取って代わることがあるか、というニュアンスの質問でした
今C++でやってる仕事がRustに置き換わる可能性が高いなら今から勉強しとこうか、と >>797
断言してもいいが、RustはC++に取って代わることは無い。
なぜなら、普通の手続き型言語での枠組みにすら入ってない書き方を強要されるから。
手短に言えば、単にC/C++と書き方が大幅に違っているだけではなく、書き方が他のどんな減の範疇にも属していない。 >>796
C/C++ でのオブジェクトの寿命の管理の難しさってのは
理屈が理解しづらいというよりはわかってても間違うという難しさなんだよね。
そして間違っていてもコンパイラは黙って通すことも多い。
C/C++ を長く使っていればそれを感じることって結構あるでしょ。
そういう部分のプログラムが正しいことはプログラマが保証しなくてはならんわけだ。
でも Rust では言語処理系の側でやってくれる。
C/C++ で面倒な部分を Rust では自動でやってくれる。
まわりくどいのは確かだけど、それで楽できるのも確かなので、
どっちを取るかって話だな。
オブジェクトをどこで後始末するか。
管理の主導権はどのモジュールに持たせるか。
そういうのって C/C++ でも考えてるよね。
C/C++ ではプログラムに書いてないだけで本来はあるはずのものなんだよ。
(C++ だとスマートポインタの導入で少し楽にはなったけど。)
自分が何を考えていたのか、そして何を考えられていなかったのが
明らかになるのはそれはそれで楽しいと思う。
まあ、それは俺が趣味でやってるからかもしれんな。 >>800
そうだよ。
そんでもって大抵の人間は設計がヘタクソだし、
ヘタなところが検出されるなら検出されないより良い。 >>799
変数束縛やら所有権や借用の概念が複雑すぎて、そっちの方が C/C++の
メモリ管理よりミスし易い。 >>802
間違いなくミスし易いけどミスした箇所が検出できないということはあまりない。 設計がヘタクソなヤツが書いたソースのメンテやらされるのは最悪だけど自分で組み上げるならC++以外有り得ない
各々の力量が顕著に表れやすい最高の言語には違いない
バカも容易に炙り出せるしな >>803
仮にあなたはちゃんと理解できても、一般のプログラマは変数束縛やら所有権や借用の概念を理解することが難しすぎるので、C/C++を置き換える言語にはならない。
それらの概念は学習コストが高すぎるどころか、一生理解できないプログラマが多いだろう。 >>805
誤解のないように補足しておくけど、俺は Rust が C++ を置き換えるという主張はしてないからね。
C++ の重大な欠点を (実行コストをあまり払わない形で) 改善しているのは確かってだけ。
そんでもってそれが必要な場面は間違いなくあるってことも。 >>807
new TYPE[] のようにしてヒープから配列として確保されたメモリは確かに
要素数の情報を持っている。
しかし、new TYPEのように配列ではない場合は、高速化のために情報を
持ってない処理系もある。そのために 前者では delete[] を、後者では
deleteを使うことになっており、間違った組み合わせを使った場合には
不具合を生じる。
また、ポインタは、ヒープから確保された配列ばかりをポイントしているとは
限らず、例えばスタック上のローカルオート変数や、グローバル変数をポイント
していることもあり、その場合には、要素数の情報は全く持っていない。
さらに、Cの場合、関数の引数に TYPE buf[] のように配列を書いても、
TYPE *buf に自動修正される仕様となっている。
そのため、配列を受け取るのは、必ずポインタということになる。
しかし、ポインタで受け取るということは、そこには、&a のように、
ローカルオート変数も実引数として指定して呼び出すことも出来る。
その場合には要素数が無いので、あなたの望みをかなえる高速な
一般的方法が存在しない。
望みをかなえるためには、言語の拡張が必要となる。 Rustっていろいろ清々しいよね
関数型言語に必須じゃねえのと思うリスト関係がぽっかり抜けてるのは不満だけど >>808
ヒープに確保した配列の要素数はやはりメモリ上にあるんですね
手段がないのは文法として一貫性をもたせられないからということでしょうか
なるほど、回答ありがとうございます delete [] pと同じように
sizeof [] pを用意すりゃいいのにね
pがnew []されてなかったら誤動作するって挙動ならdeleteと同じだろうに >>791
>C++の配列は長さの情報を持ってないってことになってるけど
>長さを与えなくてもdelete[]できるんだから、メモリのどこかにその情報はあるよね?
new したときは、その領域サイズが実行時にユーザーのみえないところに保存される、というだけなのでは?
C/C++ の配列は長さ情報を(自分でそう書かないかぎり)持たないとおもいますよ 設計がダメな場合コンパイラにいくら指摘されようと根本的には治らんのだが、
(たいていそういう馬鹿はコンパイラ通すためにmut,RefCell,unsafeを使いまくる)
そういうのを少しもわかってないバカがrust推しなんだよなぁ。
構造体を1から作り直さなきゃならんかったり根本的に間違ってる。 >>808
new TYPE[]するとき内部的にサイズ情報を持つ保証ってあったっけ?
例えば自前でoperator new []を実装するとき、予め2^nバイトのブロックを所定の数用意しておいて、要求サイズに応じて必要十分な大きさのブロックを返すなら、割り当て時に要求されたバイト数または要素数の情報を保持しないという実装も可能かと思う。 デストラクタ呼ぶ必要ない型だと、size情報持ってないと言うことなんだろうね >>820
デストラクタの実装も、返ってきたアドレスの値でどのサイズの領域か(割り当て要求されたサイズではなく、自分で区切ったブロックのサイズ)が分かるようにしておけば大丈夫でないかな? >>822
すまん、勘違いでした。全部忘れてください アドレスだけじゃなくて長さも受け渡しするインターフェースにしましょうとしか。 オブジェクトならCORBA、データ構造だけでいいならASN.1とか。 >>822
TYPEがデストラクタを持つclassの場合に、ptr = new TYPE[n] で確保されたメモリ
を delete[] ptr とすると、 正確に n 回デストラクタを呼び出す必要がある。
new が n * sizeof(TYPE) より大きめのブロックを確保した場合でも、
delete[] ptr 時に正確な n の値を割り出す方法が必要となる。
なので、n の値は ptr の値さえあれば知ることが出来ることが必要条件となる。
つまり、少なくともデストラクタを持つ TYPE の場合に TYPE の配列をヒープから
確保した場合には、配列の要素数を必ず配列の先頭のポインタの値から「知る」事が出来る。 >>827
もうちょっと簡単なのないですかね。
型情報要らないんで。 型情報が無けりゃデシリアライズしても使いようがあるまい。 双方向mapって何使うのがいいですか?boostのbimap?
それともこのくらいは自作してる人のほうが多いですか? 型情報ないならそもそもデシリアライズできないし
型情報なしで成り立つ、つまり型情報を事前に知っている前提なら
バイナリでそのまま送ればいいだろ 型がわかっててもコンテナはそのままではバイナリで送れない >>834
そのやり方教えて。
あめさんあげるから。 ちゃんとやるならPODに詰め替えてからchar配列へreinterpret_cast >>826
シリアル化ってのにどういう要件を置くかだな。
同じ環境でデシリアライズ出来ればよいのであれば >>837 で十分だろうし、
データ形式が決まってて (あるいはデータ形式の側を中心に策定したくて)
それのシリアライズとデシリアライズを (それぞれ別の環境で (ときには言語も違うかも)) やりたいということなら
protobuf などのツールを使うのはよい案だと思う。 boostにあるじゃないですか
googleのなんか使うんじゃありません >>791
>>807
実装依存だと思うけど hoge[-1] あたりに格納されてた >>840
VC++の場合、ptr = new TYPE[n] で確保された場合は、確かに
ptr[0] == n
になっていた気がする。
「確かに」というのは言葉のあやで、厳密には覚えてないが、
VC++の new で使われる組み込み関数のライブラリのソースコードを見ると分かる。 >>841
すまん、
ptr[-1] == n
の間違い。 >>842
あ、すまん、正しくは、大体、
((DWORD *)ptr)[-1] == n
だ。
ptr[-1] だと、sizeof(TYPE)分、アドレスが戻ってしまうし、
結果の型も DWORD とかではなく、TYPE 型になってしまう。 >>843
言っておくが、new char[n] とかでは、駄目な可能性は有るよ。
話は、「TYPEがデストラクタを持つとき」のnew TYPE[n]に限定。 一時オブジェクトの寿命について、ご教示ください。
例えば、以下のようなコードがあった時、
void foo(const char* c); // 外部ライブラリの関数につき変更不可とする
void main()
{
const std::string s = "aaa";
foo((s + "bbb").c_str());
}
一時オブジェクトstring(s + "bbb")の破棄が行われるのは、
関数foo()を呼ぶ前でしょうか、呼んだ後でしょうか。
調べた範囲では、「完全式の終わり」という話が出てきたのですが、
どこまでが完全式なのか判断できませんでした。 >>846
この場合はその行の終わり。
セミコロンのところだと思っていい。 すごくどうでもいい話なんだけど、
JIS では完結式という用語を使ってるのに完全式って言葉の方がよく使われているよね……。 >>846-847
式の一部であるような式が部分式で、
そうでないような式が完結式って言う。 >>847-849
ご回答ありがとうございます。
大変勉強になりました。 newって意外と速いんだな。
アクセスは不利かもしれないけど。 >>854
速いよ。
高速なゲームでも普通に使える。 でもスタックは常にキャッシュに乗ってるから、そこらへんでどう変わるのかな。 キャッシュに乗るくらいの量だったらそもそもクリティカルな重さにはならんだろ。
newで問題になるのは10万とかそのくらいのオーダーをがっつりfor文で呼ぶとかそれくらいのことする場合。 >>857
VC++の場合、コンストラクタが無い場合、new が必要とする時間は 170クロック。
3.0GHz の CPUの場合、1.7 * 10^7 回(1,700万回)くらい new してやっと一秒
位。
だから、問題になるのは、1万回ループではなく、100〜1000万回くらいのループ。 もちろん、スタック変数で済むならスタック変数の方がいい。
ただ、スタックは容量に限りがあるので全部スタックという訳にもいかない。
ヒープにも限りはあるにはあるが、それは OSやマシンの限界。 コレクションがソートの有無でだいぶ変わる。
trie_base_benchmark__sorted_words_1
trie assign.
409ms
size : 466551
words : 466551
trie insert.
762ms
size : 466551
words : 466551
std::set insert.
69ms
std::unordered_set insert.
149ms
(assigned) trie find.
24ms
(inserted) trie find.
25ms
std::set find.
194ms
std::unordered_set find.
63ms trie_base_benchmark__random_words_1
trie assign.
2034ms
size : 466551
words : 466551
trie insert.
2026ms
size : 466551
words : 466551
std::set insert.
490ms
std::unordered_set insert.
146ms
(assigned) trie find.
158ms
(inserted) trie find.
169ms
std::set find.
477ms
std::unordered_set find.
62ms 挿入速度が変わるのは仕方ないとしても、検索速度が変わるのは、キャッシュじゃないかと思うんだけど。 std::sort: 306ms, (466551count).
先にソートしてから挿入したほうが速度的にお得っぽい。 >>854
速いといっても
単純な演算と比べれば劇遅 >>867
とにかく、足し算/引き算が1クロック程度、new が170クロック程度だからね。
使い方を間違えなければ劇遅とはいえまい。 auto hentai = SM(std::move(羞恥心)); >>871
回路はほぼ共有してるんじゃないの?
2の補数を使うのもそれが理由なんだろうし。
少なくとも Pentium 時代まではクロックは同じだったはず。
近頃の事情は知らんけど
GCC あたりで強い最適化をかけてみても引き算か足し算を特に避ける様子もないので、
まあだいたい同じなんでしょ。 >>870
C++の場合、+ひとつだけでも裏でどんなコードが動くか油断ならない。 >>871
+ と - で速度が違うCPUは見たことがない
- は順番が関係あるので
処理によっては遅い事がある
b = 1 + b
b = 1 - b 整数だけの話じゃなくてってことか。
ある程度の常識的判断が出来る場合もあるけど、
基本的には実装次第だわな。 組み込み型じゃなけりゃそりゃね
+ でミサイル発射とか >>870
new より + の方が 170 倍速いと言うことだ。 >>874
一度bをnegateしてから足す処理系があるかもな >>874
確かに引き算には順序があるので、足し算より最適化に不利になることがある。 newが常に数百クロックで済むと思ったら
間違いかもしれん… 経験的にはnewが遅いと思ったことは無い。
なお、コンストラクタの処理時間以外はnewはmallocと同じ速度。
ゲームメーカーでも必要な場合に malloc を使うことは問題ないとされている。 new からしてmallocを呼んでる実装が多い気がする。 そりゃnew用とmalloc用でヒープ別けたら無駄だし ヒープからの割り付けをする機会を減らすことで実行速度を上げる工夫はよく聞く話ではあるよな。
ただ、そこまでギリギリのチューニングが必要ってことがあまりないだけで。 newは最悪値が読めないからなぁ
組込とかシビアなゲームでは使い辛い >>887
よっぽどでない限り、AAAゲームでも使われてるよ。 最近では小規模組み込みでもC++を使う事はあります
new / deleteやヒープを無効にしたり
newのみでdelete出来ないようにしたり
なんてこともあります また馬鹿が無駄に一般化してできるワイ言ってんのか。。相変わらずだな。 >>891
そりゃそういう例もあるわな
だから何?w スレで、do{}while()はダメっぽいこと書いてあったけど、なんでダメなの? >>887
でもお前は組み込みにもゲーム開発にも携わってないじゃん >>899
ごめんねー、俺はプリンタ屋さんなのw
ゲームは知り合いの話ね >>901
俺は制御周り、上位インターフェースからのデータを描画ルーチンにに渡したり、下位インターフェースにデータ渡したり、パネルとかの制御をやってる
描画部分はまた別の人がやってる プリンタってプロセッサはどんな感じのを使うんですか?
newってあるんですか? プリンタのヘッドについてる穴の数は決まっているんだから、あまりヒープが必要無さそうな気もする。 std::vectorの上にヒープを作っても速度的に大丈夫なことは確認した。 昔はSHシリーズとかR2000とか
今はARMもそれなりに使ってる
制御だとnewは基本使わない
あと俺がやってるのは業務用のLBP メモ問題は結局ホワイトボード買ってきた。
ホワイトボードをワンノートに撮影するという昔っぽいことに。 ワンノートのアンドロイド版はカメラにホワイトボードのモードがあるんだけど、テカリ消してくれないし、ホワイトバランスも調整してくれない。 PostScript くらいならプリンタの側で処理することもあるし、
世間で想像されているよりは高級なことをやっているんじゃないかなぁという気もする。 モーター動かしたりするのはnew使ったらダメなんだろな。 >>900
ゲームに関しては、かなりちゃんとした現場で昔から malloc は使われていたし、全社的に使っても問題ないとされていた。 >>919
で?
使われてる例も使われない例もあるよ
タイミングにシビアなゲームだと使い辛いと言うだけ >>918
最大実行時間が読める専用のヒープを持ってたりするよ 選べるってことは、用途によって使い分けが必要って事なんだろな。 ループ内で可変長のvector使っているようなのは、外に出してループ始めにclearする方がいい
ループごとにvector出力しなきゃいけない場合も、moveしないでcopyした方がいい >>920
意見されたら喧嘩売りたくなる病気なの? mallocは使い方が余程ひどく無ければ、性能上問題になることはない
問題になっている場合もプロファイラでその部分だけ対策すればどうにでもなる
断片化やmalloc自体の管理領域容量が気になるほどの環境では使わない方がいいが >>927
リアルタイム系の仕事したことないならそう言う考え方でもいいと思うよ そもそもリアルタイム系の処理で、実処理部分でmallocするってのは普通しないよね
初期化時に必要なバッファはあらかじめ確保しておくものでしょ
そこはmallocだろうが静的確保だろうが変わらないし >>929はループの中で毎回malloc freeしてるからそりゃ性能が気になるよね >>925
std::vector<TYPE> は、リンクリストではなく、「可変長配列」なので、std::list<TYPE> に比べて、TYPE のコンストラクタがデコボコした頻度で
多めに呼び出されてしまう傾向がある。TYPEのコンストラクタの中で何かをnew していると、new が呼び出される回数をグラフにした場合、
デコボコになるため、速度的に滑らかさがなくなってしまう可能性が考えられる。
それは、newの速度がデコボコなのではなく、std::vector が持つ悪い性質の一つ。
速度的に「滑らか」にしたいならば、std::list の方が適している。
そもそも、C言語がポインタを用意したのは、リンクリストを使いたかったからで、Cはデータ集合用のデータ構造として動的リストではなくリンクリストを用いるのが伝統。
Cの高速性とはリンクリストによるものと言っても過言ではない。
newも、mallocもコンストラクタも、リンクリストと最も相性が良い傾向がある。
cppreferenceなどでも、std::vectorが出てくることが多いが、Cの新かを発揮するにはstd::listの方が良い。 >>932
誤:Cはデータ集合用のデータ構造として動的リストではなくリンクリストを用いるのが伝統。
正:Cはデータ集合用のデータ構造として動的配列ではなくリンクリストを用いるのが伝統。 いやいや、速度がシビアならreserveしとけと
cとの親和性考えなきゃdequeも良いが、cのAPI呼び出し考慮すると結局vectorをうまく使うのが一番良い >>929
std::vector<TYPE>を使っていて、TYPEのコンストラクタの中でnewするのはリアルタイム処理には向きません。
その場合、std::list<TYPE>に変えれば劇的に速度が安定するはずです。 >>934
CのAPI呼び出しで集合を渡す場合、通常、集合の要素はコンストラクタを持ちません。
その場合は、std::vectorは適すでしょう。
ところが、要素がコンストラクタを持つ場合は、std::listが適します。 vectorで再配置する際にmoveされない前提なのね >>936
補足すれば、APIは、リング0のシステムランドで実装されていることが多いため、
リンクリストの様な複雑な構造が用いられることが少ないのです。
しかし、それはAPIに限った話で、Cは誕生したときから、要素数が変化する
集合には、動的配列よりもリンクリストを用いるのが伝統でした。
伝統と言うよりも、リンクリストこそがCの核心・本質といっても過言では有りません。 >>937
C言語とはリンクリストのことです。
動的配列は、Cの文化ではありません。 アドレスで直にアクセスできる言語の強みはリンクリストで活きるからごもっとも >>930
そう言う事
平均的には間に合っても確保や解放にかかる時間が読めなくなる
100万回に1回でもダメならダメっていう世界だしね
>>931とかはそう言うことがわかってないので頓珍漢なレスになってるw >>934
reserveしただけだとOSによっては実メモリ確保しなさそう…
で初回アクセスでおもむろにページが用意されれる
ヨカン それだとmalloc使うこと自体不味いだろ
確率でmmapしちゃうのだから >>937
moveを使いたい場合、要素の TYPE クラスに move 用の記述が必要となるため、手間がかかります。 is_pod_vで事前条件を確認してるけど、PODはなくなるんだってね。 >>935
まあお前がそう思うならそうなんだろうな
お前ん中ではな… listで美味しいのはsplice使いたい時くらいだろ
multi threadのログ統合したい時とかに、lockに必要な時間を最小化出来る >>947
POD = trivialかつstandard_layout
だから後者を使うようにすればいい 子スレッドを休眠状態で作る方法ない?
起動直後にcondition_variable::waitとかじゃなく
初期状態として >>924
まあそりゃね
使えるようにしてもPCやスマホのように自由には使えないぞ
こまめに確保解放なんてことはしない
基本最初に確保して終わり
解放はしない
だから確保しか出来ないヒープも選べる >>927
それはPCやスマホなどリッチな環境の場合
>>931
一見軽そうで重い関数があったりするから
同じ人が同じ時に作ってたらそんな処理にはしないだろうけど 白物家電のマイコンやら、pfcのマイコンやらもやったが、そんなのはそもそもmalloc使うような環境じゃなかったしなぁ
RAMもkB単位で少ないし、自由に関数呼べるほどスタックも無いし
割り込み部分はアセンブリで書いてた 今は冷蔵庫や電子レンジもAI積んでネットワークに繋がるIoT時代だけど
それでも組み込みって未だにそんな感じなの? まあそれは特に東南アジア向けだったし
日本よりさらにチープだったのかも いまだにチープな8bit CPUもたくさん使われている cortex-m0とか載ってたらもう小躍りしちゃうくらいのリッチさだよね リッチなCPUを使うって事は
それだけ求められる事が大きいわけで でもCPU節約するために人件費かけて結局商品高いじゃん 趣味じゃないんだから
当然トータルで考えるよ
開発工数、単価、機能性能、信頼性、供給、大人の事情、... ゲーム業界の人だけど
new使っても問題ないってのはおれの常識とは異なる
まず問題が広すぎる
言いたいことはデフォルトのグローバルヒープを無邪気に使っていいか
ということだと仮定すると
AAAクラスでそんな杜撰なことしてるところはないと思う
組み込みもそうだがリアルタイム性が必要とされるところでは、メモリ予算というものがある
グラフィック、オーディオ、ネットワークなどのモジュールごとにメモリいくらと決められる
モジュールの責任者はその中でやりくりする
ここで大事なのはメモリの最大使用量を保証しなければならないってこと
必要ならローカルのヒープは作ったりするが、この時点で担当者が気ままにnewってのは認められない
基本的にすべてコントロールされる
現実的に最大量が正確に見積もれないものもあるがそれでも最大量は決める といってもグローバルヒープを使わないわけじゃない
オープンソースのもので無邪気にmallocするものは多数あるが、それほど荒ぶらなければそのまま使う
(リアルタイム性が不要なら仮想メモリに任せる)
あとmalloc遅くないという論調の人がいるけどそれはベストケースの話でしょう
ヒープメモリが不足したり一度に巨大なメモリを確保する場合はシステムコールになるからずっと遅くなる
ワーストが見積もれないものはリアルタイムで使いづらい
まぁ昨今は仮想マシン上で動くゲームが多数あるわけで気にしなくていいレベルという意見はある
ただesports系で一瞬カつくとか商品性に関わるわけで
また後から直すのも地獄なので
最初から計画的に作るべきだろう ここC++スレだよね、つかぬことだけど
記憶管理はいつでも如何様にもカスタマイズできるようにtypename Allocatorになってるわけじゃん
なんでいきなり組み込みには向かないとかキリッてんの? >>968
typename Allocatorとかすげぇ初心者っぽい
キリってるのはお前だ >>968
標準ライブラリでもallocatorが指定できないものもあるんだよ
もはや今のc++で標準ライブラリを全面的に使いつつ、ヒープを個別に差し替えるのはかなり非現実的だ
allocatorを差し替えられてもnewするタイミングや量はリバースエンジニアリングしないとわからない
それが問題になることもある てか、静的確保したメモリブロック使うアロケータ書いてそれで標準コンテナ使うのが基本じゃね
まあeastlでも良いが >>971
> 標準ライブラリでもallocatorが指定できないもの
例えば?
newだってoperator newですぐカスタマイズできるし
placementで環境依存の細かい設定もできる
ライブラリはISO/IEC14882に固執する必要はなく
サードパーティでも内製でもより都合のよいほうを使えばいい
というだけの話 カスタマイズの話なら真っ先にnewの話をすべきなんだが順番おかしくね?
ていうか今時はallocatorより先にpolymorphic resourceだと思うが
というかそもそもmallocの速度の話からであって、いきなりallocatorの話したり
C++全体を否定されたかのように過剰反応するとか・・ 仕様通りに書けばいい感じにうごいてくれて、責任は俺にはないとか
思い込んでんじゃってるキッズなんだろう。
デバッグするなんてことはもちろん頭にない。 >>890からの流れでは直後からnewが出てきてたろ
C++が組み込みに向かないという主張の
理由がmallocじゃおかしいだろ
それしか使えんわけでもなし >>968に突っ込むと>>890に同意したことになるのか >>973
> > 標準ライブラリでもallocatorが指定できないもの
> 例えば?
でしょ?
お前さんは人並み以上にc++知ってると思うけどこの事実知らない
どこで使われてるか知らなきゃ置き換えができないよね
答えはあえて教えない
標準ライブラリのヘッダーをnewでgrepすればallocatorを通さないものが見つかるさ
自分で確認してこりゃ置き換え無理だわと悟って欲しいw
もし見つからないなら後で書くよ
ちなみにグローバルにnewを置き換えるぐらいならmallocのバイナリを差し替えた方が早いし確実 >>979
横からだが、具体的に誰のどこを指してそう思ったのかよろしく >>966
もちろん、むやみやたらと使って全く問題ないわけではない。
が、本当に必要な箇所で使う程度なら(多くの場合)余り問題ないという程度。
大体ゲームの場合のnewやmallocは、敵や弾やイフェクト、3Dオブジェクトなど
を1つずつ収めるために使うことが多いが、ゲームの1シーン内に登場する個数が
newやmallocが問題ない程度に元々なっている事がわりと多いと言うだけ。
3Dの雑草の葉っぱ一枚単位で new したりすると問題になってくるかもしれない。 >>981
なんとも感覚的な話だね
だいたい動けばOK!って感じ?
おれは仕事でそういうもの作りはしない コンシューマかPCかでも違うだろうし
(自分はさほど詳しくないが、基本コンシューマは標準ヒープ使わないはず)
ジャンルによっても違うんじゃね
PCのMMORPGなんかだとシーン中のメモリ確保は必須だろうし
あと草は普通同じメッシュやテクスチャ使うだろうし、揺れを入れるにしても一つ一つにデータ持たせるなんてアホなことしないだろ >>978
「後で」かw
もう1000間近だし期限切らないでおけば時効だろってか? >>985
sgjaAMaLが、自分の話に傾聴してきた人の質問に答えなかった
つまり自分の考えを伝える努力を中止したということでしかない
何人も自らの意見を他人に伝えるには
その意見を説明するしかなく
説明をやめることは沈黙に等しい 黙って調べてくれば?
調べて無いと結論づけられればまた偉そうに出来るだろw ちゃうねん。
僕が組み込みいうたのはArduinoのことな。
RAM2KBやし。 >>984
条件は明示してるんだからおれが書くかはお前に委ねられている
1000が迫っているぞw この手の人最後まで答えないか
答えても的外れなのしか見たことないわ arrayのどこに動的メモリ確保が出てくるんだよ
アホか 漏れはnewのときたまの遅さの可能性に警鐘を鳴らしたからセフセフ、 やっぱnew/deleteのレイテンシーを設計に乗せるには非ページプールメモリにアロケートするべきですよねー なんかスレ止めてたら悪いから書いておくよ
ひとつは17からallocatorがdeprecatedになったstd::functionね
これは結構知られてるばずだ
定期的にこれ濫用する人が現れるんだけど中身理解してから使うか判断しろと職場では言っている代物
もうひとつあげるなら、
処理系によってかなり違うかもだけどstd::threadも中でこっそり内部クラスをnewしてるはず
ただスレッド間で引数を引き渡すためのものでサイズは小さいしスレッド作るコストの方が遥かにでかいから問題にはなりにくい
他にもあるけどとりあえずこんなもんで std::functionを使わないと1 bitもプログラムが書けなくなった漏れガイル、
クロージャをいちいちクラス定義から手で書く日々に戻るのはいやじゃー このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 17日 3時間 0分 7秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。