【初心者歓迎】C/C++室 Ver.104【環境依存OK】
レス数が1000を超えています。これ以上書き込みはできません。
エスケープシーケンスやWin32APIなどの環境依存なものもOK
そのような質問は必ず環境を書きましょう
半角空白やタブでのインデントはスレに貼ると無くなります
コードを貼れる所
http://codepad.org/
https://ideone.com/
前スレ
【初心者歓迎】C/C++室 Ver.103【環境依存OK】
https://mevius.5ch.net/test/read.cgi/tech/1530384293/ c++builder10.3 community
IID_PPV_ARGSを使わない場合どうしたら良いか教えてください
何を入れたら良いのかわからないです
#include <windows.h>
#include <tchar.h>
#include <shlobj.h>
#include <shellapi.h>
#include <commoncontrols.h>
void __fastcall TForm1::Button1Click(TObject *Sender) {
IImageList *piml;
SHGetImageList(SHIL_JUMBO, IID_IImageList, (void**)&piml);// pimlがNULLになる
SHGetImageList(SHIL_JUMBO, IID_PPV_ARGS(&piml));// 成功
} わけのわからん言語をこねくり回して、つまらんことしてちゃ、つまらん。 >>997
UTF-8 は char * に入れるもの
char32_t * ならぎりぎりセーフ
wchar_t * は wcs 用
UTF-32 を wchar_t * に入れる utf8は漢字仮名に3バイト使ってることわかってんのか
処理を簡単にするためいったんwchar_t使うのは普通のこと
でなければ文字数のカウントすら文字コードを調べる羽目になる 調べる羽目になるっていうけど、たったそれだけのことでしかない
当然、パフォーマンス的に最適な方法は場合による >>8
c++17は調べてないが、
char32_tだと文字列処理のライブラリも正規表現も使えないだろ。
既存のライブラリ使うためにまた変換するのか?
>>9
たったそれだけて、文字列処理なんか主たる作業じゃないC/C++プログラマにとっては、
utf8の文字コード常に思い浮かべながらコーディングするなんてのは不快極まるだろ。
*x == 'あ'
これが書けないことがたったそれだけかよ そもそもchar32_tてutf32用だろwwww このなかで一番美人なのって真ん中だよね?深キョンレベルだと思うのだが
ちなみに向かって右は目も鼻も整形してるって本人が公言してるけどそれ抜きにして誰が一番美人だと思う?
http://bigsta.net/media/1933567086757747003_3564907098 VSだとwchar_tは16ビットだろ。
だから3バイト以上/文字あるutf8だとおいしくもなんともないが、
unixは32ビットなんで、シェル出力をfgetwsでwchar_tで受け手、時にwstringで処理すると、
fgets->charより格段に楽に処理できる場合がある。
環境依存であんまり人に推奨できないだろうけど、unix, gcc限定なら正しく処理できる
もちろんwslでも使える 次から次へと嘘を並べるのがウリナラ
密漁船を捜索中だった→密漁船は既に発見し救出中(実際は瀬取り中?)だった
レーダーは水平以下へ照射していた→上空へレーダー飛んだのはなぜ
機体は真上を飛んでいた→実際は1km以上遠方だった
カメラを向けただけで照射はしていない→レーダーも回転して対面していた 環境:Win10/VC++2015
WinSockでマルチキャスト受信のプログラムを作っているんですが、
マルチキャスト送信している別PCとの接続において、
以下のケース2の挙動に困っています。
■ケース1(期待する挙動)
LANケーブルが接続されている状態で受信ソフト起動
⇒ recvfrom()で受信する
⇒ LANケーブルを抜く
⇒ recvfrom()がブロックする
⇒ LANケーブルを挿す
⇒ recvfrom()がデータを受信し、ブロックが解除される
■ケース2
LANケーブルが接続されていない状態で受信ソフト起動
⇒ recvfrom()がブロックする
⇒ LANケーブルを挿す
⇒ recvfrom()はブロックしたまま、いつまで経っても解除されない
(受信&ブロック解除してほしい)
なぜrecvfrom()はブロックされたままなのでしょうか? >>18
selectは「複数ソケットのとき」という先入観があったのですが、
1ソケットのときでも使うんですね。
ありがとうございました! gccでしか確認してないが、warningは出るんだが
前にu8をつけない'あ' は int (4バイト)展開されるんだな
u8つけてしまうと下位1バイトしか処理されないんで正しく処理されない。
wchar_t buf[0x100];
としとくと
buf[i] == L'あ'
ではwarningすらでない. >>21
いったいいつの時代の話してるんだ古すぎるんだよ情弱
C++17から問題なく使用できる 情弱がねごとほざくからそのたんびにイラン労力強いられることとなる
ちったぁ情報収集してこいよダニ どうせだったら、utf8専用のchar8_t型も用意しといてくれたら良かったのに。
ascii文字圏の連中にはどうでもいいことなんだろうけどw 教えてください。
C++のvectorについてです。
あるvectorの要素を自分自身に追加したいとき、どうすればよいのでしょうか。
例えば、v.push_back(v[2]);のようなことをしたいのです。 >>27
それ以外の何を望むの?
特定場所への挿入v.insertぐらいしかないじゃん 27です。レスありがとうございます。v.insertでうまく行きました。
v.push_back(v[i])だとなぜか空の要素が追加されてしまい、困っていました。 >>30
まともなpush_backの実装なら対策されているので問題ないはず。
無対策でも明示的にコピーコンストラクタを呼べばうまくいかくも。(要素の型をTとする)
v.push_back(T(v[2])); あ〜そういうことか
俺もハマりそうだなそれ
でもそれはvectorの実装側の責任になるか >>27
意図しないエレメントが追加されてしまうC++は何?バージョンも併せて教えてよ 環境書くのを忘れてました。すみません。
Win7、Visual Studio 2008です。 >>32
まともでない実装ってのはどのテンプレート?つかコンパイラ? >>35
thx
なるほど10年前のコンパイラならstlにバグ残ってる可能性あるわな
2011、2014、2017でずいぶん新しくなってるよ
仕事で2008指定されてるとかじゃなければ2017入れて損することあんまないと思うけど さすがにvectorではまともでない実装にお目にかかったことはない。
VisualStudio2010のMFC独自コンテナCArrayで同じ問題ではまったことがあっただけ。 マジかよ MFC 最低だな!
失望しました。WPF 使うの止めます vsに2011ってのもあったのか、いやあ勉強になるなぁ >>31
参考になりました。ありがとうございます。 gnuのobstackってざっくり理解するなら普通にデータ構造としてのstackのいち実装って認識であってますか? Privateにメンバ関数を置くのって別にいいですか? いいんじゃね?
そのクラスの中のみでよく使われる関数とかprivateにする デバッガってどう動いたら正常なんでしょうか
vscodeでハロワしてみてブレークポイントで止まる→これでいいんだよな?となりまして リクツを語ると
デバッガにデバッガを適用するとバグかどうかを検出できない Win32APIなんですが、
ウィンドウクラスにアイコンハンドルを設定してWS_OVERLAPPEDWINDOWスタイルで
CreateWindow()すると問題なくタイトルバーにアイコンが表示されるのですが、
WS_POPUPスタイルでCreateWindow()した後にSetWindowLong()でWS_OVERLAPPEDWINDOWスタイルに変更すると、
タイトルバーにアイコンが表示されません。
WM_SETICONをSendMessage()しても変わりませんでした。
どうすれば表示されるようになるでしょうか? >>56
そちらはスレが盛んでないので、こちらでお聞きしました・・・ >>55
http://eternalwindows.jp/control/controlbase/controlbase06.html
http://chokuto.ifdef.jp/urawaza/api/SetWindowLong.html
SetWindowLong 関数で変更されたそのデータは SetWindowPos 関数が呼び出されるまで反映されません 👀
Rock54: Caution(BBR-MD5:79b7e0206b0fd5ffcfddd514fa488d36) >>59
SetWindowLong()後にSetWindowPos()はコールしていたのですが、
WM_SETICONをSendMessage()するときのアイコンハンドル取得方法がまずかっただけでした(汗)
(LoadIcon()のHINSTANCE引数が正しくなかった)
今は問題なくアイコンが表示できています。
お騒がせしました! >>60
https://g.co/kgs/ZEZu9X 👀
Rock54: Caution(BBR-MD5:36abcc1a7fb24404caf692865ab3af18) >>57
盛んでないなら先ず盛んにしろよ
欲しい者は先ず自ら与えると言うぞ C++て3年周期で新規格リリースされるんだなC++20が来年発表て、
えーかげんもうついていけんわ
家電のモデルチェンジじゃあるまいし。言語の追っかけなんかやってられん。 C言語の需要はそういうところじゃねえの
もうこれ以上進歩しないが大抵のことはできる
適度に難しいところもある >>65
もしそうしたければ古い版の規格で書いてもええんやで。
C++20 が出ても C++11 が消滅するというわけでなし。
まあ主要なコンパイラがサポートしなくなったらしょうがないけど…… C++11が神過ぎる。
それまでとは雲泥の差。
これだけでずっと戦える。 >>67
言語って自分だけで済まんだろ
キャッチアップしていかんと人の書いたコードが読めなくなる
こんな短期間でアップデート繰り返すんじゃなくもっと精査した上で規格変更しろといいたい
アップデート繰り返す度にユーザ減少してるだろ >>66
new/delete無造作に使ったコードを組込なんかで書くと、
メモリフラグメント作りまくるだけだからな。
ハードウェアの一部としてRTOS上で安定動作させるためには、
ポインタ使いまくりのbetter Cとして書くしかない。
4kB メモリのRL78でコード書いてみろと >>69
C++の良かったのは仕様が枯れてることだったのにな
今は逆を逝っててどんどん人が離れて逝ってる utf-8の文字コードが格納されてるchar配列から、デコードされた文字をstd::string型に入れる方法を教えてください
以下のような変換を実装したいです
char ai[] = {0xe3, 0x81, 0x82, 0xe3, 0x81, 0x84}; // "あい"のutf-8コード
std::string str = ??
std::cout << str << "\n"; // prints "あい" >>72
aiの最後にnull文字は入れないの?
入れないなら
srd::string str { ai, sizeof(ai)/sizeof(ai[0]) }; >>69
時間を掛けたら扱う項目 (提案) も増えるからどっちでも同じだよ。
一度の変更が大量になるよりは小さな変更を頻繁にした方が良いというポリシー。
その方が実際の運用で出た問題をフィードバックしやすいという利点もあるしな。
>>73
配列の大きさを知るには std::size か std::extent を使えよ。 C++ には C 以来伝統の sizeof / sizeof 以外に
配列の要素数を知る方法があったはず…と思ったが std::size だったか。
でも標準で使えるのは C++17 以降だよね。
「C++ならテンプレート使えばできますよ」的な情報は色々あるけど、
結局、移植性を考えると古典的な sizeof 割り算が便利だったり。 ちょっと知ったかは、よくよく初心者を馬鹿にする。
自分も、初めは、初心者だったくせに。 std::sizeが使えなかったとしても(主要なゲーム機の環境の1つはC++14止まりだし)、テンプレートで取得するのはC++の移植性には影響しなくないか? ていうかGUIとかマングリングの統一とかvtblが最初に来ることとか
テンプレート周りばっかりじゃなくて解決して欲しい問題いっぱいあるんだけどなぁ
あと個人的にはプロパティとかも欲しい 配列の要素数を取得するだけのものを自分で書くならこんな感じかな。
template<class T, size_t N>
std::size_t size(T (&)[N]) {
return N;
}
実装自体には sizeof を使ったって害はあまりない (あえてする意味もないけど)。
template<class T, size_t N>
std::size_t size(T (&a)[N]) {
return sizeof a/sizeof a[0];
}
sizeof でのやり方を「そのまま」書く、またはマクロで覆うのは、
型チェックの支援を受けられないから変なミスをしやすい。
変数 a が (配列ではなく) ポインタのときに
sizeof(a)/sizeof(a[0]) という式がコンパイルは通っちゃったりするし。
変数名を二回書かなきゃならないのも、
何かの修正のときにうっかり片方だけ書き換えたりとか有りがち。
プログラミングをそれなりに長くやってると、
馬鹿みたいなつまらないミスをした経験のひとつやふたつやみっつや二百くらいはあるでしょ。
型システムはそういうのを多少なりとも事前に検出してくれるありがたい仕組みなんだから、
積極的に活用したいところ。 C++標準じゃないけどVC++の_countofが重宝してる >>75
>時間を掛けたら扱う項目 (提案) も増えるからどっちでも同じだよ。
同じ訳ないだろが、
仕様変更、追加したものの、さんざん使ったあげくそんなもん使うなってのはいくらでもあるだろ。
auto_ptrはどーした。
だから3年なんて製品のモデルチェンジ並の仕様変更じゃなく、言語オタク共がもっと時間をかけて精査して、
10年に一度ぐらいの変更にしとけってこった。
そもそもCのプリプロセスだったわけで、
Cとの整合性は確保した上で双方同時に仕様変更しろといいたい。
だいたいどっち見て仕様変更してんの?言語オタクのセンズリか?wwww 3年ごとなのはいいと思うけど、クラステンプレートの引数推定なんか
関数テンプレートみたいに推論できないテンプレート引数が残る形に出来ない上に
エイリアステンプレートには使えないしクラステンプレートの参照にも使えないし
デフォルトテンプレート引数では省略できないしで・・
便利だけど、あまりにも片手落ちじゃね?と思うことはある >>84
> 同じ訳ないだろが、
> 仕様変更、追加したものの、さんざん使ったあげくそんなもん使うなってのはいくらでもあるだろ。
同じだよ。
散々使ったからようやくわかったことで、ただの言語オタクどもがどんだけ理屈をこねた
ところで現実的なプロダクトの実際なんかわかりゃしない。
精査をしっかりすれば事前にどうにか出来てたと本当に思うのか?
> auto_ptrはどーした。
これはまあ……アレだ……
これ自体は擁護しようがないほどアレだけど、
一番アレなのを抜き出して言うのもちょっとどうかなって。
強いて言えば、当時としてはスマートポインタという概念を提示出来たという
成果といえなくもないんじゃないかな……。
> 10年に一度ぐらいの変更にしとけってこった。
https://i2.wp.com/ds3.jp/wp-content/uploads/2017/07/023.jpg
> だいたいどっち見て仕様変更してんの?言語オタクのセンズリか?
そうならないために言語オタクにゆだねない (実際の運用で見極める) という選択なのに、
お前はもっと言語オタクに活躍しろって言ってんだぞ。
おかしいだろ。 仕様変更が止まってる言語はともかくとして仕様策定のない言語に比べればC++の更新スパンは割と長い方という認識がある
これより長いのメジャーどころだとC11(1,20年)/Fortran2008(5年)/Ada2005(10年)/Haskell(5年前後)くらい?
Haskellなんかは処理系拡張ゴリゴリだしアテにならないし他はもう古めかしさを感じるなぁ まぁ、TypeScriptは年6回updateしてるけど次が待ち遠しいな。 426名無しでいいとも!@放送中は実況板で2019/01/10(木) 18:17:49.03ID:b7PfIJnh0
新しい物好きな人は、よく、古いもの馬鹿にする。
古いものに、大切なものがあることが、
よくあることを、知らない人が多い。 古いという感覚を持つと話をしただけで古いものが悪いとは一言も言っていないが……?
一方でもしその良さが「新しい仕様を頻繁に覚えなくて良い」なら、言語に対して掛けるコストが減る事と、自身が怠惰である事の2面性を常に持つかもね
プログラマなんて怠惰でナンボだけど覚える事に怠惰か書く事に怠惰か人それぞれよね
個人的には草案で嬉しそうな機能を追加します!って言いながら実際の仕様では無限に延期される方が嫌 これな
youtube
qqwgldvnNlk
#t=41m41s >>82
配列の参照のsizeofは配列のサイズじゃないから害はあるな() >>84 は面白いよな、散々使うことで問題が見付かるって自分で初っ端から言ってるのに「だからスパンを長くしろ」つまり散々使うことが出来ないようにしろって言ってる
そして最後には言語オタクのセンズリかって、言ってる事が弾けまくってるな。
言語オタクのセンズリになってるのが不味いから、積極的に一定毎に更新するようにしていってるんだがな おれは >>84 に同意だな
数年で更新ってそれがどれだけワークしてるのさ
だいたいどれだけ認知されてるのかようわからん小さい機能追加が山盛りな一方で
大規模なconstexprとかひかえめにいって大クソじゃん?
理論もなければ、現実のワークフローなにも考慮にはいってない
結局オナニーでしょ、何オタクかはしらんが 1.仕様が確定してからでなければ実務には使われない
2.実務で使われないと良し悪しは分からない
3-1.仕様確定のスパンが短いと、仕様に提案されてから試されるまでが短い(もし悪ければ次で撤回も可能)
3-2.仕様確定のスパンが長いと、提案されてから実務で試されるまでが長い(撤回されないと言えば聞こえは良いが、当然悪いものが残り続ける)
んで仕様策定を言語オタクのオナニーって言ってるのに、実務で試されない、策定の期間だけ伸ばして言語オタクなんとかしろって言ってるように聞こえるからよく分からんわけだ
だって君たち仕様確定してからじゃないとそうそう草案の機能なんて使わないでしょ?追わないでしょ?私だってそうだ
期間が長ければその間に普及する概念も多くなるし(少なくともc++はそれを取り込む方針の言語なので)あんまり長くすると大変だと思うよ >>97
c++14のconstexprは条件分岐とかループにも対応してるから、そこそこ使えるよ。
文字列リテラルの長さを取得する関数とかも定数化できるし。
テンプレートの非型引数をあれこれする関数を定数化したりとか。 機能追加したい人が、ブランチして機能追加して実務で実証して、
それから正式に仕様を提案すりゃいいじゃん
なんで仕方なく業務でC++使ってるだけなのにベータテストみたいな
仕様更新に巻きこまれなきゃならないのさ 仕様を確定させないと各コンパイラでの実装と互換性チェックとか出来ないし、
既存のコードが動かなくなるわけでもなし、
10年くらい経って十分枯れた機能を使ってれば良いだけでは? >>99
その程度の最適化はコンパイラが勝手にやればよくね?
もっと大規模なことしたいからわざわざconstexprなんてキーワード追加して
かつ人間様がわざわざそれを指定するんだろ?
で大規模なことをできる仕様か?あれが?
どうせみんなデバッグするときにconstexprをはずしてんだろ?
アホと思わないか? >>103
Visual Studioでしか試してないけど、わざわざ外さなくてもデバッグビルドでは定数化されないのが普通じゃないの? constexpr相当を勝手にやられたら、参照してるほうがリコンパイルが必要か判断できなくなるんじゃないの? constexpr指定を使わずに同じような定数化を自動でやるとなると、
一度全ての関数を定数化可能か調べるためのプレビルドみたいなことをしないと無理だよね。 定数畳み込みなんて古典的な最適化手法だし、
gccはstrlenの最適化やるだろ
だからもっと大規模なことをやるためのconstexprだろと言ってる その最適化をコンパイラ依存でなく標準規格化したことに意味があると思うんだけど。
gccで出来ればあとは何でも良いの? 珍説どうも
その程度の最適化技術を持たないコンパイラベンダなんてどうでもいいな
clangのバックエンド自分で作った方が早い constexpr 相当のことはコンパイラが最適化で頑張るのが筋だというのは
まったく正当な意見だと思うんだが、本当に速度が必要な個所のチューニング
をしたいとき、つまりコンパイラの最適化以上のことがしたいときに
打てる手段が無かったりだとか処理系の拡張構文を使わなければならないというよりは、
不格好でも constexpr の方がマシ。
C++ は現実的に使えることを指向した言語で、現実はクソなんで、
クソを少しマシに書けるようにするってのは妥当な選択肢。
コンパイラが十分に賢いだとかいうような
理想的な世界で生きてる人は別に constexpr を使わなくてもいいよ。 pythonやmatlabみたいに配列やvectorを:とかでスライス抽出できないんですか? 技術スキンだけ高い奴が、できる奴と思い込んでるチキン。 ++20のfilterでスライスみたいな事ができるようになる
しばし待たれよ >>110
constexpr指定はコンパイラにはわからない関数呼び出し先で
定数化できる計算であるとコンパイラに教えられるので
指定できるならした方がいいだろうけど
>本当に速度が必要な個所のチューニング
そういう個所がコンパイル時にわかってる定数だけで構成されてる例なんて
まず滅多にないんだけどね >>115
>> 本当に速度が必要な個所のチューニング
> そういう個所がコンパイル時にわかってる定数だけで構成されてる例なんて
> まず滅多にないんだけどね
constexpr はコンパイラに対するヒントであるだけでなく、プログラマにとっての制約でもある。
「そういう (速度が必要な) 箇所」であるにもかかわらず実行時の値に依存しているということを
プログラマが気づくことが出来る (ので分離するなどの工夫をする機会があるかもしれない)
というのは十分に便利だよ。 わかってないな
本当に解決しなきゃいけないボトルネックが、たかだか定数の畳み込みだけで
解決出来ることなどまず無いと言ってんの
ただの数回、数十回の普通の演算はそのままやっても十分速いんだよ
むしろ定数化できるとこを全部定数化したせいで、(即値にならないような構造体の場合)定数を読みに行くコストの方が大幅に高くなる可能性もある
constexprというか言語の機能を盲信しすぎ あと、
>「そういう (速度が必要な) 箇所」であるにもかかわらず実行時の値に依存しているということを
ファイルから読んだ内容、mainに渡された引数、ネットワークから受け取ったデータ
そういうの(および一度でもそれらと関わった変数)全て実行時の値だってわかってる? オフラインで複雑な計算して、結果をバイナリで埋め込んでおくことはよくやる
ゲームなら当たり前にやるワークフローだよな
しかしそういう典型的な用途にconstexprは向いてないという間抜け具合
C++でなんでもやるというのが目的になってんだよね
こういうのをオナニーって言う >>117-118
やりたいときに出来る方法があるというのは無いより「マシ」と私は >>110 で述べたが、
それが君にとっての妄信なのかい?
要するに、 constexpr の成果は限定的すぎると言いたいんだろ?
ほとんどの機能は個別に見ればどうでもいいような些細なものなのは普通のことだ。 何度も言ってきたが、負けを認めたら死ぬ病気なのか?君は ついでに言えば、俺は「指定できるならした方がいい」と書いた
俺が成果を限定的だと貶してるんじゃなくて、
君が過信してるの >>122
じゃあ何が問題なんだい?
指定できるならした方がよくて、指定できるようになってるのは指定できないより良いというのなら意見は一致してるじゃないか。 >本当に速度が必要な個所のチューニング
>をしたいとき、つまりコンパイラの最適化以上のことがしたいときに
>打てる手段が無かったりだとか処理系の拡張構文を使わなければならないというよりは、
>不格好でも constexpr の方がマシ。 (途中送信してしまった)
本当に"速度"が必要なときに速度より移植性やC++標準への準拠を優先してconstexprマンセーする
これを過信と言わずして何と言う >>125
速度が必要な個所が「なるべく」移植性が高い形で表現できればそれに越したことは無いし、
更にそれ以上が欲しいなら移植性を犠牲にすることも出来るんだから、
constexpr の導入に何の問題もないだろ? C++で有名人になりたいです
どうすればいいでしょうか? >>128
c++ のコンパイラを c で記述すれば、それだけで有名になれると思います
gcc が c から c++ になったときは心底残念に思っていました >>130
つ ttps://www.amazon.co.jp/dp/4797344369 >>94
はちみつなんとかもそーだけど、
おまえもほんま馬鹿やね。表面しか読めないんだな。
10年間、言語オタを隔離してしまえといってるのだよ間抜けちゃん。
世の中から隔離された世界でせんずりこいてろといってる。ザーメン臭でくさいやつは地上に出るな。
大体、大規模プログラミングはすでにC++には向かないことが露呈して久しく、
せいぜいbetter Cとして生き残るぐらいしか道はないのにどういう意図を持っての3年ごとの改訂なんだ。
ポリシーなき改訂ははた迷惑なだけ
これだけ頻繁に改訂されると、スペック以外の解説本では、すでにストラウストラップ本自体改訂をキャッチアップできてない。
その邦訳ともなればますます現行仕様から浦島太郎になるのは必至。せっかく覚えた頃に新スペックの登場か?
C++初心者はいったいどの本買ってるのさ?キチガイ言語オタ江添本でも買うのか?
結局、ユーザー減少させてるだけだろうが もしかして、最初の「なる」はNULLと掛かってる?
中身のない人間、アクセスしちゃダメな奴、みたいな意味で。
ちなみに自分は「ヌル」派。
だってNULLを「ナル」と読んだら「ぬるぽ」と言えなくなるもの。 >>131
一応買ってみました
でもどうせコンパイラ作るならC++でClangとかの実装を勉強したい C++好きな人って、C‡‡、Java嫌いな人が多いのって偏見ですか?
関数型言語かRustの話しかしてない気がします >>132
C++ の言語としてのポリシーはこのように提示されている。
Stroustrup 自身がその著書に書いたもの。
委員会の公式な文書にするとかどうとかいう議論はあったけど、
結局どうなったのかは知らない。
・C++ の進化は現実の問題をその動因とする
・完全主義にはこだわらない
・C++ は今現在役に立つ言語でなければならない
・人に何かを強制しない
・静的タイプシステムに対する暗黙の違反が無い
・同じ機能なら人に教えやすい方を選ぶ
・C のプリプロセッサは使わないように
・C との正当でない非互換性が無い
・C++ 以外に他の低レベル言語を必要としない (アセンブラは除く)
・使わない機能はコストを発生させない
これらの考え方に基づいて今要求されているものが (不完全でも) より素早く反映しやすくする
リリース体制として ship train model が導入された。
多くの人が関わるので妥協はあるだろうが、一環したポリシーの下で改定されている。
そのポリシーを気に入らないでいる自由はあるし、それはどんどん主張して良いが、
ポリシーが無いというのは事実誤認だし、自分にとって妥当ではないからといって
必要としている人を侮辱するべきではないよ。 俺が以前「D&E読んでないのか」、って言ったせいではちみつはD&Eの受け売りするようになったな・・・
ttp://i-saint.hatenablog.com/entry/20101012/1286822888
「あるプログラム言語を使うためにその言語の弁護人になるべきではない。」
そういうただの弁護人になってるバカは大抵C++を実用レベルで使ってない人間ばっかりだ >>140
?
このスレで言われたから読んだということは無いはずだが、どの発言のこと?
正確に覚えてないけど
私が持ってるやつは (日本語版の) 初版だからたぶん 2006〜2007 年頃には読んでるはず。 現実的な問題があるならそれは解決されなければならない問題であって、
改定を先延ばしにすることを要求するのはおかしな話じゃない?
ドキュメントが追い付いていないのは、これは確かにあるけど、
翻訳とかに時間がかかるのが分かっているから
早め早めに改定がリリースされるのはむしろありがたいことでしょ。
デカい改定が一気にくるよりは。
constexpr が限定的に過ぎるとかいうのはわかってる話で、
だから制限を緩くしたり consteval を検証したりしてるんだろ。
それでも必要だと判断したから入れたんだから、
そこに文句付けたって今更な話で擁護もクソもない。
駄目な部分があるのは知ってるっつーの。 それでも要るんだよ! >>138 回文には気づかなかった。
「なるな」「人間に」がそれぞれ反転同一で、
それらフレーズを反転同一になるように並べて作成した回文か。
「人間になるな人間に」でも構造的には同じね。
いくらかPPAPな感じがしないでもない。
あと、正規表現のパズルっぽくもある。 酢にピリッとした風味を足すのに使えます
_人人人人人人_
> スピリタス <
 ̄Y^Y^Y^Y^Y^Y ̄ はちみつと関係ないと思ったけど、餃子の方には関係ありそう。
しかし、C++スレッドでの真摯な態度と裏腹に、
他所ではどういうキャラクタなんだろ、と思わせる投稿ね。 真摯かねぇ・・・・希望的観測で詳しくないことに首突っ込んだり
自分の間違いや認識の誤りは絶対に認めないクソコテなのに
まぁそれも俺の主観だから他の人がどう思うかは知らんけど。 >>145
風味って鼻から空気が出る時に感じる食べ物の香りかと思ってたわ c++が対象にしてる現実問題って何だ?
c++使う大規模プロジェクトってゲームがまずあると思うけど
例外禁止未だに普通だし標準ライブラリも限定的にしか使わないよ c++で書かれたc++のコンパイラのことだろ
ここが0.001%早くなるだけで世界から年間100000時間くらいが節約できるんじゃねえの じゃあLLVMのコーディングスタンダードこれな
https://llvm.org/docs/CodingStandards.html
例外、RTTI、iostream使わない
現実に使えるソフトってのはこういう制約で作るわけだ
C++の標準化やってる連中はメタプログラミングで遊んでるだけ
現実問題なんて何もわかってない だから、ブラウザ、ロケット射的距離のシミュレーション、機械学習 >>153
初心者ってのはC++の例外のバイナリモデル説明できねーやつのことな >>154
でC++がそれらに対してどんな問題解決してくれたんだ? >>152
そこらへんはしゃーない。 便利な機能も害悪な場面は有るし、
ある時点では有用だったものが後には足を引っ張ることもある。
あるプロジェクトで縛りを設けるからといって
それが現実の全てというわけではない。
ただ、例外を使わない方向というのは大きなプロジェクトでは
そこそこあるかも?
>>153
例外が忌避されるのは他の言語と接続したときに、
呼出した側が例外を捕捉できないというのが致命的で、
つまりはそういった場面が想定されるようなライブラリでの一般的な規則。
外へ出る前に例外を全部キャッチしてしまうってのでも、
まあなんとかならんことはないが、
近頃では std::optional を活用した方がいいという雰囲気はある気がするね。
Go や Rust は最初からそういう方向だし。 このスレ、初心者を見下す者ばかりだし、
何が 【初心者歓迎】だよ。
【初心者歓迎】はずせ。
そう言うと、「何にもそんなことしてないよ」
とか、レスが来る。
子供スレ。 optionalはヒープ使わないだけでnullと大差ない
せっかく静的にnot nulが保証されてるとこを壊してしまう
ほとんどアンチパターン 趣味でC++齧ってるやつと本気で仕事としてやってるやつじゃ格が違うんだよ C++では好きなだけ効率を犠牲にして安全を手にすることができる
効率を犠牲にして安全を手にすることを余儀なくされている言語とは区別すべきだ 業務で使ってない素人は平気で例外禁則とか言って返り値チェックで死ぬほど汚いコード書くんだよな まぁ業務と違って趣味は時間を無駄につぎ込めるから
人によっては素人の方がレベル高かったりするけどな
そういうのと比較するのはホントやめて欲しい >>163
例外禁止されるのは業務の方だろ
一見汚くなるがそちらの方がバグが少なくメンテしやすいという判断で
トップダウンで強制される
趣味なら最新の機能ばんばん使って自由にやりゃいい 実際には例外を禁止するとバグが増えてメンテしにくくなるんだけどな そのソフトが気に入らないなら、
そのソフトを使わなきゃ良いだけだし。
そんなことも、いい年になって、わからないのか。 単なるエラーを返すのに例外機構みたいな大域脱出って牛刀感あるよな。 エラーコードの取り間違いやチェック漏れがないように書くにはすごい集中力が必要で神経をすり減らす作業
スローすれば僅かな労力で安全に済むところをわざわざ戻り値にするのは事を大げさにするだけ なあに、例外のcatch漏れや例外安全を欠いていないか注意するのと比べたら
たいてい局所的に判断できるから大したことない。
>エラーコードの取り間違いやチェック漏れがないように書くにはすごい集中力が必要で神経をすり減らす作業
検査例外じゃない例外機構でそれを保証するのも簡単じゃないと思うがな。
まぁ、一人開発で投げるのもcatchするのも全部把握しているという前提ならわからんでもないが。 >>179
そのへんはチェックするツールとかあったりしない?
知らんけど。 実はキャッチ漏れは戻り値処理漏れよりはるかに少ない
戻り値処理はその場でエラー処理したくない場合にも一度変数に受け取って分岐を入れて呼び元に返すということを繰り返さなければならない
なので処理漏れを起こしうる確率が呼び出し箇所の数に比例して増えていくことになる
そして本当のエラー処理をしたい場所が隠れてしまいコードの可読性が低下する
可読性が低下すればミスがさらに増える
例外なら処理したくない場合は何も書かなくていいので間違えようがないので安心
またエラー処理をしたいまさにその箇所だけに処理を書けばいいのでコードの見通しが非常に良くなりミスも激減する
エラーコード戻し安全なコードを書くことは実は非常に難しい
エラーコードチェックのせいで無駄な変数と分岐が大増殖するので正確にシステムの状態を追うことが困難になりミスが増える
例外を使えばフローが非常に単調で綺麗になるので安全なコードを書くのも簡単になる 同じ理由で、忌み嫌われてるgoto文も、実はけっこう便利だと思う 正しく使えば何だって便利だし、
駄目な使い方をすれば何だって駄目だっていう
すごく当たり前すぎる話 >>183
>>180
プログラミング辞めてツールでチェックしてもらえば? >>180
それが検査例外じゃないかな。
いろいろ批判もあるけど、例外の内容に応じてそれぞれ異なるリカバリを確実に行うことを
保証する手段としては今のところそれ以外無いかなと思う。
まぁ、erlang/swiftあるいはgoのpanicのように、エラーの種類なんて気にせず「この下の
処理が失敗した」とだけ捉えるのが例外の扱いとして妥当なところかも。 >>181
使い捨てでないまともなプログラムはいたるところにエラーリカバリー処理が入る
つまり例外だといたるところにtry catchかつ外に投げる例外は誰がcatchするのか仕様が複雑
仕事で大規模なプロジェクトに関わったことない人はこういうのが理解できていない 例外押しのやつはどうせほとんどcatchせずにそのままexitさせてるだろ
exitするぐらいなら異常が発生した場所でabortする方がはるかにいい
確実にスタックダンプが残せる 例外が有用なのってネットワークとストレージのioぐらいという認識
それ以外で必要性を感じない
配列外アクセスとかで例外とばすなと思う >>188
そういうバグが原因の例外はcatchしなければいいんでは? >>189
だから現実的にそういうのに例外をなげる仕様にありがたみがないでしょ >>190
なんで?SEGVも起こさずに潜在的なバグとして残り続けるよりよくない? >>191
自分でcatchするならtry catchがうざい
バグ扱いでcatchしないならそもそも例外投げずにpanicされた方が調査が楽
また下手にどこかでcatchされたらバグに気づかない危険性がある
以上の理由により ID:cHsPUmRi ってcatchで全ての例外がキャッチされると思ってるのか? 例外が発生しました
「このPCの電源が入っていません」 例外機構は誰がキャッチするのか別の問題を作った
問題先送りで日本人らしい
結局本質的には何の解決ももたらさなかった
例外機構はオカルトだったんだ。占いの類 >>197
エラーを返却値で返すことにしたところでそれは同じでしょ。
どこまで上に (返却値によって) 伝播すべきかってのは
どこでキャッチすべきかと問題は同じだよ。 ダウソファイルのファイル名置換する簡単なプログラムをC++とC#で書いてみた(C++で作って、それ見ながらC#に変換した)
もともとシェルスクリプトでもいいようなプログラムなんで実行速度とかどーでもいい
コンパイル時間長が
C# <<< 超えられない壁 <<< C++
C++のコンパイル時間と比べるとC#は一瞬で完了する。これは、快適性がだんちだな。 リターンコードスタイルにすると
無駄な変数が増える
無駄な分岐が増える
エラーコード追加時に全ての呼び出し元を精査しなければならない
エラーに付随する情報を伝達する標準的な規則が存在しない
全ての正常系の処理にコードチェックのオーバーヘッドが追加される
ライブラリ内部で発生する例外への対処が困難(例外を基本としていれば容易に対処可能)
参照透過性が壊滅する
デメリットだらけ >エラーコード追加時に全ての呼び出し元を精査しなければならない
>参照透過性が壊滅する
例外ならそれが解決すると考えているならちょっとやばい。 >>203
返り値でエラー通知するようなセピア色の世界にいるとわからんかもしれんが普通に解決するぞ 参照透過性ってそういう意味だっけ?w
最近例外ない言語増えてる事実はどう考える? >>203
リターンコード方式や例外と参照透過性になんの関係があるんだろう…
>>205
> 最近例外ない言語増えてる事実はどう考える?
Go以外にあったっけ? まぁ、実際関係ないね。
同じ入力に対して常に同じエラーコードを返すなら参照透過性があると言えるし、
入力によらず場合によって例外を返すことがあるなら参照透過じゃない。 「呼び出し元を精査」とかプログラム内のデバッグに例外使ってるような書き方やね
例外処理は外部的要因(ハード、通信等)のエラーのように自分の責任外のエラーを積極的に通知するために使うべきだと思うけどな 戻り値形式ではそもそも式として書けないから参照透過性もクソもないということをまずは理解しろ
int h(P const & p, Q const & q, Z & out_z) {
X x;
Int ret_f = f(p, x); // out ref x
if (is_error(ret_f)) return ret_f;
Y y;
int ret_g = g(q, y); // out ref y
if (is_error(ret_g)) return ret_g;
z = x * y;
return RET_OK;
}
↑例外を使わない下品すぎるコード
↓例外を使ったスーパーエレガントなコード
Z h(P const & p, Q const & q) { return f(p) * g(q); } Real Programmers Don't Use Exception. >>206
rust
swiftは最初なくて後で追加
積極的に使うスタンスでない >>209
そこに丹念なエラー処理を追加していくと、あら不思議どっちもあまりかわらない >>211
それってやっぱりいるじゃん
ってことだよね w
>>212
え?
何言ってるの?
エラー処理ってなんのこと?
具体的に書いてみて >>213
エラー処理って言ったらまぎらわしかった
異常系の対応ってこと 何にでも丹念なエラー処理が必要になることはないし
丹念なエラー処理も例外の方がやりやすい >>214
エラー処理でも異常系の対応でもいいから具体的に書いてくれよ
>>209程度ならたいしたことないだろ >>216
具体的にするには前提がいるでしょ
f、gは外部から与えられてる関数で中身を書き換えることはできない
かつ至る所で使われている
p、qは誤りを含んでいる可能性があって、異常(エラー/例外)が起こりうる
異常の場合は何かおかしかったの後で調査できるようにログに残す、
または人間にフィードバックしてリトライさせる必要がある
製品レベルのソフトウェアならいたって普通の前提と要件
これを実現するとどうなるかは想像つくでしょ?
おれは例外否定派ではないよ
役に立つところは限定的と言う主張
>>188 がおれだから
まぁ確かにどちらかで言えばなくてもいいとは思ってる
ただ現状C++の標準ライブラリは例外ありきの設計に突き進んでいるから
エラーコードで突き進むのは筋が悪いのは確か >>218
> p、qは誤りを含んでいる可能性があって、異常(エラー/例外)が起こりうる
意味わからん コード書けないならそう言えば?
長文で言い訳してないでさ 普通は馬鹿に割く時間がもったいないからコード書けません 信者ですらわずかなサンプルコードを書くのをためらうほどには戻り値スタイルは厄介な代物ということがわかったね
くだらない言い訳で長文を書く労力よりも高くつくということがはっきりした 勝利宣言の後で申し訳ないけど
h()でハンドルするとしたら単に
Z h(P const & p, Q const & q) {
try {
return f(p) * g(q)
} catch (exception_invalid_arg_f e) {
throw exception_invalid_arg("arg p is invalid");
} catch (exception_invalid_arg_g e) {
throw exception_invalid_arg("arg q is invalid");
}
}
みたいにリアス海岸になるわけでしょ
でもこれはpとqの異常の区別が下からあがってくる例外で区別できてしまう特殊例
Z h2(P const & p, Q const & q0, Q const & q1) {
return f(p) * g(q0) * g(q1);
}
だとより複雑になる
じゃあこれ次の人やってみて やっぱり例外機構はオカルトだった。皆が長い間この迷信に惑わされ疲弊した >>231
まさかと思うけど>>225でcatch書かなきゃf()やg()で発生した例外はそのままh()の呼び出し側に伝搬すること知らんのか?
あと、例えば引数がおかしいと言う例外なら例外情報に引数の値などを含めて一番外側でログを採るとかするから
> Z h2(P const & p, Q const & q0, Q const & q1) {
> return f(p) * g(q0) * g(q1);
> }
> だとより複雑になる
なんてことはない ほらな言った通りになった
戻り値スタイルはただ異常処理を上位に委ねるだけでも多量のコードを書かなければならない
だから本当に処理すべき異常や正常系の処理が異常伝達に埋もれてしまいコードの可読性が著しく低下してしまう
>>225が>>209のサンプルコードの意図を誤解した理由がこれだ
>>225が間違えたのは予想された事だったんだ
>>225が例外スタイルでは必要ない障害伝達を書いてしまった理由も根は同じ
戻り値スタイルを書き続ける事によって関数コールの周りに障害伝達を書くのは当たり前の事なんだと頭の中に刷り込まれて思考停止してしまった
結果として例外スタイルを書く際にもいつもの癖で不要な障害伝達を書いてしまった
そして戻り値スタイル派の人々は自分達が戻り値スタイルの常識にしたがって書いた例外スタイルの酷いコードを見てこう言うのだ
「ほらやっぱり例外はダメじゃないか」
とね >>232
> > だとより複雑になる
> なんてことはない
具体的にコードで書けよw
要件は >>218 な
h()が異常処理の責任を持つ前提でな
上に例外伝搬させてるだけでは問題は何も解決しねーから あと
>>225
で例外投げなおしてるのは本質じゃない
単にそこでなにかしら異常系の対応をするという意味合い
人間にリトライさせることを考えると h()を呼び出したのがUIのフレームワークで
呼び出し側が "arg p is invalid" というメッセージでどっちの間違いが判定するなど
(現実には文字列で判定させる実装にしないだろうが、例な)
そこをそのまま exception_invalid_arg_f を上に伝搬させればいいだろと思うのはど素人
h() から外部ライブラリの exception_invalid_arg_f、exception_invalid_arg_g がそのまま
あがってくるというのは一般的にソフトウェアのレイヤー構造を崩してる
もちろん自分が担当している範囲ならありだが、
h() を外部に公開するような場合は仕様の責任をもつために自分で定義した例外で
投げなおすのは当たり前 とりあえず戻り値スタイルでコード書いてくれよ
例外版に直してあげるからさ >>235
ほら何もわかってない
エラー発生箇所でなんでも解決しなきゃならないと洗脳されてんだね
何もなくてもエラー処理コードを書かなければならない戻り値スタイルの書きすぎで感覚がおかしくなってる >>236
戻り値スタイルに慣れるとレイヤー境界がどこかも定義せずに例外変換をしてしまうようになっちゃうのかな
そして本当に変換が必要な例外は何かということも考えなくなってしまう
必要かどうかわからないけど何かしなきゃって強迫観念に苛まれてるのだろうね
戻り値スタイルだと伝達処理が必須だから例外スタイルになると不安になるのだろうな 戻り値を使う例
printf("%d\n",printf("1+2+3=")); 配列・ポインタ・構造体・クラス→「プログラミング楽勝ンゴwwwwww」
スレッド・コルーチン・テンプレート→「あばばばば・・・」 はい誰もコード書かないw
お前らちっさいコードとか異常系の甘いコードしか書いたことないから例外マンセーなんだよ やっぱり例外機構はオカルトだった。皆が長い間この銀の弾丸を装った迷信に惑わされ疲弊した >>244
だから後出し条件出されると困るから戻り値スタイルでコード書いてくれ
って書いてあるだろ
例外とあまり変わらないんだから書けるよね? あのなぁ、俺は他の機能についての話で何度か書いてるけど、
適切な場面で適切に使えってだけの話で、
どんな機能だってそんなに万能だと思ってるやつなんていねぇよ。
どうせ回復できない異常ならちまちまと返却値をとりまわして
上まで運ぶのはクソ面倒くせぇし、
その場で対処する必要があるようなものは
try/catch よりも if で書いた方が短くて簡単だし取りこぼしにくいってのはわかる。
どちらにするべきか判断を付けるコストの方がデカいわっていう場面なら
各プロジェクトのポリシーで一方に決めつけたって別にかまわん。
当たり前すぎて主張するのがアホくさいんだけど、
そんなことは場合によるとしか言いようが無いだろ。 異常系の処理がシビアになればなるほど例外が有利になる
リターンコードスタイルは複雑化した分岐と大量の変数のせいでミスを誘発しまくる
例外ならば必要な時に必要なだけ異常系の処理を書けばいいので混乱することはない
例外スタイルにはまったく過不足がない
やりたいことをジャストそのまま書けばよろしい 例外はその機構が重いから極端な異常系にしか使わないようにしてるのも今は昔の考え方なのかな >>250
ここ数10レスほど続いていた中身のない不毛なやり取りより>>248の1レスの方が有意義だと思うぞ >戻り値スタイルに慣れるとレイヤー境界がどこかも定義せずに例外変換をしてしまうようになっちゃうのかな
レイヤーの境界やエラーの粒度の違いに頓着しないのは、どっちかというと安直に例外投げれば良いと
考えている方のような気がするがな。
この一連の発言見ても、投げた例外が誤ってレイヤー境界を越えてしまわないようどう保証するかなんて
言及してた人いないでしょ。 >>251
例外にもいくつかの方式があって、SJLJ ってやつは例外を投げないときもやたら遅いが、
他のほとんどの方式は例外を投げないときはゼロに近いコストのはず。
ただ、 SJLJ 以外の方法というのはデバッグ情報を使うためにツールチェインとの連携が必須だとか、
ハードウェアの機能を使うとかいった制約があって移植性に難があったりもするので、 SJLJ も滅びずに残ってる。
要するに例外の処理速度は場合によるが、
普通のデスクトップコンピュータで SJLJ を使わざるを得ないようなみみっちいツールチェイン、ハードウェアって
ことはあんまりなかろうと思う。 (ある?) >>255
リターンコードスタイルはレイヤ境界どころか体系的にエラー処理を考えるということをしないからなぁ
例外スタイルの人はじゃあどこで処理すんのということもちゃんと考えてる 例外でイベント発生させて、イベントハンドラで受けるのはど? >>255
> この一連の発言見ても、投げた例外が誤ってレイヤー境界を越えてしまわないようどう保証するかなんて
> 言及してた人いないでしょ。
保証は言語側でやってくれるから言及する必要がないだけのこと
そもそも例外は>>249の言う通りその場所で必要なものをキャッチして処理をすればいいだけ swith caseで分岐する場合もあれば、
関数へのポインタテーブル作って、ジャンプさせる場合もあるわけで、
例外も戻り値分岐も両方普通に使わないか?
C++てイベントとかイベントハンドラは環境とかboost任せで、言語仕様としては未だに確定してないのか?
C++11でようやくマルチスレッドや排他制御が仕様に盛り込まれたり、
テンプレートの仕様いじくるよりこっちの方がよっぽど大事なんじゃないのか? >保証は言語側でやってくれるから言及する必要がないだけのこと
保証なんてしないよね?catch忘れたらそのまま上まですっ飛んでいくだけ。
Javaのような検査例外ならそこに差異があることを意識されられるかもしれないけど。
>そもそも例外は>>249の言う通りその場所で必要なものをキャッチして処理をすればいいだけ
そこでプログラマが考える「必要なもの」から漏れた例外は上位へ渡されてしまう。
それを防ぐためには呼び出し先から送られる可能性のあるすべての例外を把握する必要があるが、
検査例外がないなら動的型付言語のように投げる側と受け取る側とで平仄を合わせてやるしかない。 大前提が間違ってる
例外なんか最終的にはフレームワークが最上位で纏めてキャッチすりゃいいんだよ
途中でキャッチして処理するのはあくまでベターなオプションであり、それを必須とするような作りにしてはいけない >>261
> catch忘れたらそのまま上まですっ飛んでいくだけ。
闇雲にキャッチしたいならcatch(...)ってやればいいだけ w
> そこでプログラマが考える「必要なもの」から漏れた例外は上位へ渡されてしまう。
本来キャッチが必要な例外を漏らしているならそれはバグ
それは戻り値スタイルでも同じ話
違うのは例外はキャッチする必要の無い例外についてはそこで考慮する必要はない、自動的に上位に渡されるから上位の然るべき場所で考慮すればいいから
それが>>249の言う
> 例外ならば必要な時に必要なだけ異常系の処理を書けばいいので混乱することはない
ってこと >>262
半分同意。
結局のところエラーの種類に応じてきっちり対処するなら検査例外的な仕組みが必要になるが
そうでなければエラーの内容など見ずにlet it crash的に対処するしかない。
どっちつかずが一番ダメなやつ。 (検査例外とかいうJava自身も認める失敗作は論外として、)例外機構は正しく使えばエラー処理に対する関心の分離に有効なんだよ。
ところがC++では例外を煩わしいノイズと見做す人が多い。これは即ち関心の分離ができてないわけだ。
その一番の原因は、例外型がロクに標準化されてないことだろうね。
最上位での集約処理を実現するには、下位の全てのコードが制御下になければならない。
これは膨大な既存資産と貧弱な標準ライブラリを持つC++においては非現実的な前提である。 すべての例外を把握する必要はない
回復可能かつ回復が要件に含まれるなら個別に処理すべき
それ以外はアスペクトで処理すればいい >>247
だからさ、比較できるように例外スタイルで一度きちっと異常系対応して
かつスーパーエレガントなのを書いてくれよって言ってんの
お前のは体よく異常系の処理全無視してるだけじゃん
catchしたい人が必要なところでcatchすればとか言うんだろうけど
例外発生場所から遠くなればなるだけ何が原因で例外が発生して、
その回避はどうすればいいかが不明瞭になっていくってのは
散々語られてる例外の欠点
リターンコードは泥臭いが下層からくるエラーをどう処理してるかはコード見れば一目瞭然
エラーを上位に伝搬させるか、リカバリーするか、その場でクラッシュさせるか
ローカルに記述が完結できてる
APIとして外部に公開するときもインタフェースの仕様にきっちり責任持たせることができる
ちなみにプルリクでレビューする文化があればエラー無視してるような雑はコードは突き返されるだろう
見ればすぐわかるんだから
大規模な開発を経験したことない人はこういう観点でソフトウェア開発を
考えられないんだよ
最後にもう一度言っておくけどおれは例外を完全否定してるわけじゃねーから
使える場所は限られるって意見ね >>262
> 大前提が間違ってる
> 例外なんか最終的にはフレームワークが最上位で纏めてキャッチすりゃいいんだよ
これがど素人の意見
ソフトウェアの品質について考えたことがない 「不正な入力です」
「ネットワークでエラーが発生しました」
「書き込みに失敗しました」
こういう情けないダイアログが表示させて終わりのアプリを作るやつね >>269
それでも正常に回復できてるならそれでいいケースは多い
例外の最大の利点は例外安全さえ死守できていればアドホックな例外処理が必須でなくなることで、
より丁寧な処理が必要になれば後から追加すればよい
まあ組み込みとかやってる人には馴染まない考え方だろうね まあC++開発者が未処理例外=クラッシュと短絡的に考えてしまう気持ちはよく分かるよ
呼び出し階層の途中に一つでも if (hoge() != SUCCESS) errorhandle(); があれば例外安全は破綻するわけで、あまりにも非現実的 >>267
仕様は>>218が決めるんだから>>218がコードを提示すべき
>>236みたいに後出しの条件出されても困るからな >>267
> 例外発生場所から遠くなればなるだけ何が原因で例外が発生して、
> その回避はどうすればいいかが不明瞭になっていくってのは
> 散々語られてる例外の欠点
それ戻り値スタイルでも同じだろ
> リターンコードは泥臭いが下層からくるエラーをどう処理してるかはコード見れば一目瞭然
だからそれはすぐ上位で処理することが前提になってるだろ
上位に何度も伝搬したら例外と同じになる上に伝搬するコードをそこら中に書く羽目になる
> ちなみにプルリクでレビューする文化があればエラー無視してるような雑はコードは突き返されるだろう
例外処理を書かないことはエラーを無視するんじゃなくてそのまま上位に伝搬してるだけ
書かないと無視してると取るのは例外をきちんと理解してないってこと
> 見ればすぐわかるんだから
お前の能力がな w >>267
例外を使いこなせていないね
例外の型とパラメータをみれば何が起こったかはっきりわかる
おそらく君は例外の種類を使い分ける習慣がないだろ?
あったとしてもせいぜい標準ライブラリの例外をなんとなくふり分ける程度だろうね
でないとこんな発言はしないから
まずは例外を定義するところから初めてごらん
それと大規模開発をしたことがないのはそちらだろう
関数コールするたびにずらずらと変数や分岐を書かれたらあっという間に管理不能になる
大規模だからこそ標準的なコード、必要十分なコードというのが大切になる リターンコードスタイルをレビューに出すと袋叩きにされるぞ
・ノイズが多すぎて正常系のレビューが不可能
・同じくどのエラーが上位伝達、エラー変換、共通対応、個別対応なのか見てすぐにわからない
・同じく要件漏れを見落としやすい
・正常系、異常系、判断、伝達などあらゆる要素が密集して強く結合しているため仕様変更があった場合の影響が大きすぎてレビューしきれない >>275
考え方自体には同意するけど、>>271で示したように例外安全が破綻しているケースについてどう考える?
エラーコードを前提にクリーンアップ処理が記述されているコードが混入しているような場合ね
あくまでC++に限った話だけど、大規模開発で完全な例外安全を維持するのは極めて困難だか実際には絵に書いた餅と思ってる >>276
訂正
極めて困難で、実際には絵に描いた餅 >>276-277
必要なら直せばいいだけ
非常に稀な事象についてまで例外安全を遵守する必要はないでしょ
そもそもそういう変なコードが混入してる体質の組織で何を言ってるんだよ? って話だと思うけど >>279
文化と素養の問題だよ
例外の是非でこれだけ荒れる現状を見てれば、例外のスルーなんて怖くてできねえよ
そりゃあんたが全てのコードをレビューしてマサカリ投げまくってくれるなら別だけどねえ >>280
ごめん、言ってることがよくわからん
そもそも
if (hoge() != SUCCESS) errorhandle();
なんてコードがあったら戻り値スタイルでもどうしようもない
例外は魔法の杖じゃないんだから何でもかんでも例外使えば解決するわけじゃなくて戻り値スタイルより楽にできるというだけの事だよ
プログラムがデカくなるほどその差は開くけど >>281
result = hogehoge();
if (failure(result)) エラー処理();
リソース解放();
これhogehogeが例外起こしたらリークするだろ >>282
スマートポインタ使うなりcatchしてリソース解放して例外再送出するなりいくらでもやりようはあるだろ…
ちょっとレベル低くね? >>283
だからそれが例外安全だよ
勉強になったね >>283
基本的にデストラクタやリソース開放系は例外投げられると大変なことになる
catchしてなんて簡単にいってるけどもcatch(...)をそこに入れることになるのはわかるかね で、そんな当たり前のことを言って何が言いたいの?
聞きかじりの知識を披露してるとしか思えないんだが… w 例外機構は宗教
多くの人が正しいと盲信しているに過ぎない 戻り値でイベント投げるという選択肢がない言語使用自体くそじゃね? Cにそんな機能あったっけ?
それとも別の言語の信者が折伏に来ているの? >>265
そう、検査例外を正しく使うのはしばしば困難で批判も多いな。ただ、呼び出す処理がどのような
例外を返すか、静的な型検査による保証を与えてくれる仕組みとしては他に無いのも事実。
検査例外を否定するのであれば例外型に頼らない(>>264の後者)か、プログラマの努力で
整合をとってやる(>>261の最後)カウボーイ的プログラミングになる。
>>265はあくまでも例外に型を期待しているようだからカウボーイの方なんだろう。 >>291
>プログラマの努力で整合をとってやる(>>261の最後)カウボーイ的プログラミングになる。
…
…
これって「カウボーイ的」と形容されるべきものだったんですか?
catch の引数は値ではなくて、「型」だから、
テキトーな super class ERROR の下に個別エラー用派生クラスを列挙しておき、
臨機応変に catch (ERROR &e) を噛ましています…
>>256
一応例外を投げておくけれども、まじめにサポートする気はさらさらなく、
そもそもやる気は皆無・全くゼロであることを、ただ、それだけを全心全霊で表現するためだけに
throw 13; 例外の処理速度については、こういう提案もある。
https://ezoeryou.github.io/blog/article/2018-07-10-static-exception.html
要するに、投げるオブジェクトが条件を満たすときは、
暗黙の返却値のような形で例外を伝播する仕組み。
バイナリレベルの取り扱いも ABI を決めさえすれば済むだろうし、
互換性も確保しやすそうに思う。 環境の方の質問NGなら完全スルーでお願いします
Windows8.1 64bit のうえで Windows98SE でも動く C のバイナリを作ろうと思ってるのですが
LSI C 試食版以外に何か良い方法がないかなあと…
Windows98SE の方に Visual C++ 6.0 & SP6 をインストールしても良いのかも知れませんが
DLL の整合性とか不安
VC++ 2005 は iso 持ってるだけ…Windows98SE で動くバイナリが生成できるとか何とか 業務で使った経験は一切ないです
使い捨てレベルのものを書くのが目的です TEST::TEST()
{
うんたら
}
ってコンストラスタがあって、このクラスにパラメータ付のコンストラスタを追加したいとき
C# だったら
TEST::TEST(int param) : this()
{
増やす機能
}
みたいに書きますが C++ の場合はどうやって書きますか TEST::TEST(int param) : クラスのパラメータ(param)
{
増やす機能
} >>297
委譲コンストラクタでググると出てくると思う。
たしかC++11で追加された機能。 >>295-296
LSI-C試食版 って Windows 用どころか MS-DOS (16bit) の、しかもスモールモデルしか作れないじゃん。
使い捨ての、いいかげんな富豪的プログラミングしたらすぐメモリ足りなくなるぞ。
ワイとしては Open Watcom C++ を推すやで。 LSI-Cとかなっつw
昔の勉強用コンパイラといったらこれだったな >>302
Cマガの付録CDに常に収録されてたよな! >>298-299
TEST::TEST(int param) : TEST()
{
増やす機能
}
で出来ました。ありがとうございました。 bcc32c でコンパイルしたバイナリが Win98SE 上で動くことを確認…
Win98SE 上だと Turbo C が動くことを確認…
Open Watcom C++ というのは存じませんでした
確認してみます >>295
> VC++ 2005 は iso 持ってるだけ…Windows98SE で動くバイナリが生成できるとか何とか
なんで試さんの? LSI-C試食版www
懐かしいなあ
あの頃はものすごくCPU遅かったよね
486にして感激したからな
もうC言語でプログラムはしたくない
C++だ・・・ 古いOSでも動作させたいけど、ソースは新しい規格で書きたい、
と言うのは要望としてはありうるな。
>>295 はLSI-C試食版(C89相当だっけ?)を使ってるようだから、
そのクチではないのかも知れんけど。 >>310
今時なら仮想マシンでやればいいだけだろ >>312
コメント前に // つけるより
/*
コメント
*/
あるいは
#if 0
コメント
#endif
のほうがすっきりしないか? だから何?
それに同意しようがしまいが単一行コメントのときに面倒なのは変わらないよね
個人的にはエディタがコメントの一括付け外しに対応してるなら複数行でも//の方が見やすいと思ってるけど C言語の a=b; って
アセンブラで言うと、メモリ→レジスタ→メモリって移し替えてるのと同じ?
メモリ→メモリにデータコピーする時って、必ずレジスタを経由しないとだめなのかな?
アセンブラ勉強初めたばっかで何言ってんだこいつ的な感じだったらごめん。 >>318
CPU の種類による。
アセンブラはアセンブラという言語の規格があるわけではなくて、
各コンピュータの機械語の単語を便宜的に読みやすい書式に置き換えた
ものの総称なので、使える命令は各アーキテクチャのデザインに従うし、
書式のバリエーションもある。 いくつかの伝統的な習慣はあるけれど。
データの移送にレジスタを経由しなければならないようなデザインの CPU もあるし、
そうでないものもある。
メモリアクセスをする命令とその他演算の命令を明確に分離するようなデザインの
アーキテクチャを特に Load?store architecture と呼んでる。
https://en.wikipedia.org/wiki/Load%E2%80%93store_architecture
コンピュータの設計の根本を左右する方針の違いなので、
理解があやふやとはいえ、ここに引っかかりを感じたというのは才能を感じる。 >>319
自分が勉強してたCPUがたまたまレジスタ必要とするものだったということですね。ありがとうございます。
あと、intelとryzenは、どちらのCPUであっても殆どのソフトは動作しますが
この2つのCPUのアーキテクチャオペランドは同じということでしょうか?
ゲームなんかは高速化の部分でアセンブラ使う場所も頻繁にあるんじゃないかなと思うのですが。 >>317
wwww
逆に、だから何?
エディタが/* 入力と同時に
*/ を自動挿入してくれるなら全く変わらないだろ
それともおまえのエディタは / 入力で
もひとつ/ を自動挿入するように設定でもしてるのか?
ゆとりもここまで来るとどーしよーもねーな。 >>318
>>319
状況によるが、
a = b;
はメモリを介せず、できるだけレジスタ間コピーになるように最適化される。
んでメモリ to メモリを許すのはCISCと相場が決まってる
RISCはメモリ to メモリは命令にない 。命令セットを減らしてるからこそ reduce
このおかげで回路が簡単になり、所用クロック数をほぼ等しくして、クロック(Hz)をあげることができた。
このタイプはメモリ→レジスタ→メモリとせざるを得ない
今は、パイプラインを深くして、CISCでもクロックをあげられるようになったのでRISC/CISCはあんまり関係なくなった。
CICSの代表はx86なのでメモリ→メモリ命令セット調べてみ。
CISCの歴史的な経緯がわかるのは、これもCISC代表のx68kやH8は、命令セットごとに大幅に所用クロック数が違う。
それに対してx86の流れをくむ最新設計のRL78だとほとんどの命令セットが1クロックとなって。RISCと変わらない上に、
メモリ to メモリが可能となってる。それでも メモリ to レジスタに比べて1クロック増えてる。
メモリ to メモリ とレジスタ to メモリを同クロック数で実行しようとするなら、 バスラインがもう一組(例えば32bit)必要になった上に、
2ポートメモリが必要になってしまうwwww >>322
自分で複数行が前提だと言っときながら何言ってんの君 >>325
*/の自動補完は複数行だろうが単一行だろうが関係ないだろが。
おまえがエディタ支援による入力補助を持ち出したから応じてやっただけだろゆとり
入力の手間はむしろ/* */の方が楽なんだよお馬鹿さん >>325
それとさ俺が複数行限定といってるのに
>>317
>単一行コメントのときに面倒なのは変わらないよね
また単一行の話をしてるのはそっちだろーが。
おまえは朝鮮人か?それともボケてんのか? まあ例えばインテルアーキテクチャでも、
機械語の命令列を内部で μop に分解して最適化してから実行したりするので、
機械語のレベルなんてまだまだ高級な層。
内側では RISC 的なデザインとも融合していて
正直言って、そこで何が起きているのか正確に理解するのは無理。
(結果に影響しない範囲で) 命令を並べ替えることすらあり、
しかし、マルチスレッドと絡むとわけわかんなくなりがち。
Z80 の牧歌的な世界を知ってると隔世の感がある。
実際、演算能力で言えば何百倍とか何千倍とかいう規模で違うもんな…… Z80Aで、おおむね4Mhzだったような
無印Z80は知らない
日本人だとZ80AよりμPD870Cの方が普及??? >>329
μPD780C-1な。870だと電卓チップになってしまう。
詰めが甘いな :-P 初心者です
関数の引数の1つとして3種類の構造体を受け入れたいという場合オーバーライドで3つ書くのよりスマートなやり方ありますか? 関数テンプレートというものが一応存在する。
tempate<class T> void func(T arg)
{
...
}
このように記述すると、型に応じたオーバーライドをコンパイラが自動で作成してくれるという機能。
ただ、実際に呼び出すコードを書かないと(型が確定してないから)コンパイル対象にならなず限定的なエラーチェックしか行われない、
エラーが出た時に問題が関数内なのか呼び出し元なのかが分かりづらい、エラーメッセージもわけわからない、という欠点があるので、
あまり初心者向きとは言えない。すごく便利なんだけどね。 >>333-334
ありがとうございます
オーバーロードでしたね^^; >>335
Variantが使えるならVariant
対照的にunionはおすすめしない >>336
variant勉強します
ありがとうございます 投機実行がセキュリティホールになるなんて
当時の技術者は予見できたのだろうか いやー
論文ネタに困った情報系の役にたたん学者がひねり出したネタだろ
投機実行を攻撃に使った実例なんてあるのか? 煽ってたら論文ネタに困った情報系の役にたたん学者が投機実行を攻撃に使った実用法をひねり出したらどうすんだ >>340
手元にようやく SandyBridge(IvyBridge) を確保しましたのでいろいろ試してみようと思っています Googleだったっけ、見つけたのは?
役に立たない暇な部門があったんだ C++って未だにasync,awaitがないんだな?
江添とかtemplate使えないC++プログラマはポインタを使えないCプログラマと同じゴミとかいってるんだが、
templateは確かに面白いし頭の体操になるけど、templateはひな形があれば、泥臭くエディタちょい編集して使い回したり、
yacc/lex使うとか、ループのアンロールはスクリプトで展開するとかいくらでも手段はあるので、
どう考えてもasync,awaitあたりの実装の方が重要だと思うけどな。 futureでいいんじゃね。C#のawaitもFutureパターンの実装でしょ。 >>345
.net動いてるのとそれが前提でないC++では全く同じにはいかんのだろな
教えてくれてありがと コルーチン拡張は提案段階なんだっけ?
MS界隈ならC++/WinRTで使用例があるけど >>346
いや別に
C#のasync/awaitって単なるステートマシンジェネレータだし
標準化は至難だろうけど技術的にはC++でできない理由はない >>344
再帰includeとdefineの組み合わせでも大抵はなんとかなったりするなw
templateは型に縛られてるから安全な反面、不便なこともあるよね。
sjisとutf8が区別できないし。なぜchar8_tを作らなかった…(´・ω・`) テンプレートよりObjective-Cのやり方の方が好き 江添なんて最新仕様知ってる俺スゲーやりたいだけの奴だからな。
まともに使えるプログラムを書いてるわけじゃない。 >>351
江添とか書いてることみてるとムカっ腹立たないか?
何様だこいつ。しかもやってることキチガイだろ >>357
は?お前じゃあ江添より仕様に詳しくてC++のコンパイラを実装出来るような能力なのかね?ええ? 例え世界一の物知りでもそんな口の効き方をする人とは
付き合いたくないな
RMSにはEMACSやgccといった作品があるから許される この3冊は、日本人が作った神の書。
皆、基地外。基地外しか、こんな本を書けない
Linux プログラミング・インタフェース、Michael Kerrisk、2012
この本は、神の書と言われていて、翻訳本は日本しか出ていない。
著者は10年、man-pagesを書いてきた人で、翻訳者・アドバイスの千住治郎も、技術者
C++11/14 コア言語、江添 亮、2015
組込み開発者におくるMISRA‐C:2004―C言語利用の高信頼化ガイド、MISRA‐C研究会、2006
ドワンゴ江添は需要があれば、テンプレートの本を出そうか、なんて言ってるけど、既にこの本がある
C++テンプレートテクニック 第2版、
επιστημη(えぴすてーめー)・高橋 晶、2014 Linuxの黎明期にman page 書いていたのは janneさん事、中谷千絵さんだよ
エピスメーテーさんは昔っから雑誌に記事を書いていたな
The Basicだった?
真ん中の人は知らないけどどんな貢献をしたの? >>363
ざべは読んだことないけど、Cマガでεπιστημηの名前はよく見たな。
今では Teratail で C++ の質問をするとたまに回答者として出現するよ。 >>364
そうでしたか、CUJJとかは買っていたけど...CMAGは
時々だったので >>361
えぴすてーめーと高橋のC++テンプレ本は神だわ。
なんというか、読者に理解させてあげたいという熱意が伝わってくる
江添とは大違い
江添にお布施するつもりは毛頭ない。死ねばいいのに >361 の3冊は、単なる規格の文章ではなく、それをソースコードの実例にした所がすごい!
だから、プログラマーは皆、Kerrisk の本を枕にして寝ろって、言われている
たぶん、江添やMISRA‐C の本も、外国で発売されていれば、大絶賛されるはず! エピスや高橋ageて江添sageってのもよくわからんな
立ち位置違うし江添は委員会の人間だから
仕様や提案について素晴らしいとかクソとか言う権利や責務がある
それをsageるってことは「現行仕様マンセー、標準規格に欠点など無い!」みたいなことか? >>361
エピさん単著は買わないですね、エピさんの文章は今の言葉で表現するとすれば「ポエマー」が近い
同じくポエマーに分類される私がいうことではないのですけど… 元々は、Kerrisk も、江添やMISRA‐C のメンバーも、
規格をソースコードの実例で、表示してやろうという、とんでもない企画!
よく規格厨みたいな香具師がいて、企画書を読めって言うけど、
文章で書かれてもわからないし、全く出来るようにならないから、業を煮やして書き始めた
こんな面倒くさいことを、何年も掛けて書くかね?
こういうのは、忍耐力がある日本人が得意なんだろう。
外人は、まずやらない MISRA はBOSCH を引き込み損なった時点で絵に描いた餅でしょうね
デンソーが勝利すれば勝ちの目も出て来るかもしれないが >>371
>規格をソースコードの実例で、表示してやろうという、とんでもない企画
いや言語の解説本は規格をわかりやすく、ソースコードを例示して解説するでしょ。
それがなければ、規格だけでいいわけで、解説にならない。
わかりやすく書こうとしてるけど、そこの熱意の持ち方と、おつむのレベルでほんとにわかりやすいかどうかが問題なんだろ。 そら商業目的の本だったらわかりやすく書くの当たり前だろ
江添の本は読んだことないから分からんけど
売られてる本とブログで比較してないか? >>371
>こういうのは、忍耐力がある日本人が得意なんだろう。
>外人は、まずやらない
K&R も Stroustrapも規格になるまえからやってますがな
ソース示してこつこつと。
何もプログラム言語だけじゃないわ。人に説くこと、伝道師のようなwriterは日本人よりむしろ、英米人に多い。
クヌースの The Art of Computer Programmingあたり読んでみ。 >>374
反響見て、読んだやつにバグだしさせてたあとブログ印刷物なり、ebook販売するんだから
金取ろうが、無償でやるかはどーでもいい話
日本語のコンピュータ書籍なんて販売数からしてとてもとてもメシ食えないから
ほぼ実益のないめんどくさいだけの作業
ブログでわかりにくければ本になってもわかりにくいことは保証する クヌースの4-1巻目は、かなりの分量をZDD/BDDの説明に割いていて
このアルゴリズムは北海道大学で日本人が考えた物だね
で、その江添さんという方はどの様な技術貢献をしたの? >>377
警察に喧嘩売って訴訟おこしたこと以外知りませんがな
きちがいの所業なんざ まぁC++テンプレートテクニックがわかりやすい良書なのは同意するけど
高橋晶ってたまにテクニックのメリットを語るときに
デメリットに気づいてない(またはスルーしてる)ことがあるんだよな
わかりやすくても鵜呑みには出来ない ま、江添が好きならどーぞご勝手に俺は願い下げってだけ 好きとは言ってないよ
結局役に立つ&正確な情報を書いてるかどうかが全てだ というか江添のブログでも「あれ?おかしくね?」みたいなことあったから
どっちがどうとも言えないけど 型指定するのが嫌だから最初にautoを使うc++入門書籍を書こうとしてたり、
まともにプログラム開発してたら最新の仕様を追えないので開発しないとか言い出す奴とか
普通の精神してりゃ信用せんわな。
根本的にありゃ馬鹿だよ。 >まともにプログラム開発してたら最新の仕様を追えないので開発しないとか言い出す奴とか
江添みたいに標準化委員会に属してたら正しいと思うけどね
何もコミュニティに貢献しない趣味グラマだったりライターでもない奴が言ってたらアホだが すみません
n秒ごとに関数foo()を繰り返し実行するような、かつ「低負荷な」方法を教えてください。
n秒は、精度はだいたいでよくて、たぶんnは600(つまり10分)程度にしたいと思っています。
windows 10 で、gccで最新の標準C++ とboost C++ が使用可能です
よろしくお願いいたします >>389
SetTimer API を使って WM_TIMER イベントの発生を待つのが妥当な方法だと思う。
イベントが発生するまでは何もせずに待つだけなので低負荷。 >>390
windows API をつかう方法で行ってみます
ありがとうございます。
標準C++ で導入された
thread とchrono を用いて、while (1 )を回すという方法がGoogle検索で 出てきますが、低負荷な方が良いので、windows API で行ってみます。
ありがとうございます。 whileは単なる無限ループじゃなく、スレッドが立ち上がるまで、sleep で CPU を眠らせてるんじゃないの?
whileだけだと、負荷かかるし、sleep一発だと、繰り返し待ちできないから https://ja.cppreference.com/w/cpp/compiler_support
gccは並列STLまだ実装できてないんだな。がかーり
C++2xは後回しでいいから先に実装してもらいたいな
msvcがしらん間にgccを上回るC++17準拠状況になってるんだな
msがかなり頑張ってるのがかなり意外 MSが標準をわざと外して潰し合う戦略を取ってたのは遥か昔
今は協調してシェアを取り込んでから独占する戦略がメイン >>396
つ ttps://cpplover.blogspot.com/2016/05/2016.html Class TA{
public:
TB B;
}
Class TB{
・・・
}
Class TA::TA(){ //コンストラクタ
B = new TB;
}
で、TAのデストラクタが走った時点でBも一緒に消えるんですかね。
それともTAのデストラクタで delete B が必要なんですかね。 >>401
new したのなら delete は必ず書かないといけない
https://ideone.com/z0IYgT >>403
理解はしますが薦める気にはならないのです… メンバ変数にクラスを持つときはポインタ型にしてコピーコンストラクタを作るべきですか?
それともクラスの実体を持たせても大差ありませんか? 実体で用が足りるならすべて実体でよい
効率云々はまず一通り動くものが出来上がった上でそこが問題になってから考えろ 値型とエンティティを意識して作って下さい
エンティティはスマポで管理、値型は実体を持たせるべきでしょう >>412
インスタンスがアイデンティティを持つならエンティティ >>413
実数はエンティティですか?
符号付整数はエンティティですか? >>415
現実を見据えて追求すると自然と出てくる答えです 親クラスとライフサイクルが同じか数値型なら実体、そうでないならポインタでいいだろ。
動的確保よりコピーやmoveのほうがコストが低い場合とか検討の余地はあるけど、考えすぎると禿げる。 どうせそこまで最適化も厳密なメモリ管理も必要なプログラムじゃないだろ。 OS作ったり、ブラウザ作ったり、3Dバリバリのゲームを作ったり、他の言語向けに機械学習や科技計算等のライブラリを作ったり、いろいろあるよ >>423
天才達だけに許された言語なのでしょうか?
もっと身近なプロダクトはないんですか? 古い例だとニコニコ動画がC++
まあおかげで開発がスケールせずオワコン化したわけだが >>425
聞いてばっかりじゃなくてお前がどういうものを探しているか書いたら? CADとか画像処理とかビット演算系アルゴリズム(cf.ZDD)なんかは
まだまだ他の言語には負けないね >>426
>開発がスケールせずオワコン化した
これってどういう意味ですか? JavaからC++勉強中です
C++の場合、他のクラスのオブジェクトを複数持たせるときは、一般的にどうするんでしょうか
・コンテナにオブジェクトそのものを突っ込む(一番わかりやすいけど、ムーブの定義忘れとかでミスが出そう)
・コンテナにオブジェクトへのポインタを持たせる(コンテナ解放時に、クラスごとに同じようなメモリ解放処理書くのかしら)
・コンテナにポインタをスマートポインタで持たせる
辺りをネットで読ませてもらいましたが、こんな感じで良いんでしょうか?
不勉強な上、他のオブジェクト持つという基本的なことなので、なんかもっと簡単な方法を見落としてる気がしてしまいまして >>431
時と場合によりますので一般的な答えはありません >>431
Javaのオブジェクト参照はC++のポインタに該当する。
C++のオブジェクトは、型を持ったバイト列だと考えていい。
C++で自動変数を宣言すると、スタックにバイト列が割り当てられる。
newやスマポやコンテナを使うと、ポインタによりヒープでメモリーが割り当てられる。
ポインタも型を持ったバイト列。ポインタは配列のように周りのメモリーにアクセスできる。
C++のクラスは構造体に関数群を追加したもの。C++でクラスを継承すると、関数群とバイト列を引き継いだサブクラスになる。 >>431
大体、その3つの通りで、そこに述べられたものの上から優先的に選ぶ。
つまり、普通にメンバ変数にオブジェクトとして宣言するのがC++では
最も効率が良くて伝統的な書き方。それでは問題が生じる場合にオブジェクトの
ポインタとして持たせる。スマートポインタは後になって導入されたもので、
人気があるものではないので無視して良い。
二番目のポインタとして持たせるのは、例えば、今定義している最中の
クラス(自分自身)と同じ型のデータで、子どもや親にあたるデータへ
リンクを作りたいようなときか、または、ある基本クラスを継承した
色々なクラスのオブジェクトを持ちたい場合に用いる。 C/C++では、sizeofキーワードを使えば、簡単にvoid以外の型のサイズがコンパイル時に取得できる。Javaではオブジェクトのサイズを簡単に取得することはできない。
C/C++はよくオブジェクトのサイズやバイトの並びを意識してプログラミングする。 結局CのポインタってJavaとかの言語で表すなら何なんだ? なぜなら、例えばスタックに巨大なデータを割り当てると、スタックオーバーフローというエラーが発生するし、
ヒープだって、巨大なデータの割り当ては失敗することがある。
また、構造体を変更すると、構造体のサイズやデータ構造が変化して、互換性の問題が発生することがある。 >>434氏他
丁度今、ウェブ上のC++で書かれたCompositeパターンのソースを読ませて頂いてました
正に2番目で実装されてましたが、都度メモリ解放処理書くくらい当たり前なんですね、流石C++です
独学なもんで、こうはっきり言ってもらえると本当にありがたいです、使い分けて行きたいと思います
他の皆様もありがとうございました、勉強になりました >>436
Javaの動的配列はCのポインタに近いが、Javaの配列では危険なアクセスは制限されているし、参照カウントで管理されている点が異なる。
Javaのオブジェクト参照は、参照カウントで管理されており、C++の構造体/クラス型に対するstd::shared_ptrに該当する。 しかし、std::shared_ptrはヌルポを指定できるが、Javaはできない。 >>438
C++ は、デストラクタに必ずメモリ解放処理を書いておけば、そんなに
メモリーリークを気にすることはない。多くの場合にはそれで完全に処理できるから。
次のように書くだけで、ほとんどの場合、メモリーリークは起きない:
class CMyClass {
BYTE *m_pBuf;
CMyClass() { // コンストラクタ
m_pBuf = NULL; // メモリをまだ未割り当てであることをマークするためにこうしておく
}
~CMyClass() { // デストラクタ
if ( m_pBuf != NULL ) {
delete [] m_pBuf; // メモリの解放
}
}
} >>441
ナマポの場合、代入したらまずいよ。例外安全にも問題があるし。 >>441
正しくは、次のようにアクセス制御のための「public :」を書かないといけない。
class CMyClass {
protected :
BYTE *m_pBuf; // 高速化のため、自動的には初期化はされないのでコンストラクタで初期化する。
public :
CMyClass() { // コンストラクタ
m_pBuf = NULL; // メモリをまだ未割り当てであることをマークするためにこうしておく
}
~CMyClass() { // デストラクタ
if ( m_pBuf != NULL ) {
delete [] m_pBuf; // メモリの解放
}
}
}
なお、必要に応じて、コンストラクタの中で、m_pBuf = new BYTE [xxx]; のように書いても良い。
それと、BYTE は、「オブジェクト」ではないので、あなたの書いているような場合には、
BYTE *m_pBuf の部分を CSomeObject m_pObj; のように変えて、m_pObj = new CSomeObject;
のようにする。 良い子のみんなは>>441の危険性が理解できるまではスマートポインタを使ってね
おじさんとのお約束だよ >>445のデストラクタでnullチェック必要?
nullポインタをdeleteしても問題ないはずだが
二重解放防止にはならんし意味わからん >>448
超独自仕様の組み込み開発とか、メモリー管理がbuggyなプログラムでは意味があるらしい。
例えば解放したメモリーブロックをアクセスするような行儀の悪いプログラムでは意味がある。 >>441 >>445
・ 初期化を初期化リストでやらずに代入でやるのは邪悪。
・ delete に NULL を渡した場合には何もしないことが保証されているので、
無駄にヌルチェックする必要はない。
・ ポインタ型や整数型の値もまたそういう型の「オブジェクト」である。
(元質問者が Java から入ってきてるから「Java の用語で言うところの」という意味?) 初心者なので確認
コンストラクタの中に飛び込む前のメンバの初期化で例外発生したら m_pBuf は中途半端になるから
コンストラクタの中で代入するんじゃなく、メンバ初期化子で初期化しろ
という認識でいいのかしら >>451
「C++ 例外安全」でググれ。ナマポを使わずに、素直に生配列、コンテナ、スマポのどれかを使えば済むこと。マネージされてないナマポは村八分にしろ。 なんとなくわかった ような気がする
生ポそのものはコンストラクタもデストラクタに何ら操作しないから宙ぶらりんこになるのか ちょっち理解は大変だけど生ポはスマポにドンドン置き換えたい スマポならコピーコンストラクター・代入のややこしさからも解放される。 まあまあ。
スマートポインタを活用しろというのはその通りだが、
ポインタ (や例外機構) を理解せずに
思考停止してスマートポインタを使うのはあかんやろ。
ここの元質問者はまだそこを理解しようとしている
ところなんだから、スマートポインタを使わなかった場合にどう書けば良いのか、
きちんと書くと面倒くさすぎるという体験も必要だろ。 所有権の管理は人類には早すぎる。
所有権が変動するときは、スマポでOK. こんなときはナマポを使ってもよい:
処理の中で所有権が移動・消滅しない場合。
バイナリーデータやPODを生で扱う場合。
処理系がナマポやトークンやハンドルの入力を要求する場合。 生ポはスマポのオーバーヘッドすら許容できないときに使うものです
だから初心者は無理して生ポを使わなくていいです >>434
スマポは後になって導入されたもので人気がない、なんて意見は一般的ではないので無視して良い エアプwwwwwwwww今は参照カウントじゃねーよw残念だったなクソ蟻wwww それで、Cの生ポってC/C++以外で表現するなら何なんだ? >>464
仮装アドレス的な意味で来るとは思ってなかったwでも本質はそうだよなあ >>463 今の言語は極力「生のポインタ」が見えないようにしてるからなぁ。
オレの乏しい知識で無理矢理ヒネリ出すなら、
「古いBASICの peek, poke のアドレス指定に変数を使った場合」かのう。
型のない単なるアドレスって言うか数値だけど。 >>463
BYTE ptr = アドレス値;
BYTE MEM[4096 * 1024]; // 4GB のメモリ配列
*ptr ---> MEM[ptr] // ptr は MEM[] 配列の添え字 訂正:
BYTE MEM[4096 * 1024 * 1024]; // 4GB のメモリ配列 行儀よく バッファなんて 守れやしなかった
夜のサーバ オーバフロー起こしてまわった
*印見て アナルといわれた 早く添え字になりたかった
信じられぬ カーニハンとの 争いの中で
許しあい いったい何 解りあえただろう
うんざりしながら それでも過ごした ひとつだけ解ってたこと
このポインタからの 卒業 まあstatic変数やglobal変数使ってリークしてないとか言い張るバカよりかは
ナマポ使えやとは思う。
それならまだコード修正効くからな。
初心者にスマポ使わせればリークしないコード書かせることができるって考えははっきりいって幻想だわ。 昔研究室の後輩でポインタがわからないから全部グローバル変数でプログラム作ってるって奴がいて、
それはそれである意味すごいなって思ったわ。
マルチメディア系ライブラリを触る必要がある研究室なのだが。
元々組込系が得意な奴だったってのもあると思うけど。 >>476
スマートポインタを使うとコード修正効かなくなるの?どういうこと? mp4boxをちょこっといじったのを作ろうとしたんだけど、
signed int32の計算で -2112000 / 48000 の結果が 89434 になるんですが。
VS2015のx64です。 >>481 「-2112000 / 48000 の結果が 89434」
その環境を持ってないんで分からないけど、
-2112000 の32bit16進数表現が 0xffdfc600
89434 * 48000 == 4292832000.000 == 0xffdf6b00
両者のビットパターンが一致することと関係ありそうね。
被除数の -2112000 を64bitで表現する際に
符号拡張 0x_ffff_ffff_ffdf_c600 とすべきなのに
ゼロ拡張 0x_0000_0000_ffdf_c600 にしちゃって、
その後の計算は64bit正数でやってる感じかな。 >>480
本人がスマポ理解できてないってオチだろ >>477
組み込みが得意でポインタがわからない後輩
設定に無理がありすぎw 再び >>481 「-2112000 / 48000 の結果が 89434」 (間違いを訂正)
-2112000 の32bit16進数表現が 0xffdfc600
89434 * 48000 == 4292832000.000 == 0xffdf6b00
ビットパターン一致してないね。桁数多くて見間違えちゃった(テヘペロ)。
-2112000 を32bitで表現すると 0xffdfc600 であり、
これをゼロ拡張した 0x_0000_0000_ffdf_fc600 == 4292855330 を
48000 で割り算して小数部を捨てれば 89434 という答えが出る。
ということなら合ってるかな。 >>481
どうせ48000がunsignedなんじゃねーの
それにつられて -2112000もunsignedになって4292855296
その結果が薬師美代ちゃん >>479
自分が何してるか判って使う分には問題無いな
適材適所だ >>480
>スマートポインタを使うとコード修正効かなくなる
どういう風に読むとそういう理解になるのか。。
まずは日本語の理解が必要だな。 超初歩的な質問になるのですが
scanf関数を使って20個未満の任意の数だけ、数値を配列変数で受け取りたいです
たとえば「2 4 8 9」と入力し、Enterが押されたらそれで確定
num[0]=2
num[1]=4
num[2]=8
num[3]=9
としたいわけです。
どうしたらよいでしょうか?
一応自分で考えたコード(期待通りの動きをしません)を掲載します
for(i=0;i<20;i++){
scanf("%d",&num[i]);
if(num[i]==‘¥n’){
break;
}
} for(i=0;i<20;i++) if (scanf("%d",&num[i]) != 1) break; >>490
scanfや標準ライブラリの関数など、参考書とかで普通の使い方はわかると思うけど、細かい仕様をmsdnやmanコマンドで調べるようにするとかなり理解が広がると思うよ。 中途半端なUI使うよりもcsvパーサーを作るかどっかからとってくるかすれば? >>494
むしろ遅くなる方に振れるでしょうけれど、そんなのどうでもいいのでは? autoって変数の型宣言の話だよね?
コンパイルは遅くなるのか
速くしたい時はどうすりゃ良いの? C++ の auto は右辺と一致させるように推論するだけの単純機構で、
ややこしい演算で推論するわけではないので、
コンパイル速度ではほとんど差はないと思うよ。 autoはむしろコンパイル速くなるんじゃない?
いちいち型を解決せずとも、既に解決済みの型を右から左へコピーするだけでいいんだから
C++でコンパイルを速くするのは簡単で、単純にソースファイル数とインクルードするヘッダを減らせばいい
C++のコンパイルが遅いのは主にコンパイル単位という時代遅れで極めて非効率なコンパイル戦略に起因しており、実はコードの複雑さ自体はわりとどうでもいい >>496
C++を言語として選択した時点で「記述の時間やコンパイル時間を投資して実行時間を稼ぐ」という思想なのでは?コンパイル時間を短くする努力はする気がないと思います >>498
>いちいち型を解決せずとも、既に解決済みの型を右から左へコピーするだけ
この記述はコンパイル時を想定しているの?それとも実行時を想定しているの?
はっきりさせたいので念のために確認します >>490 サーバーの 503 エラーに引っかかって昨日のうちに書けなかったんだが…。
>>491 の方法だと Enter が単純に読み捨てられて scanf() が終了せず
まだ入力をよこせと言ってくるからダメみたいね。
11 22 33 (Enter) だと読み込みが継続、期待通りに動作しない
11 22 33 x (Enter) なら x を解釈する時点で scanf() が 0 を返してループ脱出
先に文字列として1行読み込んで sscanf() と思ったけど…
ndat = sscanf(s, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
&num[0], &num[1], &num[2], &num[3], &num[4], &num[5], &num[6], &num[7], &num[8], &num[9],
&num[10], &num[11], &num[12], &num[13], &num[14], &num[15], &num[16], &num[17], &num[18], &num[19]);
実際に読めた値の個数は ndat に入る。
これは書くのもメンテナンスするのも嫌だなぁ。
strtol() で1個ずつ数値を拾いつつ、地道にポインタ進める方が良いかも。 >>500 自分は >>498 の人じゃないけど。
ごく簡単な場合ながら、例えば
int val_a = func(para); // func() がint互換の値を返すかチェックが必要
auto val_b = func(para); // func() の返す型そのまんまで val_b を作ればいい
てな具合に考えると auto で定義した方がコンパイル時の手間が少ない、
という考え方にも一理あるかと。 瑣末なことだけど val_a, val_b って変数名は良くなかったね。
変数 variable の例なんだから var_a, var_b だわな。
というか、この場合は a, b で十分だ。 >>501
ありがとう。ちゃんと確認してなかったわ。
タブに空白に改行はスキップしやがるんでしたか
別案としては fgets() ⇒ sscanf() になるんかな 505の後半は無しで
1文字ずつ切り出して解析してったほうがよさそうね >>501
scanf は禁止
>>505 が正しい 人間の様な邪悪なものからの入力でscanfは使うなと、ばっちゃは言ってた >>502
>func() の返す型そのまんまで val_b を作ればいい
この発想は実行時なのでは?
>てな具合に考えると auto で定義した方がコンパイル時の手間が少ない、
実行時の発想をコンパイル時に適用していいのでしょうか? >>509
賛成です、そういうのは1ラインを秘術を尽くして何とか読み込み、後で sscanf() とかを使うべき >>512
今回の例(>>490) のように可能な限り %d で抜き出して打ち切るとなると sscanf 単発では面倒
なんとか行単位でバッファに詰めた後
連続空白などでトークンに区切ってそのトークン単位で sscanf をぶんまわすような
ほのかな中途半端感が >>510
別に実行時の発想じゃないでしょ
型を書けばコンパイラはその型名に対応する型を解決しなければならないし、
型変換の要否や可否のチェックも必要 >>514
>型変換の要否や可否のチェック
これは10中8, 9 コンパイル時にすることなのでは? >>515
初めからずっとコンパイル時間の話をしている。お前さんだけ噛み合ってないから、もう黙っててくれ。 C++です
インクルードガードがあっても関数の定義がヘッダに書かれていればヘッダが複数回読み込まれていた場合リンク時に多重インクルードでエラーが出る
ここまではわかるのですが、同じことをクラス関数で実験した結果エラーになりませんでした
具体的にはヘッダのクラス内に関数定義を書いて複数のファイルからインクルードしました
これはどういうことなのでしょうか? >>517
クラス定義の中に書かれたメンバ関数の定義は
自動的にインライン関数になる(関数の実体の定義ではない)
この場合は、複数の場所にメンバ関数の実体が作られるわけじゃない、
という説明でどうかな。 >>516
そもそも「実行時」「コンパイル時」の区別がついていないのでは、コンパイル時間の話なんかできないのでは?
だから「実行時」「コンパイル時」どちらを適用するかに執着しているだけです >>518
なるほど
クラス内に定義を書くとインライン関数になって普通の関数としては扱われないんですね
もう少し理解するために調べたのですが、インライン関数は内部リンケージのみを持つものとしてコンパイラに解釈されるらしいですね
だからコンパイラはファイル間での関数の重複を調べようとしない
そしてインクルードによって複数のファイルで同じものを読み込んだとしてもエラーにはならないと・・・
理解です
勉強になりました
ありがとうございました 失礼、なぜか >>510 を見逃してて(黙殺するような意図はまったくなかった)。
C++ は関数を宣言・定義するときに返り値型を書くから
auto で受けてもコンパイル時に曖昧さは生じないと考えたんだけど。
実行時まで返り値の型が決まらない関数って作れるんだっけ?
これは純粋に質問、教えを乞いたい。
あんまり高度な話だと振り落とされるかも知れないけど。 型推論が実行時に行われるとかトンチキこいてるやつが一人騒いでるだけ >>521
おそらく君の書いた「func()の返す型〜」をqz某が勝手に勘違いしているだけだからスルーしていいよ。
初心者が必ずしも正確な用語を使わないことくらい想像つくだろうし、文脈からして普通ならそんな勘違いはしないはずなのだが。 >>521
出来ない。
強いて言えば C++17 からは std::any があるけれど、
これはこれで実行時に型が決まるわけではなくて
コンパイル時に std::any 型であることは確定する。 >>520
> もう少し理解するために調べたのですが、インライン関数は内部リンケージのみを持つものとしてコンパイラに解釈されるらしいですね
どこにそんな嘘書いてあった?
https://timsong-cpp.github.io/cppwp/n4659/dcl.inline#footnote-94
> The inline keyword has no effect on the linkage of a function. >>525
IBMのサイトに書いてありました・・・
と思って今見返したらこれはIBMの統合開発環境のページなのでその開発環境の仕様かもしれないですね
失礼しました
https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_72/rzarg/inline_linkage.htm
>インライン関数は内部リンケージを持っているものとして処理されるので >>526
「C のみの始まり」〜「C のみの終わり」で囲まれているとおり、それはCの仕様だね。 >>525
それは inline キーワードで束縛された関数は、inline 展開される多数の実体と、外部リンケージによって外部からコールできるものとで別の実体をコンパイラは作成する、ってことですか
まあ inline しまくって無駄にバイナリーを増やすくらいだったら、ついでに1 個の外部リンケージで呼べる実体を追加したって、いろいろな面で大差がない、とはいえますね >>528
「それ」が何を指して言ってるのかよくわかんないけど、 inline 関数に対して
インライン展開されてない「実体」を生成するのもしないのもコンパイラの自由。
外部リンケージを持つ関数について複数のコンパイル単位でアドレスを取って
==, != で比較した場合には一致させないといけないので、アドレスを取られた場合には
そういうコード生成をするのが一般的だろうとは思う。 引数や関数にはconstつけられるところは全部つけるべきですか? つけて問題ないならつけるべきだけど、まあ実際は面倒くさくなければという程度… >>530
内部で書き換えないポインタや参照の引数には必ずconstをつけるべき。より自己文書化されるし、付けてないと使う側の手間が増える。>>531は元javaプログラマ 今は良いけど、半年後の自分は既に他人だと思わないと 530みたいな質問する奴はそもそもconst気にする前に関数が長すぎたり
参照と実値渡しの違いもわかってないと思われるのでその辺をしっかりやった方が良い。 入門書の類が、最初のうちは const なしで説明しておいて、
本の後半でおもむろにポインタの引数に const つけることを
載せてたりするせいかもな。
高度な、マニアックな話題みたいな感じで。
文字列(charへのポインタ)を受け取る関数を紹介したら、
すかさず const char* の説明も合わせてすべきって気がする。
const の一般的な価値が分かれば、メンバ関数での func() const {...} の
ありがた味もすぐ飲み込めて const つけまくり派になるでしょ。 戻り値を const char* してても、
char* const してなければさほど意味がない。 クソミソみたいなjavaのconstと違ってC++のconstは
コードの安全性を高めるのに必須といっていいぐらいのキーワード
とりあえず片っぱしから全部const付けて、どう頑張ってもここは
constはずさないと動くコードにできないよな・・ていうぐらいの
時だけはずす。このぐらいの気構えでコードを書けば、かなり安全な
コードになってる。他のやつが書きかえちゃダメなものをいじろうと
しても、強引なキャストでもしない限りどうやってもコンパイルが
通らなくなる。強引なキャストしてでも無理矢理強姦してくる強姦魔は
そもそも犯罪者気質なのでそんなやつに仕事をやらせてる時点で間違い 「かなり安全な」
ここで思わず笑ってしまったではないか 残念ながらバカはmutable使い出すから無意味。 俺は書換られたりはしない たぶんしないと思う
しないんじゃないかな ま、ちょっと覚悟はしておけ いやまてまて・・このスレの99%はネタでできてるけど
そこ分からないのはダメだぞ
まさに初心者向けの話題ではある こいつ能力低いなと思う奴のソースを見ると、
constなんて全く付いていない場合が多い >>543
ちょっとわかるわw
あと3文字くらいが良かった constはキーボード入力の観点からはそんなに苦じゃない
stdとかarrayが割りと入力しづらい
左右均等に割り振られてると楽な感じ const char* a = "hoge";
const char* const a = "hoge";
の違いがわからんやつは死ねとよい そんな違いを意識しないと読めないコード書く方がバカだと思う。 (そんな初歩中の初歩でマウンティングドヤ顔して大丈夫っすか先輩) >>545
>>544のこと言ってるの?
>>537は、ポインタの指し先だけでなく、戻り値を格納する変数自体を定数にしなければさほど意味がないっていう主張だと理解したけど、合ってる?
ローカル変数を定数化したければ呼び出し元が勝手にやればいいし、戻り値をconst char*にする重要性に比べたらそれをする必要性なんてごく僅かで"さほど意味がない"なんてとても言えないと思うけど C++ってC言語の負の遺産を引き継いだ言語だろ?
constは廃止すべき constみたいな糞どうでもいい些末なことより
配列のサイズとオーバーフローの管理を強化するべきだったんだよ
互換性捨てなきゃならんが >>557
そこはCの負の遺産を引き継いだのではなく、可能な限り実行時オーバーヘッドを小さくする実装手段を提供するというCの基本スタンスを継承しただけだろう。それが負の遺産というなら他の言語の方が適切なんだからそれを選択すればいいよ。
C++を使いたく、ある程度の実行時オーバーヘッドが許容できるときはstd::vectorという選択肢があるけど、それじゃダメなのか? >>556
const に関しては C++ で新規導入された仕様を ANSI C に逆輸入、
みたいな感じじゃなかったっけ?
そのせいか、定数としてconst変数を使えないとか中途半端になってる。
C++ が C の負の遺産を切り捨てるべきだったとしても、
const はその「C の負の遺産」の範疇に含まれないかと。
いずれにせよ、今さら言っても、現に存在する C++ はどうもならんよね。
そういう新プログラミング言語が出ても、それは C++ じゃない別物ってことで。 とりあえず数値以外はconst参照渡しが基本でおk? >>557
at()使え。
>>556
constが負の遺産とか頭おかしい。
ドキュメントにこの変数は内部で変更しませんとか書くよりよっぽど楽だろ >>562
負の遺産だよ。
const キーワードを廃止して
デフォルトの挙動を const に出来れば
どれほど良いことか。
という意味で。 >>563
それなら同意するけど>>556にそんな意図はないでしょ >>564
皮肉っぽい言い回しをしてみたかっただけ。 そこまで挙動を変えるなら別言語でやれば良いし、実際rustとか他の言語としてあるだろ。 使わないで済ませる事ができるなら、使わないで置く方がうまく行く >>563
>>567 も書いてるけど、それ何てRust?と思った。 負の遺産でも互換性とのトレードオフだしな。
いいことばかりじゃないけど、悪いことばかりでもない。
とりあえず const は付けれるだけ付けとけというのが
ベストプラクティスだと思う。 >>563
引数だけなら同意してもいいけど変数はどうするんだ?
for(variable int i = 0; i < 10; i++){
とかはあまり書きたくないぞ >>571
まあそこはもしもの話だから。
最初から const なら文法もそれに
沿ったものになってただろうさ。 確かに、関数内で作ったローカル変数だけデフォルト変更可能、
他所から持ちこんだ、ポインタの先や参照、グローバル変数へのアクセスは
基本的に読み出しのみ許可で、明示した場合だけ変更できる、なら
「勝手に書き換えたのは誰だ!?」ってバグは減りそうだね。 そうそう、だから普通にC++書いてる人は
とりあえず引数に全部 const つけるでしょ
それはそういうことだよ 引数じゃなく method の const は後悔することがちょいちょいと
class foo {
public:
void method() const;
}; constつけときゃいいってのもなんか胡散臭い印象しかないな。
そんなことよりも変更や生成を行う場所、タイミングを局所化するってのが本質だと思うが。 const が必要なところに付けるって考えるよりは
const では駄目なところでは外すという考え方の方が
安全っぽいという話であって、
適切に使い分けろというのは大前提のことだってことは補足しておく。
const が当たり前だって気持ちになると
変更が必要な個所は自然に局所化されるでしょ。 const連鎖くらったらほどほどでいいやと思うようになる なんというかもう修正が一切されないコードしか想定してない印象を受ける。 やりすぎオブジェクト指向といっしょで
事故起こりにくいとこでこだわっても変更に弱くなるだけ 複雑怪奇で理解不能にしておくと、
変な改造されないで済む 初心者で申し訳ないんですが、c/c++を学ぶため何か作りたいのですが、cで作る意味のあるいいお題はないでしょうか。JavaやC♯、rubyは一通りかける感じですがcはmallocなど知ってはいても使ったことはないレベルです。よろしくお願いします! >>583
ビットマップ画像を読み込んでブラーをかけてビットマップ画像として出力 >>583
いきなり「実務的な」プログラムを書くのはオススメしないよ。
C/C++ には歴史的経緯によってクソな落とし穴と「未定義」がたくさんあるので、
たとえ期待通りに動いたとしても正しくないプログラムであることは多い。
初心者向けのしょうもない (他の言語でやる入門と大差ないような) 題材で小さなプログラムを書いて
ブログとか Qiita とかに書いておけばベテランがよってたかって指摘してくれるさ。
そういうので基本的な落とし穴くらいは理解してから進んだ方が良いと思う。 HDDの中を検索するプログラムとか、整理するプログラムとか
こういうのがあったら便利だなっていう物を考えて作ってみる
途中分からなくなったら、ここに相談に来ると良い
親切な人が教えてくれる、かもしれない
あてにはしないこと おっさんらジイさんらの世代だと
「こういうのあったら便利だよな」と思って作りはじめるパターンは有効だったけど
今はそういうの探したらほとんどあるからある意味不幸だよな
しかも自分で作ってたらとてもここまで作ってるヒマないっていうぐらい高機能なのが多いし >>584
>>585
>>586
ありがとうすごく参考になりました。デスクトップランチャーとかほしいと思って作るならWPFだし、Cで実用的なほしい物ってむつかしいんですよね。初心者向けの小さなプログラムは上記のブラーとかでしょうか?Cで書く意味がある題材ってわからなくて。。。 >>588
そもそも自分がC/C++を身につける意味があるかというとこらから見直した方がいいのでは?
直ちに必要な訳ではないが将来的に身に付けたいというなら、先に他の人が言っていたようにいきなり実用的なプログラムから入るより練習問題レベルの小品をコツコツ作っていった方がいいと思う。 どうしても自分が欲しくて既存のものがないってケースでも、
既存のものをバッチファイルで繋げればできるって程度のものだったりするもんな。
そういう意味じゃ、日常ではスクリプト言語の方が使うことが多いとは思う。
俺が一番最近に書いた C のプログラムもスクリプト言語の拡張パッケージだし。 >>588
例えば容量の大きなHDDだと、同じファイルが複数場所にあったりするじゃない?
そういうのを見つけて、チェックした後削除すれば容量節約という実利もあるよ >>588
C/C++ で書く意味ということに最初は拘らなくてよいと思う。
こだわらなくてもプログラムの構成の仕方、書き方には確実に違いがあるから、
むしろ比較しながら学んだ方がいいかもしれない。 C/C++使う必要性がわからないならやらないのが正解
今だにこんなクソ言語使ってるのはそれしか選択肢がないから
あるいは物好きな言語マニアか 先に他の言語やらんとC++の必要性はわからんと思う こんなにレスもらえると思いませんでした、他の言語スレや板だともっと殺伐としてます。。。ありがとうございます。
低レイヤを高速で処理できるのが魅力だと思うので最終的には任意のパケットを送受信できるデーモンを作りたい。ので、>>591のいう同名ファイル検索デーモンから始めようと思います。 ならechoサーバーから入ってhttpサーバーという定番ソケットプログラミングコースもおすすめ
まぁでもその検索デーモンとやらでファイルの扱い勉強してからでいいだろうな
高速化に興味あるならC/C++の標準ライブラリでなくOSのnativeのapiを積極的に使うのもいい
ファイルならメモリマップドファイルを使ったり(ファイル名調べるだけなら不要だけど)
他には検索アルゴリズムに凝る方向とかね >>595
同じファイルというのをどう判定するかだな
ファイル名なのかハッシュ(中身)なのか globalに宣言されてる変数と同じ型同じ名前で
関数内にlocalに宣言されたものがあるとき
警告出してくれるオプションって何だっけ >>595
なんで、そんな面倒くさい事をしなきゃならないんだ?
Ruby なら、PowerShell から、1-liner で、
Rubyで作られた遅いウェブサーバー、WEBrick が起動する
ruby -run -e httpd . -p 8080
そのフォルダに、index.html があれば、
何も考えなくても、これでブラウザからアクセスできる
http://localhost:8080 >>599
お前は相手の意図を理解する気がまったくなく、人とのコミュニケーションができないことをさっさと理解して、巣にかえって閉じ籠っていてくれ。
ここはお前に用がある奴は一人もいない。 みなさんありがとう
今日は会社で暇だったのでコピペベースながらUDPで任意のメッセージ送受信出来るようになった
ヘッダでincludeする構造体って宣言済みのクラスみたいな感じで使えることを理解しました。(udphdrを使わずにsendしたからか、送れたけどudpチェックサムは自動で計算されなかった)
tcpは、というかhttpサーバは難しそうですが頑張ります! >>598
gcc/clang だと -Wshadow だな。
-Wall -Wextra とは別に指定する必要があるようだ。
細かいことを言えば、同じ型でなくても、名前が隠される場合は警告が出る。
今ネットで調べて確認、これからオイラも使うことにする。 同じ意味だけど型が違うときの変数名ってどうされてますか?
いつも困ってます。
例)
float2 fPos( 1.0f, 2.0f );
XMFLOAT2 fPos( fPos.x, fPos.y ); ←当然同じ名前は× >>603
float2でfPosって付けてるならXMFLOAT2ならxPosとかでいいと思うが… >>603
よくシステムハンガリアンは悪と言われるけど、この例のように同じ内容で型名の違いに意味がある場合は、型名に関するプリフィックスをつければいいんでない?
とあるライブラリに渡す境界部分ならそのライブラリ名に関するプリフィックスとか。 初心者ですみません、こんなコードをみたのですが2点わかりません。
char packet[1500];
memset(buf, 0, sizeof(buf));
ether_header *eh;
eh = (struct ether_header *)packet;
たぶん、1500byteのメモリを確保して0埋め、ether_header構造体のポインタを宣言してpacketのアドレスを渡す、としたいのだと思います。
分からないのは0埋め対象が宣言されていない変数bufであること、packetのアドレスを渡すのにわざわざether_header型のポインタにキャストしている2点です。よろしければ教えてください。
https://qiita.com/marufeuille/items/81f323a52a6fd3bd530c >>606 の引用元を見るとコード片だから、実際にはコンパイルしてないんだな。
char packet[1500];
memset(buf, 0, sizeof(buf));
は、packet と buf が同じもので、正しくは
char packet[1500];
memset(packet, 0, sizeof(packet));
なんだと思う。最初は両方とも buf と書いてあったけど
「もっと自ら語る変数名にしよう」と packet に変えたはいいが、
memset() の方では直し忘れた、というお話かと。
(struct ether_header *) のキャストは、コンパイラの警告対策だな。
…って言うか、これキャストしないでも警告だけで通るのね。 やってきたパケットのうち 頭のEthernet Header にフォーカスしてる意図でのキャストかな?
最終的には char [1500] で受け取ったパケットの配分を(パディング無しで)
struct TCPpacket {
Ethernet_Header eth;
IP_Header iph;
TCP_Header tcph;
char* TCP_payload[]; /* 末尾可変サイズ */
};
に配分したいんだろうけど、手を抜くなら union にしそうだわ
union Packet {
struct TCPpacket tcp;
char* packet[1500];
}; >>604
>>605
ご提案ありがとうございます!
何らかのプリフィクスで識別が妥当そうですね。
ローカル名前空間みたいな概念があると便利そうですが・・・。
local namespace XM
{
XMFLOAT2 fPos;
}
float2 fPos( 1.0f, 2.0f );
XM::fPos = { fPos.x, fPos.y }; どうせ長ったらしい関数書いてんだろ
それがそもそもの間違い >>607
>>608
>>609
ありがとう、cがとんでもなく難しい言語かと誤解するところだった。 いやーCは簡単な言語だけどC++はとんでもなく難しい言語だと思うぞ
解説本が電話帳より分厚いなんてな自然言語超えてる しかも、言語仕様の改訂が3年ごとと早すぎて、
邦訳解説本はもちろん、原書でもリリースがおいつかず、
仕様改訂を繰り返すたびについてこれないユーザーをふるい落とす恐るべき言語
仕様改訂の世代を重ねるごとに中国以上の人口減少率でユーザー数が減少する既に終わった少子化言語ww なんか皆C++はむずかしいむずかしいっていうが、そんなむずかしいか?
俺的には今時のECMAScriptと各種フレームワークの使い方のほうがよほどむずかしい。
2、3年もすると何だかイノベーションがどうのこうのいってまるっきり別物のコンセプトのがでてくるし・・。
C++なんて基本概念はもう何十年もかわらんだろ。あとはその都度必要なstlとかの機能覚えればいいだけ。
楽なもんだよ。 有名所のライブラリでラムダ式使ってるの見たことない 『プログラミング言語C++』第4版は電話帳より厚いね。
あれは解説書だよな。1300ページ以上ある。
ちょうど新しい電話帳が届けられたばかり。
田舎住まいだから都市部に比べて電話帳が薄いってこともあるけど。 C++は新しい言語仕様が次々に追加されるせいで、
同じ細かな処理をするにも人によって書き方が色々になって、
「同じ言語で同じ処理をしてるはずなのにソースは似ても似つかない」
「自分で書くには便利だけど、他人の書いたプログラムは読み解けない」
てな状況になってるんと違うかな。
わざわざストラウストラップ先生が「言語の全部を知らなくても、
徐々に理解しながら使えばいい」と書いてくれてるけど、
他人のソースを読む際には役に立たないアドバイスだよね。 >>615
CもC++も仕様は簡単
ライブラリやアルゴリズム考えるのが面倒で生産性が低いだけ
それを難しいと勘違いしてるだけ こういうc++の危険さをまったく認識できてないやつが一番困る
std::forwardの意義を誰にでもわかるように説明してみろよ C++11以降とそれ以前で違い過ぎるのが問題では? >>623
「徐々に理解しながら」は、 C を既に知っている人を明らかに想定していて、
今では C がそんなに支配的でもないという状況を思うと適切な動線とは言えないという意味でも
あまり役に立たなくなってきていると思う。
ただ、追加された機能を見ると、
新しい書き方の方が間違い難くて綺麗で一貫していることが多いので、
肥大化するから追加するのをやめろとも言い難いんだよな……。 皆、ドワンゴ江添亮の本を読んでいないから、C++ の恐ろしさがわからないのだろう
詳細を突っつくと、無限にややこしいものが出てくるw
だから江添でさえ、詳細は省略しますって書いてあるw
>>610
1バイトずつ、check sum を計算するような場合は、そういうように、union にするのが定番 udpパケットを送れるようにはなったのですが、wiresharkで確認するとudpフレームのchecksumが未定義となっていました。。。
そこで1からやりなおしたいのですが、ソケットはrawで開くべきなのでしょうか。いまはudpなのでdgramで開いてsockaddr_inのインスタンスをつかってsendtoしています。 enumについて教えてください
enum { ..\..\VAL1, VAL2 };
このような書き方でコンパイルが通る環境はありますか?
case ..\..\VAL1:
というのも許される環境はありますか?
c/c++ よくわからんが、識別子の定義を変えたいということか? >>631
調べた方が足りませんでした、NICのTCP offloadingという機能が有効になっていたせいで、NICより手前でキャプチャするとunverifiedとなっているようです。大変失礼しました。 >>619
>今時のECMAScript
いや、ハードウェアに固定されたバイナリーですらなく、ソフトウェア上で決められた決め事になんら意味を見出せないのですが、それでも javascript とかに熱意を抱けるコツがあったら教えてください >>629
いいかげんにニコ動をなんとかしてほしいです、昔も重かったけれども今も重い、これはなんとかならないのですか? >>636
>>619の書き込みのどの部分を読んでその質問がでてきたんだ?なんかバグってね? 引数のmove受け一つとってもrustの3倍くらい難しくなってるわな。
シンタックスが特殊だし、オーバーロードはされるわ、特殊な右辺値に対してのみ動作するとか
根本からおかしい。 物作った事の無い人の重箱の隅つつき+詳細未記載本なんて
時間の無駄だというのが良くわかった。
石田晴久の通信プログラムとか技術書展の方がマシ ソース書くときに気を付けるのはとにかく引き継ぎしないといけなくなったときに楽になるようにって点かな。
上から読み下していったときにわかりやすければなんでもいいと思ってる。 構造体で例えば
struct POINT{
int x, y;
};
があるとき
struct POINT p = {1, 2};
と定義と代入を同時に出来ますが
一度代入したものを後から書き換えるとき
p = {3, 4};
と書くとエラーになるみたいで
p.x = 3, p.y = 4;
と書かないといけないのが面倒です
先生なんとかなりませんか? ああできた
p = (struct POINT){3, 4};
これでいけました 構造体一括代入はANSI以降の機能だからOS/9とかCP/M68K
のC言語では当然のように動かない C++だと
p = POINT(3, 4);
もいけるかな >>644
たぶんそうだったと思います
ありがとうございます >>645
C++11 以降なら p = {3, 4}; でもいけるよ。 C の p = (struct POINT){3, 4}; は、構造体の一括代入に違いないけど、
(struct POINT){3, 4} の部分が「複合リテラル」compound literal だから
使えるのは C99 以降だね。 >>643
理由が"面倒"だったのに、文字数増えてるよねそれ >>649
これは、C++ に合わせてほしかったな、と思うのです c++の規格って言ってもその辺、c++のいつの規格だよって話になるんじゃないの? >>629
会社の売り上げに貢献せず、警察を提訴するような
キチガイ高卒社員が資産食い潰してるんじゃね?wwww >>622
すでに3版でも電話帳より厚いよ
まともに読む気になるのは2版までだな。
熱意あるうちはともかく、ふと我に返ると俺何してんだろって。
そんで、言語覚えただけじゃプログラムてかけないしな。 C++でまともなWebサービス作れるエンジニアなんて相当単価高そう
もうオワコン動画の便所掃除やりたがる奴なんていないだろうし サービスを書くのに C++ の比率は高くないかもしれんが、
サービスを支えるインフラには C++ を使うことだってあるだろう。 「困った」と
「助けたい」をマッチングする
新たな出会い系アプリか? まあJavaは糞これは間違いない
Java使うぐらいならC#使うほうが10倍まし Javaはコボラーと同じく湿った猫のような臭いがします Java並に大規模な開発事例ってC++にはあるの? >>670
人月商売をやってるだけで大規模()とは言わない
Linuxカーネルほど大規模なのはJavaではない unreal engineとかクッソ大規模に見えるけどどう? 工数でいえばそんなもんクフ王のピラミッドには遠く及ばないだろう 甘い
甘いなぁ
人月換算だと同じだよ
死者数すらも一致してる 20年前で70万ステップぐらいでビルドに1Hぐらいだったなあ むしろ>>670が思う大規模なjavaプロジェクトを知りたい 人数かけて、webページの遷移ごとに別人が開発して、似たような処理をするコードが100倍くらいに膨れ上がって収集つかないようなのが大規模なんじゃね c++じゃなくてcでnamespaceって使えますか?あるいはnamespace相当の機能ってどうすれば実現出来ますか? 重力波を検出するのに世界中の電子望遠鏡を接続してリアルタイムに通信してるようだけど
ああいうシステムのコードって何で書かれてるの? FORTRAN ? >>685
cでは使えない
ほぼ上位互換だからc++使えばいいじゃん >>686
マジレスすると、ああいうのはファイルに落として時々バッチ処理してるだけ
言語はだいたいFortranかC++が多いだろうね std::chronoにnanoseconds取り扱う型があるけど
これってwindowsでもナノ秒の精度ちゃんと取り扱えるの? c++11以降はあれ明らかに生産性下がってんだろ。。
誰か本当のことを言ってやれよ。。 >>691
表現できるだけ
計測できるとは言っていない じっさいにやったらわかるが、結局 Windows API の持ってる精度までしかでない
あたりまえっちゃーあたりまえだが >>694
試そうと思ったらどう試すのがいいんだ? 短時間、というか連続で何度も時刻の値を入手して、
値の下の方の桁がかならずゼロ並びになってるとか、
時刻同士の差を取って、ある値より小さな数が出ないことから、
解像度の見当を付けるくらいかな。
もっと良いやり方を知ってる人は教えてください。 差をとってその偏差を見ればいいんでは
高解像度タイマーならたぶんcpuのクロック程度の解像度じゃないの
パフォーマンス測定に普通使うし
個人的にはchrono使わずにosのapiかコンパイラの組み込み関数使う
そっちの方が信頼できるし、chronoは型がガチガチすぎて面倒くさい std::vectorの最初の要素数は
std::vectro<foo> bar(12);
みたいにコンストラクタで指定できますが、同様に
std::vector<std::vectro<foo>> bar
のように入れ子になったvectorの両方の要素数をコンストラクタで指定する方法はありますか? 結構難しいと思うがね。
最近のCPUはターボブーストいうてサボるし、命令順序入れ替えるし、キャッシュの乗り方でnano秒程度は簡単にズレるだろうし。 >>701
std::vector<std::vector<foo>> a(100, std::vector<foo>(200)); Cで書かれたライブラリから来た構造体にスマポをあてる方法はありますか? どうなんだろ?
普通に考えたらデストラクタでfreeを呼べばいいから、それ用のライブラリがありそうな気はするけど。 >>706
スマポ弄ってアロケートだけしないようにすればいいんじゃね? 「来た」というのが構造体へのポインタをfree責任ごと渡されたという意味ならカスタムデリータだろうな。 ありがとうございます
カスタムデリータは知りませんでした
Cで書かれたライブラリにmallocしたポインタを返してくる関数があって生ポいやだなあと思っていたところでした 最近スマポ使えスマポ使えってうるさい割にはカスタムデリータ指定出来ることも知らなかったりするんだな
自分が使ってるもののリファレンスすら読んでない奴が安全性とかどの口で言ってるんだろう codecvt_utf8
codecvt_utf16
codecvt_utf8_utf16
こいつらの糞加減に 最近カスタムデリータ知ったから嬉しがってる奴がいるなw >>711
すいませんね、リファレンスなんかそっちのけで、ネット情報だけで、プログラム組んでます。 >>714
図星だったか、すまんな
というかマウント取るための屁理屈考えてる暇あったら手動かした方がいいよ 図星しとか意味分からん
ひょっとして>>711 disってるのか? w 最近図星って言葉を覚えたので使いたいんだろう
察してやれ >>711で言ったことが図星だったか?という意味なんだが
アホが多いインターネッツですね 今度はインターネッツという言葉を覚えたのか
どんどん賢くなっていくな カスタムデリータごときでよくそこまでドヤれるもんだなw 実際c++やるやつのほとんどの動機がマウントとりたい以上のものではない。 大学四年かけてC++と機械学習学べば年収1000万とか本気で言ってる奴らだからな() 相談なのですが
テキスト形式のライセンスファイルへのファイルパスを渡さないと使用できないライブラリA
そのライブラリAを使用するライブラリB
私が作成しているのはライブラリBです。お客さんに使ってもらうものなんですが、「ライセンスファイルをセットで提供して適切な場所に置いて使ってもらう」という手間を省きたくてライセンスファイルをライブラリBに埋め込めないかと思案しています。
とりあえずライセンスファイルの中身をソースにベタ書きし、実行時に一時ファイルとして作成しライブラリAにそのパスを渡すことで上手くいっているのですが、もっとスマートな方法はないでしょうか?
ファイルパスを渡さないといけないので無理ですかね… ライブラリAが要求するのは
ファイルシステムに認知されるファイルの形式でないといけない
だから中間ファイルに書き出して、そのファイルパスを渡すしかない
つかライセンスを埋め込んだ場合何がしかの事情で
ライセンス変更の必要が迫られた場合ライブラリBを構築しなおすことになるんだが
そういう管理でいいのけ? >>728
ヘッダーと共有ライブラリのセットです。 >>729
やっぱ他にないですよね…
継続的にバージョンアップ重ねて提供してるんですが、ライブラリAについては今後も使い続けるか微妙なんでお客さんに〜のように運用してくださいってお願いするのはまだやめておきたいんですよ。
まあその面倒ごとを避けようとするスタンスが一番よくないのかもしれませんね。 というか自分がお客さんの立場にたってみれば、「カレントディレクトリにライセンスファイル置いて使ってください」と言われたら「はいOKです」ですむ問題ですよね。
やはりちゃんとライセンスファイル提供して使ってもらうべきかと思ってきました。 >>730
どう配布すんのかしらんけど
共有ライブラリと同じとこに置いて固めるなり、インストーラー書くなりすれば十分やろ
たいして報われん努力やと思うわ
それよりライブラリAは何がしたいんか気になるわ
意味あんのかそれ >>733
ライブラリAはwebAPI叩くからその時にアクセス権限チェックでライセンスファイルを使うようです。 >>732
ロードされてる共有ライブラリのパスはとれるはずやから、
そこにライセンスファイル置いておく手はある 変数と型についてなんだがメモリは2進数でデータを記録していて、それを何byteで区切って、どういう意味を持つか(正の整数のみとか)を型で決めてるんだよね?だとしたらポインタに型があるのはなぜ?どれもアドレスを示すんだからある意味int型でいいと思うんだけど >>736
そういう言語もあったよ。
でも、ポインタを経由しただけで型がわからなくなるんじゃ、
型システムが意味を成さないだろう。
元と違った型としてアクセスしようとしたときに、
型情報がなけりゃコンパイラが捕捉しようもない。
それはプログラマの責任で正しく扱うってのならそれでもいいし、
実際、 C/C++ はプログラマがやりたければポインタを整数に型変換することも出来るけど、
(言語仕様としてはほとんど保証はないが。)
人類は間違うのでな。
型が合わないエラーなんてたびたび出しちゃうもんだろ。
もし型がなければそれはスルーされてわけのわからない挙動をするプログラムになるんだぞ。
そういうのはもうやめようって話。 >>736
ポインタに格納されるアドレス値は32bitとか64bitとかの整数でそれ自体は同じ型として扱えるとしても、そのポインタの指す先にある物の型が分からないと色々困るでしょ。
ポインタ型としてvoid*だけでプログラムを書こうとすればその必要性がわかるはず。
同じバイト表現だからといって同じ型で表さなければならない道理はない。用途や演算結果が異なるのだから別の型として扱うのはある意味自然なことだと思うよ。 >>736
参照はずし、つまり*演算子で「ポインタの指す内容」を取り出すときに
そのポインタがどんなデータを指すポインタか分からないと困るでしょ。
構造体を指すポインタで p->menber とかする場合も同様。
>>738 の「void*ポインタだけ使って書いてみる」ってのは、
ポインタに型のある有り難さを実感できる良い課題だね。 Cのポインタ型はK&Rのプログラミング言語Cに書いてある通り、単なるアドレスを保持する型じゃなくて配列の仲間なのよ。
例えば
char *cp =“abc”;
で
*(p+1)の様に書くと、ちゃんとcharサイズ分ずらしたアドレスを指してくれる。
その本には
(当時の)優れたプログラマたちがやってた事を言語仕様として取り込んだと、という様な事が書いてあったと思う。
ポインタが示す先の型とサイズやらの心配はC言語では不要だ、すげーだろ?的な。 Cのポインタ型はK&Rのプログラミング言語Cに書いてある通り、単なるアドレスを保持する型じゃなくて配列の仲間なのよ。
例えば
char *cp =“abc”;
で
*(p+1)の様に書くと、ちゃんとcharサイズ分ずらしたアドレスを指してくれる。
その本には
(当時の)優れたプログラマたちがやってた事を言語仕様として取り込んだと、という様な事が書いてあったと思う。
ポインタが示す先の型とサイズやらの心配はC言語では不要だ、すげーだろ?的な。 >>741
>>741
>*(p+1)の様に書くと、ちゃんとcharサイズ分ずらしたアドレスを指してくれる。
*(cp+1)の間違い >>737
>>738
>>739
>>740
ヒューマンエラー防止
型のないポインタを宣言すると中身のbyte長が不明
ってことかありがとう
740のコードを見て疑問に思ったんだけど*cpは一つのアドレスしか記録できないから配列の先頭(文字a)のアドレスを記録するよね。このとき配列の長さが3だという情報はどこにあるの?(脱線するけどNULL終端も数えて長さ4?) >>743
ポインタが指す先にいくつ分の領域があるか(いくつ分を参照してよいか)は記録されてないから、プログラマが自分の責任で管理するしかないよ >>743
直接長さを示す情報はどこにもないよ
だから、cの「文字列」は単なる文字の配列だけではなく、0終端が必要
>(脱線するけどNULL終端も数えて長さ4?)
その通り
(NULLはnullptrとしてのみ使ったほうがいいよ
混同してないならいいんだけどね) >>740
>>741
>ポインタが示す先の型とサイズやらの心配はC言語では不要だ、すげーだろ?的な。
サイズって型のサイズでした、すみません。
配列長さは
sizeof(*cp) / sizeof(型)で取ってねって書いてあったよね? \0終端が来るまで確保されていると想定して受け取り側は動作する
だから終端記号がないと色々まずい
(ので、バッファ長も指示する関数が後から増えた) 便乗質問でごめんやけど
delete [] p;
この場合deleteはどうやってサイズ調べてんの? >>746
char *cpで宣言してるならその計算じゃ配列サイズはとれないよ。 要素数の算出は
sizeof(配列) / sizeof(配列[0]) または sizeof(配列) / sizeof(*配列)
ではなかろうか? コンパイル時に確定する値だから
実行時には定数として埋まってるんでないの?
(ほんとんどの環境で インタープリターはしらんw sizeofは演算子だから動的じゃないかな
最適化で消し飛ぶ可能性はあるのかもしれんけど >>748
実装依存だと思うけど、p[-1]とかに長さが書いてあったりする アンカー長くなるから省略するけど
みなさんありがとう VLAのこと完全に忘れてた sizeof(配列) は動的だわ sizeof の結果は動的な判断が必要な場合 (いわゆる VLA) を除いて整数定数であることは保証される。
C++ には VLA は無いので sizeof が動的であるかどうかを心配する必要はないんだけど、
それは置いといて、 C++ で配列の大きさを知りたいときは std::extent の方がよくない? >>756
>>744-755
というアンカー表示方法も、知っておいてね。 昔はstd::extent持ち出したりしたが今はstd::sizeだな uint8_t *addrb =(uint8_t *)0x00F00000;
uint16_t *addrw =(uint16_t *)0x00F00000;
*addrb = 0x10;
*addrw = 0xF0F0;
0x00F00000番地に0x10と0xF0F0を書き込むコードらしいのですが、最初の2行がよく分かりません。アドレスが4バイトなのにポインタはそれより小さくて問題ないのでしょうか。右辺のキャストは何を行っているのでしょうか。
よろしくお願いします。 >>762
・整数だから昇格するよ
・整数即値をポインタ型に変換してるよ
ポイント先のデータは多分、バイト型だよ
マップドIO系のCPUではよく見るパターンだね >ポインタはそれより小さくて問題ないのでしょうか。
*addrb = 0x10;
*addrw = 0xF0F0;
この文を見て上の疑問に到達したのかな?
ポインタは addrb や addrw で その変数の器の大きさはアドレスを格納できる大きさ
*addrb で アドレスにさされた先の内容を示す 内容の大きさはその型による
*addrb は uint8_t 型でおそらく1バイト (1オクテット)
*addrw は uint16_t 型でおそらく2バイト (2オクテット) ありがとうございます。
理解できました。
そもそもアドレス自身のサイズがあるものと勘違いしてました。 アドレス自身にもサイズはあるけどね。
sizeof(*addrb) == たぶん 1 (8bit)
sizeof(*addrw) == たぶん 2 (16bit)
sizeof(addrb) ... 近頃のPCでは 4 (32bitアドレス) か 8 (64bitアドレス) かのう。 メモリ消費についてききたい。
8byteのa,b,cっていう変数と、それを結合した24byteのdっていう変数をクラス内で扱いたいんだけど、素直にやると48byteメモリ消費だよね?
代わりに24byteのdと、8byte型のポインタ(4byte)3つ宣言したら36byteのメモリ消費で12byte/オブジェクトの節約になると思うんだけど、最適化したければ意識するべき?
あるいはコンパイラがその辺は上手にやってくれて最小限のメモリ消費になる? >>767
ポインタ先をチェック・確保するのにヒープメモリーと計算コストが掛かる。 >>767
宣言次第ですね。
メモリ節約だとdを配列にしておくといいかなとおもいました。 >>767
それ実体の24byteが別に要るだろ… 下のソースをコンパイルしてコマンドプロンプト(cmd)で実行すると「鷗」の字が出力されません
int main(int ac, char **av){
setlocale(LC_ALL, "");
fwprintf(stdout, L"[%c]\n", 0x3042); // [あ] と表示される
fwprintf(stdout, L"[%c]\n", 0x9dd7); // [?] と表示される
return 0;
}
同じコマンドプロンプト(同じwindowsインスタンス上)で
python3 からだと(スクリプト経由でもIDEでもどちらも)
print(f'[{0x3042:c}]') # [あ]
print(f'[{0x9dd7:c}]') # [鷗]
表示されます
setlocale(LC_CTYPE, "en_US:utf8");
にしても同じでした
python3 からだと表示出来るということは
fwprintf に問題があるということでしょうか? Windows は、Visual Studio だろ
TCHAR マクロで、sjis/Unicode を切り替える。
Windows用の環境を揃えないと、無理だろ UNICODE
_UNICODE
とかは定義してあります
それに[あ]の方は表示されてるので
TCHAR が char と誤認識とかめっちゃ的外れな指摘だと感じます fwprintf
ワイド文字を書き込む場合、ファイルはバイナリー・モードでオープンするか、
o_ccsid または codepage パラメーターでオープンする必要があります。
これにより、ワイド文字に対して変換が発生しないことが保証されます。 >>767
もしかして windows で 24bitカラーを取り扱いたい話? union で楽する
#pragma pack(push,1)
typedef union {
BYTE e[3];
struct { BYTE B, G, R; };
} BPP24_t;
#pragma pack(pop) >>768-770 >>775
ありがとう説明不足だった
厳密にはL2フレームを実装したくて
DMAC6byte
SMAC6byte
TYPE2byte
とかを結合して送りたい。
んだが、結合用の変数を用意するとメモリ消費二倍な気がしていやだなと。
で、それぞれはポインタにして結合用の変数の0、6、8byteめを指定してやればいい気がして聞いてみた >>776
プロトコルスタックでそういうデザインはよくある
nicにわたすときのdmaもそんな感じ
しかしその数バイトの処理はこだわるところじゃない 規格で標準ライブラリ中のメソッドがconst指定されていない場合これをconst指定するのは規格違反ですか?
具体的にはuniform_int_distributionのconstなインスタンスを生成してoperator()(URNG& g)を呼び出すとMSVC(VS2017)のみ通り、gcc4.3.2とclang4.0ではコンパイルエラーになりました
N4140及びN4659を参照した限り、上記のオペレータはconst指定されていませんでした >>776
フレームの組み立ては迷うことなくstructでいいと思うのですがどうでしょう。ちなみにpingではは素直にstructで組み立ててあります。 >>777
確かに数バイトなんだけどね
>>779
cppで書いててクラスのプライベート変数として持ってます
結合どうするかだけ悩ましい >>780
ああ、なるほど。structでガワ作っておいて、ペイロード書き換えてバッファに溜めていくって感じでしかやった事しかないですけどケースバイケースなんでしょうね。 C++難しすぎねえか?
こんなの新機能を網羅してる人どんだけいるんだか・・・ >>783
別に網羅せんでも使えるところだけ使えば良い。
常に新しい機能を把握しておく必要はない。
使わない方が良い機能というのは有るので、駄目な部分を把握する方が大事だと思う。
(その結果として新しい機能に行きつくこともあるけど。)
新しい機能を使わないと回りくどくなるだけだが、
駄目な機能は致命傷になる (という可能性をコンパイル時にエラーに出来ない) こともあるので。
今の C++ で nullptr でなく NULL を使う理由は全然ない、みたいなのとか。 てかコンセプトが待ち遠しい
templateの黒魔術っぷりが大幅に改善されるよね
エラーメッセージが分かりやすくなるのが大きい コンセプトとモジュールは C++er の悲願って感じだからな……。
今まで土壇場での延期を繰返した経緯を考えると次も本当に入るのか
疑わしい気はするけど。 配列のアドレスが表示できません。何が悪いのでしょうか。結果はからになります。
unsigned char a[100];
cout << hex << &a[5] << endl; >>788
&a[5] は「unsigned char を指すポインタ」なので
cout << では「'\0'で終端する文字列」として表示しようとするのよ。
なもんで >>790 の通り void* にキャストして、
具体的なデータを指さない「単なるアドレス」扱いしてくれと指示。
ちなみに >>789 は効果ないでしょ。
でも C++ の作法としては static_cast<void*>(&a[5]) と
長々しい名前付きキャストを使うべきなんじゃろか。
個人的には static_cast<const void*>(&a[5]) まで書きたいけど。
inline const void *to_voidptr(const void* p) {return p;}
てな具合に、字数を減らすための変換用の関数でも使うか。
…何か標準的で短い書き方があったりするのかしら。 文字はcharだけでsigned/unsignedは整数扱いするとかしてくれりゃよかったのにな。 coutなんて使うのが悪い
printf()でおk qDebugばっか使ってたからcoutの使い方なんて忘れてたわw そういえば「cout << &a[5] でアドレス値が表示されない」ってのは
char 系の配列やポインタの場合だけで起きる特殊例なのかな。
ユーザーが operator<<(ostream&, T*) の再定義をしない標準の状態で、
オブジェクトのアドレス値を送ったらアドレス値以外の何かが表示される型って
標準か有名どころのライブラリで、何か知ってる? operator<<(ostream&, T*) の再定義をしないライブラリで
オブジェクトのアドレス値を送ったらアドレス値以外の何かが表示される型を定義しているものは?
という質問に置き換えてみた gccのiostreamのソース辿れば全部書いてあるよ。 >>797
ほう、どこに書いているのかわかってそう言っているのですね、それはすごいですね ライブラリのソースコードを辿っていくとビルトイン関数だったりして萎えることもあるので、
まずは仕様をちゃんと読もうな。 >>799
ostream のヘッダ単独は意外に分量少なくて一通り見られたよ。
char系以外には...
operator<<(nullptr_t); // #if __cplusplus >= 201703L で条件コンパイル
operator<<(__streambuf_type* __sb);
があるみたい。本当にこれだけか確実ではないけど。
nullptr_t の方は「nullptr が送り込まれたら "nullptr" と表示しろ」だと思うが
__streambuf_type* __sb は分からん(定義は別ファイル、みたいだし)。 現在アルゴリズムの勉強をしています
ソートアルゴリズムで有名な基本挿入法で与えた5つの整数を小さい順に並べるプログラムがうまく動きません
基本選択法、基本交換法(バブルソート)は書けるのですが…
ソートアルゴリズム、アルゴリズムそのものは図で正しく書けるとは思うのですが、コードに落とし込むのがうまくいきません
書いたコードは稚拙ですが以下のものです おかしな点を教えてくだされば幸いです
#include<stdio.h>
//基本挿入法
int main(void){
int temp=0,j,i;
int ary[5]={9,6,1,5,2};
for(i=1;i<=4;i++){
temp=ary[i];
for(j=i-1;j>=0;j--){
if(ary[j]>ary[i]){
puts("aaa");
ary[j+1]=ary[j];
}else{
puts("jais");
j--;
break;
}
}
j++;
ary[j]=temp;
printf("a[%d]は%d a[%d]は%d¥n",j,ary[j],i,ary[i]);
}
for(i=0;i<=4;i++){
printf("%d¥n",ary[i]);
}
return 0;
} puts(“aaa”)やputs(“jais”)はprintf(“a[%d]は%d 〜”)の3つは、プリントデバグのために書いたものです…消し忘れました
すみません >>803
https://ideone.com/gIcJzp
納得がいくまで printf() を仕掛けるのはいいことだと思います。 class C
{
public:
void f(){}
};
C* pc= new C;
pc.f();
コンパイルエラーが出るってことは、コンパイラはpcがポインタであることを
知ってる
なのになぜ、->と記述させるの? ClassAのメンバにClassBがあってコンストラクタかsetterで外部から与えたいんだけど、
ClassBが大きくてできるだけコピーしたくない場合はどうするのがベストですか?
コピーコンストラクタが呼ばれた場合に初めてコピーされるようにしたいです
unique_ptr<ClassB>型にするとスコープを外れるときに落ちました
Class ClassA{
public:
ClassA(ClassB &b) { m_b.reset(&b); };
ClassA(const ClassA a) : m_b(new ClassB(a.m_b)){};
・・・
private:
unique_ptr<ClassB> m_b;
}
main(){
・・・
{
ClassB b;
ClassA a(b);
} // ここで落ちる
・・・
} > m_b.reset(&b);
ヒープオブジェクトじゃないものをunique_ptrに突っ込んだらダメ。
カスタムデリータ用意するなら別だけど。 >>809
この場合にスマートポインタは違うようですね
メンバは実体にして渡すときにムーブすればコピーは発生しないという認識は正しいですか? ClassAはClassBそのものを所有するのか
それとも外部のClassBへの参照を保持するだけなのか?
そのものを所有するなら外部から与えるのではなく
ClassAの中でClassBを構築するのも検討してみれば
// ClassAのコンストラクタ
// 11以降ならムーブとかも
ClassA(ClassBの構築に使う引数) : m_b(前記の引数) {} >>810
スマホ使う前にオブジェクトの所有権を明確にせよ。 ClassBの構築に使う引数も大きいためコピーを避けたいところです
基本的には参照を保持するだけにしたいところですが、ClassBがスコープを外れて破棄される場面ではClassAに実体をコピーできるようにしたいです なんでそこでわざわざコピーしたいの?
最初からnewでヒープに確保すりゃコピー必要ないのに。 AにB*とunique_ptr<B>を作って
AがBを使うときは常にB*経由でアクセス
Bを所有させたいときだけunique_ptrにヒープ管理だけさせる 2つ持つという発想はありませんでした
試してみます 昔、openGLを使ってC++出遊んでたんですけど、また最近触りたくなりました
皆さんC++で何作ってますか?
個人開発規模でお願いします >>817
昔作ったツールがひょんなことで役立っています…
あるディレクトリを別のドライブにコピーするだけのことなんですが、いや、まあ、Windows はなかなか御しがたく、path 文字列長が一定範囲を超過すると止まってしまう変てこなコマンドラインツールが未だに現役だったりするのです…
https://mevius.5ch.net/test/read.cgi/tech/1434079972/53 >>818
システムコールってやつですか?
オブジェクト指向と並列処理を勉強したいと思ってるのでQtもいいかなと思ってます
どうでしょうか? Qtのデメリットはライセンスだけだから個人でやる分には良い選択 オブジェクト指向を学ぶのにRubyあたりを使うのは
どういうデメリットが?
Pythonは「バージョン違いによる仕様変更」に
入門書レベルのコードが影響されるのであれば「良い選択とは言えない」ことになりそーだけど >>821
せっかく新しい言語を学ぶなら、近い将来役に立たなくなる言語より他の役に立つ言語を選んだ方が合理的だと思う pythonて破壊的な変更があったのは20年近く前なのに、未だに古い仕様で書かれた入門書が出回っているなら、オブジェクト指向学習に最適化どうかとは別に、問題な気が。 Qt5.12.2はLGPLライセンスでインストールしとけばok?
他のライセンスは初見 "Qt Creator 4.8.2 CDB Debugg..." と "MinGW 7.3.0" 64-bit" 入れたら Hello World の窓が表示できるようになったけど、
練習ならそんなかんじでok? しばらく正常に動いてるように観えてても
あとで問題が顕在化して困るパターン どのような問題が発生しうるのでしょう?
もっぱら個人用の練習用とする予定 ID:K5RuTlhq です
>>826
https://www3.sra.co.jp/qt/licence/index.html を見て『グラフ作成パッケージQt Charts入れておいた方が便利かも』と思い
いったんアンインストールしてみたのですが、
[Qt 5.12.2 のセットアップ] の画面で
Qt Charts
Qt Data Visualization
Qt purchasing
Qt Virtual Keyboard
Qt WebEngine
Qt Network Authrozation
Qt WebGL Streming Plugin
にチェックを入れたとしても LGPL が選べるようです
サードパーティーの追加パッケージで問題となりうる…? >>828
具体的に「どのような問題が顕在化」し「どのように困る」ことになるのでしょうか
クラスとメンバ関数のみの指摘でも構わないので、示していただけませんか?
また、その問題を回避する方法は何なのでしょうか? >>832
LGPLを選べたとしてもQt Chartsを使っていればGPLv3
GPLと非互換のライセンスのライブラリを使うなら問題になる
だがそもそも練習段階ならライセンスなど気にせずどんどん書け 昔は知らんが5.12.1ならQt ChartsはLGPLで許諾されるよ? はっきりとGPLv3と書かれてる
https://www.qt.io/download
Open Source->Additional features->Data visualization の?を参照 条項はこれから確認する
>>837
インストールの操作手順からしたら
不意打ちも良いとこだなあ
Qt Charts をチェックした状態で[次へ(N)]ボタンを押したときに
「修正を受けたGPLv3」以外のラジオボタンが無効になってないと
UIとしておかしくねえか
あと「100%GPLv3と一致で修正条項なし」なん?
そうだとしたら、なおさらおかしい そういえば
LICENSE
などと大文字ファイル名にしないと効力が発生しないとする「糞判例がある」と聞いたことがあるけど、日本の裁判所?
ググっただけでは見つからなかった
最高裁判例なら検索結果の判決文をPDFで読める訳だがなあ
そのようなケースを敷衍すると、帰結として、Qt chartsはLGPLとなりうる
GPLv3 については逐条解説もあるから、そっちの内容も確認してみてちょ(あくまで「解説」) 純粋に「Qt のライセンス」の話なのでスレチ?
copyright notice の表示方法の適切性について、GPLv3って基本的には明確には記載してなくね
ただし今回のケースだと、「インストーラが LGPL によるライセンスを表示した状態」で先に進める以上
0. Definitions. の第8パラグラフ(1) 反対解釈により、「GPLv3は適用されない」と読む余地がある
実際、GPLv3 につき "displays an appropriate copyright notice" してないもの 書き込み制限受けたので続き。多分コレで終わり。
あのインストーラが表示している著作権表示は明確に LGPL だから適用条件満たしてないと解釈する余地がある、と
…わたしはただの学習者だから大騒ぎすることでもねえんだがねえ… int& a;
int &a;
どっちにすべきでしょうか 「すべき」というのは規格表での『shall』のことですか?
それとももっと別の意図がありますか? std::add_lvalue_reference<int>::type a; そんなこと気にする前に参照の変数を未初期化で使おうとするなよ。
みたいなツッコミを入れたくなるけど、コンパイル時にエラーが出る
間違いは必ず見落としなく直せるから実際は大きな問題じゃないよね。
「ポインタ宣言の * を型名に寄せるか変数名に寄せるか」と同じで
一貫した書き方をするかぎり、どっちでも構わんでしょ。
個人的には「変数名に寄せる」派だけど。 int& a, &b;
int &a, &b;
自分も後者の方がいい >>847
> 未初期化で使
コレの解釈は揺れそうだが、たとえば
int *i;
とか、
int *i;
int j;
i = &j;
とかいうかんじのことかしらん わからない事をここで質問しようとレスを書いてる最中に「わかった!」
ってなることが多々あるんだが、この謎の現象は何なんだ・・・ 自己解決パターン
質問するときに頭の中が整理される→解決
質問するために再現する必要最小限のコードを書く→問題の切り分けが出来る→解決
いろいろあるが >>851
何が駄目なのかわかれば解決法は自明であることが多い。
逆に言えば、解決法がわからないときは問題が何であるかわかってなかったりするんだよ。
だから、きちんとした形に質問をまとめれたなら、それはもうほとんど解答でもあるんだ。
この手法を利用してバグを取り除くやり方としてラバーダックデバッギングというものが知られている。 C++erならRust学べって風潮嫌い
なんで学習コストがある言語を2つも学ばないといけないのかと思うし >>849
あんまり大それた意見とではなくて
void func()
{
int &a;
...
}
と宣言したら、参照先不明の &a を作ろうとしてるから
必ずコンパイルエラーになるじゃろ、程度の指摘。
…ただ、この投稿を書こうとして気がついたんだけど、
class samp {
int &a;
...
};
てな具合に、クラスのメンバとしての宣言ならエラーにならないね。
ちゃんとコンストラクタで a に参照先を与えるなら許される。
要するに >>847 の前半部分は間違ってた、ということ。
正しい場合もあるけど、常に正しいわけじゃない。 その場合でもコンストラクタで初期化してなかったらエラー出るんだから
説明自体は間違ってない >>853
テディベアをおいておくというエピソードなら有名だね >>854
難しいことも違った方向から見るとわかりやすくなることもある。 質問です。
cinの戻り値のistream&がなんでif(cin)みたいに真偽判定に使えるのかが発端です。
https://stackoverflow.com/questions/8117566/why-istream-object-can-be-used-as-a-bool-expression
こことか見たんですけど、
1.istreamはbasic_iosを継承してて、
2.basic_iosで型変換演算子explicit operator bool() const;が定義されてる
ってとこまでは理解しました
ここからが質問なんですけどこの型変換ってのは勝手に行われるもんなんですかね
if(something)って書いたらif(bool(something))っていつもやってるんでしょうか 型変換以前に0やnullポインタを評価するとfalse、0以外の値はtrueと評価されると決まっているからだろ。
あと暗黙の型変換はよく起こる。 if 文の条件判定部は bool 型を要求してる前提で解釈,翻訳してるんじゃない >>859
yes.
条件部はブールを要求し、もしブールでない場合は常に型変換する。 前橋和弥さんのC言語ポインタ完全制覇という本で、
PCの環境(CPUの種類など)によってデータのメモリ上の配置は異なる
(構造体のパディングをはじめ、ただの単体のintでさえバイトオーダーが異なる(ワークステーションではビッグエンディアン採用だったりする))
ので、メモリの内容をバイナリでディスク上のファイルに出力したデータは別環境で読み込んで使おうと思ってはいけない
というような事が書いてありましたが、この話はWindows以外の環境や古い環境を前提とした話なのでしょうか?
同書にWindowsではBMPファイルをfwriteでファイルへダンプしていていかにもWindowsらしいとも書いてあるので、
Windows環境ならゲームのセーブデータとしてクラスをまるごとfwriteでバイナリ出力したファイルを別PCでロードしても問題ないのでしょうか?
(Xeonとかワークステーションマザーとか関係なしに、IntelCPU&Windowsの環境ならばリトルエンディアンで統一されている?)
(Macではビッグエンディアンになるが、Windows環境のみ対応のゲームを作る上では無視してよい?)
という認識は間違っているでしょうか?
パディングの違いなどもWindowsやVisualStudioが自動で良きに計らってくれるのならありがたいのですが… windows間だから「別環境」ではなく「同じ環境」
だからwindowsでも同じ
そのbmpデータをmacに持って行っても使えない
なので磁気コアをダンプして永続化したようなデータは、他の全ての環境で使えない
60年代くらいから知られている >>865
Windows環境であれば、別PC(別ハード)でも同環境とみなして良いのですね
>>WindowsではBMPファイルをfwriteでファイルへダンプしていていかにもWindowsらしいとも書いてある
読み直したら、違ってましたm(_ _)m
可変長構造体の節で、
WindowsではBMPをfwriteなどで可変長構造体まるごとダンプしていて、
BMPのような他の環境にもっていく可能性が高いファイルを構造体まるごとダンプしているのがWindowsらしい
というような内容でした
Windows級の一流プログラマーでも構造体まるごと出力を使っているのであれば、
ゲームのセーブデータで構造体やクラスをまるごとバイナリ出力しても問題ないととらえてよいのかな? >>866
bmpファイルには仕様があるので「Windowsのプログラマがどうたら」なんぞ関係無く仕様に従って読み書きすべし
(現実には仕様に従わない入出力をやらかすアプリ毎に対処することはあるが)
自分で定義した構造体でも外部に公開するなら仕様を決めそれに準ずるべし
公開しないならそれこそ構造体丸ごとダンプなり好きにすれば良い
実際にそういう実装は珍しいものじゃない
どうせ環境の変化で困るとしてもそれは自分だけだからね >>864
今でもそうだよ
書いたコードがたまたま正常っぽく動くからと言って
仕様にない動作を期待するコードは糞 つまり、後で困りたくなかったら、フォーマット(読み書きするサイズと順番?)を決めて
構造体のメンバ変数ひとつひとつ読み書きしていかないとだめなのか
…めんどくさいなー 異なる環境で扱う可能性のあるファイルならフォーマットを決めるのは当然だが
メンバ毎にアクセスしなければならないかどうかは処理系によるだろう。
仕様さえ合えば構造体で読み書きしてもいいわけで。 構造体まるごと fread/fwrite した後に
環境に応じて必要な場所だけLE/BE の変換をかける
htons とか htonl とか使う どういう読まれ方をするか分からない時はXML型式のテキストファイルにしてしまう >>871
有能!
と思って調べたら、ホスト トゥー ネット(ホストのバイト順(リトルエンディアン)からネットワークのバイト順(ビッグエンディアン)への変換)ですか。
バイトオーダーはこれで問題なさそうですね。
でも、まだです!まだですよー回答者様!
次はCPUによってアライメントの行い方(パディングの量)が違う問題についてです!
fread/fwriteで構造体まるごとバイナリ読み書きする時のパディング値が別PCで異なる場合に良い対処法を教えて下さいませ!
ないなら諦めて
>>872さん
のオススメのXMLを勉強します! 自分では使ったことないけど、BoostのSerializationは? パーサコンビネータはバイナリファイルに使ってもいいんだよ。
あとは protobuf とかのジェネレータ系のツールもありかな。 VC++用に使ってるマシンのCPUがivy bridgeのi5の3570なんだけど、
そのマシンでは8の倍数バイトを境界としてパディングが入ってるかんじなんだけど、
Core2Duo世代のCPUだとどうなんだろう?
4の倍数バイトを境界とする様な古いCPUがネットバースト世代以前とかの相当古い環境だとしたら、もう動作対象環境から外しても良い気がしてきた
そうだとしたら、クラスまるごとバイナリ読み書きでよいのかな >>876
E8400の機があるから調べてみよっか?
何で検索したら調べ方出てくるか教えてくれたらやってみるよ >>877
ありがとう
これでどうかな?
//-------------------------------------------------
#include <stdio.h>
#include <conio.h>
class ClassName
{
public:
int int_1;
double double_1;
char char_1;
double double_2;
};
int main(void)
{
ClassName class_obj;
printf("クラスインスタンスのサイズ:%d\n",sizeof(class_obj));
printf("int_1のアドレス:%p\n",&class_obj.int_1);
printf("double_1のアドレス:%p\n",&class_obj.double_1);
printf("char_1のアドレス:%p\n",&class_obj.char_1);
printf("double_2のアドレス:%p\n",&class_obj.double_2);
_getch();
return 0;
}
//-------------------------------------------------
クラスインスタンスのサイズが24なら4の倍数バイト、32なら8の倍数バイトの境界になってると思う
(8の倍数バイトの境界なら、各メンバのアドレス(16進数表示)が全部8違いになってるはず) >>878
ソースありがとう
クラスインスタンスのサイズ:32
int_1のアドレス:0036F7A0
double_1のアドレス:0036F7A8
char_1のアドレス:0036F7B0
double_2のアドレス:0036F7B8
これで情報足りるかな?
ttps://i.imgur.com/YAVbZWa.jpg >>879
どうもありがdd
Core2Duoで8バイト境界になってるなら、もう4バイト境界の環境の事は無視しても大丈夫なのかもね
思ったんだけど、もしかしたら、32bit(4バイト)のみ対応のCPUと32bit/64bit(8バイト)両対応のCPUの違いなのかな?
違うかな?そんなに単純な話ではないか・・・ 本質じゃないがxmlじゃなくてjsonがオススメ
もっと突っ込むならyamlがオススメ YAML は人間が読むこともあるなら可読性とのバランスで選ぶことはあるかもしれんが、
機械可読であればよいような場面で選択する理由は無いんじゃないかな。
既存のライブラリを使えばどれでも手間は大差ないとは思うけど、
バイナリ表現だと MessagePack とか Bencode とかいった選択肢もあるし、
どうして色々なフォーマットが登場したのかというとなんだかんだで「場合による」としか言い様がないからなんで、
まあ主要なやつを一通り特徴を把握しといた方が良いよね。 何にじゃねえな
yamlはperl
jsonはjavascript
時代の流れでjsonが優勢になった
出来ることや表現力はあんまり変わらない yamlは最近dockerとかkubanetessとかansibleとかインフラ/環境系ツールのせいでやたら触る事が多い もう16バイト境界なんてのも出てきてるのか
VisualStudioのプロジェクトのプロパティのC/C++のコード生成で
構造体メンバのアライメントを8にするか、
コード上で #pragma pack(8) とすれば
強制的に8バイト境界にできるみたいだけど、
マシンに最適な既定値のアライメントから変更する事で速度が遅くなったり
何か不具合が生じたりするものかな? 既定のアライメントというのはふつう、メンバの単純型のサイズに合わせられるはず。
16byteの単純型を使うのでなければ16byte境界にする必要もない。 問題ないなら旧環境との互換性重視で4バイト境界にするのもありかな? 互換性重視なら、各メンバを自然なアライメントに配置して手でpaddingを挿入して#pragma pack(1)。
>マシンに最適な既定値のアライメント
少なくともx86の場合、それが4とか8とか決まっているわけじゃない。 >>891
#pragma pack なんて MS の方言でしょう?そんなのを使いながら「互換性重視」とか矛盾してませんか? C言語ならともかくC++なのに例外を避けようとする人ってあたまおかしいのかな
標準ライブラリもその他のライブラリも例外を投げる前提なのに頑なに例外を避けようとするってそうとうに筋が悪い非合理的な選択肢だよね >>894
例外の実装方法の一つ sjlj に抵抗を感じるのなら、それは感覚として正常だと思います
C で sjlj を使用しての例外実装コードが書けますか?書けない場合は >>894 は単なる馬鹿か宗教者だと思います >>895
何が言いたいのかわからん
sjljが重いのが嫌なのか
あの仕組み自体が気色悪くて嫌なのか
でも今時sjljで例外実装なんてしていないよね
わざわざ選ばない限り SJLJの話じゃないです
例外を避けてオレオレエラーコードを返す迷惑な人達の話です 例外もまともにキャッチされないので
どっちもクソです エラーの発生頻度によるのでは?
throwは高コストだから発生頻度が高い場合は戻り値で処理した方がいい システムによる
航空機の運航システムでのエラー処理はどうすりゃいいわけさ >>899
入力の検証、パース以外で頻繁に発生するエラーって例えば何でしょうか?
そもそもthrowはコストそんなに高くないのでは?
エラー情報(コード、メッセージ、下位エラー情報、スタックトレース等)を戻りでコピーしまくるほうが高く付くと思います >>896
自分で実装できないものを、その仕組みもわからないのにホイホイ使ってしまってもいいのでしょうか?
他の言語ならともかく、C/C++er がそういうところに無自覚なのは大いに問題があるのでは?
そんなことでデバッグできますか? >>896
>今時sjljで例外実装なんてしていないよね
じゃあ win32api の構造化例外sehでも許容しますよ >>902
内部構造がわからないものでもAPIドキュメントを読んで使えるようになるのが正しいプログラマでは? まあそういう賢いプログラマなら当然の様にSpectreの可能性に気づいて対策していたんだろうね。
きっと >>904
他の言語ならそうですね
でもC/C++ において、そんな態度でいいのですか? つまりすべてのAPIをスクラッチでかける人間以外使うなと言うことなんだな 大体sj,ljが肝なのだから、そこ丸投げしたら同じようなもの 内部構造まで把握してなきゃ使っちゃだめなんていう烏滸がましい思想を持ってると
実装に強い影響を受けるエラーコード返し方式を選んでしまうのだろうな なんかライブラリ使ってるだけの輩がイキリ出しとるなw
確かにライブラリによってはそのライブラリの単体テストなり書いといた方が良いこともある。 静的例外の提案がある。
使える例外オブジェクトに制限があるし、
静的例外を投げる可能性がある関数は型として明記しないといけないけれど、
見かけ上は例外の構文を使いつつ
実質的に返却値と合わせて例外オブジェクトを受け渡すような方法をとれる。
https://cpplover.blogspot.com/2018/07/c.html
江添氏もこれには期待しているらしいことを書いている。 >>911
SOLIDを実践しないからそんなおかしなテストを書くはめになるんでしょうな 例外便利だけど、例外が高確率で起こる場面じゃ使うと遅くなるから、仕方なく結果コード判定してとかの糞コード書かなきゃいけなくなる。 >>912
いいアイデアですね
早く実現して普及して欲しいものです
エラーコードを返す非常識なコードが世界から駆逐されますように 俺は戻り値をboolにするかbool*のout引数を用意してエラー内容はメンバに記憶しておき、
成否だけで十分な場面では単純にbool値だけを見て、詳細が必要な場面だけエラー内容を取得する
ってやり方が気に入ってる >>914
入力の検証、パース以外でそんな場面ありますか?
それと、その場面は一般的なシステムでもよく採用されるのでしょうか? ファイルシステムでパスが存在するかとか権限があるかとか
リソースを確保できるかどうかとか
いくらでもあるでしょう >>916
例外を使わないとこうやってエラー処理がガラパゴス化するんですよね
私が今日弄ったシステムでも一部のコードだけ中途半端に特殊なエラー処理ルールを採用しています
本当に困ります
胃が痛いです そりゃそのシステムの問題じゃね?
例外なら「中途半端に特殊なエラー処理ルール」にならないというわけでもあるまい。 >>918
ボトルネックになるほど存在しない確率が高いファイルに連続アクセスしているならそんな小さな最適化前に見直すべきところがありそうですね
リソースについても同様といえます >>920
人間のやることなので完璧は無理でしょうな
比較の問題になります
例外とエラーコード返しを比べればどちらが標準的な型式に収まりやすいか?という問題なら例外が圧倒的に優勢でしょう 例外にすればエラー検知は簡単になるでしょうが
そのエラーに対してどう処理するのかはケースバイケース
標準的な方法なんて無いと思うけど
そこが肝心な所で優勢かどうかは些末のことだと思うよ 例外はcatchで標準化されますが?
その後のことは例外とエラーコードの比較って文脈で語ることじゃないな
強いて言えば例外の方が再通知の仕方もより標準的と言えるが 戻り値がboolならそれが正常終了したかどうかを表していることは誰にでもわかる
呼び出し元を正常系と異常系の単純な分岐にでもしておけば致命的なバグになることはない
例外の場合はその発生率が極めて低い場合にtry-catch忘れが起こると致命的なバグを含んだままリリースされかねない >>925
boolの解釈は人それぞれ
bool is_invalid() const;みたいなのもあるよね
あるいはただのビットフラグのON/OFFを示してるかもかもしれない
そもそもそれが処理の成否を表しているかどうかすら統一されてない
リターンコード方式ではリターンコードと分岐の洪水による目くらましでコーディングミスが多発する
それは必要なcatchを書き忘れる確率よりもずっと高い確率で発生する
例外は処理すべきものだけしか書かないから見通しが良く仕様書との比較もしやすい
リターンコード形式では何もしなくてもいいのに定型処理を書かねばならず
それによってどのエラー処理が仕様書に書かれた本当に必要なエラー処理なのか目で見てわかりにくい catch 以降でエラー内容に応じて振り分ける訳ですか?
気が遠くなりませんか? >>927
あぁ
そもそも例外の文法すら知らないのか >>919
リターン値方式に比べて exception のメリットは何でしょうか?
そしてそのメリットは本当にメリットでしょうか? >>916
エラー値を取得するタイミングがずれるようだとスレッドセーフを保障できなくなるのでは? >>922
>標準的な型式
なにを「標準的」とするかは世代差があるのではないですか?
java や c# に慣れた人は exception を推すでしょうし
ここで >>922 を私が強く非難している理由は、「標準的」というバズワードで自説を合理化する、その自分勝手さという点にあります >>925
>try-catch忘れ
>>925 が return-value 派か exception 派かはここでは問題にしません
しかし、この「try-catch」忘れ、という単語の存在そのものが、exception の利点が利点になっていないことを如実に表現していると思います
忘れないようにするための exception が忘れるもとになってしまっている、とか、全然おかしいんじゃないのでしょうか >>929
レスを読んでください
>>931
異なる世代の衝突があった場合は今を優先すべきでしょう
過去の過ぎ去ったことにいつまでも縋り付いては先へ進めません
ちなみにC++の標準ライブラリは例外を採用しました >>932
例外はエラー対応を忘れないようにするためのものではありません
例外はエラーの通知方法を標準化することとコーディングの労力を大幅に低減するための機構です
エラーコード形式でも分岐を忘れることはありえます
むしろ不要な分岐も定型処理として書かなければならないエラーコード形式ではノイズが多くミスや忘れが多く発生します >>933
>レスを読んでください
どのレスかアンカーをいただけませんか?
>>933
>異なる世代の衝突があった場合は今を優先すべきでしょう
>過去の過ぎ去ったことにいつまでも縋り付いては先へ進めません
「今の方が昔よりよくなった」という世界観に立脚しているのであれば、その説は説明できますが
「今よりも悪くなった」と考えている人を説得することができないのではないでしょうか?
>>933 が必要なのは「今の方がよくなった」と言い切れるメリットがなにか具体的に明示することだと思います。
単に「新しい方がよい」という主観だけを振り回しても、アンチ exception の意見を持つ人は納得できません
>>933 は具体的なメリットを明示することをせずに「新しい方がよい」という主観ばかり述べているのだから、議論の仕方をしらない「馬鹿な文系」に私からはみえるのです… >>934
私の考えるところの exception の利点の一つは、exception の発生した階層から遠く離れたところでも、その exception を catch して処理を記述できるところにある、と考えています
もう一つは exception を catch するとき指定するのは class だから、このエラークラスを派生関係として階層化することで、エラー体系の構造化ができるところでしょうか(派生クラスでも基底クラスでも catch できる、という点です)
しかし exception の話が持ち上がる度に、私の思う上記二点の excption の利点は言及されたためしがありません…
これでは exception の本当にいいところがメリットとして理解されていない、というか、メリットになり得ていないようですね…
exception は単なる無駄コスト食らいなんじゃないですかね… >>935
沢山あるので面倒です
今日のレスを読み直してください
悪くなったのが事実であれば新しいものが普及する前に消えるでしょう
普及してしまった時点で一部のロートル以外は良くなったと考えている証拠です >>936
離れた位置で捉えられる点はコーディングの省力化に暗に含まれると考えていいでしょう
全ての階層で定型処理を書かなくてもいい==離れた階層でも捉えたいところでだけ処理を書けばいい
ということです
例外の階層化についてはその通りですね
地味なので忘れがちですが便利です >>934
>エラーの通知方法を標準化することとコーディングの労力を大幅に低減する
ここでもバズワード「標準化」を使っていますね、漠然とした抽象的な単語を並べればいい、という思考の粗さが気になります
それに異常系の記述はどうあがいても、場合わけして都度逐一記述するしかないのは、return-value 派にしても exception 派にしても同じで、記述する中身が減るわけじゃありません
それとも exception で書けば記述が減るというのなら、何か書いてみてください
>>934 を読むにつけても、>>934 は本当に物事を突き詰めて考えているのですか?
世間がこういっている、とか、Java や C# ではそうしている、とかいう空気の読みあい、ポジション取りの忖度しかしていないのでは?
>>934 はたぶん文系プログラマなんでしょうね、私には強くそう推察されるのです… >>937
アンカーを書くことくらいもできないのですか? >>937
>悪くなったのが事実であれば新しいものが普及する前に消えるでしょう
google のコーディング規約では exception を推奨しないようですよ
https://ttsuki.github.io/styleguide/cppguide.ja.html#Exceptions
悪いものでも消えずに、もっと悪いことには悪疫として蔓延しているものもありますよ、もしかすると C++ の exception もその一つなのでは? ちなみに例外はもうすでに新しいものではありません
長年多くのプログラマによって効果が実証され続けてきた枯れた機能です
例外に変わるエラー処理機構が流行らなかったという事実が例外の完成度の高さを裏付けています >>939
エラーに対するハンドリングのコードについては例外とエラーコードの比較の外だとすでになんどか書きました
例外によって削減されコードは無意味な定型処理のことです googleが例外使わない理由は、例外を否定する類いのものでは無かったような >>942
>例外に変わるエラー処理機構が流行らなかった
というか exception そのものが流行らなかった、というべきでは…
なんども繰り返しますが「新しいものがいいもの」「枯れた機能」とかいう主観はいらないから、「exceptionの具体的な利点」を書くべきです
>>943
言っている意味がわかりません、お手数ですが、少し字数を使って説明いただけますでしょうか? >>944
「例外安全」を保障するのが、これは滅茶苦茶しんどいので、その一点で嫌われているんだとおぼろげながら感じています >>941
googleが常に正しいわけではないでしょう
例えばそのページでは、例外安全性を考慮していないコードのリスク、つまりリソースリークについて書かれてますがリターンコード形式でも解放を忘れればリークするのは同じことです
そして、さっきも書きましたがリターンコード形式では余計な定型処理がノイズとなってそういったミスをしやすくなることが問題です
コントロールフローが追跡難化するリスクも全く逆でダラダラと必要ない定型処理を書かれた方が追跡が難しくなります
自分で考えずに権威を盲信する人を文系と揶揄することがありますが
もしかしてあなたも文系なのでしょうか? >>945
例外を受け取ると何もせず上位に通知するメソッドを考えてください
例外形式ではコーディング量は0です
リターンコード形式では少なくともリターンコード値が正常系か異常系か判断して戻す分岐が必要です
これは少なくとも1行の無意味な定型処理を追加しなければならないということです
実際にはそのプロジェクトの規約によって1行どころでは済まないことが多いのですが… >>947
リターンコード形式で発生する余計な定型処理のノイズの例と例外でそれを回避できるケースの例をください
書かなきゃいけないコード量は本来大差ないはずです 例外安全というか、googleで想定しているリソース解放漏れって要はRAIIになっていないって事だよね >>946
リターンコード形式でも例外安全性(エラー安全性とでもいうのでしょうか)を守るには大きな労力がかかるはずです
リターンコード形式なら自動的にリソースが安全に解放されて全ての状態が実行前にロールバックされるといったことはありません
例外でもリターンコード形式でもリソースの解放と状態のロールバックの責任はプログラマあります >>947
>例えばそのページでは、例外安全性を考慮していないコードのリスク、つまりリソースリークについて書かれてますがリターンコード形式でも解放を忘れればリークするのは同じことです
そこで exception の実装に話が戻るのです
exception の実装(例えば sjlj, seh のどちらかひとつでいい)はどうしても(隠れたところに)グローバル変数を必要とするのではないですか?
これはスレッドセーフや例外安全を考えるときに、大きな癌になりうるでしょう
一方、return-value 方式は、頑張ればローカル変数だけで記述できる
return-value 方式の方が考えるのが楽ではないですか?
>自分で考えずに権威を盲信する人を文系と揶揄することがありますがもしかしてあなたも文系なのでしょうか?
かりにそうだったとしても最初は「新しいものはいいものだ」で押し通そうとした、あなたには言われたくないですね… >>949
例外の場合
T val = f(...);
エラーコード場合
T val;
int ret = f(..., val);
if (is_error(ret)) return ret;
最小だとこの程度でしょう
とはいえ膨大なコードベースになるとこれだけでもうんざりしますが >>948
その例外の上位への素通し、って、確かに >>936 では私も例外の利点だと書いてしまいましたが、でも実際には嫌われることなんではないですか?
java は下位ルーチンが発生させる例外(のうちのある種類)は、上位側で catch しとかないとコンパイラが怒るんではないでしょうか? 嫌われないよ
RAIIじゃない場合
一度キャッチしてリソース解放したあとスローし直さなきゃリソース漏らすというだけ >>956
なるほど、だとすると、>>936 で書いた「exception の発生した階層から遠く離れたところでも、その exception を catch」できる、というのは無条件では c++ では利点にならないですね、return-value 式とほとんど変わらない… >>952
たとえグローバル変数を使った実装だったとしても例外の利用者にとっては透過的なので問題はありません
スレッド処理でも問題はありません
同じスレッドでは利用者は何も気にせずに例外使えます
スレッドを結合するところでは例外を転送してください
そのための標準的な方法も用意されています
エラーコード形式の場合はスレッド間転送も標準のない独自形式になるのでより難しそうですね >>954
Javaには例外時に自動でリソースを閉じるための構文が存在しない時期がありました
検査例外はそのときの名残です
GCされるまで自動で閉じられることはないからちゃんと手動で解放しろと注意喚起する意味では検査例外にも価値があります
逆に言うとRAIIやusing/IDisposeのような機構が適切に使われている場合はうっとおしいお節介でしかないわけです
ちなみにリターンコード形式場合はリソースを確保していない場合でも定型処理を書かなければなりません
したがってそのうっとおしさは検査例外とは比較にならないほどの負担になります いつもはうっとうしいQZ某が、今日は概ね論理的な物言いをしているように感じる。
対する例外推しの彼は、饒舌だが自説を貫こうとするだけで相手を納得させるような説明はしようとせず、議論をしていつもりで議論できてない人のように見える。リアルなフォーク准将を見ているような気持ち悪さがあるよ。
ちなみに俺は例外も戻り値も適材適所で使い分けて一貫性がとれていればいいんじゃね、という意見だけど、議論に加わる気は無いのでスルーしてくれ。 納得させる気は最初からないからね
ただ単に事実を語っただけ 機械学習とかアプリケーションレイヤの開発をしてて普段はJavaとかpythonで書いてるんだけど相談。
手間や保守を考えるといくら早く動作しても全部cで実装は厳しくて、複雑な計算とかだけcに渡そうと思うんだけど、このレイヤだとそんなもんだろうか?実際の仕事での使われ方の例があれば教えてほしい。 例外安全という言葉には色々と含まれるけど、
とりあえず最低限度の保証としては「リソースリークが起こらないこと」とすると、
C++ ではデストラクタで後始末するのが基本だ。
(RAII)
私が強調しておきたいのは、リソース管理の配慮はクラス定義に押し込めることが出来るということと、
可能な限り押し込めるべきだということ。
エラー発生の通知に使うのが返却値であれ例外であれ、
エラーへの対処の中にリソース回収のコードを書かなきゃならないようならその時点でダメなコードだ。
デストラクタで回収されることをあてにしたい。
(bad_alloc のような致命的なやつはちょっと話が違ってきたりとか、単純ではない場面はあるけど……。)
で、デストラクタでリソースを後始末するというのが出来ているという前提であれば、
例外を使うか返却値を使うかの差は対処のためのコードをどこにかくかの違いに過ぎなくなる。
Java と違って関数が送出する例外を型システムで管理してくれないわけだし、
引数をチェックしているかどうかもプログラマが気を付けるしかないので、そんなに違いはないと思う。
違いはないがどちらかに一貫させるのが望ましいと考えると、
C++ の基本的なライブラリに併せるべきだということになって例外を使うのが妥当という判断になる。
ちなみにグーグルのガイドラインが例外を避けることになっているのは
グーグルで使っている既存のコードが例外への配慮を充分にしてないから
やむを得ずそれに合わせるためでフルスクラッチに出来れば違う判断をするかも
ってことも書いてあるので、例外を避ける根拠としては弱い。 >>960
>いつもはうっとうしいQZ某が、今日は概ね論理的な物言いをしているように感じる。
あれ?れれ?
おっかしーなー、私もプログラムを書く人だし最低限自分の作ったバグくらいはさっさと片付けたいので、そのためにも、いつも論理的でありたいと願っているのですが… そういうとこだよ
こういうのってたいてい本人は自覚してないもんだからやっかい >>963
>違いはないがどちらかに一貫させるのが望ましいと考えると、
>C++ の基本的なライブラリに併せるべきだということになって例外を使うのが妥当という判断になる。
この意見に対しては私は痛烈な批判を浴びせることになるでしょう
曰く、C/C++ の人なら言語的な統一感よりもコスト、というか単純性を優先したくなるのではないですか?
UML のグジャグジャ感をみるにつけても、「言語法律家」なるものはきわめて忌むべき存在と私は考えています
exception を実装するためには、隠れグローバル変数をどうしても準備しなければならない
シングルコアで exception の履歴を単一スタックに全部のせることができるのなら、ローカルで sjlj を駆使して、あるいは書き手からみえないところで純ローカル変数的世界に納めることもできたかもしれませんが、
今やマルチコアで実際に複数のスタックとプログラムカウンタが走る時代で、exception の実装は OS に丸投げの複雑怪奇、ついでにコストも複雑怪奇でパンピーには理解が及ばない…
そんな巨大かつ複雑なスケールの実装を必要とするのに見合った exception のメリットは何か、今も自問自答を繰り返しているのです 単純さを選んだら例外になったというお話だったのさ。ちゃんちゃん なぜsjljにこだわるのか
コルーチンとか標準化されても使わなそうだな c++の言語仕様に例外の実装にはグローバル変数使えとかSJLJ使えなんて縛りあったっけ? >>971
実装方法までは言語仕様に記述されないでしょうね… >>972
ということは例外の実装にまで踏み込んで考えるのはナンセンスなのでは? ちなみにおれはc++の例外は大規模開発でworkしないと思ってるから
経験上ひたすら面倒な事態になる
言語仕様決めてるやつらは言語オタクで大規模開発の経験ないと思ってる >>968
いつの話をしてるんだよ。 モダンな環境では例外送出の実行コストは充分に小さい。
特別な環境で特別な対処をしなきゃならない場合を例に出しても意味がないぞ。
ふーん、そういう場合はそうするんですねとしか言いようが無い。 >>976
sjljでない場合
例外がおこらない分にはオーバーヘッドないけど、起こったときのスタック巻き戻しが重い
こういうこと知らずにクリティカルなとこで気軽に例外発生させるバカをよく見る 抽象化ができずどんな粒度でも低級のセオリーを通そうとする
早すぎる最適化がとにかく大好き
C++erに多いねこのタイプ >>978
アホみたいにmap使いまくって後でひどい目に遭うアホもよく見るな >>980
それが必要なのってC++コード全体からすると何パーセントくらいなの? >>982
しらないけどクリティカルな処理ないならc++使わなくていいんじゃないの
なんでわざわざこんなしんどい言語使う? >>981
別にmap使いまくってもいいよ
ちゃんと抽象化しとけば後でチューニングするのは簡単だから >>984
まさかw
データ構造大事だよ初心者さん 合ってるね
スクリプト言語あがりと一緒に仕事すると高い確率でそうなる
同じ事をいうんだよ
最初は抽象度高く作ってあとで最適化って
結局しないからね
だいたい薄く広く積もったオーバーヘッドは表面化しないから
んでもっさりアプリの出来上がり
であとで精鋭集めて作り直し >>988
そこで作り直すから低スキルなんだよな
前任者がせっかく変更に強いシステムを組んでやったのに台無しにするんだ >>989
変更に強いとかの内輪の都合よりUXの方が大事だよ
初心者さん >>990
その大事な大事なUXを向上させるために抽象化するんだよ新人君 さすがにそれは意味不明では?
過剰なオブジェクト指向でダメになったプロジェクトは数知れず そういうのいいから
説明できないならそこでおしまい UXの向上にはフィールドバックと変更のループが必要
度々の変更を容易たらしめるためには適切な抽象化が必要
最初から速度最適化に傾倒して抽象性を失ったシステムは変更しにくいゴミUXを抱え続ける 御託ご苦労さん
でそれどっからの流れなの?
お前さんに一度map乱用ボトルネックを一晩でtableに置き換える作業やらせてみたいわ
多数のモジュールと繋がってるやつな
最初から見積り立てて設計しとけよボケってどなられるやつな >>977
そりゃあクリティカルなところという特別な場合には特別扱いが必要ですねって
だけのことで、そんなこともわからんやつは例外を使おうと使うまいと駄目だよ。 このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 116日 18時間 38分 57秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。