C++相談室 part135
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。 !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part134 http://mevius.5ch.net/test/read.cgi/tech/1516406742/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 http://mevius.5ch.net/test/read.cgi/tech/1509780815/ ■長いソースを貼るときはここへ。■ http://codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ http://www.bohyoh.com/CandCPP/FAQ/ (日本語) VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured >>338 #ifndef 形式のインクルードガードを自前で書くとタイプ数が多いし 識別名を打ち間違える危険もあるから .h のファイルを新規作成したときに 自動的に入力されるようにエディタのマクロにしたよ。 まぁ、識別名をファイル名から作ってるから、ファイル名の変更でアレだけど。 昔(フロッピーでやってた時代?)は #ifndef 形式でガードすると どのみちヘッダファイルをまるごと読み込まなきゃならないから、 #pragma once の方がコンパイル時間において優れてる、などと言ったけど、 ハッシュを計算して同一か検証するとか手間が増えるなら 時間の面での優位性はなくなったのかな。 「技術的な」というときの技術は「プログラミング技術」の意味じゃないこともあるんだよ。 前置きが無い限り広すぎてあんまり意味ない。 実装がいくつもあるのに、仕様策定にあたっての言葉で出てくる「技術的な」なんだから文脈でわかれよ。 仕様に落とし込む難しさが元々の論点。 ハードリンクの話題は「同一のファイルとは何か」を定義する難しさの一例で、実装のことなんか言ってない。 このスレで既に上がっている選択肢だけでも ・ 内容が同じ ・ 絶対パスが同じ ・ #include ディレクティブ中の表現が同じ ・ inode が同じ (ハードリンクは同一とみなす) があり、内容の一致を選択する場合以外は言語の外の世界の環境に関する記述が必要になる。 世の中にある色んな環境のことを考慮して文面にする難しさってのはわかるだろ? そんなわけで、個人的には内容の一致だけで判定するのが (仕様として定義するにあたって) 一番簡単だと思う。 ODR に関するルールの中にも同じトークン列を要求するものがあるし。 それに加えて >>318 で取り上げた展開手順の規則をなんとかする必要はあるが、 >>321 に解を与えるような上手い簡単な規則は思いつかないな。 既に多く書かれてしまっているコードの現状との互換性を考えると >>322 のいうような、 #pragma once を書ける場所を制限するような規則は選択できないと思う。 結局は複雑なものにならざるを得ない。 そんなのほっといてモジュールの導入に邁進しようぜっていうのは妥当な方針だろ。 >>339 みたいに独善的なやつは標準化委員に向かないタイプだね 提起された問題を個人的に考えるのがイヤだから却下とかやってたら みんなやる気なくすし >>341 > 「技術的な」というときの技術は「プログラミング技術」の意味じゃないこともあるんだよ。 そういう人がいるからわざわざ「政治的」って言う言葉を入れてあるんだが理解できなかったのか? で、あんたの言う技術的な問題ってなに? 具体的に書いてくれ >>342 > >>339 みたいに独善的なやつは標準化委員に向かないタイプだね > 提起された問題を個人的に考えるのがイヤだから却下とかやってたら 意味わからん 俺が提示した内容がダメだと言うならもっといい案を提示すればいいだけ こんなスレで独善的とか頭大丈夫? 提示してねえだろ、おまえは無視つったんだよ 嘘つくんじゃねえ >>345 私はこの件について、技術的な問題があるとは述べてない。 その箇所の後に技術的という言葉は広範すぎて (言い換えれば、具体性がないので) 意味ないという意味のことを書いてるつもりなんだが。 それとは別に、私の考える問題を端的に言うと仕様の文面に落とし込むのは難しいねっていう、そんだけのこと。 >>348 現時点での問題点をはっきりさせることに意味はあると思いますよ… >>346 理解できないなら絡んでくるなよ w 「アホな利用者は相手にしない(=無視する)」って言う仕様を「提示」してるって話だ、ボケ >>350 スレチ 意味があると思うなら他にスレ立ててやれ >>351 科学技術的な議論にアホなんて用語を使うあたりお里が知れるな 形容詞には比較基準や単位をつけろボケ 俺は>>339 が正しいと思うぜ。 というか>>341 は明確に間違ってるだろ。色々と。 「ハードリンクガー」なんてのは論外。規格で定めるべき事項ではない。 規格で定めるべきなのは、 ・全く同一の中身だが実体が異なる場合でも #pragma once は有効か? (cp A.h B.h の場合にも B を読み込むか?) だ。そしてこれは当然現行のインクルードガードと同じ方向に揃えるべきであり、 ・読み込んではいけない という仕様になるのも自明だ。 絶対パスやinodeやハードリンクというのは、 ・通常のファイルシステムであれば、絶対パスが同一なら同じファイルを参照する (=同じ中身であることが保証される) ・inodeでファイルシステムが実装されているのなら、 同じinodeを指すファイル(=ハードリンク)の場合には、同じ実体を参照する (=同じ中身であることが保証される) であって、これらは「全く同一の中身」であることを確認する手段でしかない。 これらが有効な環境では間引くのに用いればいいだけ。勿論ハッシュを使ってもいい。 これらが別物に見えるのなら、それは抽象思考が出来ない馬鹿だからだよ。 ファイルシステム毎にC++の規格をいちいち決め直す必要があるなんて、おかしいだろ。 今後新しいファイルシステムが考案される毎に、毎回C++の規格を刷新するつもりか? 例えばWindowsでは同一ドライブに複数のドライブレターを割り当てることが出来るが、 それでどうなるかをC++の規格に定めるべきだと?マジで馬鹿だろ。 最終的に規格に定めるのはつまり、 ・全く同一の中身の場合には #pragma once は有効 (=現行のincludeガードと同様) であって、揉めるとしたら、 ・意味的には同一だがバイナリ比較では異なる場合 (例:最終行に空白や改行が追加された場合や、コメントのみの変更の場合) (=現行のincludeガードでは読み込まれないが、単純な方法では同一性の確認が難しい場合) だが、これも方向としては現行のインクルードガードと合わせる方向、つまり、 ・読み込んではいけない とされるべきであり、これもまた自明だ。 (とはいえここは実装的に揉めるかもしれんが) そもそも「同一性の確認」をファイルシステムに依存する考え方自体がおかしい。 もうじき #include 対象を url 指定するような時代にもなるだろうし。 (善し悪しはさておき、PHPではこれが出来る) そうしたら、「同一かどうかは中身で判断する」という選択肢以外はなくなる。 こんな当たり前の話が分からないのは完全に老害化してる。 そしてやる気がないのは今更意味がないからだろ。ほぼ全ての環境で実装済みだ。 > Cray C and C++ 以外では全て実装済み > https://en.wikipedia.org/wiki/Pragma_once 勿論糞長いパスとかにしたらはまることもあるが、これもよくある話でしかないし、ユーザ責任でいい。 規格に「パスは○○文字まで」と決めるわけにも行かんし。 > 途中でバッサリとパスが切られて、まったく同じシンボル名になって、 > 初めてincludeしたファイルなのにスキップされるという、 > なかなか原因解明が困難な不具合に襲われる……といったケースがあるかもしれません。 > ……はい、体験談です。 > http://cpp.aquariuscode.com/include_guard 二重にインクルードすることを想定しているヘッダーファイルって、存在するものなの? pragmaとか書かなくても、勝手にやってくれたら問題あるの? >>358 <pshpack?.h> <poppack.h> >>355 要旨が混乱していますね >例えばWindowsでは同一ドライブに複数のドライブレターを割り当てることが出来る つまり、今読み込んでいるヘッダファイルがかつて読んだファイルと同じ実体かどうか、を決める方法は**基本的にない**と主張しているのですよね そう主張するのなら、 >・読み込んではいけない >という仕様になるのも自明だ。 「読み込んでいいかどうか」を決める方法がないのに「読み込んではいけない」と決めていいのですか? 条件を満たすかどうかチェックする手段がないのに、その条件を仕様とするのは無意味ではないですか? >>358 たくさん存在する。 インクルードする前後のマクロ定義によって挙動を切り替えて使うようなものもある。 基本としては宣言というか、別のコンパイル単位にある関数などのインターフェイスを取り込むために使うものなんだけど、 アクロバティックな使い方をしてるものはそれなりに多いよ。 プリプロでループを実現するには再帰includeは欠かせないからな >>361 むしろそっちのほうに、 二重インクルード可能みたいな宣言を用意してほしいわ >>360 マジで言ってるんなら死ね。 俺の意見は、 ・#pragma once は現行のインクルードガードと同じ方向に仕様化すべき であって、実際これで文句が出ることはないし、妥当だろ。 つかお前、>>340 を理解してるか? int lengthOfLcs_r(const char x[], const char y[], int ix, int iy, int xsize, int ysize) { static int **lengthTable = new int*[xsize]; for (int i = 0; i < xsize; ++i) { lengthTable[i] = new int[ysize]; } if (ix == xsize || iy == ysize) { return 0; } if (x[ix] == y[iy]) { return lengthOfLcs_r(x, y, ix + 1, iy + 1, xsize, ysize) + 1; } return max(lengthOfLcs_r(x, y, ix, iy + 1, xsize, ysize), lengthOfLcs_r(x, y, ix + 1, iy, xsize, ysize)); } #include "/dev/tty" も知らない雑魚はもう黙ってろよ >>365 の関数は、再帰的な関数です。 その再帰的な関数内で static な配列を利用したいのですが、動的に確保した 領域を解放するにはどうすればいいのでしょうか? 再帰的な関数なので単純に関数の最後で解放するというわけにはいかないので 困っています。 >>365 動的計画法で配列に計算結果を記録しておき利用したいんです。 なので static にしています。 >>364 わけて考えてみますね インクルードガードはプリプロセッサ名前空間内の一つのプリプロ識別子を犠牲にして、機能させようとしているわけですよね #progma once が犠牲にする**べき**ものは何でしょうか? >>365 の関数はまだ書きかけなので、計算結果を記録した配列の値はまだ利用していません。 >>>365 lengthTableのポインタ値をなんとかしてグローバル変数に持ち出してatexitに登録するか 最初からそのグローバル変数でnewするか どうせプログラム終了時にヒープ丸ごと消えるんだから放置するか 一から書き直すかの4択 >>365 あ、すみません。 なんかおかしなことを書いてしまいました。 >>371 ありがとうございました。 すみません。質問がちょっとおかしかったので、質問を代えさせていただきます。 ある特定の関数内でしか見えないグローバル変数のような変数というのはC++にありますか? 考えているのは、関数 func でそのグローバル変数のような変数 a を宣言する。 func 内で呼び出している再帰関数 rec_func 内でのみそのグローバル変数のような 変数 a を利用したい。グローバル変数のような変数なので、 rec_func の引数として a を渡す必要はない。 何度も呼び出される再帰関数に引数として同じ変数を渡し続けるのはなんか 無駄なことをしているように思われたので質問しました。 本を読むとグローバル変数は使うなと書いてあるので質問しました。 >>373 でいう変数 a の代わりに、クラスを作って、メンバ変数を利用すればいいですかね? rec_func はメンバ関数にすればいいですかね? でも、そのためだけにクラスを作るというのもなんだかな―という感じがします。 >>360 一応添削しておくと、 > 今読み込んでいるヘッダファイルがかつて読んだファイルと同じ実体かどうか、を決める方法は**基本的にない** × 同じ実体かどうか、を決める方法は ○ 同じ実体かどうか、をパス等で決める方法は ただし俺はそもそも「中身」を見て確認すべきで、同じ実体だったら云々、という話はしてない。 cp A.h B.h の場合にインクルードガードでBを弾くとして、 当然Bは「ファイルとしては」「読み込まれ」、「コンパイル対象としては」「読み込まれない」だろ。 #pragma once はインクルードガードの自動版なんだから、インクルードガードと同じ仕様でいいんだよ。 そして逆に、実体が異なっていてもこの場合はインクルードガードは利くのだから、#pragma once も利くべきなんだよ。 ファイルパスでの識別ではこれは実現不可能だろ。 >>369 意味不明。何も犠牲にするべき物は無いと思うが。 というかな、規格化するなら方向は自明で、 ・#pragma once はインクルードガードの代わりに使われているのだから、 現行のインクルードガードを機械的に #pragma once に置き換えして問題ないように仕様化すべき でしかないだろ。これで誰も文句ないと思うが。 >>374 の心配があるんだったらクラスにしたって裏でthis渡すようになるだけだから一緒よ ポインタ渡すコストが気になるならグローバル変数にするしかない >>365 のコードのままなら末尾再帰の最適化かかるだろうから問題にならんと思うけどな クラスを作ってそのプライベートなメンバ変数を、 ある関数内でのみ利用できるグローバル変数の ような変数として使うというのは邪道でしょうか? >>373 > ある特定の関数内でしか見えないグローバル変数のような変数というのはC++にありますか? 見た目だけの話ならラムダでキャプチャすればいい。(クロージャ) ただ、今気づいたが、C++のラムダって名前付けられないから再帰できないね。 変数の直接呼び出しも試してみたが、以下は通らない。 auto f = [](int x) {return x? x+f(x-1) : x;}; なんでこんな糞仕様にしたんだ? JavaScriptも当初はそうだったが、不便だったので名前が付けられるように変更した。 この変更を知ってて無視してるのなら頭おかしいし、 知らないのなら不勉強だし。(言語仕様に携わる奴は他言語の動向も見ておくべき) 名前を付けられて悪いことはないし、技術的に不可能って事も無いと思うが。 ID:4xU9Va0kM=ID:HtO+dzj70 #include "X:\sandbox\aho.h" #include "Y:\sandbox\aho.h" これでどうなるかをC++の規格に定めるべきだと言っているのはおまえだけ //X:\sandbox\some_app.cpp #include "aho.h" #include "some_lib.h" //Y:\sandbox\some_lib.h #include "aho.h" おまえq文字列の解釈をまさか知らんのか? >>353 反論されてぐうの音もでないのかよ 5チャンは初めてか? w 同じファイル 同じ中身 大きく分けて2種類あり、 それぞれ、同じの定義の詳細は色々と考えられる >>382 > ID:4xU9Va0kM=ID:HtO+dzj70 勝手にアホな認定するんじゃねーよ そもそも俺はハードリンクとかのファイルシステム依存の話は処理系依存にした方がいいって思う >>384 人を嘘つき呼ばわりして謝ることもできない奴がなに言ってるんだよ w 効いてる効いてるw 嘘つき呼ばわりじゃなく嘘つきという真実を指摘されてファビョーンかよ おまえは考察自体を放棄した この事実はどうにもならない >>381 自己レス。 すいません出来ました。以下通ります。autoは無理のようです。 std::function<int (int)> f = [&f](int x) {return x? x+f(x-1) : x;}; >>373 見た目だけなら、上記のようにラムダで再帰すれば書ける。 またいつもの奴が暴れてるのか 相変わらず不毛な話してるな それで結局#pragma onceが採用されてこなかった理由はなんなん? 所詮 pragma だから この部分は処理系依存が強く出るので >>388 >>351 にまともな反論してから出直してこい w >>393 反論とは論に対して反駁することをいう おまえは論を示していない 結果に至る思考過程をすっ飛ばしている おまえこそ日本語を憶えてから出直して来い もう一度言う、反論とは論に反駁することだ まともに反論できないことはよくわかったよ w 事実を書いてあるだけで思考過程なんて関係ない 事実ってなんだよ 「アホは切り捨てろ!」とかいう標準規格として最低最悪の解決策を取れっていうのはお前のクソみたいな「意見」だろうが お前の意見は必ず自動的に実現して事実になるの?神なの? そういう意見を書いてあると言う「事実」な マジで理解力無さすぎ w >>397 それは違う 何からどう演繹した結果なのかを示さねば戯れ言に等しい 戯れ言でよければ過程は伏せたままでいいぜ どーせそんなもんバカにはねえだろうがな >>400 じゃあ俺も、お前はここに二度と来ないでに全財産を福島と熊本に寄付した上で家族もろとも自殺するべきであると意見するわ こういう意見を書いてあるという事実に反論できなければお前の負けな >>401 お前が何を言っても>>339 に書いた「無視」と言う文言を理解できなかった>>346 がいたと言う事実は変わらない しかも誤魔化すために話そらそうと必死な>>353 がいた事実も変わらない >>402 別に意見を言うのはいいんじゃね? それに何の意味があるのか知らんけど w C/C++の規格はgets()とかいうアホな使い方しか出来ないアホ関数を30年も削除出来なかったくらいアホに気長に付き合う規格なんだよ 広く使われ続ける規格の宿命としてその方針は変えられない だからお前の言うようなアホを無視して切り捨てるという選択肢が採用されることはないという事でこの話終わりな >>403 もう一度言う 提示してねえだろ、おまえは無視つったんだよ 人をアホよばわりしようと焦るあまり 論議そのものを粗末に扱ったのが おまえの運の尽きだ そこでどんなに暴れようが おまえは何も論じていない よって論に反駁してもらえることもない ましてや事実に反駁というシュールなことをする者もいない >>405 マジで言ってるの? gets() なんてアホには使えない関数の典型だろ バッファーオーバーフローはプログラマーの責任 って言う言語だぞ w >>376 言葉尻を捕まえて悪いが、クラスや関数を作ることをそう大仰に捕らえることはない。 単純な機能のクラスや関数など幾らでもある。 >>406 >>351 を読み直せ 無視するのは誰で誰を無視するのかを答えてみ まあ恥ずかしすぎて答えられないだろうからまた明後日の話に逸らそうとするんだろうけど w >>410 読み直して欲しいのかよ お願いしろよ 読み直してやるかも知んねーからw りかいできないならからんでくるなよダブリュー 「アホなりようしゃはあいてにしない(イコールむしする)」っていうしようを「ていじ」してるってはなしだ、ボケ C/C++は池沼お断りの言語なんだから、このスレも同じノリでいいと思うぞ。 指摘しても理解できないのは、日本語が出来ない=池沼だから。 慣れる慣れない以前の問題だ。 ていうか#pragma once規格化不能論者が言い立てる不可能ケースは (1) #ifdef〜#endifインクル〜ドガ〜ドでも曖昧さが残り処理系依存になるケース (2) #pragma onceで自動的にガード条件を設定する際の困難(#ifdef 〜の記号をうまい具合に考え出すことに相当 (3) #ifdef〜#endifインクル〜ドガ〜ドにおける既存のアクロバティックな使い方への対応(>>361 (4) #pragma onceで想定されるアクロバティックな使い方の解釈(>>321 のn種類しかない (1)は#pragma once固有の問題ではないから、#pragma once規格化の障害とは言えない ハードリンクとかの件でここまで費やされた長い紙数はムダすぐる… (2)と(3)は、#pragma onceが力量不足ならそのケースだけいつでも#ifdef〜#endifインクル〜ドガ〜ドに戻ることができる プリプロセッサの基本特性まで変えようというのではないのだから… (4)はエラーにすればよい #pragma onceの解釈を単純な#ifdef〜#endifインクル〜ドガ〜ドの置き換えと限定するなら可能なはずや いままで20数年にわたって規格化委員会で話題に上りながら規格化されないのは、 この件の抜本的な技術である「モジュール」の規格化が控えていると全員が錯誤していること、これにつきるだろうJK >>416 とりあえず、 #pragma onceの仕様を文章にしてみて そんなに簡単じゃないから ■ #pragma onceの俺様仕様 (ヘッダファイルの集合の規定) 1. インクルードされるヘッダファイルを#pragma once付きとそれ以外とする。 ただし、次のいずれかに該当する場合はエラーとする(ヘッダファイルに含めない) (1) #pragma onceがコメントを除くファイル先頭に現れた場合 (2) #pragma onceがコメントを除くファイル先頭に現れ、かつ ファイル内の#if〜#endifの入れ子がファイル内で完結しない (ヘッダファイルの識別) 2. #pragma once付きのヘッダファイル同士は、ファイル名で識別する。(ディレクトリパスは無視) (ヘッダファイルの展開) 3. #pragma once付きのヘッダファイルのうち、上記2の規則により同一と判定されるファイルは 単一のコンパイルの中で、2回目以降の展開を無視する。 4. #pragma once付きでないヘッダファイルの展開は現行どおりとする。 いじょ >>418 #pragma onceってファイル先頭に置くものだと思ってた ファイル末尾とかにおけばいいの? ソフトウェアが巨大化してくると、サブモジュールが各々同一のSDKを抱えてるなんてことがある。 複数のサブモジュールを読み込んでるソースコードは間接的に同一ヘッダを読み込む可能性があるが、 cvs等が異なるidを埋め込んでいたり、それぞれ微妙にバージョンが異なっていたり、エンコーディングや改行コードが異なっていたりする場合、 Includeガードならビルドできるが、pragma onceだと同一ヘッダを異なるファイルと認識してしまい、エラーになってしまったので、サブモジュールを全て自前で修正する羽目になった。 なんてことがあるかもしれない。 結局ヒューリスティックな実装しかないんでないの? 訂正; 誤: (1) #pragma onceがコメントを除くファイル先頭に現れた場合 正: (1) #pragma onceがコメントを除くファイル先頭以外に現れた場合 >>420 >>418 の仕様によるヘッダファイルの展開のどこにヒューリスティック要素があるのかkwsk、 >>418 >ファイル名で識別 過去遺産をすっぱり切り捨てる斬新な発想に目から鱗 >>423 藻前は>>418 の仕様の項番4を理解していない 出直せ 今後ヘッダファイル名にはドメイン名を頭につけなきゃいけないね。 メアドでもいいかな? >>417 適当な処理系の言語リファレンス見ればいいだけ そんなに難しくはないぞ >>422 420が提起した問題に答えろ kwskはそれからだ >>427 是非は置いといて、ファイル名で識別するって書いてあるじゃん 文盲なの? つまりfooSDK/interface.hとbarSDK/interface.hは同一として判定するんだな たいへんだー #pragma onceの前に改行があったらエラーですかwww >>420 それ単に管理がなってないだけだろ どのバージョンのヘッダーを読み込むかを管理できてないとか怖すぎる >>432 どう管理しろと? 混用しているライブラリに偶然同じファイル名があって どちらもインクルードガードされているということを 「管理」で回避できるのか? >>432 えー、cvs keywordはどうするのー? サブモジュールを格納してたリポジトリ毎に値が異なるよ? 自動的に改行コードを修正してくれるリポジトリの場合はー? まずは世の中のプリプロセッサのpragma onceの仕様がどうなっているかを調べるべきかと >>433 話の流れを理解せずに無駄に絡んでくるなよ... インクルードガードならとりあえずビルドできるって言う話だぞ >>434 同一のSDKなんだから同一のものを指すようにすればいいだけだろ 目的は インクルードのループを防ぎたいのと 同じ定義を複数回行うことでエラーになるのを防ぎたい ってことだよな これをインテリジェントに行ってくれるのが理想 インテリジェントな物を仕様にするのは難しいし、 時代が進めばインテリジェント具合も変わる >>418 みたいなあまりにショボい仕様だと 後々不満が出ることになる >>437 答えになってないぞ 今 #pragma once について話しているよな インクルードガードを #pragma once でやっていたらどうなんだ ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる