- 1 名前:デフォルトの名無しさん mailto:sage [2018/03/31(土) 20:20:06.25 ID:o3PNwIlC0.net]
- 次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part134 mevius.5ch.net/test/read.cgi/tech/1516406742/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 mevius.5ch.net/test/read.cgi/tech/1509780815/ ■長いソースを貼るときはここへ。■ codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ www.bohyoh.com/CandCPP/FAQ/ (日本語) VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
- 248 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 22:09:13.69 ID:oFP/MhUD0.net]
- シングルコアのPCかも
- 249 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 22:17:20.63 ID:1ikED9ud0.net]
- pthread使うとひとつの処理が倍速にでもなると思ったのだろうか
- 250 名前:片山博文MZ mailto:sage [2018/04/23(月) 22:21:51.35 ID:ATy8dQXfd.net]
- 不完全な質問はスルーすっと
- 251 名前:デフォルトの名無しさん [2018/04/23(月) 22:42:58.69 ID:7US5BnQm0.net]
- 舌足らずですみません。コードはこんな感じです。
threadFunctionは単なる加算値、joinFunctionは集計処理です。 コアは物理2論理4です。 template< class ArgType > void Reduce( std::vector< ArgType >& threadArgs, void* (*threadFunction)(void*), void (*joinFunction)(std::vector< ArgType >&) ) { const size_t threadCount = threadArgs.size(); threads.resize( threadCount ); std::vector< void* > voidPtrArgs = CastArgsToVoidPtrs( threadArgs ); for ( int threadIndex = 0; threadIndex < threadCount; ++threadIndex ) { sched_param schedParam; schedParam.sched_priority = sched_get_priority_max( SCHED_FIFO ); pthread_attr_t threadAttribute; pthread_attr_init( & threadAttribute ); pthread_attr_setschedpolicy( & threadAttribute, schedPolicy ); pthread_attr_setinheritsched( & threadAttribute, PTHREAD_EXPLICIT_SCHED ); pthread_t& thread = threads[ threadIndex ]; pthread_setschedparam( thread, schedPolicy, & schedParam ); pthread_create( & thread, & threadAttribute, threadFunction, voidPtrArgs[ threadIndex ] ); } for ( int threadIndex = 0; threadIndex < threadCount; ++threadIndex ) { pthread_t thread = threads[ threadIndex ]; pthread_join( thread, NULL ); } joinFunction( threadArgs ); }
- 252 名前:デフォルトの名無しさん [2018/04/23(月) 22:45:44.01 ID:reOPAGg30.net]
- >>243
この世界では、何かやって思い描いてたようにならなかった場合 まず自分の能力不足を疑うのが鉄則
- 253 名前:デフォルトの名無しさん [2018/04/23(月) 22:51:38.20 ID:reOPAGg30.net]
- >>248
アハハハハ!ジョークのつもりかなんか? そうじゃないならjoinの動きを勉強しろ
- 254 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 22:53:42.39 ID:voecBiJS0.net]
- 釣り針デカいな
- 255 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:14:39.42 ID:gZ/aKTVF0.net]
- いまだに関数ポインタ使ってるのか。野蛮人。
std::functionってスレッドセーフじゃないの?
- 256 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:18:02.49 ID:YIxEn5Qs0.net]
- いまだ関数ポインタが使いこなせないんだけどやばいかな?
- 257 名前:デフォルトの名無しさん [2018/04/23(月) 23:20:18.71 ID:reOPAGg30.net]
- 考えたらjoinの問題じゃないか
もし「単なる加算処理」が1スレッドでメモリ帯域使い潰していたらマルチスレッドにしてもどうしようもないのは明らかだよ
- 258 名前:デフォルトの名無しさん [2018/04/23(月) 23:21:31.95 ID:reOPAGg30.net]
- >>253
未だに関数ポインタなんて使ってるほうがやばい
- 259 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:30:05.62 ID:1JtTwXqR0.net]
- 画像処理で合成処理をパラメータでもらう場合があるんだが
その場合内部処理と対応させるために関数ポインタは使うが そういうのもダメ?
- 260 名前:デフォルトの名無しさん [2018/04/23(月) 23:35:26.41 ID:reOPAGg30.net]
- ダメってわけじゃないけどさあw
C++ならもっと柔軟性のあるやりかたが幾らでもあるってこと
- 261 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:36:21.76 ID:lnjW6wzS0.net]
- virtual関数もラムダ式も関数ポインタ
- 262 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:40:33.42 ID:awXEdMZR0.net]
- std::byteが邪魔すぎるんですけどg++で無効にするオプションってありますかね?
- 263 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:50:59.76 ID:9sQDUnnSM.net]
- >>257
あんた昨日のおじいちゃんだろ。 functionの時代もとっくに終わってるぞ。 autoとlambdaで関数ポインタを使うべき。
- 264 名前:デフォルトの名無しさん mailto:sage [2018/04/23(月) 23:51:42.53 ID:gZ/aKTVF0.net]
- >>258
ライブラリ制作者でもなければ関数ポインタなんぞ触らんよ。 よほどCとの兼ね合いが無いと。
- 265 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 00:06:39.75 ID:qFc5rpEV0.net]
- >>248
threadcountいくつになってるの?
- 266 名前:はちみつ餃子 mailto:sage [2018/04/24(火) 00:06:56.48 ID:VhsA5JFS0.net]
- 忘れがちなことだが std::function は実行時の型を扱う。
画像処理などのようにヘビーな繰返しがあるような場面では関数ポインタを使った場合との間に深刻な速度差が生じることもなくはない。
- 267 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 00:16:24.07 ID:qFc5rpEV0.net]
- >>248
関数名からして、一度のreduce処理量は大したことなくて、何度も繰り返し呼んでない? thread処理に必要な処理量が相対的に無視できなくなってるんじゃね? スレッドは4本に制限して、各スレッドが処理する量を増やすかスレッドプール式にしては?
- 268 名前:デフォルトの名無しさん [2018/04/24(火) 00:17:16.38 .net]
- C++だから関数ポインタ使わないとか頭おかしい
関数ポインタのほうが高速かつシンプルに書けるならそちらを選択すべき
- 269 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 00:20:31.80 ID:N5/L/OXI0.net]
- 皆富豪ばかりではない
- 270 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 00:26:04.88 ID:RoXKv00p0.net]
- 富豪かどうかはおま環だろ
だから自己申告しないヤツが悪い なんでこっちがエスパーみたいなことしなきゃいけないんだ わたくしは教えないがあなたがわたしの環境を忖度しろってか? ヴァカじゃねえの? アフォに対してちゃあんと「テメーのスペックはいかほどですか」と尋ねろクズ 富豪かどうかはわからない、それを言わない人間がまず間違い、 それを逆手にとって相手をマウンティングするアフォがいるから話が進まない
- 271 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 00:38:30.68 ID:Sy+ZRJzm0.net]
- 関数ポインタの構文の方がかっこいいだろ!
- 272 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 00:47:04.42 ID:hfyVIq8IM.net]
- どんなスペックだろうと他のソフトがどれだけメモリや処理時間を喰い潰していようと自分の処理はサクッと終わらせたいといつも思う
- 273 名前:デフォルトの名無しさん [2018/04/24(火) 01:40:17.33 ID:2n4xWLsG0.net]
- >>260
へんてこりんなマウンティングするやつだなあ ちなみに昨日なんて俺書き込んでないからw
- 274 名前:デフォルトの名無しさん [2018/04/24(火) 03:16:15.83 ID:CsMI0xmD0.net]
- >>248
調べてみたけどさっぱり判りません。 pthread_joinで各スレッドの終了を待って、その後、集計処理をするというのはごく渡り前の処理に見えるのですが、 何が行けないのでしょうか? 別の方法でスレッドの終了を待たねばならないのでしょうか? 自分勝手デスミア線が、具体的に問題点、改善点を指摘して下さいm(_ _)m。
- 275 名前:デフォルトの名無しさん [2018/04/24(火) 03:31:10.06 ID:2n4xWLsG0.net]
- いいから「単なる加算処理」全部見せろよこの包茎野郎
- 276 名前:デフォルトの名無しさん [2018/04/24(火) 03:56:33.85 ID:CsMI0xmD0.net]
- threadFunctionが、
void* CalcBasicStatics( void* threadArg ) { BasicStaticsThreadArg* arg = reinterpret_cast< BasicStaticsThreadArg* >( threadArg ); double interva
- 277 名前:lOfX = arg->intervalOfX;
double x = arg->dividedRangeOfX.start; double sumOfY = 0.0; double sampleCount = 0; const sc::Sampler& f = arg->f; while ( x <= arg->dividedRangeOfX.end ){ double y = f( x ); sumOfY += y; sampleCount++; x += intervalOfX; } arg->sumOfY = sumOfY; arg->sampleCount = sampleCount; return nullptr; } joinFunctionが、 void CalcBasicStaticsJoin( std::vector< BasicStaticsThreadArg >& args ) { double sampleCount = 0.0; double sumOfY = 0.0; for ( int i = 0; i < args.size(); ++I ) { sumOfY += args[ i ].sumOfY; sampleCount += args[ i ].sampleCount; } for ( int i = 0; i < args.size(); ++i ) { // 結果を書き込み BasicStaticsThreadArg& arg = args[ i ]; arg.average = sumOfY / sampleCount; } } です。細々すみません。 [] - [ここ壊れてます]
- 278 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 05:46:22.80 ID:vHj8ybNt0.net]
- そのコード見ても
並列度もスレッドあたりのサンプル数も 1サンプルあたりのコスト(f)もわからないので まるで意味がない 2または4並列で、1スレッドあたり1〜10Mサンプルくらい処理するようにすれば 速くなるか少なくともスレッドを使わない場合より遅くならないと思う 同じ速度ということはメモリ帯域が律速なのかもね
- 279 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 05:46:49.67 ID:vHj8ybNt0.net]
- 同じ速度
↓ スレッドを使わない場合と同じ速度
- 280 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 05:55:18.81 ID:vHj8ybNt0.net]
- fでメモリのどっかから数値を読んでいるんだと思うけど、
これがなるべく連続したアクセス(局所化を謀る)になるようにループを構成できれば速くなるかもしれない。 この辺りはググれば色々参考になるページがあると思うが いまググッたらそれらしいページがあったので書いておく myoga.web.fc2.com/prog/cpp/opti02.htm 仕様として外からfが与えられるなら無理な話かもしれない。 もちろん interval が 1 で f(x) が { return v[x]; } のような最適なケースよりは速くならないので その辺りは無駄な努力をしないよう測っておきましょう。
- 281 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 06:54:08.05 ID:RDzdLFpT0.net]
- fの中身が公開出来るなら公開して
複数あるならそのうちの1個でいいから あと、 1回のthreadFunctionで何個くらいfを計算する?
- 282 名前:デフォルトの名無しさん [2018/04/24(火) 09:24:50.43 ID:jHZYDUEYd.net]
- >>250
joinについて勉強しろとか偉そうに言ってたのは何だったの
- 283 名前:デフォルトの名無しさん [2018/04/24(火) 18:12:35.67 ID:2n4xWLsG0.net]
- >>278
こりゃ「多分」joinの問題じゃないなと判断して>>254を書いたんだが これくらいのコンテキスト読めないとマルチスレッドは無理だよ
- 284 名前:デフォルトの名無しさん [2018/04/24(火) 18:15:41.14 ID:2n4xWLsG0.net]
- fやら具体的なargsの内容やら処理時間測定のやりかたも記述されてないし
んなもの誰も答えられるかよ
- 285 名前:デフォルトの名無しさん [2018/04/24(火) 18:32:28.83 ID:6+u8wIQpd.net]
- >>279
違う違う なんで明らかに間違えてる事を偉そうに述べられるのかと聞いてんだけど 読解力もスキルもないのか
- 286 名前:デフォルトの名無しさん [2018/04/24(火) 18:41:27.90 ID:2n4xWLsG0.net]
- >>281
本当に「明らかに」だと思ってるの?バカですか?
- 287 名前:デフォルトの名無しさん [2018/04/24(火) 18:45:24.94 ID:cOEBcXkN0.net]
- サンプルレベルのJoinの使い方をみて
「アハハハハ!ジョークのつもりかなんか?そうじゃないならjoinの動きを勉強しろ」 は流石に笑ってしまう
- 288 名前:デフォルトの名無しさん [2018/04/24(火) 18:47:53.38 ID:2n4xWLsG0.net]
- 勝手に笑ってればw
- 289 名前:デフォルトの名無しさん [2018/04/24(火) 18:49:15.43 ID:Z9G2Fq/Ha.net]
- cin で、個数の決まっていない整数たちを読み込みたいのですが、どうすればいいでしょうか?
整数たちの個数 n が分かっていれば、以下のように読み込めばいいですが。。。 vector<int> v; int i; for (int i = 0; i < n; ++i) { cin >> i v.push_back(i) }
- 290 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 18:59:54.20 ID:lGEjd9Z7M.net]
- >>282
明らかにだろどう見ても。 何をどう勘違いしたのか
- 291 名前:説明してくれよ。 []
- [ここ壊れてます]
- 292 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 19:02:18.64 ID:of0BgjlM0.net]
- >>285
他に入力がないなら cin.eof() で入力の終了を検出できるよ。 cin のブール演算を使ってもいいけど、どうにも慣れなくてね(個人の見解)。
- 293 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 19:15:13.81 ID:Z9G2Fq/Ha.net]
- >>287
ありがとうございました。 別の質問なのですが、一般的に、vectorの使用頻度というのはどれくらいでしょうか? 配列でやれることもすべて vector を使ってやるという人は多いでしょうか? それとも、効率などを考えて配列で極力済ませるという人が多いでしょうか? もちろん、ケースバイケースでしょうけれども、そのあたりの常識がないので、大体 どんな感じなのかが知りたいです。
- 294 名前:デフォルトの名無しさん [2018/04/24(火) 19:17:35.43 ID:Z9G2Fq/Ha.net]
- 自分としては、効率など細かいことは考えずに、vectorを使って問題ない
場面ではvectorを使うという風にしたいのですが。。。 vectorを使っても速度などの点で問題ない場合、一般的なプログラマーなら どうするのかが知りたいです。
- 295 名前:デフォルトの名無しさん [2018/04/24(火) 19:20:20.45 ID:Z9G2Fq/Ha.net]
- vector<int> v;
int n; cin >> n; int t; for (int i = 0; i < n; ++i) { cin >> t; v.push_back(t); } int *p; int n; cin >> n; p = new int[n]; for (int i = 0; i < n; ++i) { cin >> p[i]; } どちらにするのが普通なのかの常識がありません。
- 296 名前:片山博文MZ mailto:sage [2018/04/24(火) 19:30:42.86 ID:Eukzbh8yd.net]
- >>290
生のnew/deleteは、なるべく使わないのがいい。delete忘れ、例外などでバグの元や維持コストになる。
- 297 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 19:33:20.39 ID:Z9G2Fq/Ha.net]
- >>291
ありがとうございました。 ということはできるだけvectorを利用したほうがいいということでしょうか?
- 298 名前:片山博文MZ mailto:sage [2018/04/24(火) 19:36:23.45 ID:Eukzbh8yd.net]
- >>292
動的にサイズが変わらないなら配列かstd::array。 動的にサイズが変わるならstd::vector。
- 299 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 19:38:54.99 ID:t8t5TswZ0.net]
- >>290
上だったらv.reserve(n)しておこう
- 300 名前: mailto:sage [2018/04/24(火) 19:42:04.62 ID:B3J+xNmy0.net]
- >>289
私は書き始めは std::vector を専ら使っており、後で他のコンテナに換えています
- 301 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 19:46:25.46 ID:UxTdQ3KXd.net]
- >>293
コード読めないの?
- 302 名前:片山博文MZ mailto:sage [2018/04/24(火) 19:51:37.43 ID:Eukzbh8yd.net]
- >>296
普通の人間なら、文脈を読み取れるけど、俺はコンピューターに近いんだ。
- 303 名前:はちみつ餃子 mailto:sage [2018/04/24(火) 20:04:19.79 ID:VhsA5JFS0.net]
- >>289
実用上の問題が無いことがわかっている範囲内であれば、 深く考えずに vector だけで乗り切るのも悪い選択じゃないと思うよ。 ただ、使い分けることで意図を表現しやすい。 たとえば list を使っていれば要素の挿入や削除が頻繁なデータなんだなって思うし、 array が使われていれば要素の個数が固定なんだなって思う。 速度的に影響がない程度の規模であっても、 それが適しているような操作をこれからするのだという意思表明は人間がプログラムを読むときのヒントになる。 そして、そういうヒントは書いている途中にこそ必要なものなので、 >>295 のように後から整理していくスタイルは個人的には好きじゃないな。
- 304 名前: mailto:sage [2018/04/24(火) 20:22:55.46 ID:B3J+xNmy0.net]
- >>298
>それが適しているような操作をこれからするのだ うーむ、いろいろと考えさせられます std::vector でなら使えても、std::list では使えない、というのはあるから、最初からそれを考慮しておくのは…よくありますねえ
- 305 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 20:43:20.11 ID:Ukt80uX+0.net]
- vector は list に比べた場合、
データがメモリ上隣接して並んでいるので →そういう引数を要する
- 306 名前:e種 API にそのまま渡せる
→メモリアクセスが局所的にできてキャッシュが効く 予約領域を拡張する場合にのみアロケータが呼ばれるので追加時のアロケータによるオーバーヘッドが低い とかの良い特性もあるので要素のコピーが軽くて個数が小さいものはvectorにして損することは少ない [] - [ここ壊れてます]
- 307 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 21:34:54.87 ID:JVcrtulg0.net]
- BidirectionalIteratorとRandomAccessIteratorだろ
規格用語で言えば短く済む
- 308 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 22:35:44.34 ID:iCiOyu8i0.net]
- std::listはメモリ局所性がないので今どきのマシンだとクソ遅い
積極的に使う理由は基本的にない
- 309 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 23:33:49.11 ID:RDzdLFpT0.net]
- 積極的にって...
使いどころで使うための物だよ
- 310 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 23:51:07.95 ID:z/eaD8m90.net]
- メリットとデメリットを見極められないとコンテナを使いこなすのは難しい
昔から配列を弄り倒している古参にとってはこんなに便利な物はないと思うがね 90年初頭辺りにタイムスリップして実際に構造を真似てフルスクラッチでテンプレートなんぞなかった世界で組んでみればコンテナの挙動は自ずと理解できると思うが時代がわるかったな 今は何も苦労しなくても容易になんでも手に入る世界だからな 修業が足らんよ青二才
- 311 名前:デフォルトの名無しさん mailto:sage [2018/04/24(火) 23:55:55.63 ID:iCiOyu8i0.net]
- >>303
その使い所がよほど特殊な状況以外にないんだよ
- 312 名前:デフォルトの名無しさん [2018/04/24(火) 23:58:59.30 ID:4OXNJpQB0.net]
- 大規模C++ソフトウェアデザインという本を読んでいます。
冗長インクルードガードが紹介されているのですが、効果あるんですかね。 古めの本なのですが、最近のコンパイラだと意味ないですかね
- 313 名前:>>306 mailto:sage [2018/04/25(水) 00:13:26.67 ID:2lHeUIKm0.net]
- ir9.jp/prog/ayu/datlog/tech_cpp/1149427282/1149427282_04.html
ここの967以降に同じ質問がありました。質問撤回します。
- 314 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 00:14:20.28 ID:MdUECE2K0.net]
- #pragma once って規格化されたんだっけ?
- 315 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 01:03:31.17 ID:YD2+CY860.net]
- されてない
しようしようと20年言われ続けて技術的な問題でできずにいる
- 316 名前:デフォルトの名無しさん [2018/04/25(水) 02:07:21.83 ID:/kuz3CrQ0.net]
- 243です。
アドバイスを頂き検討したのですが、メモリが散らかっているのが原因と判断しました。 都合により細々とした実装の話は割愛しますが、付き合ってくれた皆さんありがとうございました。
- 317 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 02:33:10.54 ID:wwssDiVV0.net]
- どおりで未だに警告でるわけだ
- 318 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 06:26:59.61 ID:8qaCWrbS0.net]
- >>305
その特殊な状況の為にlistが存在する 私の場合は特殊なプログラムを書くことが多いので 使いどころは多いのかもしれない また、普通の組み込みC言語でも簡易な片方向リストとかを使ったりする (C++じゃないのでlistは無い)
- 319 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 07:15:49.01 ID:ntbHaYzVM.net]
- >>309
技術的な問題ってなに? 既に実装してる環境の方が多くね?
- 320 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 07:30:39.44 ID:kzCoHflQa.net]
- 今はモジュールの方を標準化しようとしてるんじゃ
- 321 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 08:47:25.49 ID:wwssDiVV0.net]
- 偉い人が考えてることはわからん
- 322 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 11:24:32.26 ID:iscLTfMY0.net]
- >>313
プリプロセッサは C++ じゃないからね C++ 以外の言語と共有しているツールなので それらと歩調を合わせる必要があるし プリプロセッサだけ独立の規格にするなら C++ を含め、諸
- 323 名前:言語の規格も
プリプロセッサのバージョンとどう付き合うのか 策定せにゃならん [] - [ここ壊れてます]
- 324 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 12:23:57.05 ID:ntbHaYzVM.net]
- >>316
意味わからん C/C++の規格にプリプロセッサの仕様もあることを知らんのか? そもそも他の言語と共有してる環境なんて見たことないし
- 325 名前:はちみつ餃子 mailto:sage [2018/04/25(水) 15:37:25.53 ID:7Yqb38x00.net]
- 現行では、 #include ディレクティブは「対象ファイルの内容がそこに書かれているかのようにふるまう」という規則なので、
ヘッダファイル内のプラグマ (#pragma once) の解釈が始まるのはインクルードされた後になる。 もちろん対象範囲がコンパイル単位全体に及んでしまっては #pragma once の意味がないが、 現状の仕様に辻褄を合わせるとそうなる。 実装した処理系がもうあるんだから実装に沿うように規定しなおすってことはできなくは無いんだろうが、 #pragma once を仕様に入れるのに #pragma once の項目を追加すれば済むわけではないってことは理解してくれ。 それと、プリプロセッサの仕様は C/C++ の一部なのは確かだが、 挙動を規定しきれていないのじゃないかということは指摘されている。 https://qiita.com/ruiu/items/4d471216b71ab48d8b74#3%E6%9C%8817%E6%97%A5 うやむやでやってきてるところを整理する必要は有ると思う。 >>317 Haskell (GHC) は C プリプロセッサを使うよ。 汎用的に使いたいなら M4 とかの方がいいとは思うけど、 Cプリプロセッサに慣れている人は多いから……。
- 326 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 16:38:46.53 ID:iscLTfMY0.net]
- また別な話
#includeしようとしているファイルが 過去に#includeしたファイルと同一かどうか という判定も意外に厄介だね ハードリンクできるファイルシステムと そうでないファイルシステムがあったりするし ハッシュが一致しても衝突かどうかの問題もある
- 327 名前:はちみつ餃子 mailto:sage [2018/04/25(水) 18:09:25.23 ID:7Yqb38x00.net]
- ハードリンク、シンボリックリンクが無いファイルシステムだったとしても、サーチパスの問題も思いつくな。
たとえばカレントディレクトリと、カレントディレクトリ直下の foo ディレクトリからヘッダファイルを探すようになっているとき、 #include "bar.h" と #include "foo/bar.h" は同じファイルを指しているが、表現が異なる。 同一のファイルとして除去すべきだろうか?
- 328 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 19:34:37.54 ID:ch3bizaad.net]
- #if ****
#pragma once #endif とかどうなるの? 複数回のインクルードで条件がちがっていたら?
- 329 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 20:33:35.69 ID:ntbHaYzVM.net]
- >>318
> 実装した処理系がもうあるんだから実装に沿うように規定しなおすってことはできなくは無いんだろうが、 規定すればいいだけだろ? どこに技術的な問題があるんだ? 政治的な問題だと言うならまだしも >>319-320みたいな話は処理系定義ですむ話 >>321は少し悩ましいがそもそも途中まで読んでから#pragma onceとか言われても面倒だから書くならファイルの最初に書けとかの制限をつければいい > 挙動を規定しきれていないのじゃないかということは指摘されている。 いやいや、その子ちゃんと規格読めてないだけでしょ w > Haskell (GHC) は C プリプロセッサを使うよ。 仕様を流用してるだけでしょ? 何かのコンパイラと共有してるわけじゃないと思うが
- 330 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 20:43:06.43 ID:YD2+CY860.net]
- 君よりよっぽど賢い人達が20年間悩み続けて未だに出来てないことを舐めない方がいい
- 331 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 21:22:23.29 ID:ntbHaYzVM.net]
- >>323
別に悩み続けてなんていないでしょ w #pragma onceで事足りてるからわざわざ政治的なことに足突っ込みたくないだけ
- 332 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 21:47:31.85 ID:YD2+CY860.net]
- 新規格の季節になると毎回のように標準化委員会の議題に上がってるんだが?
- 333 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 22:20:34.77 ID:fPsUNFh1a.net]
- モジュール方式になったらヘッダファイルが要らなくなる?
- 334 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 22:28:42.99 ID:iscLTfMY0.net]
- >>322
> 処理系定義ですむ話 それはおかしいでしょ ハードリンクできる処理系からできない処理系に移植したtarボールの #includeの挙動が未規定なら結局インクルードガードを自前で書くことになる
- 335 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 22:48:43.95 ID:7S1PATFb0.net]
- >>325
でも誰も進めようとしないんだろ w よくある話 >>327 C/C++ ってそういう言語だしそもそも環境変える予定があるならそんなものに依存したファイル構成にしないでしょ
- 336 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 22:55:12.61 ID:eMzyfy/H0.net]
- #pragma once なんて
once upon a time だぜ 今はもうだれも気に留めてやしねぇ
- 337 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 23:31:56.94 ID:iscLTfMY0.net]
- アホの相手は疲れたわ
もう寝る
- 338 名前:はちみつ餃子 mailto:sage [2018/04/25(水) 23:46:14.09 ID:7Yqb38x00.net]
- >>322
トピックとして大きすぎるので面倒くせえってだけの話。
- 339 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 23:50:29.61 ID:ayqRGoGD0.net]
- #pragma once
ぐらいPerlでインクルードガードに自動変換できる、 ていうか無くてもできるから自前で書くとかありえん…
- 340 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 23:51:29.73 ID:ayqRGoGD0.net]
- むしろプリコンパイルヘッダーが規格化されないの方のが悩ましい…
- 341 名前:デフォルトの名無しさん mailto:sage [2018/04/25(水) 23:58:40.94 ID:7S1PATFb0.net]
- >>330
逃げるなら黙って逃げろよ w
- 342 名前:デフォルトの名無しさん mailto:sage [2018/04/26(木) 00:10:34.39 ID:0UXBsrps0.net]
- ていうか#pragma onceとか#ifdef〜#endifによるインクル〜ドガ〜ドのシノニム以外の何者でもないと思うが
一方#ifdef〜#endifによるインクル〜ドガ〜ドは 「対象ファイルの内容がそこに書かれているかのようにふるまう」 という規則の下で立派に機能していると思うし、 >>321のように等価な#ifdef〜#endifによるインクル〜ドガ〜ドが存在し得ない場合はエラーにしたら良いと思うし、 ハードリンクできる処理系かどうかに関係なく#ifdef〜#endifによるインクル〜ドガ〜ドは機能していると思うし (だいたい1バイナリのビルド中にハードリンクの中身が変わるみたいな想定をする方がおかしい=ハードリンクはそうでないファイルと区別がつかないとみなせるハズ だったら#pragma onceも問題なく規格化が可能なのでは… 少なくとも技術的な問題とかとうていナッシング?
- 343 名前:デフォルトの名無しさん mailto:sage [2018/04/26(木) 00:21:25.86 ID:44bF0Q7g0.net]
- ちょっとはググれよ。
お前みたいなやつを「殆し」って言うんだぜ
- 344 名前:デフォルトの名無しさん mailto:sage [2018/04/26(木) 00:41:00.06 ID:0UXBsrps0.net]
- ↑ググってもボンクラが書いたような駄文が見つかるだけなので却下。
1. #pragma onceは#ifdef〜#endifによるインクル〜ドガ〜ドのシノニムである 2. #ifdef〜#endifによるインクル〜ドガ〜ドは世の中で立派に機能を果たしている にもかかわらず、 3. #pragma onceの規格化の有効な解が存在しない という驚くべき結論がなぜ導かれるのやろうか…
- 345 名前:デフォルトの名無しさん mailto:sage [2018/04/26(木) 06:29:49.76 ID:IAeApo/t0.net]
- インクルードガードを自前で書くたびに
毎度毎度ワンパターンでタイプ数だけは結構多い不毛な作業は 機械化できないかと考えるのは至極当然 むしろ何の疑問も持たないやつは適性に疑問符がつく インクルードガード用のフラグマクロの命名則にも不安がつきまとい 無名namespaceのように衝突しない保証があったらなあと思ったりもする
- 346 名前:デフォルトの名無しさん mailto:sage [2018/04/26(木) 07:22:21.59 ID:4xU9Va0kM.net]
- 要するに同じファイルであるかをどうやって判定するかの問題
インクルードガードは利用者(プログラマー)に識別子を決めさせる(押し付けたとも言う)ことで実現してる なので押し付けられたプログラマーには > インクルードガード用のフラグマクロの命名則にも不安がつきまとい みたいなことが発生する #pragma onceはこの判定を処理系側でやるんだが例えばファイルの絶対パスで判断するとかファイルをインクルードする前にmd5とかのハッシュを求めて判断するとかすればいいだけ ハードリンクとかで違う名前つけて#pragma onceがうまく動かないとか言うアホとかは無視すればいいし、ハッシュの衝突が心配と言うなら衝突した時に比較するようにすればいい どういう仕様がいいのかで揉めるのはあるけど技術的な問題とか言ってる奴はちょっと知能が足りなさすぎ
- 347 名前:デフォルトの名無しさん mailto:sage [2018/04/26(木) 07:42:18.98 ID:n/ljx3l20.net]
- >>338 #ifndef 形式のインクルードガードを自前で書くとタイプ数が多いし
識別名を打ち間違える危険もあるから .h のファイルを新規作成したときに 自動的に入力されるようにエディタのマクロにしたよ。 まぁ、識別名をファイル名から作ってるから、ファイル名の変更でアレだけど。 昔(フロッピーでやってた時代?)は #ifndef 形式でガードすると どのみちヘッダファイルをまるごと読み込まなきゃならないから、 #pragma once の方がコンパイル時間において優れてる、などと言ったけど、 ハッシュを計算して同一か検証するとか手間が増えるなら 時間の面での優位性はなくなったのかな。
- 348 名前:はちみつ餃子 mailto:sage [2018/04/26(木) 09:45:48.32 ID:P0bCzIha0.net]
- 「技術的な」というときの技術は「プログラミング技術」の意味じゃないこともあるんだよ。
前置きが無い限り広すぎてあんまり意味ない。 実装がいくつもあるのに、仕様策定にあたっての言葉で出てくる「技術的な」なんだから文脈でわかれよ。 仕様に落とし込む難しさが元々の論点。 ハードリンクの話題は「同一のファイルとは何か」を定義する難しさの一例で、実装のことなんか言ってない。 このスレで既に上がっている選択肢だけでも ・ 内容が同じ ・ 絶対パスが同じ ・ #include ディレクティブ中の表現が同じ ・ inode が同じ (ハードリンクは同一とみなす) があり、内容の一致を選択する場合以外は言語の外の世界の環境に関する記述が必要になる。 世の中にある色んな環境のことを考慮して文面にする難しさってのはわかるだろ? そんなわけで、個人的には内容の一致だけで判定するのが (仕様として定義するにあたって) 一番簡単だと思う。 ODR に関するルールの中にも同じトークン列を要求するものがあるし。 それに加えて >>318 で取り上げた展開手順の規則をなんとかする必要はあるが、 >>321 に解を与えるような上手い簡単な規則は思いつかないな。 既に多く書かれてしまっているコードの現状との互換性を考えると >>322 のいうような、 #pragma once を書ける場所を制限するような規則は選択できないと思う。 結局は複雑なものにならざるを得ない。 そんなのほっといてモジュールの導入に邁進しようぜっていうのは妥当な方針だろ。
|

|