C++相談室 part136
レス数が1000を超えています。これ以上書き込みはできません。
質問です、下記はソースの1部分なんですが、あるプロセスのメモリを検索しています。00000000〜7FFFFFFFまでを検索しているのですが7FFFFFFFを9FFFFFFFまでに増やしたいです、単純に終了アドレスを9FFFFFFFにしても検索してくれないですが何故でしょうか?
http://codepad.org/cdLpKbdw >>211
他に方法がないが、いちいち mark and sweep するなんて考えられない >>213
>循環に限らず単純な共有でもこうなるので
到達済みフラグをセットするのは開放時なので
ならない
>ドーナツ型の図形を塗りつぶすのと同じやり方(>>213)
と書いただけでは通じなかったですかそうですか、 ごめwwwwww
×:到達済みフラグをセットするのは開放時なので
○:到達済みフラグをセットするのは参照カウントを減らすときなで と思って今作ったがあんま使い勝手の良いものにはならんかったorz
使い方としては
class Foo {
sumapo<Foo> m_pCar;
sumapo<Foo> m_pCdr;
/*...*/
};
sumapo<Foo> ptr(new Foo());
と書いた後、ptrが開放されたとき、ptrが指すFooが握っているsumapoが残らず(循環があろうとなかろうと)参照カウントを減じて欲しいわけだが
これにはptrが握っているFooを開放する前に、ptrがFoo::m_pCdrやFoo::m_pCarを辿れる必要があるので
m_pCarやm_pCdrとptrが裏で手を握る必要がある ごめwwwwwwwまた言い方をちょっとまつがえたorz
誤: Fooが握っているsumapoが残らず(循環があろうとなかろうと)参照カウントを減じて欲しい
正: Fooが握っているsumapoが(循環があろうとなかろうと二重破棄を招かない形で)参照カウントを減じて欲しい
リフレクションがあればsumapoからFoo(やBar)のメンバが丸見えなのでsumapoのリンクを辿って破棄予定オブジェクトを事前にマークすることで2重破棄の防止を自然に実現できる
リフレクションが無い現行のC++なら、sumapoのデストラクタで破棄される予定なFoo(やBar)をマークだけして破棄を遅延する、みたいな細工をするしかないが
デストラクタの中から全てのFoo(やBar)のマークが完了したか知る術が無いから、sweepする呼び出しが別途要る、、
やっぱC++にもリフレクション欲しい… >>224
JavaScripterマジで死ねよ
JavaScriptのコミュニティが腐っているのは、
馬鹿であることを自覚出来ないお前みたいな大馬鹿が、嘘を平気で垂れ流しているからだよ。
そして初心者はそれを見抜けず、騙されて馬鹿が再生産されてる。
お前らがC++のコミュニティを破壊する権利はない。JavaScriptのゴミ貯めに戻れ。
お前らはプログラマ全体からするとゴミ以下のクズなんだよ。それを自覚しろ。
C++初心者の為に、俺がお前の嘘を暴いておいてやる。
> リフレクションがあれば
お前のリフレクションの使い方は、メンバの中身を参照したいだけのようだ。
ならば、全てのメンバがpublicだったらいいはずだ。
このケースで、どうやって実現出来るのか説明してみろ。
お前は本当に何も分かってない。最初から躓くと思うぜ。
オブジェクトAのメンバはすべてpublicである。
オブジェクトAのインスタンスa,b,c,dは
・aはbを参照している
・bはaを参照している(a-b間で循環参照)
・cはbを参照している
・dはcを参照している
の状態で、a-b間で循環参照があり、参照はd -> c -> b <-> aとなっている。
これらへの参照は他にはない。
今、dへの参照がなくなり、dのデストラクタが起動された。
この状態で、どのように回収されるのか、説明してみろ。
お前みたいな馬鹿には出来ないと思うぜ。
さっさとJavaScripterの巣に帰れ。邪魔でしかないから。 >>220
単純な共有と循環を区別できるコードを書いてみてごらんよ。
あなたが考えているような簡単なものにはならない。
恐らくはあなたには書けないから。
コード書かずに妄想してるから間違えるんだよ いや違うか。
普通はコード書かずともちょっと考えればそんな間違いしない。
考えずに書くから間違いばかりする。 有向グラフでマークしてトラバースすれば循環がわかるのは単方向リストくらいなものだろ
ドーナツがどうとか言ってるのは無向グラフと混同している JavascriptとC++では要求されるレイヤーが違うので、比較するのは無理だと思う。 複雑な参照を持つシステムってまぁほとんどシミュレーション系で速度も要件に入ってくるんですよ。
糞遅いJavascriptやpythonなんて普通に使いものにならずC++の独擅場なわけですよ。
pythonでAIとか笑っちゃいますね。 >>233
この場合の Python はいわゆるグルー言語でしょ。
高速なコンポーネントのパラメータを指定して組み合わせるだけみたいな使い方なんじゃないの。
高速な計算が出来るコンポーネントは C++ が主流であったとしても、
それをビジネスロジックにさっと適用するという意味での「Python で AI」は現実的だし、
実際よくあることだと思う。 高額なPython屋募集のAI案件は、99%非現実的。
AIを何も分かってな奴が企画したプロジェクト。散々利用されてきた統計学以上の成果など出やしない。
昨今のAIブームは過去のAIブームと同じく破綻プロジェクトばかりなのは言わずもがな。
なぜPythonか。失敗したときにPythonだからと言い訳するため。
そもそも簡単な言語なのに高額で募集する時点で辻褄が合わない。
嘘ついて投資募ってるのは明らか。読売新聞のAI記事読んでると騙す気満々だと分かる。
openCVスレでもpythonから入る奴は何もできやしない。最初から分かりきったこと。フフフ、笑えますね。 結局はコンポーネント間の通信回数を減らすことが肝。しっかりと設計を吟味すれば従来通りのIPCで十分だったりする。 >>235
でもAIってモジュール部分は超簡単なんじゃない? それにそんなもの「作る」って
レベルじゃないから、出来の悪い奴でもいいから一人がC++でモジュール書いていば
OKでやっぱPythonレベルの方が重要なのではないか? そのあたりはpythonのソースコードを見ると分かる
ttps://github.com/python/cpython/blob/master/Objects/weakrefobject.c C++の公式スクリプト言語はPythonだから慣れるしかない。 AIで一番大変なのはデータを食わせることだよな。パイトンでもC++でもなくて
一番重要なのはエサやりして大切に飼いならす人だよ。だから愛がないとできない。
お前等には無理だな。三日やったら課長の机に糞してとんづら。 その学習させた膨大なデータが高額で取引される時代が来るのかね OCamlがあるのだからオッパイソンがあってもいいはずだが。 >>235
ほとんどのAI案件がやばいってのは同意だが
pythonなら言い訳できるってのはねーわw
そもそもAI案件の難しさはプログラム言語がどうのとかそういう問題じゃない。 >>230-231
仮にそれでもJavaScripterよりマシだ。
お前も含めて、JavaScripterには、馬鹿かつキチガイしか居ない。
例>>220,224: 反論することも出来ず、間違いを認めることもなく、ただ逃亡
これをやるからJavaScriptのWebリソースは大半が腐ってる。
俺は知らんがC/C++はWeb上の間違いに異常に厳しかった時代があったと聞く。
それが今も引き続いていて、Web上の正確性を担保してくれているのなら、有り難い話だよ。
ゆとりには「ぼくがおこられなければいい」という幼稚園児並みの知能しかないから、
JavaScriptコミュニティみたいなことが発生する。
あれは最早完全に手遅れで、その状態のゆとりが教える側に回っていることが最悪。
連中は平気で嘘をつく韓国人レベルのモラルしか持ってないし。
結果的に間違いであったにせよ、修正しておかないと、後で読む人の為にならないだろ。
「嘘だと認めなければ嘘ではない」という、韓国人みたいな奴は、キッチリ殺すべき。
間違ったことを書いたら叩かれるのは、長期的に見ればいいことだ。
それがゆとりには分からないだけでね。
あと、わざわざID消して自演しているゴミ、それは余計に目立つぞ。
他の誰もそんなことをしてないから、逆にコテトリになってる。
お前は他でも荒らしまくってるよな。 >>227
一番足りないのは謙虚さなんだけどな。
JavaScripterは本当に馬鹿しかいないから、コードがマジでゴミしかない。
だから糞コードしか書けない馬鹿がつけあがる。
そしてそれを諫める年長者もいない。幼稚園で先生がいない状態だ。
C++は30年の歴史があって、仕様も改訂し続けているのだから、
今の仕様はその中で今一番マシな方法ということになっている。
JavaScripterみたいなぽっと出のゴミがぱっと考えて思いつくような手法を、
今まで30年間誰も思いつかなかったと思うこと自体がキチガイでしかない。 というわけで先に進める。
沸きまくっている馬鹿を振り落とす為に速度を上げるからよろしく。
>>213
> そもそも再帰的なデータ構造じゃないものなら
> 循環参照のしようがないので普通に shared_ptr で良いし
> そういう処理もごく普通によくある
「再帰的なデータ構造ではないとき、循環参照は発生しない」については同意だが、
「循環参照がない場合は、shared_ptrでいい」には反対だ。
これだとC++の速度優位性が無くなるので、俺ならGC言語を検討する。
ただしこれは宗教だからもういい。
本題は、
・shared_ptr(静的共有)必須な構造が、果たしてあるか
だ。木構造で一番身近なファイルシステムを例に取ると、
静的共有(ハードリンク/shared_ptr)と動的共有(シンボリックリンク/getter)のうち、
前者はほぼ使われてないだろ。
これは、ユーザーによる手動管理の場合、シンボリックリンクの方が明示的で使いやすいからだ。
シンボリックリンクは常に最新版を、ハードリンクは常に生成時の対象を参照するところが異なる。
速度的には静的共有の方が優位だとして、動的共有では無理な事例ってあるか?
俺が知っているハードリンクの活用事例は、WindowsUpdateくらいだ。
「動けばいい」なら動的共有の方が適切に思える。
(C++で動的共有はなかなかにきついが、動的言語なら自然に実現出来る) >>245
何故に自分のことと思ったのか知らんけど、自覚が無いよりはあったほうがいいと思うよ。
別スレでID無しにイジメられたんか? >>248
俺から見ればお前がキチガイだし、
ここがお前にとって合わないと思うのなら、お前がここに来るのが間違ってる。
ゆとりはゆとりだけでスレ作れよ。
それがお互い一番幸せな解決だ。
俺には韓国人とゆとりは殺すしかないという結論が出てる。
お前らは邪魔しかしないから。今もそうだろ。 初心者で的はずれな質問かもしれませんがお願いします。
1行に約4000文字,区切りで書かれたファイルがあり、これが1000行あります。
このファイルを1行ごとに別の配列に格納したいのですがfgetsだとchar型になりcharは256文字しか入らないようです…
どうしたら読み込みできるのでしょうか >>250
> fgetsだとchar型になりcharは256文字しか入らないようです
単に間違えたプログラムを書いている。
そのプログラムを提示してみて。 C言語を通らずにいきなりC++を使う初学者は
fgetsやcharに触れるべからず
必ずラッパーライブラリを使うべし >>250
getcを使ってmyfgetsを新たに作る
改行を調べるだけなのでそんなに苦ではない >>247
C++風に考えるとstd::shared_ptrは必要なくなってくるけど、他の言語の真似をしようとすると、必要になるんだよな。
そしてC++は他の言語から呼び出されるから。
そういう部分で必要があるのかも。 スレッド使う場合は、コピーのほうが速くないかよく考えた方が良い。
意外とコピーのほうが速い。 >>253
宗教じみたことは言わないほうがいい。
C++の入出力クラスiostream系の標準機能は失敗した代物との結論が出ている。
C++学習者は FILE* 系の標準機能を優先して使うのが正道。 >>257
iostream 系のどんなところが失敗しているのですか? >>257
あり得ない
ポインタも分からん奴に生char使われてたまるか
fgets使いたいならC言語で基礎を身に付けてから出直して来いや たしかにiostreamはデストラクタで自動的にクローズしてくれるくらいしか
メリットが感じられないから、自分でファイル入出力クラス作ってるわ iostreamはC++のテンプレートクラスが未発達だったころの遺物だよ。STLに含まれない時点でお察しではあるが。
iostreamを使うよりもshared_ptrなどのスマートポインタでFILE*をラップしたテンプレートクラスを使うほうが現代的。
shared_ptr::shared_ptr<FILE>のコンストラクタで第二引数にfclose()を呼び出すdeleterオブジェクトを渡すだけで事足りる。
shared_ptr::shared_ptr<FILE>直使いもいいが、その派生クラスを使って暗黙のFILE*型キャスト演算子を実装すれば、Cコードとの移植性がさらに高まる。
あと、iostreamはios系の様々なフラグがあるが、煩雑で使い勝手が悪い。覚える価値ゼロ。 >>258
速度じゃないか?
使いもしないオペレータのために余計な処理挟むから。
VCについてくるディンカムウェアなんか一バイトごとに仮想関数呼び出してるぞ。 訂正。
shared_ptr::shared_ptr<FILE> じゃなくて、shared_ptr<FILE>でした。
deleterサンプルは以下の通り
struct file_deleter { void operator() (FILE* fp) const {if (fp != NULL) { fclose(fp); } }};
shared_ptr<FILE> fp(fopen(filename, "r"), file_deleter());
// 以下、fp.get() でFILE*にアクセス。 まあでも、明らかな失敗だったら auto_ptr や wstring_convert みたいにとっくに deprecated にされてるよね。 class FILE_Ptr : public ns_shared_ptr::shared_ptr<FILE> {
struct FILEDeleter {
void operator() (FILE* fp) const {
if (fp != NULL) {
fclose(fp);
}
}
};
public:
FILE_Ptr(FILE* fp = NULL) : ns_shared_ptr::shared_ptr<FILE>(fp, FILEDeleter()) {}
operator FILE* () { return get(); }
template<typename T> bool operator == (const T& obj) const { return get() == reinterpret_cast<FILE*>((void*)((intptr_t)obj)); }
template<typename T> bool operator != (const T& obj) const { return get() != reinterpret_cast<FILE*>((void*)((intptr_t)obj)); }
};
void fclose(ns_shared_ptr::shared_ptr<FILE>)
{ >>266を途中で送信してしまった。
ns_shared_ptrは、boostなりstdなりstd::tr1なり自分の好きな名前空間に置き換えを。以下のように。
namespace ns_shared_ptr = boost;
グローバル関数fclose(ns_shared_ptr::shared_ptr<FILE>& fp)を別途作れば、
Cのコードをコピペ利用した時のfclose(fp)多重呼び出しを防止できる。 >>207,208
>>255,256
DOMの話か?500MBは言い過ぎだからとりあえず放置したが、
GC言語は基本的にshared_ptrの仕様だから、その実行エンジンの実装に使われるのは妥当だ。
これをサポートする為、shared_ptrは仕様上は必要だ、というのも同意する。
問題はそれがデータ構造として必要か、という点で、
DOMの場合、HTMLは共有無し/循環参照無しの単純な木だからunique_ptrだけで問題なく構成出来る。
ただしJavaScript側に捕まれている場合、ノードが木から取り除かれた場合にも保持し続けねばならず、
この実装にはshared_ptrを使わないと厳しいだろう。
しかしこれはデータ構造ではなく、JavaScriptの仕様が原因だ。
マルチスレッドのキャッシュについては、これは現時点でのハードウェアの問題で、
単純に言えば共有RAMに対して書き込みをすれば著しく遅くなるだけだ。
これはデータ構造の問題ではないので別に取り扱う必要がある。
(速度低下はshared_ptrの問題ではなく、キャッシュ構造起因)
データ構造について言うなら、shared_ptrの使いどころは、
1. 共有ノードがある
2. 循環参照はない
3. 動的に生成/消滅を頻繁に繰り返す
だと思うんだが、2の為にメッシュ構造とかは基本的にアウトで、
3も基本的にないだろ。
実はあんまり使いどころなくね?って話。 weak_ptr の使いどころを見極めるのが難しい。 >>261
>iostreamはios系の様々なフラグがある
そうそう、今いち、よく定義がわからないんだよね
それに、手元の実装がこのフラグについてまともじゃないかもしれない iostreamを今、作り直すとしたらfilesystemやstring_viewも視野に入れなきゃね C++でよく使われる各オブジェクトのスタックサイズは以下の通り。
stringstreamとfstreamのサイズは無視できない大きさであることがわかるだろう。
・GCC - ubuntu Linux x64
(sizeof(std::stringstream), sizeof(std::fstream), sizeof(std::ostream), sizeof(std::string), sizeof(std::vector<std::string>), sizeof(FILE))=(392, 528, 272, 32, 24, 216)
・Visual Studio 2017 - Windows10 x64
(sizeof(std::stringstream), sizeof(std::fstream), sizeof(std::ostream), sizeof(std::string), sizeof(std::vector<std::string>), sizeof(FILE))=(248, 280, 112, 32, 24, 8) >>273
数百バイト程度は許容できるんじゃないの。
コンテナに入れるわけでもないし。 直近のスレを見れば分かるとおり、C++は複雑怪奇魑魅魍魎だから
プログラミング初学者が手を出したらヤケドしかしない 勉強でヤケドする分には問題ないし、
むしろ沢山ヤケドして危険を避ける能力を身に着けるしかない。
実務でやったらアウトだが。 iostream 文句言われてるけど、atomic に動作するところは thread 並列環境では
そこそこ良いのでは?もちろんその分遅さが気になる場面もあるけど。 iostreamは速度を全く期待せずに使うという
C++らしからぬ面を持ったものだ
sync_with_stdio? はははは 国際化に向かないのが致命的。
これだけで捨てる理由としては十分と思う。 MSVCのstd::arrayがC++11に準拠してくれればいいのに。使えねー。
言語レベルで区間チェックしてくれたら、データ破壊の場所がすぐにわかるのに。 スタティックライブラリAが別のスタティックライブラリBのAPIを使っている場合、ライブラリAにライブラリBをリンク、ビルドして、結果できたライブラリAだけをリンクして、実行ファイルを作る形式が良いでしょうか。
それともラリブラリA、ライブラリBを別々にリンク、ビルドして実行ファイルを作る形式が良いでしょうか。 >>282
>ライブラリAにライブラリBをリンク、ビルドして、結果できたライブラリ
そんなことができるのでしょうか? >>281
msvcのat()関数は範囲チェックしないの? iostream の替わりになるようなデファクトスタンダードが登場していない以上、
ほどほどに付き合っていくしか仕方がないよ。
C スタイルは普段から使うには抽象度が低くて面倒くさい。
printf は std::string を表示するのにさえいちいち c_str を通さなきゃならんのだからな。
書式指定との整合が型システムで保証されないのも古い設計だし。
処理系の方である程度は特別扱いすることで折り合いがついてるけど、
あらためて考えるとだいぶん不格好だと思う。
コンセプトやら何やらが導入されたらもうちょっとマシな入出力ライブラリが出来たりしないもんかね?
提案くらいは出てたりしない? って思ったけど、こないだ江添っちがTwitterで「無い」って言ってた気がする。 現実的にはxmlなど標準的な形式のファイルを扱うライブラリを使うんで本当に低レベルなIOはどっちでもいい >>274
iostreamは肝心な時に使えない橙武者です。
ログ出力するクラスは歌舞伎の黒衣のような慎ましい存在でなければならないのですが、
iostreamはあたかも歌舞伎の花形役者のようなオレ様的存在感を出すので好ましくありません。
実例をあげるならば障害発生した時に、ログ用途でiostream系を使うことがあり得えます。
cout やその他インスタンスが生成されてスタックを多く使うことになります。
つまり、実運用環境とログ埋込環境でメモリ構成が大きく異なる環境になってしまうことが避けられません。
iostreamはマルチスレッド環境など対話デバッグでは追跡しにくい現象をログ出力するのに適さない、と断言できます。
橙武者、黒衣など語の意味が分からない方は、ご自身でおググり下さい。 coutってアクセスするたびに生成するわけじゃないよね? ツリートラバースするのに、再帰使うよりstd::deque使ったスタックのほうが速いな。 >>291
グローバルオブジェクトとしてずっと存在してる 内緒ですけどね。書式設定はprintfのほうがソースが見やすいですよ。 「標準出力への書き込みは遅いから」との理由で、メモリ上にログをため込むことは多いかと思います。
iostream系だと stringstreamを使うことになりますがスタックサイズが割と大きくインスタンス生成のたびに時間もかかります。
さらにいえば、MSVCの場合、snprintf()に比べてstringstreamは書き込みに3倍弱時間がかかります。
本来ならば << 演算子はコンパイル時に型が決まるので書き込みが高速なはずなのですが、
MSVCだとstringstreamがsnprintf()に負ける有様ということです。
なお、Linux GCCの場合、snprintf()とstringstreamは書き込み速度の差は少ないようです。 CとC++で演算子の優先順位が異なる所があります
どこてしょう
もちろん両方に存在するものです >>298 の問題は面白いし俺も答えに興味あるけど >>297 への挑戦とすれば
「C++は完全に理解したけどCの方は知らないよ」で逃げられるかと。 C++の規格はCの規格を参照してるし、Cとの差異も規格の一部になってるので
C++の完全な理解の中に当然含まれる アホなので優先順位の違いはわからないけど、
if ((v=f()) == 0) を if ((v=f()) = 0) とタイポしたとき
c++ だとエラーにならず v が 0 になるのは嫌な感じ if ( 0.equals(v=f()) )
こう書ければいい Cでは代入式はその結果値が左辺値にはならないから v = 1 = 2 みたいな表現は通らない
C++では左辺値になるので通る 昔定数を先に書くことで防げるって聞いたことがあるが
0=(v=f()) 昔からこういう==での判定は
if (S_OK == (result = someApi()) {...}
と定数左で書けという作法もあるけど、
流行らないのは見た目が実行順と逆みたいで妙だからかねえ 〇〇=0 はあるけど 0=〇〇 は違和感しかないからなぁ
バッドノウハウの筆頭だと思う 数学でも 0 = x^2 + 3x - 2 とかあまり書かないな まあそんなクソな書き方するくらいならテストコード書けやって話にはなるわな。 >>304-305
それいつの話だ馬鹿野郎
俺が新兵の頃には、そんなコード書いたら教官からブン殴られてたぞ!! バッドノウハウ……かなぁ…?
定数を左に書く利点は テストより手軽にコンパイルエラーで止められる事だから
個人的には採用してるんだけど
int i = 0;
/* 想定した挙動 */
if ((i = 0) == 0) { printf("%i\n", i); } /* 定数 右: 出力 "0" */
if (0 == (i = 0)) { printf("%i\n", i); } /* 定数 左: 出力 "0" */
/* typo! == -> = */
if ((i = 0) = 0) { printf("%i\n", i); } /* !!! printfが実行されない! (Cでは通らない) */
if (0 = (i = 0)) { printf("%i\n", i); } /* コンパイルが通ら*ない* 助かった! */
/* () 忘れ */
if ( i = 0 == 0) { printf("%i\n", i); } /* !!! 出力 "1" (== (0 == 0) == true) 想定外! */
if (0 == i = 0 ) { printf("%i\n", i); } /* コンパイルが通ら*ない* 助かった! */
そもそも1文字の打ち間違いなんて テストコードの記述そのものでもやりかねないし
(「絶対に間違えない!」なんていう人がいたらコードどころか作文も書いたことない奴ですぜ)
まあ使用が推奨/禁止されてるかはチームに従うとして
ぱっと見で意図が解るようにはしておくとよいかと >>310
そういうのはもはや統合開発環境の仕事なのだよ。
ていうか if の中で代入を書くとか真正のキチガイ。
有 り 得 な い すまんかった >>303 は "v = 1 = 2 みたいな" ではなくて "(v = 1) = 2 みたいな"
括弧忘れたら結合順が変わってしまう 訂正 EmacsのせいでUNIXはDOSに負けたんだっけ。 単体テスト書くと処理時間出るから、何に時間かかってるのかわかっていいよね。 やはり一番時間がかかるのはIOだから、IO少なくするのが一番よさそう。
std::vectorなんか全体コピーしても余裕の速さだから気にする必要なかったんや。 世の中いろんなコーディングルールがある
ifの中は副作用のあるコード禁止とか
goto禁止とか
3項演算子禁止とか
1個の関数は○○行以内とか
変数名は○○文字以内とか
実際に業務で書かない人が決めたりするからたちが悪い if の条件式の中で代入することは勧められない書き方だと思うけど、
「言語仕様に照らして完全に正しいけど間違いやすい書き方」にいちいち警告を出されるとうんざりする。
オプションで強めのチェックにしたときならともかく、デフォルトでだぞ。
かといって個別に警告の有効・無効のオプションを書くのも面倒くさいしなぁ。 俺も定数との比較なら
if ( 0 == buf )
って定数を左に書くようにしてる
理由は>>310と同じ意図しない代入防止 自動的に静的チェックツールかけとけば教えてくれるよ 関数の戻り値を保存した一時変数を使わなかっただけで警告出されるのは地味につらい。かといって警告を抑止するのも悩ましい。
以下のような感じ。
void test()
{
int foo = bar();
return;
} じゃなくて・・・、BARのreturnにブレークポイントだ。
VSのばあいだけど。
そんな出口の多い構造で大丈夫か。 よくわからんのだが使わんものをなんで残しとくのん? >>326
戻り値ありということは普通は副作用なく作るだろ
その戻り値を無視したら計算資源だけ使って何もしないってことだよ
なんのためのコードなのそれ? 副作用ありの関数で成功失敗その他を戻り値で返すのはごく普通にあることでは。 このスレは、「風邪をひいたんだがどうしたらいい?」との相談に「風邪をひくな」と真顔で回答する良スレですね。 相談する時は、「なんでそんなところ行ったんだ」などと“そもそも論”を始めて責任所在の確定に情熱を傾ける後ろ向きで生産性ゼロの人に相談することは避けなければならない。
これが私の設問の真意。以下が回答。
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\ItemTemplates\VC\Windows Store\1041\BasicPage\BasicPage.xaml.cpp:97
(void) sender; // 未使用のパラメーター Visual Studioなら不要な警告を非表示に出来るだろ >>324
if (buf = 0) {
}
を検出するためのテストってどんなものですか? 補足すると、マクロ定義によって戻り値が使われなくなることがある場合の警告を想定。
>>336 であげた BasicPage.xaml.cppの事例は厳密には関数の仮引数を使わない場合の警告なので若干違うが、対処法は同じ。
#define OUTPUT(x)
void test()
{
int foo = bar();
OUTPUT(foo);
(void)foo;
return;
} >>339
そのコードにエフェクトがあるならテストできるのではないでしょうか。 >>339
そういうのはコンパイル時にWarning出るから本線にマージする前には見つかるでしょ 変数で戻り値を受けとって使わないって言うのは確かに変だが
戻り値がある関数の戻り値を受けとらないって言うのは問題無いのか? >>342
>>339 に対する具体的なテストの方法を示してください >>345
それ単体テストやればカバレージ100%にならないから容易に検出できるだろ >>340
最初に書いとけよタコが
お前の想定など知るか >>339
if (buf = 0) { A }
・buf がゼロの時 A が実行されないと実行結果(出力など)が正しい結果にならない場合
・bufが非ゼロでここでゼロにされると以下同文
この2つの場合は結果がおかしいからテストで見つかる。
結果は正しいが見つけにくいリークが発生するとか
ここ間違えても結果は(常にではないが)多くの場合正しい
とかだと静的/動的カバレッジで見るしかないね。 俺の中のうざい警告
使わない引数、変数、関数の警告
セキュリティ関連
演算にカッコを付けろという警告 非適合コード: a = a + b + c;
適合コード: a = ( a + b ) + c; >>349
>演算にカッコを付けろという警告
メンテしてるアプリのソース内のMD5だか sha だかのコード(問題なく動作中)で
「&とシフトの優先順位わかってんのか?括弧つけたら?」の警告が出るが、
&とシフトの優先順位など知る気もないし書き換えるとバグる気しかしないので放置している。 質問です
std::unique_ptrはデストラクタで保持するリソースの解放処理を行うので、自明なデストラクタを持つことが出来ず、リテラル型になることが出来ないと思うのですが
デフォルトコンストラクタとnullptrを受けるコンストラクタはconstexpr指定されています、このconstexprにはどういう意味があるのでしょうか? >>353
https://stackoverflow.com/questions/30766103/why-declare-constrexpr-constructors-for-classes-with-non-trivial-destructors-e/30766445#30766445
によれば
constexpr でないコンストラクタよりも先に(恐らくはコンパイル時に静的に)初期化されるので、
例えばグローバル変数
foo apple;
unique_prt<T> orange;
とあるとき
初期化順を気にせず apple のコンストラクターの中で orange を使用することが出来る。 >>354
リテラル型とまではいかないにしてもコンパイル時に初期化してくれるんですか、なるほど
ありがとうございます Scopeのついた#defineのような書き方ってないのでしょうか?
たとえば Uart0.baud 115200を変数としてしてじゃなくてDefineで保持しておきたい
場合にScopeを整理しておきたい。 template<int baud> class Uart0 { >>356
C++では#defineではなくconstを使うと習いました 先生!プリプロセッサで完結する処理もconstを使うのですか? Constはラムに配置されますからダメですよ。
それからTemplateは型を変数にしたい場合につかえるだけです。Scopeのついた
定数がないとすると、、、、、なんか使いにくいですね。 名前空間 にconst定数を閉じ込めて、スコープ内で using namespace xxx; を宣言して名前空間を明示せずに定数にアクセス。 defineをconstに書き換えるぐらいなら別の言語使いますよね。 クビにできる立場の人がソースコードチェックしてる会社なんですね。労組がないとかただの派遣屋ですね^^ 整数に関しては遥か昔から enum がスコープ付き定数として使われてただろ >>360
組み込み向けとかでROM実行になっていなければ、どちらもRAMに配置されると思うよ。
もしもコンパイル時解決するかどうかということであれば、constでもちゃんとコンパイル時解決されるし、式(含関数)の場合はconstexprキーワードを使えばコンパイル時解決(可能なら)される。
あと、templateは型だけでなく定数も置けるよ。 考えるべきなのは2つ
コードの即値として使われるのか
値がある番地にマッピングされるのか
その都度関数コールで解決するのか
と
マッピングされる場合、どのセクションにマッピングされるのか const定数は ヘッダーファイルで宣言するだけではダメでソースファイルでconst定数の実体を初期化しなければならないので、defineより使い勝手が悪い面もある。
最新のC/C++だとその辺どうなってんの? >>369
メンバ変数でも数値ならソース側に定義要らないから
struct SimpleMath {
const static int pi = 3;
};
でいい
実体がたくさんできるのを苦にしなければ
namespace n {
const static int pi=3;
};
でもいいし >>369
関連してついでに言うとよほど古いコンパイラじゃなければ
struct T {
int k=0;
};
というメンバ変数の初期化の書き方もできて
複数のコンストラクタがあるときとか楽できるよ 実体が沢山出来るとか馬鹿かテメーは
それが事実ならリンク時にエラー大量発生しとるわ >>376
人をバカにしたい意識が強すぎるから static 変数は
外部リンケージを持たないなんて基本も忘れるんだよ。 ほら試してやったぞ
アドレスが違うから2個あるのがわかるだろ?
MacBook-Pro:tmp$ cat a.h
namespace a {
static const int b = 8;
};
MacBook-Pro:tmp$ cat a0.cpp
#include <cstdio>
#include "a.h"
extern void foo();
int main() {
foo();
printf("main %lx\n", (long) &a::b);
}
MacBook-Pro:tmp$ cat a1.cpp
#include <cstdio>
#include "a.h"
void foo() {
printf("foo %lx\n", (long) &a::b);
}
MacBook-Pro:tmp$ c++ a0.cpp a1.cpp
MacBook-Pro:tmp$ ./a.out
foo 10925bfb0
main 10925bfac ソース中で(アドレスは使われず)値しか用いられなければ実体が全く作られない可能性もあるが
オブジェクトファイル見なきゃ確認できなくて面倒だからそれは略 クラステンプレートにしておけば (そして型引数が同じであれば) リンクのときにインスタンスが統合されるので、それを利用できるかもね。 >>381
クラス使うなら普通に>>371の上の方で良いかと思う >>377
だからよう、なんでstatic付ける必要あるんだよ
付けなければ実体一つで済むだろ馬鹿かテメーは >>383
付けなかったらリンクエラー出るだろ
こういうとお前はバカだからヘッダーでは extern しておいて
どっかのソースに1つ実体を書けとか言い出すんだろうけど、
もともと>>371は>>369の「ヘッダーだけで済ませたい」への返事だからな。
まだ他に言いたいことがあるなら日記に書け >>384
出ねぇよ馬鹿かテメーは変数と扱い違ぇんだよ #defineが一番確実
最適化も一番期待できるしCとの互換性も保てる
ってことでいまだに#defineは使う
スコープ問題は昔ながらのプレフィックスで解決
小さな組み込みマイコンだと
C++でもこんな感じ と、クソ雑魚老害がさえずってます
せめてenumにしろよ雑魚 フリースタンディング環境の話をこっそり忍ばせてくる技の名前なんだったっけ。 逆に値を変えても1バイトしか変わって欲しくないときや
1バイトを無理やり変えると動作が正しく変わってほしいとき
は番地に割り当てられるようにする
PCプログラムしか書いたことがない人は気にしたことも無いだろうけど #defineアレルギー
gotoアレルギー
printfアレルギー
この板には多い mainと言う文字列見ると、猛烈に指先がかゆくなる もはやドライバ書くときしかC++使わないし、最近のC++機能は全部いらね
老害とか言ってる奴の用途なんて元々、JavaやC#で十分だろ 内容あまり理解してないがconstexprは論外なのか 定数意外の計算(変数なんかが含まれる)とコンパイルエラーになる。 constexprは関数が返す内容が定数であることを保証する
コンパイル時はインラインでその関数を走らせて順次定数に置き換えてコンパイルが行われるということだ constexprは変数も定義可能だから今回の内容なら名前空間にconstexpr変数を定義すればokかなと思ってたり... まあそういうこったな
どんだけ糞長い関数書こうとその関数を呼び出した時点で定数に置換されてコンパイルされる constexprだけど計算にとても時間がかかる場合はどうなるんだろう
延々とコンパイルが終わらないとかエラーになるとか勝手に実行時解決になるとか? constexprで学習した結果のみ実行時に用いるAI。 結論が出たようなのでまとめる
1.#defineは欠点が多い。スコープが効かないのでC++では基本的に使わないこと。
2.代わりにconstexprを使う。constexprは、汎用的に定数式を表現するための機能である。
constexprは、「constant expression (定数式)」の略語である。
例1
#define BIT(n) (1<<n)
これは汎用性が高いので書き換える必要はないようにも思えるが、正しくは
constexpr int BIT(int n){ return 1 << n; }
このように書かなければならない。
例2
#define UART_A0_baud (115200)
#define UART_A0_stop (1)
#define UART_A0_bit (8)
#define UART_A0_parity (0)
#define UART_A1_baud (9600)
#define UART_A1_stop (2)
#define UART_A1_bit (8)
#define UART_A1_parity (1)
これをconstexpr を使って綺麗に書いてみよう。任せる。 C++書けるやつはかっこいいな-
ただ俺が書こうとしてないだけだけど でふぁいん てんてきのしんにゅう がちょくじゃないから あんしんするじゃないかな
めいんすとりーとからいっぽんはいったほうが カチグミニチカイホウガアブナイヨネここはあんぜんしゅうだんすとーかーにとっては
てんごく あんじゅうのち >>402
constexprはコンパイル時評価可能(評価するとは言っていない)なのでコンパイラ依存。
コンパイル時間が伸びるのが大半だろうけど。 >>411
確実にコンパイル時に解決されてるためには
別プログラムで計算して即値を#defineがベストって事だな >>411
「とても」ってのは例えば10年かかるとかそういうの
ある数学定数の計算とか固定データの暗号化を破るプログラムとか
適度にあきらめてくれないと
コンパイルが(事実上)出来なくなる >>413 そこは即値をconstexprにしようぜ。 >>404
constexprならunsignedじゃなくても平気なのかな? >>385
リンカの挙動に付いては変数と扱いが違うせいじゃなくて
c++ では const 変数はデフォルトで static なくだけだよ
お前は正しい指摘をしている時でさえ必ず間違ったことを言う
このスレ読んでる人に嘘ついて喜んでる愉快犯か何かか は?constをヘッダにstaticで定義しているバカが居たことに驚きなんだが
そりゃstaticで定義しまくったら実体増えるのは当たり前だろ
灯台下暗しでstatic記述するバカに気付かなかったわ
バカ過ぎて話にならんわw >>419
おっしゃることは確かにもっともなことですが、basic_string::npos についてはどう思われますか? なお、std::dec, std::hex なども static const。 クラス変数は統合されるから問題ない
ネームスペースやグローバルのヘッダに書くstatic constと違って constexprをご存知でない人多すぎでは
入門書に1ページおきにこれを使えと書いてあるだろ >>418
アホ自慢?
>>423
入門書www
プロは知ってても、場合によって#defineを使う >>422
クラス変数に統合されるとなぜ問題ないのですか?
そもそも統合とはどういう状態でしょうか。
ネームスペースにstatic constを書くのとあまり違いはないように思うのですが、どう違うのか教えてもらえませんでしょうか。 static constexprにするかstatic inlineにするかテンプレートクラスに書けば実体はただ一つになると思う
普通に書いたら分裂しそう cとの互換性を無視した場合のdefineの利点てあるのですか? >>428
ソースコードをプリプロセスしたいときに使う ___
/彡彡))
|彡( >
ノノノ ヽ丿 <プロでござい
/ ̄ ̄ ̄\ n_
`/| _[]_ |/\ ( )
∧||バ| Y\ `/ /
\||カ| | \_/
(|  ̄ ̄ |
|____|
||_|i|_||
| ー|ー | >>429
かならずインラインになる保証はないのでは? >>421 を訂正。
std::dec, std::hex はマニピュレータなので定数じゃなかった。
定数なのは、std::ios_base::dec、std::ios_base::hex。 まじめにデザインパターンを学習したくて書籍を探しているのですが、Javaで
説明しているものばかりで困っています。Javaは全く知りませんし、覚えるつ
もりもありません(自分にとっては不要な言語なので)。
C++でデザインパターンを開設している書籍を教えてください。 >>436
gofっていうわりとデザパタに詳しい人も本出してるから探してみて。 サンプルがJavaで書いてあるかどうかって関係あるか?
デザパタの本ならJava特有のことはやってないはず
何をやっているのかを理解してそれをそのまま他の言語に当てはめればいい C++は反則技が多すぎるので勉強しても無駄。
常に速度やメモリ効率を重視するための言語。
高級言語でOOしたいなら素直にJavaを使うべし。 今日日、Java使うくらいならPythonを使うんじゃないの。 JavaとPythonとC++って全部用途が違うじゃん
Javaと競合してるのはC# >>436
結城ならば簡単なJava だから、C++ の知識で Java の字面は追えますよ(なんとなくわかる)
私は結城 Java を C++ に書き直して習得しました C#やJavaが動くのにC++を使うのは辛い。非常につらい。絶対にやめたい。にも拘らず
未だにC++を進める人がいるのは残念だ。
一方C++は組み込みには非常に威力を発揮する。しかし組み込みではいまだに90%
の人がCを使う。それはなぜなのか?
CとC++ではスッポンと月ほどの違いがある。しかし残念ながらそれは
C++をフルに使える場合であって、フルに使える場合ならC#やJAVAを使った方がいいわけで
フルに使えないケースであるからこそ、C++を使うのが正しいのであるから、やはりC++は
Cに比べて月ほどではない。しいて言えば月というよりは牛だろう。ともすれば牛よりも
スッポン料理が高価なように、月になれるのに牛ではやはりかなり残念なのである。
どういう切り口でも残念な言語、それがC++だ。 C++開発をした人がC++の本を書いていて、先輩に「読め!!!」と勧められたので読んで
みたが非常にわかり難い。こんな頭の構造をした人が作った言語だからきっとわかり難いの
だろうと思う。一言でいうと簡単なことを複雑に説明する。
C++という言語もアフォほど簡単なことをやたらと複雑に書かなければならないことが多い
という気がする。 Headerファイルにメソッドを書かないスタイルは誤りだ。
理由
1.C++以外でそんなスタイルをとっているものはない。
2.なぜならメソッドも実体ではなく型だからだ。分離するメリットはないがデメリットは多い。 >>446
コピペかと思ったけど違うのか
何でC#を使うべきケースとC++を使うべきケースを分けられない人が出てくるんだ?
インタープリタやC#やらがクソ簡単に書けるのはその下で煩わしいことをやってくれてる人がいるからだ 最近の勘違いしたアホ機能テンコ盛りのC++。なんでも書けますよ。 c++が複雑なのはわかるがどんどん簡単に書けるように進歩してるだろ。
autoとかrange-based for loopとかconstexprとかlambdaとか。
他の言語並みに簡単に書けるようになるのはまだまだかかるとは思うが。 使う気ないですけどね。速度が速くならないならいらないです。
使い捨て、楽したいならC#で十分ですからね。 >>454
今どきはtypedefじゃなくてusingだしconstは実体が増えるからconstexprにするべきだと思うのだがどうだろう? セットする値に singned int の範囲しか使わないなら、static const 定数じゃなくて enum でOK。
enum なら constexpr すら要らない。 enum baseってlong long使えないんだっけ? >>444
Javaは高価な機器を買わせるためにデザインされた言語だから用途が違うけど、他はソフトウェアを作るためでは? C++やるのにテンプレート使わないなんてただのマゾプレイ 小規模マイコンのソフト開発なんて
全てがマゾプレイみたいなもんだから
それでもCよりはC++の方が便利 >>462は正しいと思うけど>>461のようにテンプレートだらけになるのはどうかと思う Expression templateでmatrix乗算、それが無理ならベクトルの内積
(それもコンパイル時計算じゃなくてコンパイラの遅延評価を利用して
一種の構文を記憶したもの)を計算するETを解説してるところしらないかな。
ベクトルのETによる遅延評価計算はC++テンプレートテクニックあるから
いいけどさ。
Matrixがわからんのよ。uBLAS、MET、TVMET探してもそれらしきソースコード
が特定できん。 Expression templateは本命じゃない。難しすぎる。でも演算子オーバーロードの
弱点である一時オブジェクトによるロス(a*aみたいな乗算も含めて)を解決する
方法を20年以上前に考えたけど、それと速度を比較したい。 ユニバーサル参照で一時オブジェクトの問題は片付く? 売ってる車輪の中から探すよりも作った方が早かったり安かったりぴったりな車輪になったりする アプリ次第じゃね。
数値計算やアルゴリズムやってると、リソース、速度、必要精度に応じて、整数、浮動小数点、多倍長整数、有理数等々に対応できるように作るから、むしろテンプレしかない。 >>470
うまい。プログラムがテンプレートだらけになってる奴は必死にマイレゴブロックを作ってる。
stl、boost、atl、既成レゴブロックは数多く提供され使われてるのだ。
そんなに理想の車輪がほしければ、
それこそ新言語を作ればいい。C++にアホ機能追加してる糞どもに言いたい。 >>473
C++03を使い続けたいのなら使ってもいいんよ。 >>473
何言ってるのかわからん
stlやboostはブロックを作るための材料くらいの位置づけだぞ
テンプレートがstlのような比較的低レイヤーなところでしか使わないとでも思ってるのか
レゴブロックと言ってるのは大量のモジュールを読み込んで継ぎ接ぎしてるようなJSやPythonのコードのことだ うちの会社にもなんでもテンプレで作りたがる奴いるけど、
調べたらほとんどのテンプレが一種類の型でしか使われてなかったw >>472
色々に対応できるライブラリは動作が遅い
スペシャル版が最強 そして変更に弱いコードが量産されて最後にはお手上げになると
親の顔より見たわ >>474
過去の大量のC++コードを全否定する機能を追加するなら新言語にすべし。
Java、C#みなそれで成功している。C++の名前を借りないと使ってもらう自身がないならキミは向いてない。 提案書を読めば分かるが基本的には問題点を解決するためのものばかりなはずだがな クソみたいな汎用化はいいからまずは一つの機能の関数をまともに書けと言いたくなるバカは確かにいる。 それ。C++は当初から問題ある欠陥言語だから、素晴らしい新しい言語を作るべき。
古い大量のコードはもうどうにもならない。誰も更新費用の予算を計上してくれない。
COBOLと同じなのだ。老人のおれはC++と心中する。
おまえら若者は新しい船で新しい世界に旅立ってくれ。俺の屍を越えてゆけ。 >>477
そうならないのがc++のtemplateなんで。。
それでも型によってかき分けたほうがいいところはTMPなり特殊化なりすればいい。 C++に取って代わろうとした言語はみんな死んだか別の路線を走ってるよ 老人はC++03と心中してくれ。俺はC++14以降の船に乗る。 >>486
スマートポインタは使わせてほしいのですが… vectorはdata()が連続した領域を返さないといけないのが大きな制約になってるかも。 それがなくなったら、もはや配列ではない
配列を使うべき用途で出番を失う 一応連続した領域を返すと保証されたのはc++03から 保証されてくれないと困るから保証されるようになったんだぞ >>484
テンプレートは魔法じゃない
同等の速度を出す為には結局全て特殊化することになるし、
インターフェースも型によって違う方が良いこともある
性能、リソース、...
突き詰めれば全て特殊化
テンプレートは妥協だ 妥協というより補助だろう。
templateだけで解決しようとすれば特殊化だらけになるのは当たり前の事 cstdio と STLの連携を深めて欲しいね。
・FILE* に basic_string をバッファとして渡してメモリに読み書きする機能が欲しい。
・fgets() で得られた文字列長を再計算するコストが無駄なので、文字列長も取得できる機能拡張関数が欲しい。
何らかの処理の過程で副産物として得た文字列長を捨てて、別の場所で文字列長を再計算する無駄は、かなり多いと思う。 templateはポリモーフィズムを実現するための実装の一つです
>>495
c_str()で渡せばいいのでは >>496
基底クラスのポインタで複数の派生クラスのポインタとして振舞えるの?
template を使ってポリモーフィズムを実装できるとでもいうの? >>496
FILE*を使う関数にbasic_stringをc_str()で渡すのではなく、
setvbuf() のようにFILE*の内部で使うバッファを basic_string に置き換える意味で言いました。
fprintf() でbasic_stringに書き込むことが可能になるイメージ。
C++にはpopen()で開いたパイプFILE*に相当するiostreamがないのでこれで代用可能。 >>497
コンパイル時にテンプレートパラメータでポリモーフィズムする >>499
template を使ってのポインタがポリモーフィズムを実現できるとは思えないのですが… templateはポリモーフィズムの実装ではなくポリモーフィズムの利用が仕事。 >>497
ポリモーフィズム=継承ではない
継承もポリモーフィズムを実現するための手法の一つにすぎない
ざっくり言えば同じ名前で異なった振る舞いをするもののことを言う
関数オーバーロードもポリモーフィズム 詐欺師が「○○を実現できます」と言った時、実際には「他人の作った○○に便乗します」という意味であることが多いから、あながち間違いでもない。 >>498
boostで似たようなことができる
http://www.cplusplus.com/forum/general/16532/
これをうまいことラップして
pstream ps("ls");
ps >> str;
みたいに動作するstreamを作ればいい >>505
情報ありがとう。
欲しいのは逆パターン。CをC++でラップするのではなく、C++をCでラップする感じ。難しいか。 >>503
>関数オーバーロードもポリモーフィズム
関数オーバーロードはコンパイル時には(どこからどこへコールしているかが)確定しているものですね
そういうものに「ポリモーフィズム」を当てるのは抵抗があります
もっとも wikipedia をみると、私の考えているポリモーフィズムは「部分型付け」(subtyping/inclusion polymorphism) としてサブクラス化されています
これは私の認識を修正しないといけない… 意味の広い英単語を、ものすごく狭くて極端な用例の一つに限定して和製英語化しちゃう日本人のいつもの得意技
ポリモもその犠牲者の一つ Ad hoc polymorphismのページでは2つの要素を+演算子にかける関数がpolymorphicなものの例として書かれてるね
https://en.wikipedia.org/wiki/Ad_hoc_polymorphism 拡大解釈すればできちまうものだからな
いくらでも俺様解釈し放題
それを聞かされている衆目がついていけないと言ったとき
強弁するやつと謙虚なやつでリトマス試験紙みたいになる もともとプログラミング言語の理論の方から出てきた言葉なので拡大解釈ではないでしょ
オブジェクト指向言語がそれらの理論から引用してオブジェクト指向におけるポリモーフィズムとは継承とオーバーライドによるサブクラス化のことだと言っているだけ >>486
その理屈だとc++20が出るからお前も十分老害だよ。
てか仕様が決まった言語使ってるのは老害ってことになるな。 個人的にはどっちかというと「動物ってのはワンワン鳴く奴のことだろ?猫や馬まで動物と呼ぶのは俺様解釈の拡大解釈」
って言ってるような滑稽さを感じる >>513
「老人はC++03と心中しろ」が「仕様が決まった言語使ってるのは老害」になるて…
倫理ダメダメやな
それでプログラム書いてんの?だいじょうぶ? >>516
"以降"が解らないのにC++で判定文書けるん? C++11以降で書かれたコードがほとんど増えていないという現実。 GCCもClangも、VC++でさえ10年近く前からサポートし続けてるのにまだ足りないと申すか 昨今の潮流はオブジェクト指向と関数型のハイブリッド
この二つをどう摺り合わせるか、どの言語もまだ明確な回答が出ていない
もちろんC++も アクセス権つき構造体とユニファイドコールシンタックスで疎結合オブジェクト指向だ。
と考えたのだが、ユニファイドコールシンタックスが死んでしまった。 ifdefできるだけなしで
どんなコンパイラでも通って同じ動作するコードを書けよ
コレは命令だ お前は本当にそんなにコンパイラを使い分けてるのか? 最低限、実機で間違いなく動いて
シミュレーターで間違いなく動くようにコード書きなさい
コードはいろんな実機をサポートしないといけない
実機ごとにOSも違う ICE上でのみ動作するコード
MIRACLE ON ICE 関数型も40年前からオワコンという現実を見ようよ。
5chのスレも全く伸びない。10年で1スレ消費できないレベル。 スレが伸びないのは難し過ぎるからじゃないのか
オブジェクト指向なんかはニワカが口を挟みやすい
あれやこれやと語ることがあると自転車置き場のごとくスレが伸びるんだよ 数学板とか物理板の質問スレで2chに失望し、それ以降2chで理系関連の質問はしないようにしてる >>532
稀に神回答がつくのを期待するしかないのです クラス/構造体の非静的メンバ変数/関数へのポインタ宣言 ってのを初めて知ったんですが、
これはどういう活用方法があるんでしょうか?
struct S { int data; };
int S::*d = &S::data;
S s1 = {999};
s1.*d; // → 999
s1.*d = 123;
(参考: 改訂第3版 C++ポケットリファレンス p.39)
上の例だと、 s1.data の別名以外の使い道がないように見えます。
長い長い真名の時は局所的に略記できて便利とか?、まさかそれだけですか? なんか昔同僚がメンバ関数へのポインタ使ってて納得した覚えがあるが
なんで納得したのかはもう忘れた >>535
動的に呼び出すメソッドを切り替えたいとかだね〜 >>535
そのとき S が int 型のメンバを持たなくても int S::*d という変数宣言が許される。
(無理矢理な型キャストをしない限りヌルしか入れられないけど。)
つまり、 S がプリミティブな型でなくクラスであるならば、メンバにかかわらず int S::*d は許容されて、
プリミティブな型だったらエラーになる。
この性質を利用して SFINAE で切り替えれば、与えられた型がクラスであるかどうか判定するものを作れる。
それが >>538 の言う is_class の実装に使えるって話ね。
まあ今なら is_class を使えよって話だから普通のプログラマ的にはどうでもいいけど。
回りくどい利用法なんだけど、まあ実際のところ実務の中で必要とする場面はそんなにないから、
この利用法が代表的なものとして紹介するしかない。 初心者の質問に答えていただき有難うございます。
動的にメソッド切り替えは実際に動かして理解できました。
SFNAEで切り替えの方ははコンパイル通る形にはできてませんが概要は理解できました。 メンバ関数ポインタがあの形になってるのはまあわかるから
変数もおまけで同じ形にそろえたのかな > 実務の中で必要とする場面はそんなにない
データメンバはともかくメンバ関数へのポインタは必須だろうが >>543
ないと困る局面があるという意味では必須だけどそんな局面は滅多にないって話な >>545
バインダ使うときどうすんだよ
そりゃあエンドユーザーは滅多にというか一生使わんが
そんな話してねえぞ ある必須の用途で必要なら、その用途がいくら狭くて稀であったとしても
それは必要なんだよ メンバ関数ポインタ面倒だから出会ったら大体ラムダでラップしてしまう・・・ std::stack や std::queue に begin() end() clear() などが無いのは何故ですか
begin() end() はともかく clear() は有ったほうが良いと思うのですが >>550
機能を絞っていることが彼らコンテナアダプタの唯一の存在価値なので許してあげてください。 template<class ... Args>
void func1(Args ... args) {
outputs(buf, args...);
}
こういう可変長引数のテンプレートの場合に別のファイルで利用する場合には
どう宣言したらいいの?
void func1(???); >>546
> バインダ使うときどうすんだよ
だからバインダ使いまくるとか覚えたての初心者か
って話な
> そりゃあエンドユーザーは滅多にというか一生使わんが
誰もしてない話を勝手に始めて
> そんな話してねえぞ
とか、ギャグかよ w
>>548
>>545の日本語も理解できないのか? >>554
バインダ使えないアホか
マジになって悪かったな 関数型テンプレートってのは、型でもなしに、実態でもない。不思議な存在だ。
型だとすれば、関数プロトタイプのように繰り返して宣言しても問題ないはずだ
が、そうするとエラーになる。実態かというと、これ自体では何のコードも生成しない。
利用するときに始めてコードが生成される。 unsigned long address;
int dt;
*(char *)&address = dt;
コンパイラエラーにはならないが動作しない。ところが
uint8_t *address ;
*address = dt;
これだと動作する。なぜなんだ? =0x20000;を書き忘れていた。あとは上に同じ。 >>559 俺の環境だと上の方でも動作するみたい。
dtの下位8bitがaddressの下位8bitに格納され、addressの上位24bitは不変。
期待通りと思える。 前者はaddressの最初(または最後)の1byteだけを書き換えようとしているけど、それは意図通りなの?
後者は0x20000番地の値を書き換えようとしてるけど、そこは書き換えてもよい領域なの? おっと、未定義動作がらみで「何が起きても不思議じゃない」かも知れん。
リトルエンディアンの機械での素朴な予想レベルでの「期待通り」ね。 uint8_t *address = 0x20000;
がコンパイル通るわけねえだろ質問したいならちゃんとしろ >>546
c++で閉じてるなら関数ポインタ渡すインターフェイスより、
クラスを継承してメソッド実装させるインターフェイスのが普通だろ。
まあcからの関数ならよくあるが。
>>557
単なる型付マクロだっつーの。 マクロで再帰ができるか!!!!!!!1111!1!11!1!1!
前半は同意
あと関数を単に差し替えたい目的ならファンクタとk そういう事言うとプリプロの怖い人達が来るからやめれ
本物の再帰じゃないけど再帰っぽいことはできるらしいぞ スフィ姉を使った技についてスレッドがあってもいいかもしれない。 「マクロ使う奴はアホ」とか言う奴は、goto文も絶対に使わなそう >>563
damecaseの理由がわからない。
void Test::clear(unsigned long baseadd, unsigned int dt, int leng)
{
#if(okcase)
uint8_t * addp = (uint8_t *)baseadd;
for(int i=0; i<leng; ++i){
*addp++ = dt;
}
#endif
#if(damecase)
unsigned long addp = baseadd;
for(int i=0; i<leng; ++i){
*(char *)&addp++ = dt;
}
#endif
} baseadd=0x20000でダンプすると初期値は全部ffが入っている。
leng=100としてdt=0を書き込むとokcaseはOK100バイト0クリアされる。
damecaseは全く反応しない。 >>566
とおるよ。頭の中でCastしてくれたら >おっと、未定義動作がらみで「何が起きても不思議じゃない」かも知れん。
>リトルエンディアンの機械での素朴な予想レベルでの「期待通り」ね。
どうして?
何処が、どういう理由で未定義なの?
リトルエンディアンが問題というのはバイトオーダーが関係するということ?
1バイトのエリアに代入するのにバイトオーダーが関係するはずはないでしょ。どいういうこと?
char*pのpは1バイトデータのポインタ(アドレス)だよ。代入先が1バイトなのでエンディアンは関係ないと思うが、、、 >>579
strict aliasing ruleでググるか死ぬかどっちか選べ >>576
damecaseの*(char *)&addp++ = dt;
&いるぅ? >>579
「ある型へのポインタの値をキャストで別の型へのポインタとして扱い、
その(キャストで得られた)ポインタに対して * 演算子で格納する」行為自体が
規格で未定義になってるかも知れんてこと。確実じゃないんだけど。
キャストの時点でか、*でアクセスしたときか、格納の時か、
どことは言えないけど何となく未定義クサい感じがする。 ↓addpをインクリメントとか頭悪いの?
*(char *)&addp++ = dt;
unsigned longのaddpをインクリメントしてる
addpはポインタじゃないぞ。。。
きっとバカが動作しないといってるのは
落ちるということではない
動作はするが期待どおりの結果にならないということで間違いない
バカはなにがやりたいのか意味不明 unsigned long addr = 12345678;
char* pByte = &addr;
ならいけるハズ
*pByte++ = dt
で leng が sizeof(unsigned long)/sizeof(char) 回までの繰り返しなら
普通に落ちずに動作するハズ
ばああああああああああああああか
しかいないわこのスレ いやねcすら理解できてないヤツラが
c++とか一億年早い
こんなヤツラがc++でコード組んでるかと思うと
ぞっとするわ。。。
シロウトはおとなしくjavaにしときなさい for(int i=0; i<leng; ++i){
((char *)&addp)[i] = dt;
}
バカ向けのコードを書いてやったぞ
コレでバカにとってはすべて解決
コレがなんのことか分からないなら
もう二度とプログラムなんかやらないほうがいい
センスない、むいてない >>586
strict aliasing ruleでググるか死ぬかどっちか選べ ぐぐったぞ
http://d.hatena.ne.jp/yohhoy/20120220/p1
> 文字型。規格ではchar*, signed char*, unsigned char*が別の何かを指すことが特別に許されています。
> これは文字型がメモリ上の任意のaliasになり得ることを意味します。
どうかしたのか
もうねバカばっかりで困るわマジで
池沼しかいないの? このスレ? ちなみになchar以外で変なメモリアドレス(メモリ上有効なアドレスあっても)の位置からcharより大きいサイズの数値を参照すると
memory wrapの切れ目の問題(つまりwrap over)で
bus errorを普通に起こす計算機がある
このスレにいるようなマヌケたち以外にとっては常識だからな 役に立つ情報ありがとう。
でも、半角カナは止めてね。 >&いらん
コンパイルエラーにはならない。ワーニングにもならん。という事実を書いている。
些末なことで糞ほどワーニングやエラー出すC++だ。ワーニングにならんということは正しい
ということか、コンパイラがアフォかさもなくば、何か別の意味があるということになる。
わかるか? お前にも質問の意味が分かるように、そしてちゃんと回答ができるようにもう一度簡単に書いてやろう。
1.正しい
2.コンパイラがアフォ
3.意図とは別の意味になっている。
さあどれが正解だ。答え見ろ。 >584
はあー、未定義かもしれんて? 未定義ならエラーになるだろ。 >>589
理由を書いてごらん。理由がないと回答にならんよ。 >>585
俺はやらないがそこは問題じゃない。
アドレス値が格納されている正数を1ずつ増分しているだけだ。
>>589
お前は>>576のコードをそれに書き換えて正しく動作すると思ってるのか?
>>582>>583で答えが出てるのに、馬鹿には理解できなかったのだろうな。
俺なら恥ずかしすぎて首吊って死ぬわ。
>>594
4. お前がアフォ なにが書いてごらんだ
バカのくせにえらそうに。。。
addpはアドレスじゃない
で、addpはどこのアドレスをさしてる?
で、なにがインクリメントされてる?
バカにはまだわからないらしいわ、、、
int hoge[10]
int boo = 1234;
char* hogeee = (char*)hoge;
ex1
for (int i = 0; i < 10; ++i) {
*((int*)hogeee) = boo;
hogeee += sizeof(int) / sizeof(char);
}
ex2
for (int i = 0; i < 10; ++i) {
((int*)hogeee)[i] = boo;
}
ex1とex2、この違いわかる?
わからないなら、もうすべてを諦めたほうがいい
オレはオマエを諦める >>>582>>583で答えが出てるのに、馬鹿には理解できなかったのだろうな。
>俺なら恥ずかしすぎて首吊って死ぬわ。
ではその理由を書いてごらん。理由がないと回答にならんよ。理由が説明できないなら試験も受からんだろ。 >で、addpはどこのアドレスをさしてる?
>で、なにがインクリメントされてる?
まず、どこをさしているのか?何がインクリメントされているのか答えてごらん。 致命的に脳ミソが足りないのは理解した
アンリカバブルだ お前は解ったふりをしているだけだよ。言葉にして説明できないならな。 ここまで説明して
なんで同じ結果にならないか
分からないならもうムリだからな
向いてない
諦めなさい
なにごとも諦めが肝心 誤魔化して変なコードを追加するな。問題はこれだ。
unsigned long addp = baseadd;
for(int i=0; i<leng; ++i){
*(char *)&addp++ = dt;
}
このコードが何故動作しないか? それを説明するのが問題なのだ。 多分解っている人なら、直ぐに説明できる筈だ。
分からない人は説明できない。罵るのはさらに愚。 同じ結果にならないことはすでに説明してるからな
アドレスを格納する変数を使わないで同じ結果にしたいならどうすばいいか
まで書いた
それに対する補足説明まで書いた
もうこれ以上書くことはない
ムダ >アドレスを格納する変数を使わないで同じ結果にしたいならどうすばいいか
>まで書いた
>それに対する補足説明まで書いた
思わせぶりな回答を書いて欲しいといっているのではない。頭がいいと思ってほしいのかもしれないが
それでは「思わせぶり」でしかない。説明としてきちんとした形式を備えた自信のある回答を書いてごらん。 >>599
え、なんで?
礼儀を知らないおっさんに教えてやることなんて一つもないよ。
ちな>>597で馬鹿呼ばわりしたのは半角でバカバカ言ってるやつのことなんで。 >608
「教えない」習性の人は成長しない。ということは知っているだろ。習性というくらいだから今に始まったこと
ではない。つまり嘗て勉強を始めた時点ですでに成長はとまっているということだ。 俺は無償でお前等に考え方、回答の方法を教えている。教えることが一番勉強になる。
いままでのところ質問にたいして誰も合格点をあげることができるような回答がない。 addpの値として期待されているのがアドレス値X。&addpは、アドレス値Xを格納している変数addpのアドレス値Y(ポインタの値)。代入によって期待されているのが、アドレスXへのdtの値の格納。
XはYではないから、間違い。 というか&addp++の時点でエラーでるなこれ
コンパイラ何使ってるの? >>612
正に初歩的な質問というものは質問自体に間違いが含まれている可能性がある。
そのことに先ず言及できたのは君が初めてだ。素晴らしい。
質問者が正確に質問できた時点で回答は既になされたも同然だといわれるが今回も
例外ではない。これで終わる。 なめたことをしてくれたな。。。
558 名前:デフォルトの名無しさん (ワッチョイ 469d-mzC7)[] 投稿日:2018年06月30日(土) 08時17分40秒24 [朝] ID:p5lz5e260 [2/19] (PC)
コンパイラエラーにはならないが動作しない。
594 名前:デフォルトの名無しさん (ワッチョイ 469d-mzC7)[] 投稿日:2018年06月30日(土) 22時22分23秒05 [夜] ID:p5lz5e260 [8/19] (PC)
コンパイルエラーにはならない。ワーニングにもならん。という事実を書いている。
(ワッチョイ 469d-mzC7) ID:p5lz5e260
オマエを特定した
震えて眠りなさい ことさらに難しいコードを書いて得意がってる馬鹿がうようよ
1行に詰めるのがプロか?
新入社員が読めないようなコード書いて喜んでいるお前らが
バグを仕込む糞プログラマだわ 有能なプログラマはこんな場所で遊んでいない
暇なプログラマっていうか、仕事が無いプログラマ? プログラマにまともなコード書いてもらうも仕事の一つだからな
まともなコード書いてもらうには
こっちもプログラムが分かってないといけない
日本はウンコみたいな低品質低能のプログラマしかいない
いかに踏みとどまらないといけない最低限の一線のラインを越えさせないようにするか
そこが腕のみせどころになる
このスレみれば分かる通り
日本のプログラマは低学歴低能しかいないことがよく分かるハズ
しかも相手がなにを期待してるかも読みとれない
コミュニケーション能力も著しく低い
こんなのに仕事をお願いするほうも大変だからな
可読性が高いコードを書くことは重要だが
それ以外にもイロイロなものが欠落している struct addp_t
{
int& operator ++ (int)
{
return a;
}
int a;
};
int main()
{
addp_t addp;
&addp++;
}
# アンカーつけるのももったいない
# 5chという狭苦しい箱庭の中で目撃したことが
# おまえの全てのようだな
#
# なぜ学歴が出てくるのかよくわからんが
# 高学歴のPGくらいどこにでもいるよ >>591 ありがとう。
(signed/unsigned)char* のポインタで他の型の格納領域にアクセスすることは
規格で許されてるんだね。char* だけ特別扱いってことか。
俺も >>581 の指摘を見て検索して同じページに到達したんだけど、
> 文字型。規格ではchar*, signed char*, unsigned char*が別の何かを指すことが特別に許されています。
> これは文字型がメモリ上の任意のaliasになり得ることを意味します。
の部分を見つけることができなかった。
すると >>558 のコードに未定義動作を引き起こす点はないのだな。 >>619
最近文字コードスレで騒いでいる半角カナの人と同一人物かな? 循環参照があっても無問題で解放するスマポ作ったけど何か質問ある?
http://codepad.org/Hu6vP4qR
いやまあ確かに解放に当たり(塗り潰しのアルゴリズムで)循環を検出するだけでは済まず、
*(this->m_pRef)の解放条件が*thisの解放「だけ」である
ということの証明が必要やったわ;(訂正1)
ここで*thisはsumapo<T>インスタンス、*(this->m_pRef)は*thisが保持しているcounted_refオブジェクト
(T型のインスタンスに参照カウント等を付加してwrapしたもの)。
詳細はsumapo<T>::proveRoot()のコメント参照、
これ以外は訂正は無し >>225
Tのメンバを公開(publicにする)するだけで、
sumapo<T>の定義内のコードからTが保持するsumapo<*>にアクセスできるというなら
>>226の忠言に従ってコードを書いてみると良いんじゃー
一方リフレクションが使えるなら、sumapo<T>::setLandowner()メソッドは不要となる
(これのメソッド>>222において
>あんま使い勝手の良いものにはならんかったorz
>m_pCarやm_pCdrとptrが裏で手を握る必要がある
が指していたブツ。>>222の時点でtest01()が通るコードは書いていたんじゃわ;; >>624訂正
誤: これのメソッド>>222において
正: このsumapo<T>::setLandowner()メソッドが>>222において >>624
なんつうロングパスよ、と思ったが、コードを書いた姿勢だけは褒めてやる。
とはいえ、俺は最近「馬鹿が書いたコードは読む価値がない」と結論を出したので読まないが。
(大体において意味不明な制御を行っており、結果、
解読に時間がかかる割に得る物が全くない)
それ、アルゴリズム説明してみ。
そしてそれが正しく動くとして、何故C++がそれを採用しないかも説明してみ。 クラスTのオブジェクトを参照するスマポsumapo<T>のインスタンスpaが、クラスTのインスタンスaを参照している状況を
pa→[a]
と書くとする。ここで、[a]は、aに参照カウントその他を追加してwrapしたもの。(>>623におけるcounted_refクラスに当たる。
[a]はインスタンスaにつき唯一だが、[a]を参照するsumapo<T>は複数有り得る。
で、paとpbが循環参照しているとは、次のような状況である。
例1: pa→[a], pb→[a]、ここでpbはaのメンバ(paとpbが循環参照
例2: pa→[a], pb→[b], pc→[a]、ここでpbはaのメンバ、pcはbのメンバ(pa、pb、pcが循環参照
例1では[a]がpaとpbから参照されていることになっており(参照カウント2
結果、paの解放時、paのデストラクタで[a]の参照カウントが1になるが0にはならないので、
参照カウントだけに頼るとその時点でpaのデストラクタは[a]が解放されない。(引き続きpbから参照され続ける。
一方、pbの解放条件は、[a]の解放である(∵pbがaのメンバであるため)。というわけで解放がデッドロックに陥る。
しかしpa→[a]==>pb→[a]、という参照関係(paのみが参照関係の根である)をpaの解放時に把握できていれば、
paの解放で[a](とそのメンバpb)を解放して無問題であることがワカル
この参照関係のうち、「==>」をpb.setLandowner(&pa)とすることで設定し、-- (1)
paの解放時に全体として参照関係の根がpa自身「のみ」であることを証明する -- (2)
ことにより、安全に解放が行える。((1)と(2)がshared_ptr<T>にたいしsumapo<T>で追加になった要素
標準ライブラリに入っていないのは、(2)の証明コストがイマイチかかるからだろうJK >>627
pa→[a]==>pb→[a]、という参照関係において、pbの地権者はpa。
なお、ソースコードコメント内には「立地」という言葉も出てくるが、pb立地が[a]。 >>628
まずそういうのはインタフェースを揃えろ。
(俺はスマポは使ったことがないが、俺の理解の範囲では)
お前はスマポの仕様を勘違いしている。
オブジェクト側をラップするのはソースコードの全面的書き換えが必要になるだろ。
だからそんなことはしてない。
スマポも普通のクラスでしかなく、スマポ側に制御に必要な情報全てを持っている。
オブジェクトと癒着はしてないんだよ。
> 一般的な実装では、 std::shared_ptr は2つのポインタを保持します。
> 格納されたポインタ (get() で返されるもの)
> 制御ブロックへのポインタ
> https://ja.cppreference.com/w/cpp/memory/shared_ptr
が、まあ、言いたいことは分かるし、ここは本質的には重要ではないので、
今回はお前のオレオレ用語のままでいい。
さて本題だが、(1)は誰が管理するんだ?
プログラマが明示的に手動で管理するのなら、現行のshared_ptr/weak_ptrと手間が変わらない。
だから自動的に出来る必要があるが、これは出来るのか?
具体的に言えば、お前が言っている「参照関係の根」をshared_ptrで、
「pa→[a]==>pb→[a]、という参照関係」のpbをweak_ptrで実装しろというのが現行の仕様だが、
これに対して何が便利になってるんだ? >>631
それはC++的には意味がないだろ。
結局、現行の仕様が何故そうなのかを理解出来ない馬鹿が吠えただけだろ。
まあJavaScripterなんて所詮こんなもんだが。
「スクリプト言語使いをプログラマと呼ぶな」というのは、多少は当たってる。
彼らが書けるのは「動けばいい」程度のコードまででしかない。 pythonしか使えないやつが作った特定のサイトから画像を大量にダウンロードするだけのツールが
クソ遅いうえにメモリ4GBも使ってたので頭pythonってクソだなって思った 使える言語を聞かれてC++含めて複数答えたら
確かPHPあたりで「それプログラムじゃなくてスクリプトだよね」って言われたことはあるな
そこまで上から目線で突っ込むことか?とイラッとした記憶があるな いるよね、やたら偉そうに
自分を大きく見せようとするやつ c++,c,sh,bash,zsh,csh,tch,screen,glsl,php... >>635
それはその使えない奴の問題だろ
言語の問題とプログラム固有の問題の切り分けもできないアホなら黙っとけ >>636
PHPは言語自体の性能が低いので使いこなすのはかなり難しい。
Javascriptも同じ。
つまり、楽に性能を出せるC++に乗り換えた方がいい。 >>635
その程度のもの、文句言うなら自分で作れや。 >>635
wgetはサイトから再帰ありで指定のファイル取得できるよ。 お前らは知らないからそんな呑気なことが言える。
実際、JavaScriptはマジでゴミコードの山だ。
商用サイトでも糞重いしリークしまくりだ。
PHPはJavaScriptに比べ露出は低いが、OSSを見る限りやはり糞だ。
とはいえコードの質はPHP>>>JavaScriptだが。
DB接続があり、初心者にもコードの質が見える所が違うのだろう。
PHPerは虐げられているが、その分勘違い野郎は少ない。
最悪なのはJavaScripterだ。
一般のスクリプト言語(Python, Ruby含む)とC++等のプログラミング言語の違いは、
前者は圧倒的に「一回動作させれば終わり」な使われ方をすること。
だから、メモリリーク?何それ美味しいの?
コードが美しい?そんなことよりちゃっちゃと書いて実行させた方が早いでしょ、となる。
長期的保守の必要がない使い捨てコードばかり書いているから、
保守に耐える品質のコードを書けるようにならないだけ。
だから正確には、
「保守に耐える品質のコードを書けない馬鹿をプログラマと呼ぶな」であり、
それがほぼ「スクリプト言語しか使えない馬鹿」と一致する、というだけ。
一般的に(JavaScript除く)スクリプト言語は圧倒的に遅く、
味見ではなくガチならC/C++に書き換えるケースも多々発生する、というのも
これを後押ししている。
とはいえ、JavaScripterやPHPerみたいな馬鹿揃いでも
何とかるように出来ているのがWeb系()の凄いところ。
あれは学ぶ価値あると思うぞ。
色々C++では無駄に難しく考えすぎていたな、ということに気づかされるから。
今更導入されたラムダもしかり。あれは手抜きにはかなり便利だ。
コルーチンもそうでしょ。無しで同じ事をやろうとするとそれなりにエグくなる。 >>630
>さて本題だが、(1)は誰が管理するんだ?
いやすまん>>628の最後の一文ではそれをすっかり失念してたわ;;
標準ライブラリにsumapo<T>が入りえない最大の理由は、(1)の管理を手動でせねばならない、という使い勝手の悪さのが最大の理由
(>>222で書いた「使い勝手の悪さ」のことじゃわ
これを自動化するにはリフレクションが要る
それはそうとして、
1. オブジェクト側をラップする
というのと、
2. オブジェクトと癒着
は別の話じゃわ;
1は標準的なshared_ptrの実装ではそうなっている(counted_refという名前のクラスは実在の実装から拝借したものであって漏れの独創ではない
だいたい
>[a]はインスタンスaにつき唯一だが、[a]を参照するsumapo<T>は複数有り得る。 (>>628)
なので、参照カウンタを所有するのはオブジェクト側をラップした[a]以外ありえんのじゃわ
[a]を参照する全てのsumapo<T>は、[a]より長く生き長らえることは無い
2はsumapo<T>にとっては必要だが、shared_ptrには要らん ちなご興味のお有りの方にカミングアウトすると、>>623のコードのSUMAPO_ONマクロを0にすると
sumapo<T>は普通のshared_ptr<T>になりぬ
動作やコードを比べて見られるのも一興かと、 ちな(2)、
>「pa→[a]==>pb→[a]、という参照関係」のpbをweak_ptrで実装しろというのが現行の仕様だが(>>630)
これは、ちげう
weak_ptrを使って[a]の解放の根がpaのみであることを証明できるのは、実際に[a]を解放したときに限られるが
もし[a]の解放の根がpaだけではないと反証されたら[a]を解放してしまった後で藻前責任とれんの…?
一方sumapo<T>はそんな迂闊なことはせず、解放「前」に証明を試みるんである >>639
だから頭pythonだと言ったろ
俺がこれ遅くねえかって言ったら頭ひねった結果理由がわからんと言ってきた
俺が作り直してやったら速度が倍増したけどHTTPリクエストするだけでメモリを数十MB使われたからPythonもクソだわ >>648
> 俺が作り直してやったら速度が倍増したけどHTTPリクエストするだけでメモリを数十MB使われたからPythonもクソだわ
頭の悪い知ったかに絡まれるPython可哀想 w
低能しかいない職場なのかよ >>645-647
なるほどお前が何も理解してないのは分かった。
> これを自動化するにはリフレクションが要る
これは違う。
仮にリフレクションがあったとして、何をどうするか説明してみろ。
お前には出来ないから。
> weak_ptrを使って[a]の解放の根がpaのみであることを証明できるのは、実際に[a]を解放したときに限られるが
> もし[a]の解放の根がpaだけではないと反証されたら[a]を解放してしまった後で藻前責任とれんの…?
これも違う。
お前はweak_ptrの仕様を理解していない。
お前の言い分だと、「現行の仕様では循環参照を実装出来ない」事になるが、
これは明確な間違いだろ。
お前はこんな当たり前の事すら理解出来ないほど馬鹿なんだよ。
そもそも、
> 標準ライブラリに入っていないのは、(2)の証明コストがイマイチかかるからだろうJK (>>628)
これ自体が間違ってるんだが。
もう君は相手にする価値のない馬鹿ということでいいかな?
JavaScripterなんてこの程度の馬鹿しかいないし、お前もそうだ、でしかない。 unique_ptrの所有権ってnewとdeleteは任せろ、アクセスはご自由にどうぞという解釈でいいですか? よくわからんがリファレンスカウンタがゼロになったら解放するしょうもないプログラムか
MSのCOMもそんなんだったような覚えがあるわ 10年ぶりにC++に戻ってきました。
C++11/14/17なんて出てたんですね。
これってもうstableですか?
普通に使っても大丈夫? なにを基準にstableなんだか
古い時代のコンパイラ使っていたら一生stanbleにはならんよ >>654
stableにはさせん、させんぞぉ!
という層でC++は出来てる
常に進化するので、それに付いていけないB級はいらない
なので、あなたは使わなくていい
使いたいか、そうでないか、人に聞く前に自分の欲望で決めるのがC++だ >>656
C++0Xと騒がれていた時代のC++03のように
スタンダードなレベルに普及しているかという
趣旨の質問でした。
調べてみたらC++11くらいなら主な実装系で
サポートできているっぽいですね。
新規案件では採用してみたいです。
Web界隈は新し物好きの若者が多くて
勝手に栄枯盛衰していくコミュニティですが、
C++は化石みたいな人が多い空気があるので、
C++11以降、コミュニティが追従しているのか
ちょっと心配ではあります。 >>657
最新をどんどん使うという雰囲気ではないけど、C++11 は人権というくらいには言ってよいと思う。 出口の見えない長いトンネルをやっと出た
それがC++11だね トンネルを抜けるとそこは針地獄でした。これまでの法則は通用しません どこが針地獄なんだよ
ちょっと想像しにくいが
C++11の新機能がまったく使えないという
想像を絶するアフォいるのか? 良く、拡張子cppでCのコードしか書いてないファイルあるけど、あれってC++のコード書いても動くもの?
コンパイラはC++だよね? 仮引数リストが空の場合の解釈が違ったりとか、
文字リテラルや文字列リテラルの型が違ったりとか、
地味な非互換はいくつかある。
そのあたりを踏まなければおおよそ大丈夫。 >>657
お前含めてWeb界隈、特にJavaScriperには馬鹿しかいないけどな。
これは印象ではなく、事実な。
何を使うかはお前が決めればいいだけ。
実際、Go/PHPではstableですか?なんて聞く馬鹿はいないだろ。
この違いを理解出来ないのはJavaScripterが馬鹿な証拠。 >>663
動くと思うけど、
標準仕様にファイル名の規定はなく、どのコンパイラが使われるかはあなたのプロジェクトのビルドスクリプトの設定次第だよ
>>666
私はjs使えませんアピールしてんの? 657が煽りっぽいからしょがない
C++使えてJS使えない奴なんかいないだろ >>667
> 私はjs使えませんアピールしてんの?
そりゃお前だろ。
お前が本当にJavaScriptを使えるなら、今のJavaScripterがどれだけ酷いか知ってるはず。
そしたらそんなことは到底言えないだろ。
実際のサイトのコードも大半がゴミだし、JavaScriptのスレで定期的に盛り上がる話題は
・変数の初期化前の挙動を理解するべき ← そんな必要ない、C#ならSyntaxError
・セミコロンはどこに打つべきか ← アホか?C++ならSyntaxError
なんだからな。
あいつらがデータ構造について議論した試しがないし、それ以前にOOPも理解していない。
だからあいつらの定義では、
・上級者=新しい文法を使いこなせる人
となり、657や667みたいな投稿が発生する。
(要はJavaScripterは657,667含めて全員ゴミってだけだが)
C++の連中はそんなこと思ってないから、新文法も必要なときに使うだけであって、
必要ないと判断してるから使わないだけ。
積極的に使わないといけないと考えること自体が間違ってる。
C/C++の歴史は長いから、最低限必要な物は既に整備され尽くしてる。
(JavaScriptやPHPみたいなヘルパースクリプト出身ではない) 必要最低限はCだけでも既に整備されているので正しい >>669 新文法を必要ないと判断しているということはautoやrange-based forとか使ってないの? 古参でも理解できるプログラム書かないと仕事にならない場合もあるから
最悪C++使わないでC言語オンリーになる場合もある
というかC++自由に使える仕事の方が少ないよ C++の仕事にCしか書けない人が参加するのはありなのか? >>666
あなたが無知すぎるでしょ。
趣味で使うのならばなんでも好きなの使えばいいが、
実務で使う場合は周りのことも考慮する必要があるのです。
PHPやPythonでStableというのは
公式インタプリタが正式リリースされたということ。
コミュニティも追従して最新に対応する。
C++の場合、影響力ある実装系がたくさんあるせいか
Stable化するタイミングが分かりにくく
コミュニティも追従してこない。 >>669
あなたのいうJSはどのJSですか?
ES5ですか、ES6ですか、ES2016ですか2017ですか
はたまたCoffee Scriptですか、Type Scriptですか
一括りに語ってる時点で何もわかっていない。 JSとC++では処理系が多数あるという点では状況が似ていると思う。
C++にもトランスパイラが必要かな。 >>674
> 趣味で使うのならばなんでも好きなの使えばいいが、
> 実務で使う場合は周りのことも考慮する必要があるのです。
じゃあここで聞くなよメンドクセエ奴だな。
お前が決められる立場なら勝手に決めろ。
ただ、その程度で実務でグループ開発する際に決められる立場にあるとは思えないし、
仮にそうならよほど酷い職場だとしか。
> コミュニティも追従して最新に対応する。
Python3やPerl6見てそう思うのなら頭おかしいだろ。
PHPもいまだに5.4とかだったりするのも俺には謎だが。
(まあ何か理由はあるのだとは思うが)
> C++の場合、影響力ある実装系がたくさんあるせいか
ダウト。組み込み等で選べない場合はそれを使うしか無く、
選べる場合はMSVC/gcc/Clangの3つしかないだろ。
> コミュニティも追従してこない。
だからそういう問題じゃねえんだよ。
お前がどのコンパイラを使うか、それを決めればいいだけなんだよ。
逆にお前が勘違いしている「コミュニティの追従」があったら何が嬉しいんだ?
>>675-676
スレチ >>677
お前世界狭いな
本当に仕事してんのか? >>677
お前もダウトだがな。
>MSVC/gcc/Clangの3つしかない
こいつらバージョンが違えば全然違う実装と言っていいくらい違うぞ。
最近はもうバージョン違えば動作違うなんて当たり前なんだから使う方が気を使えやって
立場が多いのかね。 >>679
> 最近はもうバージョン違えば動作違うなんて当たり前なんだから使う方が気を使えやって
> 立場が多いのかね。
自前でガチで組むならコンパイラのバージョンは基本固定だろ。(必要ない限り上げない)
OSSなら基本は最新バージョン追従で、逆に旧バージョンなんてシラネでいいだろ。
(そもそもコンパイラのバージョンが上がって問題になるケースも希だが)
むしろお前はどんな環境でやってるんだ? >そもそもコンパイラのバージョンが上がって問題になるケースも希だが
そ・れ・が、
cuda9 はコンパイラ(VS2017) のバージョンが上がって、さっぱりコンパイルできない有様なんです… >>681
それはcudaの問題で、C++側の問題ではないのでは?
もっとも、cuda環境なら俺なら当然コンパイラもcudaのバージョンも固定、
可能であればディスプレイドライバも固定で行くが。
cudaのOSSなら、それは最新版追従しかないし、
それで旧コードが駄目ってのなら、それはstableではないとしか。
ただcudaの場合はかなり特殊だからなー。
DirectXも「互換性?なにそれおいしいの?」状態だったらしいし。
あの辺は抽象化されてないからどうにもならんでしょ。
むしろ抽象化コストを嫌っているわけだし。 >>682
VS2015 を今でも使わせてもらえるのなら、もう VS2015 は固定されているので、それでいいのですけれども…今はVS2015は「一般には」公開されていないようです
VS2017 は、なにかを追加するために MS にアクセスすると、ついでにコンパイラのバージョンもあげてしまうのです
もとに戻すのを繰り返しましたが、もう疲れました…
というか、Linux では cuda は gcc を使っているようですから、Windows でもそうしてほしいのですが… >>683
> VS2017 は、なにかを追加するために MS にアクセスすると、ついでにコンパイラのバージョンもあげてしまうのです
なるー。自動アップデート死ね、って奴か。
それはかなり厳しいね。
回避するには、自前でVS2015マシンとVS2017マシンを分けるのが一番手っ取り早いだろう。
これが無理なら、試しにユーザアカウントを別にしてみればどうだろう?
(VS2017のアップデートも別人に対しては有効化されないだろと予想)
無理なら、、、確かnVidiaはdockerを用意するとか言ってなかったっけ?
Win10ならdockerはデフォで対応してたはずだし。
(つっても俺はcudaは2.2-4.xの頃しか使ったことがないので、現在の状況は詳しくは知らない。
まあ君なりに努力しての結果なんだろうとは思う。話が全然ずれてたらすまん) 関数に引数として渡せるような多次元配列ってどうやってこしらえるのがベストプラクティスなの?
eigenとかは使いたくない
STLなら使える
サイズがコンパイル時に決まってたりはしない予定 >>687
目的によるんじゃね?
行or列が揃わなくていいならvector<vector<… でもいいわけだし 結論としては場合によるとしか言いようがないでしょ。
だいたいの場合にこれを使っておけばベストだわって言える方法はないと思う。
コンパイル時には決まらないって言ったって、
オブジェクトを構築した段階では決まるのか、
後から拡張 (縮小) することもあるのかでも判断は変わるだろうし。
ライブラリがユーザに見せる API なら抽象化されたクラスを用意した方がいいけど、
そうでもない内部的なものならポインタひとつと整数ふたつを渡すデザインでも用は足りるし。 >>687
そもそも行列がスパースかどうかで実装が異なるのが普通。
密で、行も列も長さが変わらんのならどんな持ち方しても大して変わらん。 物によってはunorded_map使うのもありかも。 >>691
世の中にはスパース配列という用語があるんだが w >>688
vector でやるという人は多いようです
真似してみます
>>690
スパースでないです >>694
ああ、指摘されてもわからない人なのか
それとも引っ込みつかなくなった人なのか 1レコードが可変長の列でもない限り
vectorのvectorとか愚の骨頂
頭ワルイ レコード作るたんびに激しいフラグメンテーションがおこるヒープをポコポコ作るとか
頭が超ワルイバカがやることです
よいこのみんなはココにいるバカなヤツラのマネはしないようにな はっきりいってな
行列ならvector1個で十分だからな
バカ以外にとっては常識 否定はしてない
行と列が可変な行列は
vector1個で十分といってる
m*nの列数の列を最初に先行してメモリアロケーションしたほうがいい
そのあとdata()で戻ってきたポインタつかっていじくり倒せばいい
とりあえず行毎にヒープを作る意味がまず皆無 すいませんめんどくさがりなんです。
一次元配列を二次元以上の配列に見せかける形にするという事か。
width * y + xみたいなアクセスね >>673 C言語オンリーのリナスとかめっちゃ有能やろ
言語習得能力と技術力はまた別の次元の話や トーパルズ君は孤高の天才だからな
同レベルでもなきゃチーム組んでもうまくいかなさそう array<array<int, 3>, 4> dimdim; 片方の長さが固定ならvector<array>でいいしだいたいそれで事足りる boostのmulti_arrayが標準ライブラリに入るのまだ? それぞれの用途ごとにクラスを作るのがいいのかもね
パフォーマンスを考えると パフォーマンスを考えると
の書き込みの後にパフォーマンス最悪なコードを貼る神経 アンカーも知らんのか w
お前になんてレスしてない 誰へのレスとか関係あるかなあ
初心者コードを貼る神経 鬱憤晴らししているんだろう
相手して欲しいだけだよ 機能拡張しろとか言う前に自分の頭が足りないのだから素直にJavaでも使うべき。
とくに自分でリソース管理できない馬鹿は。 >>717
だからお前にレスしたわけじゃねーからいちいち絡んでくるなよ、気持ち悪いわ 自分がコード貼らない言い訳してるだけだろ
気にすんな >>714のコードは[y][x]式の要素アクセスをしたいというだけのために
arraysクラスにarrayクラスのメンバを持たせているあたりがイヤソ
これがために、[y][x]式の要素アクセスがたとえリードアクセスであってもスレッドセーフでなくなる
パフォーマンスは>>702案と比べて言うほど悪くはないが、 言うほど悪くない?
悪すぎだろ
ボロいコンパイラだと特に パフォーマンスを気にするときは
乗算すら除きたいわけで >>725
ちょっ乗算なら>>702案にもwidth * y + xみたいなアクセスという形で含まれる件について:
widthを定数だとコンパイラが認識した場合は、単純な>>702案の方が最適化が効いてシフト演算なりになる可能性が高いが >>724
まあ、かなり無理矢理感があるのは事実
俺には他にいい方法も思いつかないけど
>>726
メモリーアクセスに対して乗算が問題になるケースってかなり減ってると思うけどな 画像を90度回すつもりで
for (py=0; py<height; py++) {
for (px=0; px<width; px++) {
dst[px][py]=src[py][px]
}
}
と書いたとしたら、ループ内ではwidth、heightともに定数とみなせるからループ最適化が効いて
dst、srcとも要素特定演算が加算のみになる可能性が微レ存、
この点>>702案に対して>>714のoperator[]はボロいコンパイラの場合は最適化機会を見逃す危険性は高いが
コンパイラからみてarrayに対する副作用がわからない関数呼び出しは含まれないから、原理的に最適化不可能というほどではない。 ていうかこれで良くね?
ttp://codepad.org/2sMvNgye >>729
何を言いたいのかさっぱり
>>733
だからそれでいいかどうかは>>689も書いてる通り要件による
メモリーが連続でないとヤダっていう要件があるかも知れんし ていうか>>706にすでに書いてあったorz
ただ行や列の追加をしたいという場合は>>706では済まなくて、相応のコピコンを備えた独自クラスでのwrapが多分必要
(データを引き継ぎつつ、異なる行数や列数のオブジェクトを新たに作るコピコンを設ける やっぱりな知恵遅れのバカどもはなにも分かってないわ。。。
演算処理で一番ボトルネックになるのはメモリアクセスだからな
高速な演算をしたいのにメモリをあちこちバラバラに配置する知恵遅れはいない
局所参照性を無視して乗算がどうこうといってるレベルだからな。。。
知恵遅れたちにはCPUのキャッシュという概念がない
vector1個のほうが
メモリフラグメンテーションもおきにくいし
このスレのバカどもがどうこういってる演算においても激しく有利だからな
良い子のみんなはこのスレのバカどもがいうことなんか
マに受けたりしたらダメだからな
オレの書き込みだけ信じればいい ttp://codepad.org/2sMvNgye
↑アホが書いた典型的なサンプル
良い子のみんなはマネしないようにな
こんなアホがいるというサンプルになってる
http://d.hatena.ne.jp/pknight/touch/20100330/1269945131
↑同じアホでもまだこっちのがマシ
あいかわらずオレのレスは
いつでも針の穴を通すようなカンペキなレスだ >>736
行列のrowを個別のstd::vector<T>とすることによる局所参照性の劣化は
ラスタスキャン順アクセスにおいて第i行から第i+1行に改行する時のみに限られる
(特にたまたま行列の横幅がキャッシュラインサイズの倍数でありかつ行がキャッシュラインに整列しているならば、何のペナルティーも生じない
ランダムアクセスならどっちもどっちになるからでかい配列の場合は言うほど気にしなくて良いんじゃ… パフォーマンス優先なら
メモリは連続
要素へのアクセスはシンプルに
[][] にこだわる必要はない
(x, y) や [座標] なども考える
乗算が遅い環境なら
要素数は2^nの形にするとか位置をキャッシュするとか
固定座標の処理で良いものはコンパイル時に決定出来るようにとか コンパイラをあてにするなら
生ポが一番最適化が効く
このスレだと拒否反応を示す人がいるだろうマクロを使うとか MTPでコンパイルタイムに押し込めー わぁい!
と、5,6年前にやったときは8x9行列ぐらいで
gccのテンプレート展開の限界になった記憶がある LINUXで15GBくらいのテキストファイルを読み込みこんでGUIを作ろうとしています。
ファイルが大きいため速度が出せる言語で、かつGUI作成は情報量が多いと調べやすいので、まあまあメジャーな無料のGUIライブラリを使用したいと思っています。
perl>>python>>>>C++ の順で経験があり、C++はあまり詳しくないですが、速度重視でC++で行こうと検討しています。
GUIライブラリを調べているのですが、C++のGUIはあまり情報を見つけられず、めぼしいのはQtくらいしか目に付きませんでした。
会社のサーバのローカルディレクトリにQtをインストールしてみましたが、必要なライブラリが古かったりで、インストールできませんでした。
他に何かおすすめなGUIライブラリはありますでしょうか? 公開しないならQtしかないしいつまでも古いライブラリを入れておくな GUIはTkライブラリをPerl/Pythonで作り、重い処理はC/C++プログラムとプロセス間通信と行うのがいいんじゃないですかね。 15gbのデータはguiでeditするの?
それともread onlyな入力データ? 15GBだと読み込みだけで分単位の時間がかかる
UIも難しい
巨大テキストからどうやって表示箇所を選ぶ?
スクロールバーとページめくりだけじゃ目的の箇所を探せないよ
行番号指定ジャンプ?
15GBだとメモリコピーでも秒オーダーの時間がかかるから
1文字入力するごとに後ろをずらすなんてことも出来ないから
データの持ち方も工夫しないと
そもそもメモリに収まりきるのか?
RAMは何ギガ? サーバーって事だから、いっそ使いやすい型式でDBに格納し、
Web画面で表示するっていうのはどうだろう
グラフィック表示はクライアント側に任せてしまう 全部で15GBのテキストじゃないの?
流石に1個で15GBは… 円周率のテキストファイルとかならあり得るか >>744-753
色々な情報ありがとうございます。
>>744
gccなど単体でインストールできるものはローカルディレクトリに最新をインストールしたのですが、
Qtに必要な何かのライブラリの最新版をインストールするのに文字コードがc.utf8が必要なのですが、
今はja_JP.UTF-8しか選択できず、新しい文字コードを使うにはrootでの文字コード再生成が必要なため全体への影響を考え一旦保留としています。
>>745,748
候補としてちょっと調べてみます。
>>746
PythonならCython+Kivyで直接取り込もうと検討しています。
その場合、CythonがどこまでC++の速度に迫れるかの調査から始める必要があるのですが…
少し調べたらCython内で直接C++コードを書ける云々とあったからそれだと速度はクリアできるのかなぁ?というところで一旦ストップしています。
これは深い話するとちょっとスレチな内容になってきますね。。
ちなみに今回作ったものをTCP通信で別のプログラムに接続して使用する予定です。
>>747
Read Onlyで読み込み時に演算したりarray、unordered_map、構造体などに放り込んだりして加工して取り込んだあとは参照のみです。
751さんの話は一旦形式をDBで保存しそれを参照ですが、それに近い感じで使いやすい形式に変換したものをメモリに格納し参照するイメージです。 つづき
>>749,750
固定フォーマットです。
メモリはサーバなので数百GBはあります。
>>752
1ファイルなんです。。
解析ソフトから出力された結果です。
>>753
mmapぐぐったらI/Oがネックなときに効果が期待できるものなんですね。
今調べてわかったところでは、
[1-1] fgetsのみ→30秒以下
[1-2] ・fgets, sscanf, fscanfを組み合わせてフォーマットに沿って読み込む→約5分
だったので、scanの変数格納が支配的になりそうなので、次は下記を調査しようと思っています。
[2-2] freadでバイナリで読み込んで空白、改行を判定しながら必要なところだけ文字列や数値に変換すると早いか?
[2-3] fgetcで空白、改行を判定し直接charに入れて行くと早いか?↓
char a[1024];
i=0;
while ( (a[i]=fgetc(fp)) != EOF){
if(a[i] == " "){
a[i] = "\0"; //\0を入れるとそこまでをcharの文字列として扱ってくれる??
break;
}
i++;
} あとは下記URLの「ファイルは一括で読み込め」の読み込み速度はどうかも調べてみる予定です。
ttps://qiita.com/kotauchisunsun/items/84e01c6fb621fcc1a647
それと下記も高速化のコーディングの参考にしようかと。
ttps://heavywatal.github.io/cxx/speed.html 読み込みと解析は別スレッド
解析はマルチスレッド
関数は専用化
AVXなどのリッチな命令を活用する
キャッシュを効率的に使う(何度も全体スキャンしない)
一般的な効率化技術 fgetc, scanf, printfのような激遅関数は使わない
ファイルは大きな単位で読み込む (MB以上) >>758をまずやって
>>757はそのあと考える 15GB 30秒ってことは
HDDから読んでるわけではなさそう
キャッシュかSSD まずは激遅でもいいからperlのGUIとDLL呼び出しで一通り動くものを作った方が良さそう メモリ数百あるんなら、展開した後のデータ構造工夫しろ。
数ギガ読めるテキストエディタを夢想してみれ。 コンバート系アプリだと専用端末だったりするしよくある まず固定長なら1行のバッファから読みこむだけの仕組みを作ってからの話になる
はっきりいって固定長のレイアウトに従って読みこむだけだからな
読みこみ処理の最適化なんかその後の話になる
固定長でなにをそんなに手こずってるのか意味が分からないしな
レコードのサイズはきまってるのに
fscanfとか書いてるということは末尾に改行が入ったレイアウトなのはなんとなく推定できる
レスを読んでもそもそも1レコードのサイズが何バイトなのか分かってて作ってるのかどうかすら怪しい
ファイルサイズをレコードサイズで割ってちゃんと整数になってるかとか確認してるのかどうかすらも怪しいからな
ファイルサイズだけ書いてレコード数すら書いてないしな
とにかく頭悪いヤツがしょうもないことで四苦八苦してるのは分かる 色々ご意見ありがとうございます。
まずは>>759さんのおっしゃるように、>>758さんのケアをしようと思うのですが、今のfgets+sscanfの組み合わせは下記URLを参考にしたのですが、
どれが激遅でどれが高速かの情報はどこかにあったりしますでしょうか?
(試そうと思っていたfgetcは遅いんですね…)
ttp://d.hatena.ne.jp/s-yata/20100726/1280138663
読み込み時に必要なのは、改行の判定、文字列の判定、int型で読み込んで0.025や0.1などを掛けてfloat型で保持(おそらくこれが一番多い処理)、と考えています。
ちなみに入力フォーマットは、ここから何行は文字列、ここから何行は数字の列(intに掛け算しfloatで保持したい)、という感じになっています。
最適な関数はどんな組み合わせが考えられますでしょうか?
STRING 2
AAA BBB
CCC
INT_TO_FLOAT 10
100 100 110 110
101 101 200 200
〜あと8行 知恵遅れはそれを固定長とかいってんのか
なるほどな
まず知恵遅れとは語彙の一致が成立してない 一行に存在する文字数は固定されておらず、文字列の方は文字数や空白は関係なしに単純に行数分読み込むだけで良いです。
数字の方も桁数は固定されていませんが、空白区切りの4カラムと固定されています。
STRING 3
This is pen.
hoge piyo
hello world.
INT_TO_FLOAT 9
12345 1000 10 12
101 101 999999 444
〜あと7行 1行目はisspaceでぐりぐり回して
SPを\0でおきかえればオシマイ
コレでバッファの先頭のポインタで文字列が拾える
行数は\0のポインタを1バイト分進めて
そのポインタをstrtolに渡せば拾える
2行目以降の数字は
strtolやstrtodで空白に到達したら、
その到達した位置のポインタが引数で拾える
数値も拾える
2行目以降の文字列は省略
池沼でも拾える
ここまで書けばどんなドカタでも作業はできるハズだ テキストのパースなんてそれこそperlやpythonにやらせろよ
そんなところが速度にクリティカルに効いててゴリゴリ高速化しなきゃいけないのは作りがおかしい >>768
質問者が固定長なんて書いてた?
固定長と言い出したのはあなたでしょ? >>767
読み込み以外、ライブラリなんか使わずに全て自分のコードにしてみようか
そうすれば色々とわかるはず
読み込みは16MBずつとかにすれば速い
出力先はファイル?メモリ上?
数値は32bit floatで保存するとして
文字列は?
そのままの形で使う?
読み飛ばす? >>772
お前何年前のゴミSEだよ
古代文字解析みたいな手法揚げやがって
lexical analyzer 系統使うだろ SQLite はメモリ上にDBを構築できるので試してみるのもいいでしょう。
起動時のテーブルの初期化が大変だけど、あとはサクサク。 な、知恵遅れたちはテキトーなことばっかりいってる
こんなゴミみたいなコードで速攻でかけるのに ゴミはめちゃくちゃしょうもない簡単なコードを
いちいち複雑にする
そしてもだれもメンテナンスできなくなる 数値の行は以下みたいなドロくさい処理を4回繰り返せば良い
unsigned int n = 0;
do {
unsigned char ch = (unsigned char)(*data++ - '0');
if (ch <= 9)
{
n = n * 10 + ch;
}
else {
break;
}
} while (true); だいたい分かるわ
やっぱりなPGなんか低学歴しかやらない 単に統計情報が知りたいだけならわざわざ重くしてから処理をする必要もないし
DBに入れるにしても解析しないとダメだろ たとえば1行目なんかこんなしょうもないのでとれる
int get_type(unsigned char const* buf, t_baka_type_t* pt_baka_type_t, unsigned char const** pct_next) {
unsigned char const* c_buf = buf;
for (; !isspace(*c_buf); ++c_buf) ;
if (!::strncmp((char const*)buf, TYPE_STRING, c_buf - buf)) {
pt_baka_type_t->baka_type = BAKA_TYPE_STRING;
} else if (!::strncmp((char const*)buf, TYPE_INT_TO_FLOAT, c_buf - buf)) {
pt_baka_type_t->baka_type = BAKA_TYPE_INT_TO_FLOAT;
} else {
fprintf(stderr, "氏ねヴォケ\n");
return -1;
}
pt_baka_type_t->u_records = strtoul((char const*)c_buf, (char**)&c_buf, 10);
++c_buf;
*pct_next = c_buf;
return 0;
}
はっきりいってな、2行目以降の数値も文字列もやりかたなんか同じだからな
ドカタ作業 ゴミは口だけは達者
しかもアリエナイ頭ワルイことばっかりいうからな わざわざ標準ライブラリを使うために小細工しなくても良いんじゃないの?
何がどういう順番で書いてあるかはわかってるようだし無駄に重くしなくても きっとなオマエが書いたゴミコードより標準ライブラリのほうが
バグもないし早いと思うわ いかにもバッファはみ出してそうなきったねえコードですね
いまどきポインタで文字列処理すんじゃねえよ老害 な、知恵遅れはこんなとこで書いたサンプルに
エラー処理が入ってると思ってる
もうねコレだから低学歴は困るわけ 日本のPGは低学歴しかいないのが
このスレで何度も証明されてる 低学歴に反応してるということは
図星なんだろ
もう分かってるからな
悪いけどなレスみれば低学歴なのは
残念ながらすぐに分かってしまう
低学歴特有のレスというのがある
隠そうとしてもムダ ポインタいじくり回してメモリ境界踏み壊すコードを書くのが大好きなすうぱあぷろぐらまあ様は
無駄な高学歴の方が多いという個人的な印象 あのレベルでポインタいじくりまわしてる?
どんだけオツムが弱いねん・・・ ようするにポインタが理解できてない
こんなのがプログラマさまきどってるのが日本だからな
そらなこんなのがコードいじくってたら
障害ばっかりおきるハズだわ 未だにこんな化石みたいなヤツが居たことに驚きなんだが >>786みたいに、何度も何度もスキャンするような無駄の多いコードが速いわけないだろ 低学歴は自分を大きく見せようとするからな
5f34-M0Jq ← コイツなんか典型的といっていい
わかってしまう
きっとコイツは専門卒
残念なことにレスみればすぐに分かる
だてにいままでいろんなゴミを相手にしてきたワケではない 何度もスキャン?
一回しかスキャンしてないぞ
まずコードがよめてない
ポインタは後ろにしか進んでないのに strncmpが中で何やってるか知らないんだねかわいそうに あ
もしかして
必要な1回の文字列判定を何度もスキャンとかいってるの? 低学歴によると
通常の字句解析と構文解析を一緒にするのか
なるほどな たくさんの情報大変参考になります。
サンプルコードもありがたいです。
実際に動かしながらどう動いているのか調べてみます。
>>775
読み込みを16MB単位でやってみます。
ファイルに出力することはなくて、読み込んだ情報をGUIでクリックして、
こっちをクリックするとこんな結果になっている、こっちだとこの結果、
というようなビューアを作ろうとしています。
文字列も重要な情報なので、
struct info{ それならそもそもファイル全体を解析しておく必要もないのでは? よしオマエはいい子のようだから
STRINGの部分をとるコードもあげよう
int get_data_string(unsigned char const* buf, t_baka_type_t const* ct_baka_type, unsigned char const** pct_next) {
unsigned char const* c_buf_b;
unsigned char const* c_buf_e = buf;
for (uint32_t i = 0; i < ct_baka_type->u_records; ++i) {
c_buf_b = c_buf_e;
for (; *c_buf_e != '\x0a'; ++c_buf_e) ;
// c_buf_b から始まる c_buf_e - c_buf_b の長さが取得する文字列
fprintf(stdout, TYPE_STRING":%.*s\n", c_buf_e - c_buf_b, c_buf_b); // ← ココでとれる
++c_buf_e;
}
return 0;
} >>786
入力が不正の場合にメモリフォルト起こすコードは絶対受け付けられない バリデーションチェックは自分で入れるにきまってるだろ
アホちゃうかコイツラ そういうレスしかできないからな
程度が知れるわけ
低学歴らしい いいわけ?
マジでいってるわけ?
ホントな頭悪い コードでも学歴でも何でも良いけど
勝負するなら受けるよ ハナクソは
学歴も書いてないし
コードも書いてない
で? 低学歴知恵遅れは
コミュニケーション能力もゼロに近い
そもそも唐突に
なにがしたいのか
なにがいいたいのか
意味が分からないワケ いまどき自前の字句解析処理をCでポインタ使って書くなんて
バッファ境界のチェックとか面倒だし絶対ミスるからやめた方が良いって話なのに
いきなりエラー処理完全無視したコード出されてドン引きです どんびきするとかしないとかは
オマエの勝手だからな >>821
ポインタも扱えないようなレベルならC++は使わない方が良い あんまりゴミだから自信満々なc1VUAguL0がコード貼ってるのに気が付かなかったな、ログ読み直しちゃったよ
学歴は書いてないみたいだけど >>820
勝負する気があるの?
ないの?
あるなら方法を決めるけど scanと解析に時間がかかるとかいってるから
オレはベストプラクティスをだしてる ベストじゃないと思うなら
ベストな方法はれよ
臆病者なんか 勝負に目的ねえ
まあ別にやらなくても結果はわかるけど やっぱりバカの限界というやつだな
オミヤゲだけはって寝よ
1行目とるヤツ
さっきとかわらず
int get_type(unsigned char const* buf, t_baka_type_t* pt_baka_type_t, unsigned char const** pct_next) {
unsigned char const* c_buf = buf;
for (; !isspace(*c_buf); ++c_buf) ;
if (!::strncmp((char const*)buf, TYPE_STRING, c_buf - buf)) {
pt_baka_type_t->baka_type = BAKA_TYPE_STRING;
} else if (!::strncmp((char const*)buf, TYPE_INT_TO_FLOAT, c_buf - buf)) {
pt_baka_type_t->baka_type = BAKA_TYPE_INT_TO_FLOAT;
} else {
fprintf(stderr, "氏ねヴォケ\n");
return -1;
}
pt_baka_type_t->u_records = strtoul((char const*)c_buf, (char**)&c_buf, 10);
++c_buf;
*pct_next = c_buf;
return 0;
} 2行目以降のSTRINGとれるヤツ
※ 次のバッファの継続ポインタの格納をしてなかったので追加
int get_data_string(unsigned char const* buf, t_baka_type_t const* ct_baka_type, unsigned char const** pct_next) {
unsigned char const* c_buf_b;
unsigned char const* c_buf_e = buf;
for (uint32_t i = 0; i < ct_baka_type->u_records; ++i) {
c_buf_b = c_buf_e;
for (; *c_buf_e != '\x0a'; ++c_buf_e) ;
// c_buf_b から始まる c_buf_e - c_buf_b の長さが取得する文字列
fprintf(stdout, TYPE_STRING":%.*s\n", c_buf_e - c_buf_b, c_buf_b); // ← ココでとれる
++c_buf_e;
}
*pct_next = c_buf_e; // ← たりなかったので追加
return 0;
} 2行目以降のTYPE_INT_TO_FLOATとれるヤツ
int get_data_int_to_float(unsigned char const* buf, t_baka_type_t const* ct_baka_type, unsigned char const** pct_next) {
unsigned char const* c_buf_e = buf;
int32_t i_val[4]; // とりあえずのテキトーにいれた一時バッファ
for (uint32_t i = 0; i < ct_baka_type->u_records; ++i) {
for (uint32_t j = 0; j < 4; ++j) {
i_val[j] = strtoul((char const*)c_buf_e, (char**)&c_buf_e, 10);
}
++c_buf_e;
fprintf(stdout, TYPE_INT_TO_FLOAT":%d,%d,%d,%d\n", i_val[0], i_val[1], i_val[2], i_val[3]); // ← ココでとれる
}
*pct_next = c_buf_e;
return 0;
} とりあえずのテキトーな宣言
#define TYPE_STRING "STRING"
#define TYPE_INT_TO_FLOAT "INT_TO_FLOAT"
typedef enum __ENUM_BAKA_TYPE {
BAKA_TYPE_STRING,
BAKA_TYPE_INT_TO_FLOAT,
BAKA_TYPE_UNKNOWN
} BAKA_TYPE;
typedef struct __tag_baka_type_t {
BAKA_TYPE baka_type;
uint32_t u_records;
} t_baka_type_t;
int get_type(unsigned char const* buf, t_baka_type_t* pt_baka_type, unsigned char const** pct_next);
int get_data_string(unsigned char const* buf, t_baka_type_t const* ct_baka_type, unsigned char const** pct_next);
int get_data_int_to_float(unsigned char const* buf, t_baka_type_t const* ct_baka_type, unsigned char const** pct_next); コレでとりあえず動かせる
int main(int argc, char** argv) {
unsigned char const* buf = (unsigned char const*)
"STRING 3\x0a"
"This is pen.\x0a"
"hoge piyo\x0a"
"hello world.\x0a"
"INT_TO_FLOAT 9\x0a"
"12345 1000 10 12\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a"
"101 101 999999 444\x0a";
unsigned char const* c_buf = buf;
t_baka_type_t t_baka_type;
// 実際の処理ではt_baka_type.baka_typeをswitchで分岐しながら処理することになる
get_type(c_buf, &t_baka_type, &c_buf);
get_data_string(c_buf, &t_baka_type, &c_buf);
get_type(c_buf, &t_baka_type, &c_buf);
get_data_int_to_float(c_buf, &t_baka_type, &c_buf);
} ろくなエラーチェックもしてないと自分で白状してるゴミコードを誰が動かすと思うのか 5chに貼ってしまった以上、権利的にジムしか動かせないなーw そこ突っ込むなら他にも色々あると思うが
なんでC++でtypedef struct/enumなの、とかなんで文字列がunsigned charなの、とか
メタプログラミングじゃない構造体の型名に_tとか付けるな、とか ざっと見たけどすごいスレだな
10年ぐらい前だったらこういうこともありかなって思った時期があるけど今はもうそんな時代じゃない
で大部分レスができてしまう 名前の付け方はどうせそれぞれの環境に合わせるだろうからどうでもいいけど
中途半端な最適化が良くないな
今回は用途もデータ構造もわかっているし
目的が高速化なわけだから >>842
多次元配列 (boostを使わない場合) は? ご連絡おそくなりすみません。
たくさんのサンプルありがとうございます。
今日はファイル読み込みの対応ができなかったので明日このスレを見ながら試してみようと思います。
ちなみにフォーマットはSTRING行が先にきて、次にINT_TO_FLOAT行がきます。
STRINGで始まり、INT_TO_FLOATで最後は終わります。
後出しの情報になり申し訳ありません。
>>786 でどっちが来るかの判定までしていただいていたので一応ご連絡しておきます。
STRING 2
This is pen.
hello world.
INT_TO_FLOAT 1230
100 100 110 110
101 101 200 200
〜あと1228行
STRING 5
hoge piyo
foobarbaz
It is a July 9 today
It rained all day today
INT_TO_FLOAT 830
100 100 110 110
101 101 200 200
〜あと828行 すみません、 >>849 のSTRING 5の部分は4行になってますね。
この場合 STRING 4 になります。。 作って実験してみたよ
一行に4個の数字がある行を
適当な数値を乗算して構造体のvectorに入れていく
ファイル上の位置も格納するので
間の文字列も必要な時に表示出来る
うちの環境だと
読み込みだけで77.9秒
解析だけで24.3秒
読み込みと解析合わせて78.1秒
アプリはシングルスレッドだけど
勝手にOSが先読みしてくれてるのかな?
読み込み単位は2次キャッシュに確実に収まる1MBくらいが良さそう STRINGとINT_TO_FLOATは何か関連性はあるの? 2次じゃなくて3次
struct LOG {
float num[4];
uint64_t line_start;
uint64_t line_end;
};
こんな構造体に入れていくようにしてみた
文字列はクリックした時にファイルを読みに行けば良いよね STRING n の後にn行文字列
INT_TO_FLOAT n の後にn行数値
これが交互にくる
ってことでしょ 数値に対応する何か(グラフ?)をクリックすると
その周囲の文字列と数値が表示出来れば良いのかな?
と思った 文字列の解析は速く出来そうだから
あとはUIに凝ってくださいな 数値も文字列も数行ずつかと思ったけど
1000行とかになるのか
数値ブロック、文字列ブロックは
それぞれ平均何行くらい? メモリが大変な事になりそうなのでstringとint_to_floatの行のアドレスだけ取得して、
必要になった時に読みに行ってintからfloatに変換すれば? floatの配列は別に用意して
struct LOG {
uint32_t str_start;
uint32_t str_end;
uint32_t str_line;
uint32_t num_start;
uint32_t num_end;
};
みたいな、
ブロックごとの構造体に入れていく方がいいのかな? vector<pair<size_t, size_t>> baka;//stringの開始位置とint_to_floatの開始位置をペアで管理。 適切なデータの持ち方はUIの全体表示の仕様次第と言うことになる >>806に対して反応が無いから
数値情報が事前に必要なのかと思ったが あと気になったのはGUIに表示するのはstringの一行目? 1ブロック平均500行
1行平均30文字
でも100万ブロックある
全体画面で文字列は表示しないんじゃ? 初回DBに突っ込む
初回レコードのインデックスを作る 最低限のパースを実施して各レコードのオフセットを配列に入れて必要になった時に解析して表示すればいいだけかと >>776
構文的に難しくも無いのにわざわざ遅くする理由がわからん…
ていうかそもそもlexとかyacc使いでも滅多に使わん希ガス
今回の文字列処理の件はワッチョイ 0780-Rmg1の圧勝 >>851
テストまでしていただいだきありがとうございます。
1分ちょっとならとてもいい感じです。
なるほどDRAMよりも高速なCPU内のキャッシュを有効に使うと効果的ってことですね。
そんなこと今まで考えたこともなかったです。勉強になります。
>>854
ご推察の通りです。
>>857
文字列の方はせいぜい10行〜20行です。
数値の方は何万行にもなったりします。
>>858
メモリは10GBつかっても問題にならないくらい潤沢に使えると思うので、まずは速度重視で行こうと思っています。
>>861,862
すみません昨日書き込みエラーになって書き込めなかったのでそのままでした。
クリックするたびに毎回int->float演算したら1項目で何万行もあったりするので
読み込み時に演算しておいた方がよいかなと思っていました。
>つづきます >>863
全部のフォーマットは複雑になってくるので簡易的なフォーマットをと思って出していましたが
説明していくと細かい話になってきましたのでもう少し具体的なものを書きます。
テストまでしてもらっているのに変わってすみません。。
-------------------------------
SECTION_NAME @
11200 11200 2 Jun 9 23:23:00 2018 A
This is pen. B
hello world. B
x 1 2 C
100 1 -2000 10
101 10 -2001 10
y 2 4
-100 10000
-101 10100
x 3 28
QQ subname -1 0 0 1 -21000000 600000 2 D
100 100 110 110
100 100 110 110
〜あと26行〜
SECTION_NAME E
@GUI表示する
A11200がx or yの個数、3カラム目がテキスト行の個数、それ以降は捨てる。11200のところは1の時もあれば100万超えることもある
BGUI表示する
Cこれが非常に多く、ひたすら繰り返される。x,yはランダムでくる。
1カラム目はx or y固定。x=次行に来る数値は4カラム。y=2カラム
2カラム目は1からインクリメントしていき、Aの11200回出てくる。カウント数値
3カラム目は次行から始まる数値行が何行かの数値
Dx or yの次の行にたまにこの行があります。この行も使いますが、ちょっと複雑なのでまずはスキップで。
Eここからまた@の繰り返し、要するにファイルの最後はCのところで終わる。
------------------------------- すみません、上記QQはQQという固定文字です。
行頭が"Q"のときはこの行という判定で良いと思います。
>>859,860
格納先は構造体に入れようと思っていて、下記のようにテキスト行も入れようかなと思っていました。
struct x_or_y{
char type; // x or y
int num; // Cの2カラム目
float list;
};
struct elem{
char section_name;
char comments;
array系の何かの型 x_or_y_array; // 配列にしておくと(Cの2カラム目-1)で簡単にアクセスできそう
}; なんかのログなんだろうけど、ログ吐く時に読み込みやすいように出し方考え直した方がいいよ
大本が変えられないならパイプ繋いでフィルタ噛まして、読みやすいように直したファイルを並行して吐くとかさ
というかまず単にSECTION_NAMEごとにファイルぶった切っておくだけで良かったりしない?難しく考えすぎてない? どういうGUIが必要なのかわからんから的外れかもしれないけど
ワイならSECTION_NAMEごとに集計したHTMLファイルかなんかを出力するプログラムをワンパスかけてから
後でそのHTMLをブラウザで見ることを考えたくなるんだけどそれじゃダメなの? >>869
> 今回の文字列処理の件はワッチョイ 0780-Rmg1の圧勝
>>851の圧勝
>>851は0780-Rmg1みたいな遅いコードとは違う >>871
UIの表示内容はどういう感じを考えてる? A
1カラム目と2カラム目は同じ数字?
1カラム目がxの個数、2カラム目がyの個数?
C
y 2 4 の後、データ行が2行だけど4行の間違い?
データ行の値の範囲は? 初めて開くファイルは使いやすいように変換して(キャッシュとして)保存しておいて
次回以降それを使うか
全ファイルバッチ処理で事前に変換しておくか
かな
ファイルを開く度に分オーダーかかるのは使いづらい
どちらが良いかは使い方次第で 15GBオーダーのファイルがすでにいつくかあって
今後も増えるってことで良いんですよね? >>873,874
ソフトが出しているログなので変えられず、並行で吐くこともできないんです…
> ワイならSECTION_NAMEごとに集計したHTMLファイルかなんかを出力するプログラムをワンパスかけてから
これも考えたのですが、元ファイルと加工したファイルが常に等価ではないので、
間違って古いままの加工ファイルを参照する事故を、全員が気にする必要が
出てくるため今は保留とし、どうしてもできない時の最終手段と考えています。
こういうご意見も新しい視点が見えたりするんでありがたいです。
>>877
こんなのをイメージしています。
====================
項目名 | 個数 ※各カラムの説明行
====================
-SECTION1 | 11200
subname1 | 8800 ※subnameがあれば折り畳みツリー形式。なければ折り畳みなし
subname2 | 2400
+SECTION2 | 1
+SECTION3 | 666
====================
This is pen. ※SECTION1を選択するとそれに対応するテキストをここに表示
hello world.
====================
1 2 3 4 5 6 7 ※上と同じくSECTIONに対応した数値を特定できる番号を表示
8 9 10 11 12 13 14 ※ここはHTMLぽいものにし、数字クリックでその数値をprint
....
==================== >>878
> 1カラム目と2カラム目は同じ数字?
2カラム目が何の数字かまだ把握できていません。
とりあえず1カラム目と2カラム目の数値比較を行い、違う場合はエラーにしようと思います。
> y 2 4 の後、データ行が2行だけど4行の間違い?
ご指摘の通り4行の間違いでした。
> データ行の値の範囲は?
intの範囲を超えるか?ということですか?
int(-2147483648〜2147483647)で大丈夫と思います。
>>879
ユニークな名前で重複しません。
>>880
仰る通りどちらも一長一短で、今回は874さんに回答した通り、古いキャッシュを参照する事故を防ぐため、まずはテンポラリファイルを作らないことを考えています。
>>881
ファイルは毎回更新されて新しい15GBのファイル1つをインポートします。
15GBも現在のMAXサイズなのでそのうち20GBとかのものが出てくる可能性はありますが、
そこは「読み込みをひたすら待つ」と割り切りで考えています。
>>882
@の行→100行以下
Aの行→SECTIONごとに1行出るので同じく100行以下
Bの行→SECTIONごとにせいぜい20行程度。(20行*100行=20000行)
Cの行→SECTIONごとにたまに数千万のSECTIONあり(全SECTIONだと数千万〜億超えも出てきそう)
1つのSECTIONで数千万や億になり、それ以外のSECTIONは1000以下だったり、
1千万のSECTIONが複数SECTIONになることもあります。
そしてCに対して数値行が1行〜数十行、場合によっては数百行がくるので、Cとそれにかかる数値行が支配的になると思われます。
あと忘れていましたが、テキスト行は日本語がくることもあります。
それ以外は1byte文字です。 キャッシュせず
変換して保存しないとなると
ほとんど読み込み時間
解析はそれに比べれば速い
なので
もし高速化したければ
全読みしない方法を考えるしか
全読みの時間くらいは待てるっていうならその方が簡単だけど
読み込み15GB 30秒って異様に速いな
うちの8TB 7200rpmのHDD(内側の方) だと78秒
SSD? RAID? キャッシュ? RAMディスク? >>885
HDDだと思います。
サーバ用なので高速なんですかね。
ちなみに cat /proc/cpuinfo でCPUも調べたらXeonで20コア以上ありました。
(ハイパースレッドかもしれませんが)
〜次キャッシュも民生用CPUより多いと予想されます。 >>885
あと、全読みの時間は >>851 を参考にすると2分くらいにはなりそうなので、それくらいなら全然待てます。
fgets, sscanfの時は5分かかっていて、それで我慢するしかないのか、と諦めかけていたので。
評価もscanfもしないでfgets()だけで78秒なんですかね?
大きな違いはCPU、CPU内臓キャッシュ、HDD、メモリあたりと思いますが、それだけで本当に半分以下になるのか少し気になりますね。 とりあえずみなさんのコードを眺めましたが初めて目にする関数だらけで自分のレベルでは全くついていけてないです。
一つ一つの関数がどんな動作をするのか調べていきます。
>>782,833 を見るとcharのポインタをインクリして読むやりかたとか昔ちらっと読んだことある。程度のレベルなので。。
今833-837の動作確認ができたので、まずはこれがどう動いているかと、バイナリ読み込みの手法について調べていきます。 >>887
fgetsじゃなくて
freadで1MBずつ読むだけで78秒
庶民の普通のHDDはこんなもんです
解析入れてもほぼ同じなので
読むのに30秒なら解析入れても30秒で終わるよ
もちろんうまく作ればだけど ここはC++スレだからstd::regex使いなよ
>>833よりは速いし安全だぞ 速いわけが無い
コードを書いて時間を測ってみなさい sscanfが遅くてなんとかしたい
っていう話題なのに
DBだとかhtmlだとかregexだとか
頭がおかしいのが多いな 何度も表示させたいなら、解析結果をDBに格納しておくというのもいい方法だと思うが
事前にできるなら、見かけ上の実行時間も節約できるんだし エアプ野郎が多いからねこのスレ
何の意味があるのかは知らんが DBって要望がチャンと出てくる前の話だろう
サーバーで動かす位しか条件書いて無かったぞ >>892
ループごとにregexオブジェクト作り直して時間測ってりゃ遅くなるわな
あれは使い回すもんだよやり直し うん、regexよりはspirit::qiだよね
ワッチョイ a781-UVFsは的外れにも程がある
そしてそれ以前にregexもspiritもC++初心者に勧めるようなものではない 要件が全部出ていたわけじゃないのに
エスパーが登場して的当てたのか?そりゃスゴイな >>743の時点で低レベルな記述が適していることくらいわかるだろ
15GBのテキストだぞ 遅いから早くしたい
どんなに頑張っても無理なら
遅くてもよい仕組みにするという手もある そもそも最初のフォーマットと全然違うやんけ
普通にfgetsでとって、必要最低限の位置をマーキングするほうが
メモリに入れるのはそれだけ
位置からメモリブロックをとって、>>834>>835みたいなやりかたで表示が必要になったときに解析 そもそも解析アプリが出力してる規定されてるフォーマットなのに
いちいち形式をチェックする必要すらない
ホントな知恵遅れはなにをいってんのか意味不明だからな
クソニートのエアプログラマがテキトーなことばっかりいってんのは分かる スケジュールを開始するボタンに名前をつけたいけどいい名前が思い浮かばない
できれば6文字以内で
開始とか実行はダメ ちなみな
fgets()は知恵遅れのキミラが考えてるよりぜんぜん速い
このスレの知恵遅れが書くようなクソコードより全然速い
書式付の標準関数は書式解析のオーバーヘッドがあるからクソ遅い ちなみにな手で入力したときは
fscanfやsscanfは使えない
書式より引数が少ない場合簡単に死ぬからな
手で入力してるデータの場合fgets()でデータとって丹念に解析するしかない
つまりfscanfやsscanfの使用も想定する=間違いなく妥当な形式の入力がある
ことを意味する 同じ事を何度も書かなくて良い
>>758
あとfgetsよりfreadの方が速い
当たり前ですが メモリブロックとるときは
普通にfreadでいい
どうせ改行位置は解析しないといけないから
fgetsにやらせとけばいい
知恵遅れはTPOにあった関数の使い方がわかってないからな 知恵遅れはなにをどういった場面で使うのか分かってないからな
そもそも話がかみあうワケがない
知恵遅れにありがち
電車みて電車の型番いえるだけみたいな頭悪いのが
このスレにはウヨウヨいる わざわざ改行検索だけの為にメモリスキャン
ガチガチにチューニングするつもりならあり得ないですね 適度なチューニングで妥協するんであれば
fgetsで良いかも知れませんが freadで読む時間とほぼ同じ時間で解析まで終わるので
中途半端な解析で止める必要もなくて
直接使いやすい形にすれば良い
あとは>>885 >>889
なるほどですね。
解析入れてもあまり変わらないのか。
scanfって本当に遅いんですね、嬉しい誤算です。
話題に出ているregexですが、↓ここを見た感じ、
ttps://www.sejuku.net/blog/25962
下記のように感じました。
perlやpythonの正規表現と似た感じなので使えるかもしれません。
1文字づつシフトしてスペースや改行を判定しながら抽出するより早いのであれば試して見ようと思います。
regcomp →正規表現オブジェクト?の作成。()でグループ化。読み込み前にすべてのフォーマットパターンを生成して使い回す。
regexec →正規表現オブジェクトを使ってパターンマッチ
rm_so、rm_eo →マッチの先頭、終端が取れるので文字列が拾える。こんな感じ?→strncpy(&str, data+match[i].rm_so, match[i].rm_eo - match[i].rm_so);
regfree →読み込み終了後にすべてのオブジェクトをこれで開放すればいい?
spirit::qiはググりましたがまったくわかりませんでした。。 15GBともなると
関数を呼ぶ時間でもトータル時間に影響するんでね
fgetsの関数コール回数だってバカにならんでしょ
全てのfloatをvectorにpush_backするだけでも
結構な時間ですよ
この辺も工夫しないと 正規表現なんか使ったらコンパイル済の正規表現でも
クソ遅いにきまってるやんけ
そんなもん使うならスクリプトでやったほうがいい >>922
だからregexもspiritも使わなくていいってばw
すでに実例出してくれてるような昔ながらのC言語的な書き方でいいと思う
まともな実例も示さずに「○○使え」は無視していいよ ちなみに gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0 だと、 C++がちゃんとしてて、std::getline()はfread()と同じくらい速い。
各自で実際に試してみるとよいだろう。
Visual Studio だとstd::getline()はfgets()よりも遅い。
コンパイラによって性能に極端な差がでるのがC++のiostream周り。iostreamが地雷扱いされる主因。 15GB なんて、もし画像ファイルなら、触った途端に、メモリ不足でフリーズするレベル。
普通、8GB ぐらいしか、メモリを積んでいないだろ
1行毎に、読んでは捨てる方式じゃないと無理。
それか、ファイル分割する
Ruby で、HTML, Node.js などが良さそう。
それか、DB >>871のフォーマットでC++で作ったら
解析15GBで8.6秒
1バイト平均2クロック!
これを越えるには
マルチスレッド / AVX命令 /アセンブラ / GPU
に手を出さないと無理かな
----
Haswell
3.4GHz固定
シングルスレッド
C++で1文字ずつ15G文字解析
普通の命令のみ使用(SIMD命令は使用しない)
数値の合計のみ計算して結果を最後に表示
固定4KBを繰り返し解析、トータル15GB分の時間を計測
---- 1ブロック内に数値が数万あってどうUIで表示すんのか気になる 数値ならグラフにするとか画像にするとかフィルターを通してから間引くとか音声にして鳴らすとか
まあ色々とあると思う >>926
おとなしく1文字づつ評価します。
>>933
8.6秒早いですね。
自分はまず初バイナリ読み込みなので勉強から始めてとりあえず1行読みができましたが、
アスキー読み込みのfgetsの方が早かったです、、
コードを載せるのでどこが悪いか見てもらって良いですか?
対象=13GBのファイル(約8億行)。
○fgets版 →約17秒
if((fp=fopen(file_path,"r"))==NULL){
printf("file not open %s\n", file_path);
return 1;
}
while( fgets(buf,MAX,fp) != NULL ){
buf;
}
次にバイナリ読み↓ ○バイナリ読み版 →約44秒
struct CCC {
FILE *fp ;
bool read(char* file_path);
t_read_db read_db;
};
bool CCC::read(char file_path[]){
FILE *fp;
if((fp=fopen(file_path, "rb"))==NULL){ printf("ファイルを開けません。%s",file_path); return 0; }
unsigned char buf[BUF_SIZE];
int newline_index;
while( !feof( fp ) ){
size_t size = fread( &buf, sizeof(buf[0]), sizeof(buf), fp );
// 終端処理。最大値で取得されてなければそこを末尾にする
if( size != BUF_SIZE ) buf[size] = '\x00';
// 取得bufの最後尾が改行でなければfpを改行まで戻す
if( buf[size-1] != '\x0a' ){
newline_index = -2;
for(; buf[size+newline_index] != '\x0a'; --newline_index);
fseek(fp,newline_index+1,SEEK_CUR);
// bufの最後の改行の次にx00(null)を入れてそれ以降をカット
// 「配列参照はポインタの移動より遅い」とあったがbufは実体で移動できないので[]参照で代入。
buf[size+newline_index+1] = '\x00';
}
unsigned char const* c_buf = buf;
while( c_buf[0] != '\x00' ){
print_line(c_buf, &c_buf);
}
}
} bool print_line(unsigned char const* p_buf, unsigned char const** pct_next);
bool print_line(unsigned char const* p_buf, unsigned char const** pct_next){
unsigned char const* c_buf = p_buf;
//改行位置を検索
for(; *c_buf != '\x0a'; ++c_buf);
char line[LINE_SIZE];
strncpy( line, (char const*)p_buf, c_buf - p_buf );
// nullで区切らないと過去に代入した文字数より少ないときにゴミが残る
line[c_buf - p_buf] = '\x00';
++c_buf;
*pct_next = c_buf;
return true;
}; ○fgets版 →約17秒
○バイナリ読み版 →約44秒
両方ともとりあえず文字列の読み取りまでしていて、条件は同じではないかと思うのですが、freadのほうが倍以上遅いです。。 >>935
fgetsで悩んでる人がそのハードル超えることできるか心配してるんですよ すみません、44秒はfreadの読み込みサイズ(BUF_SIZE)が512byteでした。
16MBにすると34秒になりましたが、それでも倍の差があります。 >>942
mmapがいるかなぁ
BSD grep のソースのコメントにこの辺りの高速化の
コツが書いてあるので一読されたし >>943
mmapですか。
要チェックですかね。
でもそれだけで数倍早くなるとも思えないし、 >>933 さんの8.6秒は圧倒的パフォーマンスですね。
シングルスレッドで特殊なものは使ってないようだし、たった4KBの繰り返しだし。
根本的なところから違いそう。。
>>933
もし可能であれば、テストしたコードを見せていただくことはできませんでしょうか? あのな
そこまで読みこみ速度を気にするなら
そもそもFILEポインタ使う関数なんか使うなよ
そもそもFILEポインタ使う関数はバッファリングしてるから
いちいちメモリコピーしてんのに
そこまでガタガタいうなら
openとreadで普通にメモリブロック読みこむ処理にしろよ
ハゲ >>940,941
setvbufも初耳です。
941さんのコメントからすると、これまた難しそう。。
色々と情報ありがとうございます。 ちなみになFILEポインタは構造体にファイルデスクリプタもってる
fopenでopenを呼び出してファイルディスクリプタ生成して構造体に保存してる
ファイル読むときはファイルディスクリプタでread使ってバッファリングしながら読みこんでる
このスレの低学歴どもはこういう基本的なことわかってんの そのsetvbufというのが
バッファリングするバッファのサイズだ
つまり、バッファにたまったメモリをひたすらコピーしてる 32bit越えるmmapとか
そんなやばそうなもん使うのか
まずちゃんと動作するか確認することになるわ 休日にオレのエレガントなファイル読みこみ処理作ってやるから
楽しみにしてなさい HDDの一番外側15GB
セクタ直読みで60.1秒
平均 250MB/s でした
7200rpmの8TBのHDDです >>851の77.9秒はHDDの内側の方でfreadでの読み込み
どちらもHDDの限界と思います >>944
解析時間のほとんどが>>782のようなコードです
ちょっと変えましたが 改行を探す為だけにスキャンする必要はありませんし、コピーする必要もありません
ほとんどをしめる数値の行は
>>782の処理で区切りまでポインタが進みます >>951
ありがとうございます。楽しみにしています。
>>933,952,953
解析と読み込みを分けているんですね、8.6秒は解析で、読み込みがHDDのハード限界の60秒(高速な外側)、77.9秒(低速な内側)。
そこで >>851 の読み込み、解析合わせると78.1秒でほとんどがHDD律速ということか。
>>954,955
ご説明ありがとうございます。 >>782 の動作を調べてみます。
freadの扱いで質問なのですが、byte単位で取得すると最後尾が改行ではなく途中で終わることがあるので、
改行区切りになっているdata変数がだと思って、937に書いたコードでは、自分がわかる知識で考えて、
freadで読み込んだあとに改行のところまでfseekで戻しているんですが、この考え方はあっているのでしょうか? data変数がだと思って →×
data変数が必要だと思って →○ >>952
すみません、あと、 >>936 に書いているfgets版のコードだとどれくらいの速度が出ていますでしょうか?
fgetsで回したものと fread + >>782 のコードでどれくらいの比率になるのか気になりました。 MS製の金毘羅でfgets(), fgetc()を試す場合は、_CRT_DISABLE_PERFCRIT_LOCKS 必須で。 無能な働き者が書いた半角スクリプトなんて誰も走らせたくない >>956
読み込みの境目の処理方法はいくつかあります
A. 1行全体が連続してバッファに存在しなくてもいい作りにする
B. リングバッファ
C. fseekでファイルポインタを戻してから読み込む
D. あまりをmemcpyでバッファの先頭にコピーしてから読み込む
E. ほか
読み込み単位が大きければ C. or D. のコストは無視出来るので C. D. で
読みこみ単位が小さければ A. B. なども考える
といった感じかと思います
今回私は解析処理が簡単に作れて、HDDの読み込みに一切影響を与えない、D.で作りました >>958
fread
fgets
ReadFile
読み込みだけだとどれも78秒 >>959
ttp://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-8.1.0/gcc-8.1.0.tar.xz
これを使ってるので、まずはMSのオプションは関係なさそうです。
でもMSのコンパイラは早いという記事をこの前読んだのでそっちの方に乗り換えた方がいいのかな。
完成した後に両方テストして良好な方を検討しようと思います。
>>962,963
A,Bは難易度高そうですね。
Cは自分がやった手法のようですが、Dはポインタを戻す分の再取得が無いのでCより良さそうに見える。
Dを検討してみます。
fgetsもfreadも同じ時間ですか。
となるとfgets 13GB 17秒だから、そのレベルの速度は出るはずなのか。
今782のコードを調べて動作がわかってきました。
char演算で文字コードを数字の始点に移動させ9以下で数字以外(スペースor改行)を判定。
*10で桁を表現し、文字コードの番号で演算。(文字→数字変換していない!!)
このファイルで支配的な数字行が文字→数字変換が一度もないおかげですごく効きそう。
原理がわかるとなるほど!となるけど、1桁ずつ演算、文字コード演算は自分がやってたら絶対にたどり着かない発想です。 text/byte stream は異なる。
文字列はバイトじゃなく、テキスト
バイトは構造体など、構造が決まっているもの
改行区切りで、改行の位置が変わるものは、テキスト処理 通信データなどは、可変長構造体
ヘッダーなどは固定サイズで、データ部分は可変サイズ。
可変部分のサイズが、ヘッダーなどに書いてある >>969
C99なら規格化されたのでgcc拡張は要らなくなった C99の可変長配列はC++には取り入れられなかったし、
C11ではオプションに格下げされたんじゃなかったっけ?
年式でフラフラする機能の典型例のような記憶がある。 >>971
可変長配列(VLA)については、そのとおり
しかし >>970 >>969 で指しているのは、構造体内の 0 長配列メンバ、または C FAQ 2.6 >>971
VLA のことと誤解してないか?
ここで言ってる「可変長構造体」は構造体の最後の要素が不完全型であることを許すルールのことだと思う。
struct a {
int a;
int b[];
};
このとき sizeof(struct a) は要素 b を含まない大きさを返す。
malloc(sizeof(struct a)+(bの大きさとして確保したい大きさ)) とすれば b が可変長な構造体として使える。
このルールが出来る前 (C89) は仕様に沿ってこのようなことをしようと思うと
配列 b の大きさを便宜上 1 として指定しておく、
つまりは
struct a {
int a;
int b[1];
};
としておいて malloc のサイズ指定のときに要素一個分の大きさを差し引いて調整するようなことをしていた。 すまん、皆の言う通りだ。ちゃんと読めば
構造体の末尾メンバの0サイズ配列の話だと分かる流れだったのに、
なんでか裸の配列の要素数だと思いこんでしまった。 GCC拡張をしたとして
struct a {
int b[0];
};
のsizeof(a)はいくつなんじゃろうか… >>977
ゼロが返ってきたぞ。
ただし、 C/C++ におけるオブジェクトはメモリの一部を占有するものでありポインタで示せるものという要求があるので、
それと矛盾なく使うには色々と気を付けないといけないかもしれない。
ちなみに、クラスのメンバにストレージを割り当てないこと (要するにサイズゼロのオブジェクト) を許す [[no_unique_address]] という属性が C++20 で追加されてる。 そんなクソみたいな使い方しかされない機能入れるなよ。。 複数回allocateを抑制するための機能(関数)はc++にもたくさんあるじゃない >>979
非staticなメンバを一つも持たない上、そのクラスのポインタを扱わない(=多態性を必要としない)のに
継承したりメンバとして持ったときに1バイト追加されるのがうざいからだろ >>978
ええー!!!
struct c {
};
のsizeof(c)は1だった(と思った!)が!! 最適なプログラムを書く必要のない立場の雑魚は黙ってろよw >>981
static なメンバしかない、しかもポリモルフィズムしない(interfaceな使い方でもない)
ってそもそも継承するのが設計として間違いじゃねーの? c++つかってるとロジックやアルゴリズムなどの本来の目的より
こういう横道にそれた話題ばかりになることが多い
手段が目的化するので困る 関心の集中の先はプログラムで実現できることになるべきだけど
c++はそっちより言語自信や仕様や実装に目が向く
時間が無駄に費やされやすい 最適なプログラムを書くのもC++の目的だ
ロジック以外のことに目をそらしたいなら他の言語を使え c++は幅広い書き方ができてしまうのが一番困ったところ
10年前のコードが完全に動いてるにも拘わらずゴミに見えてしまう >>984
非staticなメンバが無い、ってのはメンバ変数ね(非staticなメンバ関数はあっても関係ない、つまりインターフェースも含む linuxと聞いてた(>>743)のになんでMSのコンパイラの話がでてんねんと
まず実機でコレ走らせて試験をしなさい
@ 下のソースをコンパイルしてbaka_testという名前の実行オブジェクトをつくりなさい
linuxなら↓こっち
https://ideone.com/e9iA5m
windowsなら↓こっち
https://ideone.com/D4T1zh
A で、こんな試験をする
https://ideone.com/82BnFZ
ちなみにwindowsはバッファサイズを
セクタバイト数の倍数でないとちゃんと動作しない
それはwindowsの仕様だからな(メモリアドレスはmallocで返ってくる先頭のポインタオフセットで問題ないことは分かってる)
バッファサイズを何バイトにするのが読みこみで効果的か
決めたほうがいい
試験結果をちゃんと報告するようにな
あとOSは64bitでいいんだな
それによっても話がかわってくる ちなみにwindowsでopenとかread使うのはクルクルパーだからな
msのランタイムがウンコなのは有名だからな
msウンコランタイムのopenでCreateFile呼び出してる
msウンコランタイムのfopenでopen呼び出してる
msウンコランタイムのreadでReadFile呼び出してる
msウンコランタイムのfgetsやfreadでread呼び出してる
わかった? >>993
ありがとうございます。
g++ -o baka_test $file_name
echo 512,`./baka_test $input 512` > baka_result.txt
echo 1024,`./baka_test $input 1024` >> baka_result.txt
〜
上記を13GBのファイルで試したら下記結果が出ました。
512,13
1024,7
2048,5
4096,3
8192,2
16384,2
32768,2
65536,2
131072,1
262144,3
524288,2
1048576,2
2097152,2
4194304,2
8388608,2
16777216,3
33554432,2
67108864,3
134217728,3
268435456,3
536870912,3
1073741824,3 これは一度に読み込むサイズは4KBを超えると速度に影響はなく、
>>962 のC,Dパターンの場合だと、最低1行分のバッファが必要なので、
その場合、一行のバイト数のMAX値で決めれば良い。
ということでしょうか? どんだけ速いHDDやねん。。。
すでにキャッシュされてんのか
その13とか7とか5とかいう数字は
ディスク読みこみ(ディスクの内容をバッファにコピー)にかかった時間は秒だぞ
ちゃんとコード書いてmsecにして計測したほうがよかったのかもな
暇だったら、シェルで精度の高い計測値だせるように工夫しなさい
数十秒はかかると思ってたからmsecなんか考えてもなかったわ
で、実機のOSは64ビットでいいのか
ここ結構重要だからな すみません忘れてましたlinux 64bitです。
> 128Kで2秒かからない
これのことですね。 →131072,1
昨日の夜(今日の朝5時)までやって >>962 のCパターンでようやく一通りファイルを
読み込めるようになりましたが、やはり速度が出ていません。
13GBファイルで確認
fgetsのみ解析なし →17秒
freadで各文字列解析、数値行の演算を行ったもの →1分超え
コード書いてて気になる箇所がいくつかあるので質問しようと思ったけどもう1000になりますね。
次スレで質問させてもらいます。 なんかよく分かってもらえてないようだが
この値はブロックで読みこむ固定のバッファリングサイズ
1行分とか関係ない
プログラムではきっと
バッファリングされたメモリを解析することになる
とりあえず今回は、必ず128K単位で読みこむ
128K単位のメモリを
正直もっと増やしてもいいとは思う
あととりあえず行の最大バイト数は256バイトで十分でいいや このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 36日 16時間 10分 3秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。