C++相談室 part136
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。 !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part135 https://mevius.5ch.net/test/read.cgi/tech/1522495206/ このスレもよろしくね。 【初心者歓迎】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 >>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++だとその辺どうなってんの? ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる