C++相談室 part149

レス数が1000を超えています。これ以上書き込みはできません。
1デフォルトの名無しさん
垢版 |
2020/02/18(火) 06:19:41.54ID:xvjipUWj
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part148
https://mevius.5ch.net/test/read.cgi/tech/1580471646/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
2020/02/18(火) 07:30:53.57ID:6S1dA7EZ
STLつかうと一気に実行ファイルサイズが10倍に?!

環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない

すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。

C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

---- テンプレ ここまで ----
2020/02/18(火) 07:50:56.98ID:KHr4ndHy
std::functionを使うなと言われたのは残念だが
newのときたまの遅さの可能性に警鐘を鳴らしたから勝利宣言しちゃおうかなっ
かなっ
2020/02/18(火) 08:39:06.73ID:vOZ3pUbp
>>1
2020/02/18(火) 10:35:35.23ID:xvjipUWj
function・・・それだけか?
なんか組み込みにC++は向かないとまで
大きく出る理由として弱すぎね?
2020/02/18(火) 10:36:23.95ID:xvjipUWj
あ、IDは気にしないでね
スレ主としての発言じゃないよ
2020/02/18(火) 10:43:38.96ID:TnY2bwh5

それ言ってたのは別の人だし過剰反応しすぎだろ

というかあのキッズを叩くと必ず単発煽りが出てくるのは恐らく同一人物だろうな

>>3
標準ヒープ使われてもいいなら使えばいいじゃん
2020/02/18(火) 10:48:05.96ID:xvjipUWj
君は誰?
組み込みにC++は向かないなんて思ってないなら
俺はそれ以上言うことないけど
2020/02/18(火) 10:55:26.54ID:TnY2bwh5
>標準ライブラリでもallocatorが指定できないものもあるんだよ
の人ではないよ

というか何がそんなに気に入らないのかね
組み込みに向かないと言ってた人はArduinoがどうこう言ってたろ
実際RAMが少ない環境ではかなり慎重に使わざるを得ないんだろ、知らんけど
2020/02/18(火) 11:00:57.59ID:Nm2LYTxd
std::function は (呼び出しの型が一致さえすれば) どんな関数オブジェクト (または関数ポインタ)
でも格納できるというのは強いんだが、
実際にはコンパイル時に型が確定できる場合の方が多いと思うので
std::is_invocable_r で制約を付けた方が少し性能は良いと思う。

でもテンプレートって型引数ごとに実体化されちゃうから、
素朴に考えると引数をラムダ式で与えてたら呼び出しごとに実体化されることになっちゃうよな……。
(最適化で上手く統合されることもあるかもしれないけど。)
どちらを選んでもいいことばかりではないので、結局は場合によるとしか。
2020/02/18(火) 11:05:28.20ID:xvjipUWj
>>9
何がってそのままだよ
組み込みにC++は向かない、という意見に反対だ
2020/02/18(火) 11:09:15.65ID:TnY2bwh5
だから過剰反応しすぎだろ
functionの話してた人はゲームだろうが
反対するなら根拠を示せばいいし
少なくとも別の人の話は混同するな
2020/02/18(火) 11:11:12.73ID:TnY2bwh5
>>10
ラムダなら実体化っつっても毎回関数オブジェクト作るのと変わらんやろ
2020/02/18(火) 11:13:33.03ID:xvjipUWj
IDなんかアテにならない
基本的に匿名掲示板なんだから
人違いはそう言えばいい

もっとも、それを信じるかどうかは別だが
2020/02/18(火) 11:19:56.99ID:TnY2bwh5
まさか前スレID:tDJaHP5Kじゃないだろうな?
2020/02/18(火) 11:42:54.44ID:xvjipUWj
>>15
いや俺tDJaHP5Kだよ
過剰反応するなっていうおまえさんこそ
なんでそんなにとんがってるんだ?
色々勘ぐってしまうぞ
2020/02/18(火) 11:48:32.16ID:TnY2bwh5
>「後で」かw
>もう1000間近だし期限切らないでおけば時効だろってか?
こんなん書いてよく開き直れるな
側から見てて気分悪かったぞ
ちなみに俺は前スレnfQlnp9bな
2020/02/18(火) 11:55:50.57ID:Nm2LYTxd
>>17
それは妥当だろ。
あの場面ではライブラリにアロケータを指定できない場合があると主張しながら例を示さない
のは議論の仕方がわかってないクズだし、そういう奴に遠慮してたら話が進まねーよ。
2ch って元々そういうところじゃん。
2020/02/18(火) 11:59:04.13ID:xvjipUWj
ああ、あいつか
元々newの話だったのに
mallocの話だってクレーム垂れてきたやつね
2020/02/18(火) 11:59:40.16ID:TnY2bwh5
は?頭湧いてんのか?
最終的に例出されたなら反論か謝罪かどっちかだろ
そこで逃げるという選択が取れる方がよっぽどクズだと思うがな
2020/02/18(火) 12:01:31.50ID:TnY2bwh5
毎回荒れる原因作ってんのお前らだろ
さんざん煽って言い返せなくなったら別人に成り済まして単発煽り入れたり
マジ邪魔だわ
2020/02/18(火) 12:03:20.38ID:xvjipUWj
それから俺は元々特定のレスや人物に異を唱えたわけではなく
流れ全体に対しておかしいと思ったことを言ったのが968だったぞ
2020/02/18(火) 12:07:30.24ID:Nm2LYTxd
>>20
前スレで野党に喩えたのはそういうとこね。
事実関係は議論の前提だから、共有しないで先延ばしする理由はない。
カルトクイズに答えられない相手を見て悦に入るようなやつがクズでなくてなんなんだ。
2020/02/18(火) 12:08:17.71ID:xvjipUWj
だいたい喧嘩売ってきたのは978で
それまで平和的に話していた俺が
ひとこと言い返したのだけ取り上げて
気分悪いとかどういうバイアス持ってるんだよ
2020/02/18(火) 12:11:28.72ID:TnY2bwh5
>前スレで野党に喩えたのはそういうとこね。
それはどうでもいい、問題にもしてない

>カルトクイズに答えられない相手を見て悦に入るようなやつがクズでなくてなんなんだ。
悦に入ってたかどうかは本人に聞け
というか調べ方は出してくれてただろうが

お前も都合の悪いことからはとことん逃げるから、悪いが相手したくない
2020/02/18(火) 12:14:37.63ID:TnY2bwh5
>>24
>>978もそれまでのお前の態度と同程度には平和的だと思うが
どういうバイアス持ってるんだよ
悪いがもうキチガイキッズの相手はしたくない、絡んで悪かったな
2020/02/18(火) 12:17:59.50ID:xvjipUWj
自己弁護にしか見えねえ
どうやら勘ぐりは当たってたようだな
2020/02/18(火) 12:21:22.79ID:TnY2bwh5
アホか
俺が前スレ>>978本人だったらもっといじり倒してるわ
2020/02/18(火) 12:27:49.37ID:xvjipUWj
言えば言うほどドツボだぜw
2020/02/18(火) 13:53:54.86ID:Nm2LYTxd
MinGW のライブラリを見てたら std::function にも SSO が入ってる。
データメンバの総計が 16 バイト以下の関数オブジェクト (キャプチャした変数が少ないラムダ) なら new は呼ばれない。

※ string ではないのにこの最適化を SSO と呼んでいいものなのかどうかわからん
※ 16 バイトというのは環境によるだろうし、 SSO がないこともあるだろう
※ とはいえ、主要な実装ではだいたい有ることを期待できるのではなかろうか

間接参照にはなるから std::function はわずかにコスト高には違いないかもしれないけど、
ちょっとしたことに使う分には急激に実行コストが上がるというほどではない。

リソースの限られた組み込み環境だといずれにしても基本的なライブラリも
自前で用意せざるを得なかったりもするだろうし、
標準ライブラリをフルセットで使えるほどの環境ならみみっちくリソース消費量を抑える必要もないだろうから、
使いどころが適切であれば全体としてはあまり問題にならなさそうという感想。 (あくまでも個人の感想です!)
31デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:23:06.88ID:iYoDhrK1
ちゃうねん。
2020/02/18(火) 17:35:08.64ID:Nm2LYTxd
そうか (´・ω・`)
33デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:37:59.36ID:iYoDhrK1
僕はArduinoこそC++パワーが必要と言ってるんですよ。
34デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:41:06.24ID:iYoDhrK1
Arduinoは様々な亜種があるので、テンプレートでゴニョゴニョすると、何かいいことが起きるのではないか?
そんなことを議論してほしいわけですよ。
メモリーは2KBしかないけれども。
35デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:45:54.66ID:iYoDhrK1
ちなみにエルチカとこんな感じ。
最大32256バイトのフラッシュメモリのうち、スケッチが932バイト(2%)を使っています。
最大2048バイトのRAMのうち、グローバル変数が9バイト(0%)を使っていて、ローカル変数で2039バイト使うことができます。
2020/02/18(火) 17:46:01.07ID:Nm2LYTxd
>>33-34
僕って誰や?

ランタイムのパワーが必要ないものはリソースの少ない環境用に積極的に活用するべきだとは思う。
Arduino についてはよう知らんけど、ドキュメントを見た感じだと type_traits のような
(実行時の) マシンパワーが要らないようなものまで除く必要はないやろという気持ちになる。
37デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:48:36.87ID:iYoDhrK1
C++標準ライブラリはないけどテンプレートは使えます!
38デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:51:48.28ID:iYoDhrK1
魔術師が活躍する舞台として最高だと思いますが。
なぜ参入してこないのか。
39デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:58:28.64ID:iYoDhrK1
Running 5 test cases...
---------- std_algorithm__adjacent_find_1 ----------
std::vector<std::uint32_t>
size(): 104,857,600
std::adjacent_find: 66ms

---------- std_algorithm__is_sorted_1 ----------
std::vector<std::uint32_t>
size(): 104,857,600
std::is_sorted: 66ms

---------- std_algorithm__sort_1 ----------
std::vector<std::uint32_t>
size(): 1,048,576
std::sort: 119ms

---------- std_algorithm__unique_1 ----------
std::vector<std::uint32_t>
size(): 5,242,880
std::unique: 4ms

---------- std__vector__copy_1 ----------
std::vector<std::uint32_t>
size(): 104,857,600
copy assignment: 220ms
new std::uint32_t[]
size: 104,857,600
std::memmove: 55ms

*** No errors detected
40デフォルトの名無しさん
垢版 |
2020/02/18(火) 17:59:19.58ID:iYoDhrK1
一億個コピーで220msだった。
2020/02/18(火) 18:04:45.17ID:Nm2LYTxd
>>38
たぶん探せばそれっぽいライブラリもあるんちゃう?
https://www.google.com/search?q=Arduino++C%2B%2B+template+library
42デフォルトの名無しさん
垢版 |
2020/02/18(火) 18:05:23.55ID:iYoDhrK1
ありがとん。
2020/02/18(火) 18:08:56.36ID:sX1qjJQt
>>30
SSO = Small-string optimization
44デフォルトの名無しさん
垢版 |
2020/02/18(火) 18:13:40.86ID:iYoDhrK1
Arduinoも一応newは使える。
使わないけど。
2020/02/18(火) 18:25:28.71ID:Nm2LYTxd
>>44
new を使わずに、かわりにどうすんの?
46デフォルトの名無しさん
垢版 |
2020/02/18(火) 18:27:32.40ID:iYoDhrK1
2KBしかないからローカル変数。
47デフォルトの名無しさん
垢版 |
2020/02/18(火) 18:31:23.28ID:iYoDhrK1
基本的にグローバル変数を駆使するしかないけど、結構強烈に最適化かかるので、意外と2KBで何でもできる。
2020/02/18(火) 18:45:24.62ID:Nm2LYTxd
プログラムが極端に小さいなら高度な抽象化をする甲斐がない。
抽象レイヤを挟むことで綺麗になるよりも複雑さが増すだけになりがち。
本当に使いまわす部品は綺麗に整理するに越したことは無いけど、
メモリ 2KB かそこらの環境ならベタ書きで十分でしょ。 (YAGNI 原則)

C++ が組み込みに向いていないとは言わないけど、
そのレベルで極端にリソースが制約されている状況では必要でもないと思う。
49デフォルトの名無しさん
垢版 |
2020/02/18(火) 18:46:17.48ID:iYoDhrK1
パソコンでは、恐れることなくnew使って良いと思うけど、static_vectorというのも自作した。
2020/02/18(火) 18:48:40.47ID:Nm2LYTxd
>>48
もちろん単にやるのが楽しい! というのも動機としてはありうるので趣味でやる分にはどんどんやったらいいと思うけど。
51デフォルトの名無しさん
垢版 |
2020/02/18(火) 18:48:49.63ID:iYoDhrK1
>>48
まあ確かに。
でも使いまわし出来ると便利だし、C++なら...やってくれる!
2020/02/18(火) 18:58:47.76ID:CLqeafa/
いやいや、固定小数点とか組み込みだからこそのtemplateがふさわしい場面は結構あるよ
53デフォルトの名無しさん
垢版 |
2020/02/18(火) 19:00:28.24ID:iYoDhrK1
小数点難しいよね。
難しすぎるわ。
2020/02/18(火) 19:15:07.85ID:Nm2LYTxd
>>49
どういう意味で static なの?
大きさが固定ってこと?
2020/02/18(火) 19:17:56.69ID:CLqeafa/
ストレージ内蔵だけど内蔵キャパまでの可変長対応とかかね
知らんけど
56デフォルトの名無しさん
垢版 |
2020/02/18(火) 19:20:46.06ID:iYoDhrK1
>>54
std::arrayにsize()をプラスした。
2020/02/18(火) 22:11:25.01ID:xmvP8wvk
std::arrayは最初からsize()持ってるんだけどどういうこと?
2020/02/18(火) 22:36:37.92ID:OK0tQotL
static_vectorってまんまboostにある
最大の長さが確定してるvectorで
メモリ確保は初期化時だけってやつ
それこそ組み込みやゲームでは有用
上の人のと同じかどうかは知らんが
2020/02/18(火) 23:58:14.54ID:2AC9Ct1n
組み込みでboostとかwwwwwwww
2020/02/19(水) 00:04:41.69ID:SdiIukjt
>>11
向くか向かないかなんて主観なんだからそこを力説してもしゃない
向くと思うなら自身の経験をもとに定性的に説明してみなはれ

あと組み込みってもピンキリだから
マイコンでモーターをPID制御するのと、
組み込みLinuxでメディアサーバー作るのとでは全く異なる世界
そこは区別しないと意味ある議論はできないね

後者は両論あるだろうけど前者はどうだろう?
そもそもモダンなc++で開発できる環境あるのかな?
2020/02/19(水) 00:14:57.80ID:SdiIukjt
>>59
省メモリデザインなクラスがあったりする
2020/02/19(水) 11:06:52.75ID:YKckgIGu
>>59
駄目ですか?
使えるなら使っていいンじゃなすか?
2020/02/19(水) 11:43:37.70ID:91lcAktP
YAGNI // "You ain't gonna need it" : 機能は実際に必要となるまでは追加しないのがよいとする。
Ajail 開発

↑こういう開発哲学の様なものは他にどんなものがありますか?
真逆の哲学でも構いません。
2020/02/19(水) 11:49:31.95ID:91lcAktP
>>63
【KISS の原則 (英: KISS principle)】
「Keep it simple stupid.」(シンプルで愚鈍にする)、もしくは「Keep it simple, stupid.」
(シンプルにしておけ!この間抜け)、もしくは「Keep it short and simple.」(簡潔に単純にしておけ)
という内容の、1960年代の米国海軍において言われた、経験的な原理・原則の略語。
その意味するところは、設計の単純性(簡潔性)は成功への鍵だということと、不必要な複雑性は避けるべきだ、ということである。

【なし崩しの機能追加主義】
KISSの原則に反して、仕様が徐々に複雑化していくことは、ソフトウェア開発の世界でよくみられる。
これは、「なし崩しの機能追加主義」として知られる。
ソフトウェアが複雑になるにつれて、使い方を習得する時間が増えたり、操作に手間取ったり、どれが重要な機能なのか分からなくなったりする。
さらには、ハードウェアへの要求スペックが高くなったり製品価格が高くなったりもする。
しかし、大多数のユーザーが実際に使用する機能は、そのごく一部であったりする。
ユーザへの負担や開発コストを考えると、単純なソフトウェアの方がユーザフレンドリかつ生産性が高い可能性がある。
2020/02/19(水) 12:01:28.84ID:2IDaZuEt
今風の入門でおススメの方法はありますか?
2020/02/19(水) 12:14:44.61ID:26AgvMdu
KISSの原則、俺は正しいと思う
オーバースペックなものを作っても、その「オーバー」な部分が
あとで必要になったとき不十分なんてことが起きやすいからな
案件の「今」を最大限に最適化するのは義務と言ってよい努力だし

なし崩しの法則は、変更要求に対する不適切な対応が積み重なって起きることだ
既存のソースコードや回路図の微修正で済ませようとするあまり
それまでの反省を踏まえてきれいにリメイクすれば解消する問題が
ずっと影を落とし続ける現象はそこいら中あふれかえっている
2020/02/19(水) 12:18:11.23ID:26AgvMdu
車輪の再発明なんて例えをよく見かけるが
じゃあ今の車輪はまだ木で出来ていたり
パンクしやすいチューブタイヤだったりするのか
進歩の原動力たる、たゆまぬ努力に対する
アイディアキラーは見逃しちゃダメだ
2020/02/19(水) 12:25:05.81ID:mcS2XXQq
>>63
契約プログラミングとかもそうかな?
C++20 にサポートが入る予定だったが、次以降に延期された。
まあ言語としてのサポートがあろうとなかろうと関数が機能するための前提条件
を意識したり明記したりするのは良いことだと思う。

文芸的プログラミングという考え方もある。
説明文とコードを分離せずに書くようなもの。
提案者 (クヌース) が考えていたのは文章説明を中心にする考え方で
コードの方が従属するようなものだけれど、
コメントとしてドキュメントを書くようなものなら doxygen や Javadoc はよく使われているね。
コードを書いているときはちゃんと把握できているからドキュメントを後回しにしがちだし、
コードがドキュメントであるようなものが理想とか言う人もいるんだけど、
数日前に書いたものさえ割と忘れるのが人間なので文書で残すのは大事だと思う。

テスト駆動開発も割とメジャーかもしれない。
仕様をテストコードとして書いて、それを満たすように実装を進める手法。
テストできるように作らなければならないという点で実装に制約が付くのが嫌われがち
ではあるようだけど、仕事でやる開発なら客にアピールしやすい気がするなぁ。
2020/02/19(水) 12:33:07.39ID:1d0evbZI
doxygenで作られたドキュメントあんま役に立たないよ
特にテンプレートリッチなコードだと余計なものや個々の実体化までドキュメントに入る
まぁそれを避ける方法が無いわけではないしdoxygen用にコメントをきっちり書くのは良いことなんだけど
2020/02/19(水) 12:36:18.94ID:mcS2XXQq
>>67
車輪の再発明っていうのは、車輪を知らないで「発明」することだよ。
既に普及しているものを知らず、学ばずに思いつきでやって既出の失敗を繰り返す愚かさを言ったもので、
学んだ上であらためて自分で作ることや改良することを否定してはいない。
2020/02/19(水) 12:38:12.62ID:mcS2XXQq
>>69
個別のツールについては私は良く知らないんだ。
ここではドキュメントとコードを同時進行で作るという考え方の話。
2020/02/19(水) 12:39:50.65ID:91lcAktP
>>70
ところが、「車輪の際発明」と言って批判する人こそが、全く試しもせずに妄想していることも多い。
この言葉をインド人が言っているのを見て、だから後進国のままなんだな、と思った。
2020/02/19(水) 12:49:36.29ID:2IDaZuEt
車輪を題材にした慣用句であり、世界中で使われている。

「広く受け入れられ確立されている技術や解決法を知らずに(または意図的に無視して)、
同様のものを再び一から作ること」

を意味する。
2020/02/19(水) 12:50:53.30ID:2IDaZuEt
MS officeのフリーの互換製品を作ることは違う
2020/02/19(水) 12:53:30.09ID:26AgvMdu
>>70
同じことだ
学生や新米が何か思いついて実験してみてるところへ
身も蓋もないことを言ってやる気なくさせる老害は進歩の邪魔だ
2020/02/19(水) 12:56:26.39ID:2IDaZuEt
会社で仕事中にやるのはどうかと
2020/02/19(水) 13:00:54.35ID:Ss05ZG60
パーキンソンの凡俗法則

どうでもいい話題ほど紛糾する
車輪の再発明がどうとか
gotoがどうとか
2020/02/19(水) 13:03:08.09ID:26AgvMdu
>>76
俺、サラリーマンやってた頃は
手が空いたとき色々実験してたよ
向上心のないやつを蛇蝎のごとく嫌う上司だったし
2020/02/19(水) 13:20:13.47ID:mcS2XXQq
>>75
それは思いつきとは言ってもまだ学びの段階の中の話でしょ。
学ぶためにやってるのなら別にいいよ。
学習段階によって当然知っているべきことを学べてないなら軌道修正はするべきだが。

程度問題とか状況というものもある。
上にあげたような方法論がある程度の確立はしているとは言っても、
業務に取り込むにあたっては色々と試行錯誤はあるもんだしな。

>>76
仕事に必要な学習なら業務時間中にやるべきだし、
そのための時間が与えられないなら会社が学ぶなという方針なんだろう。
2020/02/19(水) 14:19:48.03ID:2IDaZuEt
学ぶ?

毎回プロジェクト初めに同じものを同じだけ時間かけて作り直すのが学習?
前のを使えよ
2020/02/19(水) 14:22:23.51ID:2IDaZuEt
プロジェクトが始まったらニコニコ顔で同じ作業を同じように繰り返して
夜になったら必要もないのに残業してふーってニコニコして仕事
ある程度満足したら帰る

そしてプロジェクト終了間際には死んだような顔をしてこんなの間に合うわけないとか言い出す
車輪の再発明にかけた時間をそこに回せよと
2020/02/19(水) 14:24:46.25ID:2IDaZuEt
プロジェクト始まったころにSEが間に合って仕様書も来てないのに意味もなく残業してるやつら
何をしてるのかと思うと勉強しようと思ってとか言って全然関係ないことをしてる

家でやれよバカ
死ね給料泥棒
2020/02/19(水) 14:25:49.01ID:2IDaZuEt
× SEが間に合って
○ SEが間に合っていなくて
2020/02/19(水) 14:31:07.87ID:mcS2XXQq
業務でやるならそのあたりのバランスを決めるのは管理者の裁量次第だろ。
2020/02/19(水) 15:47:16.31ID:26AgvMdu
>>80
自動化できるものは自動化すべきだね
コピー一発で済むものとジェネレータがいるのとある

俺、ジェネレータ作るの楽しくて好きだ
86デフォルトの名無しさん
垢版 |
2020/02/19(水) 18:54:08.67ID:c56NWov4
ちゃうねん。
2020/02/19(水) 20:05:22.56ID:pJACNDga
学習に時間を使ったのに同じように失敗する馬鹿。
糞シンタックスを覚えることに時間かけるんじゃなくて
普通にメトリック取ったりテストコード書けって話なんだが、理解できないのだろう。
2020/02/19(水) 20:59:46.31ID:nxdxypdV
> 俺、ジェネレータ作るの楽しくて好きだ

この場合のジェネレータって一体何?
2020/02/19(水) 21:23:32.66ID:whud32zD
同じものを1度作っても2度目作れない
同じくらい時間はかかっても2度目作ると3度目は作れるようになっている
それは無駄ではないと思っている
2020/02/19(水) 21:25:41.56ID:26AgvMdu
進歩するやつと、しないやつの差だね
2020/02/19(水) 21:44:51.30ID:+b2jXVCZ
マ板でやれや
2020/02/20(木) 01:47:49.50ID:PvXqkd+D
海外の掲示板で「車輪の再発明」することを馬鹿にしていたもう一人の人は、哲学科出身で、宗教関連の発言ばかりしてる人だった。
理系ですらない。
自分では作らずに口だけ達者な人だった事が追跡できた。
2020/02/20(木) 06:55:14.71ID:yQ1/Uz2n
全然関係ないことを持ち出して
自分と意見の違う人を馬鹿にできたつもりになってるやつは
論理的な思考が極度に苦手な、理系文系以前に無学なやつだ
2020/02/20(木) 08:03:45.73ID:+tqyS5qM
>>92は車輪の際発明を馬鹿にする人が一人しかいないという命題に対する反例
としては全く正しい
2020/02/20(木) 08:12:44.06ID:+tqyS5qM
>>82
プロジェクトを効率よく回した方が良い
あと残業を作業者自身の裁量に任せるのはシステムがNG
裁量労働は結果責任を果たせば会社が回るクラスの仕事をしているハイクラスな奴用

SEが必要なときに前の仕事が終わっていないかもしれないからロックしておくというケースで
前の仕事が終わったSEが次の仕事のスタートまでの間、
定時内に会社で独学するのは別段怒るほどのことではない
2020/02/20(木) 08:50:33.12ID:Gm5IubjH
そういう話はマ板でやれ
2020/02/20(木) 09:47:42.29ID:Yj7GP6kt
ここ老害のおっさんばっかりだからな
ところ構わず自分の言いたいことを言いまくる
はいおっさん続きどうぞ
2020/02/20(木) 10:09:43.20ID:npv/ZYAv
そういう煽りもマ板でやれ
2020/02/20(木) 10:47:00.85ID:yQ1/Uz2n
他人が自分と違う意見を持つ事実を受け入れられず拒否反応するだけな幼児性は無学のさらに以前の問題だ
2020/02/20(木) 12:32:07.99ID:nBoep86z
「車輪の再発明」という言葉は、加工貿易しか生きる道は無い日本を必ず衰退させる。
2020/02/20(木) 12:39:19.67ID:oKHcb/fS
車輪の再発明すら出来ない無能にはこの上なく都合のいい言葉だなw
2020/02/20(木) 12:53:00.71ID:nBoep86z
>>101
実際、最近では同じ事を作ることすら出来なくなっている。
103デフォルトの名無しさん
垢版 |
2020/02/20(木) 12:55:22.08ID:/g2XBbXj
教育や訓練でやっていることは「車輪の再発明」だよ。
2020/02/20(木) 15:45:51.57ID:nBoep86z
>>103
というか、ホリエモンロケットもアポロのエンジンを真似ているだけとされるのに
何度も墜落したり、三菱のジェット機(旧MRJ)もボーイングなどとほぼ同じような
ものだけど、納期を大幅に延期しまくっても完成できてないように、同じものを
作るということですら簡単では無い事がある。
逆に言えば、ソフトウェアでも売り物と似たようなものをフルスクラッチで作れたと言うことはなかなかの技術力があったということ。
2020/02/20(木) 16:01:29.09ID:yQ1/Uz2n
>>79
学生と新米と言ったがそうでない者が
既存のものを知った上で再考することだってある

最初に出した例えで、木でできた車輪や
チューブタイヤがあるのを知った上で
さらに進化できないかなんて話は珍しくもない
そこへ木の車輪があるのに何をしてやがると
突っかかるのをやめるべきだと言っているんだ

人がどんな目的で実験しているのかを
勝手に決めつけている点も問題だ
2020/02/20(木) 16:45:38.50ID:s7d9UeaP
>>105
学んだうえで改良しろってのは最初から言ってることで、そこは否定してないじゃん。
何言ってんの?
そもそも >>75 で出てきた老害ってのはどっから湧いて出てきたんだよ。
お前が文句付けてるのはお前が言い始めた老害に対してであって俺じゃないだろ。
2020/02/20(木) 16:49:30.16ID:s7d9UeaP
マ板でやれって言われてるのはそういうとこだよ。
困った老害がいるのならそりゃ大変ですねとは思うが、
C++ 板で言っても知らんがな。
2020/02/20(木) 16:49:55.00ID:s7d9UeaP
あ、板ってのは間違い。
109デフォルトの名無しさん
垢版 |
2020/02/20(木) 17:01:05.95ID:/g2XBbXj
美術科の大学生が200万円自腹かけて作った卒業制作品に買い手がつかないのも「車輪の再発明」ゆえの想定内。
2020/02/20(木) 17:30:21.03ID:Nllb9nDe
困った老害ってお前だろ。。
2020/02/20(木) 17:34:54.13ID:bN6ydBCc
というかはちみつはあくまで趣味グラマなのにプロでやってる人の事情に知った風な口きいて首突っ込むから
それに反論すると必ず話がややこしくなる
スルー推奨
112デフォルトの名無しさん
垢版 |
2020/02/20(木) 17:35:14.56ID:MajNX5le
ちゃうねん。
2020/02/20(木) 17:43:17.07ID:gPd57Xg0
プロでも環境によって全然違うのに、一律に使えないと断定するから反発されているってのが目立つと

組み込みやコンシューマのゲームに限定しても使える、使えないは変わるのだから
2020/02/20(木) 17:45:42.57ID:Nllb9nDe
まあc++の思想としてどんな状況でも使えるユニバーサルな言語を目指してるってのは
あるからな。真に受けて馬鹿が狂信するってのはある意味では不思議じゃない。
2020/02/20(木) 18:18:26.70ID:yQ1/Uz2n
>>106
おまえさんは何か思いついたとき
その思いつきと同様の先人の業績をいちいち調べ上げるのか

俺はそんな悠長なことをするより即やってみたい
調べるのはそのあとだ

木の車輪だって自分でやってみなきゃ気持ち悪いし
アンプは量販店で買えても回路組んでみたい
パンピーとハッカーの違いはそこだろ
2020/02/20(木) 18:20:33.96ID:nBoep86z
「板違い」というが、議論と言うのは多岐に渡って派生しても良いもので、それでスレッドが機能不全になってしまうのは、コメントがツリー状にできない2ch/5chそのものの問題点。
2020/02/20(木) 18:23:17.73ID:nBoep86z
>>115
>おまえさんは何か思いついたとき
>その思いつきと同様の先人の業績をいちいち調べ上げるのか
ここ、気持ち分かる。
なんでもやってみる前にすぐに調べようとする弊害と言うものが指摘されている。
調べずに自分の頭でやってみることが脳を鍛える。
118デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:27:28.32ID:MajNX5le
じゃあお前らの車も木の車輪に変えろ。
2020/02/20(木) 18:32:13.55ID:s7d9UeaP
>>115
車輪の再発明という言葉が出たからその意味に当てはまらない場合だと思うと私は言ってるだけで、賛否の意見は無いよ。
所詮は俺は趣味人だもの。
120デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:33:53.67ID:MajNX5le
耳に木の車輪付けろ。
2020/02/20(木) 18:34:07.37ID:nBoep86z
エンジンやモーターとかなら他社のものを買ってきて分解すれば学べるが、
プログラムの場合、自分で小さなものから作った方が学べることが多い。
既に出来ているものは複雑すぎて本質を学ぶのは難しいし。
それにFOSSはなぜかサイズが大きくて無駄が大きいことが多い。
2020/02/20(木) 18:34:58.48ID:gPd57Xg0
stdにあって条件的にそれで十分なのに、わざわざ劣化版作る奴には車輪の云々って言葉が当てはまる
大体そう言うのバグっているし
123デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:35:04.24ID:MajNX5le
Arduinoやってみた感じでは、組み込みにもC++は有効だな。
124デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:36:48.29ID:MajNX5le
static_vectorはダブル・アレイのリロケートに使った。
125デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:39:50.51ID:MajNX5le
ダブル・アレイで一番効果あったのは、解放されたノードをリンクリストにつなげるときに、整列させるのが一番効果あった。
ダブルアレイは挿入でさえノードの解放が発生するので、確保・解放を壮絶に繰り返す。
この時、リストの末尾に追加するなら、何も計算が必要ない。
整列させるなら検索が必要になる。
ところが、整列させた方が挿入も検索も早くなるという結果に。
すべてキャッシュだと思う。
126デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:42:07.37ID:MajNX5le
ちなみにヒープはstd::vectorの上に作った。
std::vector単体のベンチとると遅いんだけど、実用上はそんなに遅くない。
そういうわけで、最近はstd::vector上にヒープ作るの流行ってる。
127デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:45:18.27ID:MajNX5le
キャッシュに乗るか乗らないか、それが人生のすべてだと思う。
128デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:47:17.83ID:MajNX5le
ツリーも試作してみたんだけど、std::vectorの上にヒープ作った。
ヒープの何が良いかって、そのままserializeできるとこだと思う。
129デフォルトの名無しさん
垢版 |
2020/02/20(木) 18:54:16.16ID:MajNX5le
耳が嫌なら鼻に車輪をつけるべき。
130デフォルトの名無しさん
垢版 |
2020/02/20(木) 22:11:14.05ID:fXEOX4Gg
linuxでC++使ってる人っている?
2020/02/20(木) 23:17:42.47ID:vG9Ftm7S
今はwindows案件ばかりだけど
数年前くらいまではlinuxばかりだった
LL以外はほぼc++のみ
2020/02/21(金) 00:34:16.72ID:/A8YzA6j
車輪の最発明は
2020/02/21(金) 00:35:19.65ID:/A8YzA6j
車輪の再発明は結果的にそうなるというものであって
そういう現象なのであって
良いも悪いも善も悪も
ないお
2020/02/21(金) 00:37:46.17ID:/A8YzA6j
真に手間をかけたくなくて時間が惜しい当事者ならアルゴリズム辞典ぐら普通当たるし
そうではなくて他者とか部下が車輪の再発明に時間を浪費するのが我慢ならないのなら
正解を提示してやるべきだろうJK
マ板でやれ、
135デフォルトの名無しさん
垢版 |
2020/02/21(金) 00:42:29.43ID:IvNL6hmL
車輪の再発明って例えばどんなものをいうの?
2020/02/21(金) 00:52:38.31ID:/A8YzA6j
文明を0からやり直すとか
糸車と水車でコンピューターを作ることとか
いろいろ
2020/02/21(金) 03:47:53.07ID:4WjPaOvH
>>135
何かをやりかけた人をやめさせて、それ以上発展させないようにするために使われる言葉かもしれない。
2020/02/21(金) 03:49:56.83ID:4WjPaOvH
>>137
もう一つは、既存のプログラムのステークホルダーが、新しく作らせずに既にあるものを使わせようとするための口実や詭弁かも。
2020/02/21(金) 04:13:25.48ID:4WjPaOvH
この言葉、NPO団体勤務の人が使っているのを見た。
偉そうなこと行ってるけど、実績も学歴もたいしたこと無い。
2020/02/21(金) 04:21:00.31ID:4WjPaOvH
とある掲示板を見ていたが、この言葉は「その人の中では正しい」だけだと思った。
彼によれば、「自分で書くより既存のものを使ったほうが、大抵の場合は優秀だから」
ということであるが、それは彼の場合であって、自分で書いた方が優秀なものが出来上がる確率が高い人には当てはまらない。
要はIQが人並みを遥かに超えた人と、人並みの人の場合では異なってくる。
2020/02/21(金) 08:00:14.20ID:bpnRR2uh
メンデルの遺伝の法則とか車輪の再発明がもう何度目だナウシカ状態、
2020/02/21(金) 08:01:15.19ID:2hInWAVR
そもそも自分が優秀だと勘違いしてるヤツだからこそ
糞の山を量産して満足げなんであって

自分の愚かさを理解できてるやつは
糞の山作りかけてる時にそれに気付いて引き返す
2020/02/21(金) 08:11:44.84ID:Ml11ZCQR
そろそろC++の話に戻ろうか
2020/02/21(金) 08:51:54.20ID:XQ35bdbs
なんで既にあるものをそんなにもう一回作りたがるの?
めんどくせえじゃん
2020/02/21(金) 08:54:49.38ID:CRE0rstC
わかったC++の話にもどろう
まずはC++で効率のよいコレクションクラスの実装について・・
2020/02/21(金) 10:54:03.44ID:ZYgKzVvr
>>144
ねえ、プログラマなんて既に数え切れないほどいるのに
なんで自分もなりたがるんだろうね

他の職業にもすべて当てはまるね
無職がいいの?
147デフォルトの名無しさん
垢版 |
2020/02/21(金) 12:36:04.12ID:TKnLlA6x
無職も既に沢山居るのでもう不要だね
148デフォルトの名無しさん
垢版 |
2020/02/21(金) 12:38:05.46ID:TKnLlA6x
あ、死ねって意味じゃないよ。死者の数はもっと多いのでそっちの方がもっと不要。
2020/02/21(金) 14:12:28.80ID:0hFCFeWT
「自分の愚かさを理解できてるやつ」
これはみんなが同じ力量であることを前提にしていて、こういうところが嫌だ。
2020/02/21(金) 16:33:28.19ID:ZYgKzVvr
天狗になるのも、どうせ馬鹿だからと居直るのも
正反対のようで共通点がある
2020/02/21(金) 16:43:32.32ID:0hFCFeWT
この分野はレベルの差が大きいので、一般レベルからは有り得なくても天狗とは限らない。
2020/02/21(金) 17:42:31.96ID:Q29ljCA8
gotoの次は車輪か。
テンプレに付け加えていけよ。
記録することで無駄な議論を減らすってあたりまえのことができてないから
馬鹿なことを何回でも繰り返すんだよ。
安倍政権といっしょでさ。
2020/02/21(金) 17:49:18.82ID:ZYgKzVvr
gotoの話はみんな通る道なんだよ
後輩が議論するのを邪魔してやるな
2020/02/21(金) 17:51:05.91ID:EehroR5T
152
ドヤ顔で語ってそう
2020/02/21(金) 18:18:48.49ID:kxM5KQ/J
goto hell;
156デフォルトの名無しさん
垢版 |
2020/02/21(金) 19:02:09.52ID:IvNL6hmL
コンテナの基本はどうやらヒープのようなのですが。
157デフォルトの名無しさん
垢版 |
2020/02/21(金) 22:32:22.91ID:IvNL6hmL
テストを書くのがとても難しい。
158627
垢版 |
2020/02/21(金) 23:03:40.37ID:3bMJAyBr
書いて下さい。さあ!
2020/02/22(土) 00:13:48.42ID:3tA6OTRM
>>154
おまえみたいな馬鹿にうんざりしてるとこだよ。。
馬鹿はゴキブリみたいなもんだからな。
160デフォルトの名無しさん
垢版 |
2020/02/22(土) 00:18:04.12ID:M9bzP2wG
std::vectorはPODだと最終的にmemmoveが呼ばれるのにmemmoveよりだいぶ遅い。
それと何故memomoveなのかよくわからない。
2020/02/22(土) 01:05:00.59ID:TST3TeQo
159
くやしそう
2020/02/22(土) 01:19:12.99ID:+dvEVrBH
ここは趣味でプログラミングやってるギーク多そうだけど
まともなC++人材がいないせいで進歩がウン十年遅れてる業界がかなりあるから
どうかそういうことに飛び込んでいってくれないかな?
あ、給料はたぶんクソ安いけど日本への貢献と思って
2020/02/22(土) 01:23:04.30ID:5xQhS6+V
>>159
その気持ち分かるよ
>>152みたいな隙あらばアベガーゴキブリにはいい加減ウンザリだよな
2020/02/22(土) 10:02:22.31ID:3tA6OTRM
実際に馬鹿に馬鹿って言わないと安倍政権みたいな状態になるってのが今の政治に対する教訓だわな。。
ここも同じか。
2020/02/22(土) 10:46:14.31ID:L9oQb3BP
>>164
誰に向かって言っているのかは知らないがお前自身に言い聞かせているんだろうな
166デフォルトの名無しさん
垢版 |
2020/02/22(土) 10:46:44.30ID:M9bzP2wG
---------- std__pair__construct_1 ----------
std::pair<std::uint32_t, std::uint32_t>[]
  size(): 104,857,600
  construct: 0ms
  for (std::uint32_t i = 0; i < n; ++i) a1[i].second = i; 30ms
struct twice { std::uint32_t i1, i2; }[]
  size: 104,857,600
  construct: 0ms
  for (std::uint32_t i = 0; i < n; ++i) a2[i].i2 = i; 0ms
167デフォルトの名無しさん
垢版 |
2020/02/22(土) 10:47:53.49ID:M9bzP2wG
一億個書き込んで0msなのは最適化で消えるんですかね?
168デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:07:40.21ID:M9bzP2wG
なんと最適化で消えていました。
2020/02/22(土) 11:12:11.00ID:4F0O272/
そりゃn=0なら繰り返すわけない
170デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:14:58.08ID:M9bzP2wG
n == sizeなんですよ。
171デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:18:06.93ID:M9bzP2wG
今度は最適化で消えないように末尾をIOしたら、なぜかstd::pairのほうが速くなった。
std::pair<std::uint32_t, std::uint32_t>[]
size(): 10,485,760
construct: 0ms
for (std::uint32_t i = 0; i < n; ++i) a1[i].second = i; 20ms
1[n - 1].secondt10,485,759
struct twice { std::uint32_t i1, i2; }[]
size: 10,485,760
construct: 0ms
for (std::uint32_t i = 0; i < n; ++i) a2[i].i2 = i; 42ms
a2[n - 1].i2 10,485,759
172デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:19:11.90ID:M9bzP2wG
最適化で変数が消されないようにするおまじないってないんですかね?
173デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:21:18.77ID:M9bzP2wG
当然と言えば当然だけど消されないようにしたらスタックオーバフローするので、グローバル変数に追い出したら、構築時間を測る方法が無くなった。
174デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:22:23.37ID:M9bzP2wG
意味が分からない。
175デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:24:06.01ID:M9bzP2wG
nをsizeと書いておいた方が後でわかりやすいのかな。
176デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:27:04.70ID:M9bzP2wG
大きなスタックをとる方法かms以下を測る方法みつけないと測れない。
177デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:32:12.14ID:M9bzP2wG
C++の最適化は異常すぎる。
2020/02/22(土) 11:37:21.93ID:FQZLMBs9
おまえが頭悪いのは十分わかったから、もう書き込むな
179デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:37:23.90ID:M9bzP2wG
ちなみにグローバル変数で一億個確保したら今度はClangがギブアップした。
1000万個ならClangでもいけた。
180デフォルトの名無しさん
垢版 |
2020/02/22(土) 11:56:13.47ID:M9bzP2wG
std::vectorは初期化子リストによる構築が出来るんだけど、そこでもオーバーフローしたような気がする。
でも、元ネタは別にスタックに入れなくてもどこかにあるはずなので、なぜそうなるのかよくわからなかった。
2020/02/22(土) 12:30:58.63ID:sQwxiot/
特殊学級の子が乱入してきちゃってるやん・・・
182デフォルトの名無しさん
垢版 |
2020/02/22(土) 13:42:24.73ID:M9bzP2wG
なんだと!
183デフォルトの名無しさん
垢版 |
2020/02/22(土) 15:42:46.89ID:M9bzP2wG
スタック使えるのがC++の利点だよね。
2020/02/22(土) 16:27:02.47ID:vUJdNmYs
そもそもコードを書いた時点でされるであろう最適化を
まったく予想できていない
もうこの時点で脳味噌がコンパイラの知能より劣ってるのが確定
これすらわからんから延々と馬鹿な実験を続ける
2020/02/22(土) 16:38:08.08ID:/f58S0oT
バカな実験は勝手にやっててくれて構わないが、いちいちここに書き込むのはやめて欲しい。バカなことでも呟いていれば誰かが正しいことを教えてくれるだろうというスタイルなのだろうか?
186デフォルトの名無しさん
垢版 |
2020/02/22(土) 16:49:06.66ID:M9bzP2wG
>>185
ハイそういうスタイルです。
C++コミュニティは親切なので誰かが「ちげーだろバカ」と教えてくれます。
187デフォルトの名無しさん
垢版 |
2020/02/22(土) 17:30:17.04ID:M9bzP2wG
他に気付いたことは。
gotoはかなり使い道がある。
newは意外と速い。
std::vectorはコンテントによって最適化してくれるので基盤としてなかなか良い。
188デフォルトの名無しさん
垢版 |
2020/02/22(土) 17:33:20.63ID:M9bzP2wG
メモリー分断化は全く問題にもならなかった。
そんなに心配ならOSもJavaで書くしかない。
2020/02/22(土) 18:27:04.22ID:8Q4grnkR
構うから図に乗るんだよ
煽られてもガン無視しとけ
2020/02/22(土) 18:30:13.87ID:5jIrjfcF
>>186-187
マイクロベンチマークは特性を見極めるのに使うべきで、
その特性が用途に適合するかどうかという視点で見ないと意味ない。
当たり前だがあらゆる意味で最強ってことはそうそうあることではなくて、
良い部分もあれば悪い部分もある。

普段はかなり良質な機能でも、その悪い部分を使うような用途だったら
使い物にならないかもしれない。

「間違い」っていうのは目的にマッチしないってことなんだよ。
目的・用途が示されないベンチマークがダラダラ流れててもそこに間違いもクソもない。
指摘を期待するなら指摘できるような形に整理して欲しい。

C++ スレだから言語仕様に反することは (目的にかかわらず) 間違いと言うかもしれんけど、
言語仕様で未定義のことでもやむをえずやることは C++ ではあることだしな。
191デフォルトの名無しさん
垢版 |
2020/02/22(土) 18:36:22.97ID:M9bzP2wG
まずbenchmarkをとる方法がわかってないから。
2020/02/22(土) 22:36:47.98ID:8zrZxrX6
ベンチマーク取ること自体が目的なのはプロセッサベンダーとパソコンオタクだけ
まず要件があって、それを満たすことの判定のために設計するのがベンチマークだ
193デフォルトの名無しさん
垢版 |
2020/02/22(土) 23:06:34.77ID:M9bzP2wG
だいたいの感覚がわかればいいんだけど。
2020/02/23(日) 00:36:06.65ID:VTsgWMQb
ベンチマークは比較のために行うものなのでは…
2020/02/23(日) 03:50:37.25ID:e8YTPgwZ
>>188
そもそも、Javaの方がメモリー効率が悪い。
現実的にはGarbage Collectionはメモリーの節約にはならない。
2020/02/23(日) 06:59:13.39ID:pCDQSm7+
>>194
実装と実装の比較をする場合もあれば
試作と要求スペックの比較をする場合もあるね
197デフォルトの名無しさん
垢版 |
2020/02/23(日) 10:37:28.13ID:UFB+Qlam
>>194
比較のために取ってるんだよ。
入力がランダムな場合と、整列されてる場合とか。
生ポインタとstd::vectorとか。
だいたいの傾向が見たい。
2020/02/23(日) 14:00:58.11ID:5lcMrU2O
でお前は何を相談したいわけ?
中身のない活動報告しないくていいから
199デフォルトの名無しさん
垢版 |
2020/02/23(日) 14:18:49.75ID:UFB+Qlam
>>198
まあそういわれればそうかも。
スイマセンでした。
2020/02/23(日) 14:24:51.96ID:DiMPdgV2
Twitter とか Qiita とかで書いといて
2020/02/23(日) 14:40:09.27ID:yDpSritD
車輪どころか分裂勘違い君を再生産するのがC+++じゃねえか
202デフォルトの名無しさん
垢版 |
2020/02/23(日) 17:05:04.58ID:UFB+Qlam
だから悪かったって。
そんな怒らなくたっていいやん。
203デフォルトの名無しさん
垢版 |
2020/02/23(日) 17:08:42.45ID:UFB+Qlam
しかも+一個多いし。
2020/02/24(月) 01:13:48.48ID:1U5lho1x
質問ですが「〜の最大値」って英語で書くと「Maximum value of 〜」だと思うのですが、
<limits.h>のINT_MAXのようにMAXimumを後置にする書き方もそこそこ見かけます
〜MAXという名前と、
MAX〜という名前では英語圏の人的にはどっちが自然?
2020/02/24(月) 01:20:48.67ID:ZsrQSj47
〜MAXはINT_MAXみたいな不変の固定値
max〜はある配列の最大要素みたいなその場で求めた最大値の変数名に使いたくなる
日本人だからこれがネイティブな感覚かどうかは知らん
2020/02/24(月) 09:25:34.25ID:T8+Aa3p6
std::numeric_limits<int>::max() も語順は int, max だね
2020/02/24(月) 10:19:08.00ID:Bhg0SWzZ
>>206
C++ の文法的な制約による順序だから命名規則としての語順とは別物だと思うけど、
こういう風に文法で縛ってくれる形での記法だと (英語的な) 自然さに悩まなくて良いよね。
2020/02/24(月) 10:26:25.85ID:T8+Aa3p6
int というカテゴリの中に max があるべきか
max というカテゴリの中に int があるほうが合理的か
どっちだと思う?

俺は後者は、あまりにも漠然とした概念のカテゴリ名で探す気が失せそうに思う
205が指摘しているように同じ英単語でもどういう意味で使っているのか解釈に幅がありすぎ
2020/02/24(月) 11:45:35.94ID:FPuN7ayr
無理にクラスにせず関数にしろってのは
「無理な分類はするな」っていうC++の理念じゃないの
2020/02/24(月) 12:00:57.87ID:T8+Aa3p6
ファンクタなんかその逆なんだが
2020/02/24(月) 12:20:34.36ID:QkZvP/Ht
ここまで「英語圏の人」からの回答ひとつもナシ
2020/02/24(月) 12:33:29.35ID:T8+Aa3p6
そんなん5chに期待してるのか?
2020/02/24(月) 12:50:58.82ID:uK6l/p4b
>>211
西洋圏の人の場合、例えばハンガリアン記法では、人の人数は、numPerson、
CPersonへのポインタは、pPerson、Textが0終端文字列であることを表すためには、
pszTextとする。
これらは、number of persons, pointer to a person,
pointer to string with zero end for Text (???)
などに対応している。最後のはよく分からない。

ならば、maxPerson のようなつけ方もあってよいはず。しかし、
でも、PERSON_MAX というような命名法もある。
他の変数と並べたような時に、どちらが整理し易いかなどでそのプログラマが判断しているのだと思われる。
結論から言えば、オールマイティーな命名法は無い。
2020/02/24(月) 12:59:00.32ID:T8+Aa3p6
システムハンガリアンはハンガリー人が作ったんじゃないぞ
アメリカ人がtypeという英単語の意味を誤解して始めた今日では物笑いの種になってるやつだ
2020/02/24(月) 13:01:10.57ID:T8+Aa3p6
英語圏にもアホはいるんだよ
マイクロ波とガンマ線が区別できなくてヌークだヌークだ言ってる田舎者のせいで
スマホ恐怖症になってる情弱が後を絶たない
2020/02/24(月) 13:02:35.90ID:y8NirncW
むしろ英語圏こそアホの割合が多い
2020/02/24(月) 13:21:01.25ID:vxbZ0MKw
英語ができる=かしこい
と日本人は思いがちだ
日本では外国語はかしこくないと習得が難しいが話し相手の外国人は普通のやつが多い
知能指数が20くらいは違ってるはずだから会話内容は絶対かみ合っていない
でも話している日本人は交流できていると思って喜んでいる
日本人の言う知能と外国人の知能も多分かみ合っていないんだろう
2020/02/24(月) 19:53:54.48ID:XuGp3j1T
ここも話がまったくかみ合ってないしな
2020/02/25(火) 15:34:57.13ID:djWltYEA
>>63
少し話がずれるが、OOPには、「SOLID」原則なるものも有る。
2020/02/25(火) 19:09:36.06ID:SJd9VeEz
SOLIDとoopはそんなに関係はないけどな。
oopに神経使うくらいならSOLIDやTDDの理解に時間をかけた方が近道だわ。
2020/02/26(水) 11:19:43.59ID:L12u8R2Z
std::mapの値を取得するときに、右辺値で取得するより.at使う方が例外処理がある分遅いですか?
2020/02/26(水) 14:11:24.83ID:VEltjo/b
そんなことも聞かないとわからない奴は安全な方使っとけ
2020/02/26(水) 21:11:26.26ID:5tO15yqv
速さにこだわるのは中二病の証。
2020/02/26(水) 21:14:58.60ID:tn+NOmwK
富豪的プログラミングは厨三病の証かw
客の表情を一切気にしないオナニー野郎
2020/02/26(水) 22:17:02.48ID:5tO15yqv
地デジになってザッピングが遅くなった。
2020/02/26(水) 22:42:40.23ID:5tO15yqv
客の表情を気にすればこそ安全性・堅牢性が最重視される。速度は二の次。
2020/02/26(水) 22:58:05.64ID:HHiZy6zP
そんなもん要件次第
2020/02/26(水) 23:07:12.19ID:5tO15yqv
>>227
はぁ?そんなわけないだろ。
すでに安全性・堅牢性が確保(割り切りも含む)されているから、速度改善に注力できているだけだぞ。
2020/02/26(水) 23:13:57.21ID:wxEFNPzX
安全性と堅牢性を要件に必要としない案件って何だろう…
2020/02/26(水) 23:55:17.99ID:LU1U8Jw/
>>228
とにかく時間を節約したいから速いソフトが欲しいってことは多々ある
正しく使う限り正しく動くなら問題ないのでそれ以上の安全性は不要
他者から攻撃されることはないから堅牢性も不要
そういう状況普通にある

身近な例ならお前だって使い捨てのスクリプトに過剰な引数チェックとかしないだろ?
2020/02/26(水) 23:58:44.34ID:wxEFNPzX
そんな使い捨てのもんを客に出すの?どういう案件?
2020/02/27(木) 00:15:30.08ID:HQmHUU7r
「無能な働き者」を納品しちゃダメでしょ。
2020/02/27(木) 00:28:55.91ID:iUBnhgkM
>>231
納品したりパッケージ開発するだけが
ソフト開発の仕事じゃないってことだよ
2020/02/27(木) 01:13:36.33ID:G3iz3let
レコメンド関係は安全性なんかよりも効率重視だがな。
スマホゲーなんかもすぐ落ちるじゃん。
それでも遅くてカクカクするよりかは喜ばれるわけだ。
2020/02/27(木) 01:40:09.31ID:01yj9LF4
お高いシミュレーションソフトなんてちょっと入力ファイルや引数間違えただけで落ちるけど
2020/02/27(木) 02:32:36.12ID:HQmHUU7r
おやおや?
例として挙げられるのは、スマホゲームとシミュレーションだけですか?
2020/02/27(木) 02:33:32.23ID:HQmHUU7r
趣味レーション(笑)
2020/02/27(木) 07:13:57.74ID:MeoIkHme
>>226
おまえさんは速度を重視するのに安全性と堅牢性を犠牲にするのか?
ずいぶん甘い考えしてるな
2020/02/27(木) 07:16:26.27ID:MeoIkHme
>>235
ユーザー入力は厳格な検査を経て内部ロジックに渡すのが鉄則だろ
そういうのをサボる口実に速度を持ち出すクズはプロジェクトから叩き出せ
2020/02/27(木) 07:58:08.43ID:76IAsN1p
>>239
プロジェクトって言うか売り物買っただけなんだが
GUIでもメッシュ細かすぎると描画重すぎて実質ハング状態になったり
2020/02/27(木) 08:56:58.29ID:gp31hmMe
だから堅牢性よか速さが欲しい
数十億ポリゴン使うなら速さを優先しないとそのソフトは実用じゃない
描画されないとそのソフトが存在する価値がないからな
2020/02/27(木) 09:02:02.25ID:MeoIkHme
自分はソフト屋でございハードは全くわかりません
なやつが詰むケースだな
2020/02/27(木) 09:53:05.86ID:G3iz3let
絶対安全で一日かかるプログラムよりも
3回に一回は落ちるが10分で終わるプログラムのが価値のある場面は多いよ。
まあ場面によるしトレードオフの話だからどっちでもいいのだが
意固地になるのは違うだろうという話。
2020/02/27(木) 10:21:33.33ID:MeoIkHme
「落ちる」ことなく一見正常終了のように振る舞い誤った結果を出力するゴミプログラムの価値はゼロ
2020/02/27(木) 15:59:17.88ID:HQmHUU7r
コンパイラの最適化に期待するコードを書くよりも、処理するデータ量を減らす努力をしたほうがいい。
2020/02/27(木) 16:13:34.90ID:MeoIkHme
「ほうがいい」 「よりまし」と言って下位に位置づけたものを不要という暴論
2020/02/27(木) 18:10:34.05ID:DcMelsSn
3回に1回落ちるようなクソプログラムが配列末端や不正ポインタからゴミを読んで計算結果に混入させてないと誰が保証してくれるの?
そんなゴミクズを混入して一生懸命計算したゴミ結果に何の価値があるの?
何でもいいからそれっぽい数字が出てりゃいいの?だったら/dev/urandomから適当に数字吐くスクリプトで十分だな
お前のクソプログラムの価値はその程度だ
2020/02/27(木) 20:16:23.17ID:6N44UBOd
>>231
ハードのおまけのサンプルソフトとか大学の研究室用のツールとか
使う相手もそういうのが理解できてることが前提だし契約もそういう不具合についても規定する
2020/02/27(木) 20:19:13.39ID:6N44UBOd
>>247
> 3回に1回落ちるようなクソプログラムが配列末端や不正ポインタからゴミを読んで計算結果に混入させてないと誰が保証してくれるの?
絶対安全で一日かかるプログラムの出力も誰も保証してくれないけどねw
2020/02/27(木) 20:22:55.14ID:MeoIkHme
日本語でおk
2020/02/27(木) 20:25:59.58ID:gTm/hLBR
だいたい新バージョンってのは新機能だったり高速化だったりが売りになっている。
旧バージョンでも動いてたシミュレーションはベンダーでもユーザーでも同一の結果が出るか確認するからバグはあまり混入しない
ある程度ユーザー側で検証が済んでからユーザーは移行する。
新機能はパラメータがちょっと違うだけでバグったりするから安定するまで結構な頻度で更新版が出る。
2020/02/27(木) 20:28:40.63ID:gTm/hLBR
自分の利用する範囲で正常系入力にたいして妥当な結果さえ出ていれば、それ以外でどんなに酷いバグが混入していようがユーザーはあまり気にしない
ユーザーによってはバグフィックス版への移行に対しても慎重なところも良くある。
2020/02/27(木) 21:17:41.74ID:0ftqea78
そろそろC++の話に戻ろうか
2020/02/27(木) 21:27:11.49ID:Y1qHWJOB
わかった、C++の話にもどろう・・
まずはC++で堅牢なメモリリークのないポインタ管理をすべきか
それとも速度優先である程度のリスクを負うコードを書くほうがいいかについて
2020/02/27(木) 21:33:59.93ID:01yj9LF4
つか、速度必要なところではポインタに変換して演算するけど所有権管理はスマポでやるだろ
2020/02/27(木) 22:46:18.56ID:MeoIkHme
>>254
ナマポよりスマポを使えって言いたいんだろ
他人に何を自分のスキルに合わせて話せと?
前提が違うから話しようがないんだが
2020/02/27(木) 23:33:30.63ID:G3iz3let
>>254
ケースバイケース。以上。
後はバカが極論語るだけの世界だ。
2020/02/27(木) 23:37:21.61ID:KVIeYgu/
>>254
しれっとメモリリークをなくすと必ず速度が犠牲になるという前提になってるけど、
そんなことは無いので無意味な話題。
2020/02/27(木) 23:56:49.44ID:09BJJqOH
バカが極論語るというよりも
素人が空想語るって感じだけどいつもこのスレってw
2020/02/28(金) 00:35:10.61ID:ANl57hab
ファイルのバイナリ読み込みをしています。
下記のように最初の2バイトが単位レコードのバイト数を表しているとき、
単位レコード全体を表示しようとしているのですが、うまくいきません。
どうすれば表示できますか?

00 08 FF FF FF FF FF FF
-----
|
+----------------- レコードのバイト数

typedef unsigned char BYTE;
// dataはすでにファイルからバイナリデータとして読み込んでいるもの
int rec_size = (data[0] << 8 | data[0+1]);

BYTE* temp;
temp = (unsigned char*)malloc(sizeof(BYTE)*rec_size+1); // 改行を含めたメモリ確保をしているつもり
memcpy(temp, 0, (size_t)sizeof(BYTE)*rec_size);
temp[sizeof(BYTE)*rec_size] = "0A"; // 改行コード挿入しているつもり

printf("AAAAA %s\n", *temp); //レコード単位を表示
exit(EXIT_FAILURE);
2020/02/28(金) 00:42:03.60ID:bgqQewMR
memcpy(temp, 0, (size_t)sizeof(BYTE)*rec_size);
2020/02/28(金) 00:44:25.91ID:ANl57hab
まずそもそもunsigned charは文字列ではないから%sではだめですね。
どうすれば16進数表示が出来ますか?
2020/02/28(金) 00:45:57.88ID:bgqQewMR
あるいはこれか

printf("AAAAA %s\n", *temp); //レコード単位を表示
2020/02/28(金) 00:47:19.38ID:bgqQewMR
>>262
これコンパイルエラーだろ
実際のコードを張り付けろ
2020/02/28(金) 00:52:57.99ID:YKTB7lSA
あまりにぶっ壊れすぎて何がしたいのか分からん
レコードってのは長さの2byteを含む?
長さ以外は文字コードでそれを文字列として表示したい?
それともバイナリで16進表示したい?
2020/02/28(金) 00:53:13.01ID:ANl57hab
%xにしたらコンパイル通りました。が、出力結果は「0」になりました。。

typedef unsigned char BYTE;
// dataはすでにファイルからバイナリデータとして読み込んでいるもの
int rec_size = (data[0] << 8 | data[0+1]);

BYTE* temp;
temp = (unsigned char*)malloc(sizeof(BYTE)*rec_size);
memcpy(temp, 0, (size_t)sizeof(BYTE)*rec_size);

printf("AAAAA %x\n", *temp);
2020/02/28(金) 00:57:06.59ID:ANl57hab
下記バイナリデータがあったときに、頭の2バイトが8なので、8バイトをtempに格納し16進数で表示したいです。
連続したバイナリデータで今読み込んでいるレコード単位がどの部分を読み込んでいるのかを確認しようとしています。

data = 0x0008AABBCCDDEEFF
2020/02/28(金) 01:02:23.82ID:ANl57hab
実際のdataには下記のようにバイナリファイルの全データを読み込んでいるので、そのうちの一区切りのレコードを表示したいです。
data = 0x0008AABBCCDDEEFF0004AABB0005AABBCC

よく考えたらtempにmemcpyせずにdataから直接表示できればそれでもいい気がしてきました。
2020/02/28(金) 01:03:07.59ID:cn9U0Abk
貼ってるコードがデタラメすぎて意味不明だからとりあえずやりたそうなことをベタ書きするぞ
これで合ってるか?これをカッコよく書きたいって話?

for(int i=0; i<rec_size; ++i){
 printf("%x\n", data[2+i]);
}
printf("\n");
2020/02/28(金) 01:10:04.09ID:ANl57hab
>>269
そのイメージです。
0008から表示させたいので printf("%x\n", data[i]); ですね。
これをスマートに表示できますか?
2020/02/28(金) 01:16:02.14ID:YKTB7lSA
for(size_t i=0,l=0;i<全体の長さ;i+=l){
l=data[i]<<8 + data[i+1];
for(size_t j=0;j<l;++j) {
printf("%02.2X ",data[i+j]);
}
printf("¥n");
}
2020/02/28(金) 01:21:12.05ID:YKTB7lSA
l=... + ...
じゃなく... | ...
2020/02/28(金) 01:25:11.44ID:ANl57hab
ありがとうございます。
bit演算させて%02Xで表示させるんですね。

%02.2X は %02X になりますか?
2020/02/28(金) 01:28:52.77ID:YKTB7lSA
.2はいらなかった
2020/02/28(金) 01:31:26.71ID:ANl57hab
うまく表示できました!
今勉強中で助かりました。
ありがとうございました。
2020/02/28(金) 08:17:52.68ID:HgMPj0rf
>>275
いえいえ、お礼なんか要りませんよ
277デフォルトの名無しさん
垢版 |
2020/02/28(金) 14:55:15.47ID:IJJvPlCN
また行き詰ったので教えてください。。
http://codepad.org/YzpjTJeN

上記コードで3つわからないことがあります。
(1)itemsリストを作り、構造体のITEM_A, ITEM_B, を追加していく
そもそも構造体の中身が違うものを一つのリストに追加できるのか不明。
(2) itemsに動的にリスト追加
(3) itemsのリストをfor()で1要素づつ表示させる
※(1)(2)がわかれば(3)は自分でもわかるとは思いますが。

どのように書けばよいかわかりますでしょうか?
278デフォルトの名無しさん
垢版 |
2020/02/28(金) 15:06:55.04ID:IJJvPlCN
itemの数が膨大にあり速度がほしいので、リストに追加するところは先に個数を確保したいのですが、0xEEまで精査しないと何itemあるのかわからないので、vectorで動的追加しかないかなと思っています。
emplace_backだとpush_backよりは多少速い?
2020/02/28(金) 15:56:05.44ID:lgmUZMDZ
>>277
ITEM_AとITEM_Bってtypeの値が違うだけで同じ構造体で良いような気がするが…
280デフォルトの名無しさん
垢版 |
2020/02/28(金) 16:36:45.32ID:Zl8S5zbV
>>268
ダンプするだけか。
2020/02/28(金) 17:40:47.76ID:nMLR2isw
vector使うかどうかよりも、毎回raw領域確保するほうがよっぽど問題と思うよ。
dataは何処かにおいておいて、rawにコピーせずに場所だけ指し示すようにしたほうがいい。
いずれにしても、計測なき最適化は害悪。
2020/02/28(金) 17:47:29.10ID:OpAeM4nJ
>>277
データの塊はどこかに置いたままにしておいて
イテレータで切り分けるスタイルで書いてみた。
https://wandbox.org/permlink/4D5XbHG7S1cw3fAL
283デフォルトの名無しさん
垢版 |
2020/02/28(金) 18:14:07.42ID:6NG7oGkA
新型肺炎COVID-19は人工的に作られたともそうでないとも言われている。
プログラマの意図しないバグを含むプログラムを公開してしまったとしたら、そのプログラムは人工的ではないと言えるのか?
284デフォルトの名無しさん
垢版 |
2020/02/28(金) 18:17:18.92ID:6NG7oGkA
人工の定義は?
2020/02/28(金) 19:23:47.33ID:OpAeM4nJ
>>277
少しだけ >>282 を改良。
僅かに速度も速くなってるかもね?
https://wandbox.org/permlink/7AuMCemoXRudfFmt
2020/02/28(金) 19:55:10.54ID:ZcWDRqtu
このプログラムの最終目的はなんなんだろう
作ったitemsリストは表示するだけじゃなくて後で別の目的に利用するのかな
287デフォルトの名無しさん
垢版 |
2020/02/28(金) 20:34:59.53ID:eXGvTrLS
std::stringをkeyにして作成されたstd::mapからfind関数を用いて検索する際に、
std::string_viewを利用して検索をかけたいのですが可能でしょうか?
もしくはstd::string_viewを利用して検索する方法等はあるのでしょうか?
2020/02/28(金) 21:36:33.76ID:IJJvPlCN
色々ご意見ありがとうございます。

>>279,280,281
後出し情報で申し訳ありませんが、バイナリファイルを読み込んで
そのバイナリデータの途中に別のレコードを追加したり、
削除したり、文字列置換したり、
といったことを行い、最後にファイルに書き出そうと考えています。

>>286
ご推察の通り、データを読み込んで一部を加工したファイルを出力しようとしていました。

>>282,285
サンプルコードありがとうございます。
ふんだんにc++の文法が使われているので、作っていただいたサンプルコードを今調べているところです。。
まだc言語レベルの記述しか理解できていないので。
とりあえずイテレータ部分を調べています。

加工しやすいように一度内部で数値や文字列に変換したdatabaseを作り、それに対し追加、削除、文字列置換などの加工をしてファイルに出力する。
というフローを考えていましたが、みなさんのご意見を参考にファイル出力するときに加工しながら出力する方式で検討してみようと思います。
2020/02/28(金) 21:40:11.81ID:YKTB7lSA
>>287
型をmap<K,M>の代わりに
map<K,M,std::less<>>にしておく
2020/02/28(金) 22:23:20.74ID:lgmUZMDZ
>>288
> そのバイナリデータの途中に別のレコードを追加したり、
> 削除したり
と言うことならvectorよりlistの方がいいと思う
2020/02/28(金) 23:38:48.68ID:ANl57hab
>>290
ご意見ありがとうございます。
listがいいと思うのは任意の位置に挿入したりできるから。
ということでしょうか?
2020/02/29(土) 01:31:35.79ID:WzbNfV7+
C++ は C と互換性があって C の延長線上でも使えるのが利点だとは C++ の設計者自身も言ってるけど、
C の延長線上で使ってたらやっぱり C の延長線上な設計になっちゃうと思うんだよなー。
その延長線を伸ばしていっていずれ C++ の習得に至る (あるいは至らなくてもよい) 、みたいな想定らしいんだけど、
今となっては C から C++ の距離がデカすぎる気がしてる。

だからどうするのが良いという意見はないのでぼんやりした感想でしかないけど。
2020/02/29(土) 01:51:00.65ID:VOzt624K
今や互換性があるというよりも使いやすいFFIがあるって認識のがメジャーだろう。
2020/02/29(土) 04:10:54.37ID:TuWp9ykk
>>277
codepadはC++03だったと思うが、03では構造体のメンバの=によるデフォルト初期化は
(static constな、配列でない組み込み型を除いて?)許可されてない
ので14が使えるideoneになるけどとりあえず最低限動くようにした
https://ideone.com/1RUIfn

どうしても03じゃないと困るなら直す
あとRuntime Errorって出るのは単にmainで1を返してるから(0にしたら直る)
特に関数の戻り値を使いもしないのに常にintにしてreturn (1)って書くのやめたほうがいいよ

>>292
>今となっては C から C++ の距離がデカすぎる
そう思うなら余計な改変はしないでやれよ
2020/02/29(土) 04:27:18.26ID:TuWp9ykk
あ、そういえばバイト列全部持ってるから別にサイズ入れる必要無かった
2020/02/29(土) 08:31:09.13ID:wNArNR7j
>>291
そう、
> itemの数が膨大にあり
の状況でvectorに挿入/削除したら死ぬ
> 速度がほしい
のに対してlistが最適かはわからんけどvectorより100倍マシ
2020/02/29(土) 09:47:01.15ID:GnUNXfgB
>>296

vectorについて調べてみました。

>ttp://vivi.dyndns.org/tech/cpp/vector.html

上記に下記がありました。

>insert() の処理時間は O(N) 。O(N) とは配列要素数に比例して処理時間を要するという意味。 データ数が100倍になると、処理時間も100倍になる。
>それに対して push_back() は O(1) なので、データ数がいくら増えても常に一定時間で処理が終わる。

大量のリストで先頭の方に挿入するとやばそうですね。
これは気にしていませんでした。
ありがとうございます。
2020/02/29(土) 11:08:38.27ID:ih/BSqRh
listは要素を手繰るのがクッソ遅いから、事前に挿入位置のノードのポインタを知っている状況でないといけないことに注意
毎回前からスキャンして挿入なんてやってたら結局O(N)でメモリアクセス効率がゲロ悪い分だけvectorより遥かに遅い
2020/02/29(土) 11:23:57.34ID:5T8vHxV4
C89とC2xの距離も大きくなってるけどな
あっちがこっちに寄ってきてるから
2020/02/29(土) 12:12:18.31ID:Xdrhue/n
>>298はなぜかvectorだと瞬時に検索できると思ってるw
2020/02/29(土) 12:18:08.81ID:Cury2uAw
検索とかどこから出て来たんだ
2020/02/29(土) 12:20:17.33ID:Cury2uAw
ていうかとりあえず組み上げてから実測した方がいいよ、似たようなことはすでに言われてるけど
2020/02/29(土) 12:48:35.09ID:gvjpz0iS
dequeにしてみれば
2020/02/29(土) 12:54:52.89ID:WzbNfV7+
>>297
vector の方が先頭に追加するのが速いこともあるという観測データが有る。
https://cpplover.blogspot.com/2017/02/c-p0550r0-p0601r0.html
今時の機械は事情が複雑すぎて予想できない。
まず実測しろってよく言われているのはこういうこと。
やってみてからどこが効いてるのか調べた方がいい。
2020/02/29(土) 13:18:08.51ID:GVKyjNMb
>>300
少なくともlistに比べたら瞬時だね
さすがに挿入位置まで毎回スキャンしてたらlistに勝ち目はほぼ無いから、そこで突っかかるのはさすがに無理筋
listを擁護したいなら先頭への挿入か挿入位置のノードのポインタが既知のケースに話を限定しなさい
2020/02/29(土) 13:53:20.08ID:wNArNR7j
>>305
> 少なくともlistに比べたら瞬時だね
えっ、何その魔法w
2020/02/29(土) 14:00:40.18ID:bs6YePUD
挿入が主な目的な場合って普通はheap使うんじゃねーの?
あんまり任意の位置に挿入するってシチュエーションはないように思う。
2020/02/29(土) 14:13:58.78ID:B70Sj2ZJ
>>304
そういうこともあるんですね。
プログラムは難しい。
2020/02/29(土) 14:38:39.67ID:ZbPwrBbB
>>307
heapからのメモリを繋ぎ合わせた集合体がリンクリストで、それがSTLでは
std::listになっている。
2020/02/29(土) 14:41:54.28ID:ZbPwrBbB
>>298
Cでは、リンクリストを使って、ノードの位置を保持するためには、index値ではなく、ポインタ値を用いる。
STLでは、index値を前面に使う設計になっているのが問題。
元々、リンクリストは、ノードを巡るのは非常に高速。
ノードの位置をポインタで維持している限り「検索」作業は入らない。
2020/02/29(土) 14:44:16.50ID:ZbPwrBbB
std::listには問題が有るかもしれないが、リンクリストというデータ構造自体は、文字列(string, CStringなど)のクラスを作るためなどをの一部の例外を除いては、動的配列よりもほぼ全面的に優れていると言っても過言ではない。
2020/02/29(土) 14:45:35.17ID:ZbPwrBbB
本来は、Cの最も優れている点を言えといえば、そのリンクリスト一点と言っても過言ではない。
2020/02/29(土) 14:49:01.60ID:ZbPwrBbB
>>310
stlでは、ノードの位置を維持するために、先頭を0として、0,1,2,... というような「連番」で管理しようとしてしまう。
そのために、リンクリストである所の std::listを使う場合、先頭から順番に「たどる」作業が必要になってしまい、>>298が言うような「クッソ遅い」現象が起きる。
しかし、それは、stlの設計のクソさによるものである。
2020/02/29(土) 14:59:22.48ID:WzbNfV7+
>>313
> 「連番」で管理しようとしてしまう。

なんで?
std::list のイテレータは実質的にポインタだしそれで記憶しておくもんじゃないの?
2020/02/29(土) 15:05:36.96ID:VpO1O9GW
この前からヒープヒープ言う小僧がいるけど
普通ヒープといえば
- 木構造のヒープ
- ヒープメモリのヒープ
どっちだと思う?
おれは後者だけど
2020/02/29(土) 15:11:14.78ID:1OIyhpL7
文脈によらない「普通」なんてないだろ。
「ヒープ」と出てきたらどっちの意味で使っているのか注意しなきゃならない。
2020/02/29(土) 15:32:56.54ID:ZbPwrBbB
>>314
そうなのか。
だとしたら >>298 が言っていたのはなんなんだ?
2020/02/29(土) 15:34:53.49ID:HY2ZFlSm
順繰りたどらなくていいリンクリストってあるの
2020/02/29(土) 15:40:33.93ID:GnUNXfgB
下記のようにすると、最後にprintfしているときにはnameに値が入っていません。
set()を抜けたときに開放されてしまうのではと思うのですが、どうすれば保持出来ますか?
char* name; のところを char name; にはしたくないと思っています。
mallocとかを使うのでしょうか?

class AAA{
public:
char* name;
};

int AAA::set(){
char temp_name[5];  ←ここで確保した変数がset()が終わると開放されてしまう??
temp_name = "NAMAE";
name = temp_name;
return(1);
}

void main(){
AAA aaa;
aaa.set();
printf("NAME %s\n", aaa.name);
}
2020/02/29(土) 15:44:30.24ID:ZbPwrBbB
>>298
例えばテキスト・エディタを作っている場合、ある一点Aに50文字を挿入する
というようなことがおきる。
この場合、50文字を挿入する前に、Aの場所のノードのポインタ値を求める。
カーソルの位置に挿入する場合には、最初からポインタ値を持っているようにしていれば「求める」必要は無い。
一度ポインタ値が分かった後は、50文字追加する際に挿入場所として必要なポインタ値は長々と最初から「たどる」ことなく分かる。

たどる場合も、各行の先頭のポインタ値をすべて保持するようにしておけば、まず行Yの先頭のポインタ値を見つけて、あとは、そこから列Xのポイント値を求めるための計算量は余り多くは無い。

このような場合、全てのデータをstd::vectorのような動的配列で保持しようとするのは基本的に速度が遅くなることが多いが、リンクリストは速度的に安定する。
2020/02/29(土) 15:44:56.46ID:WzbNfV7+
>>317
vector と同じように考えるなってことを言ってるだけだと思うよ。

逆に vector では要素の追加とかがあった時にイテレータが無効になるので、
あまりイテレータで保持すべきではないという事情がある。
コンテナとして最低限度共通のインターフェイスが付いてるけど、
やっぱり内部の事情は意識しなけりゃなんねぇなぁという話。
2020/02/29(土) 15:45:04.74ID:HY2ZFlSm
スコープ抜けたら当然解放されるよ
c++ならchar*じゃなくてstd::stringでも使った方がいいのでは
2020/02/29(土) 15:48:52.44ID:ZbPwrBbB
>>320
例えばの話、要素数が多いような巨大なデータを動的配列で確保したとする。
この動的配列のトータルバイト数をW(バイト)としよう。
この配列の要素数が、本当の意味で増やす動作が入ったときには、メモリの容量が
一時的に 3*W(バイト)必要になる。
Wが実メモリのぎりぎりに入るくらい大きい場合には、仮想記憶が必要となりとても遅くなる。

一方、リンクリストだとそのようなことがない。
2020/02/29(土) 15:50:57.05ID:ZbPwrBbB
>>321
後半部。
そういえば、vectorの場合、途中にデータを追加した場合、それより後ろのindex番号がずれてしまうので、その部分を指していた今までのイテレータは使えなくなってしまうのだね。
2020/02/29(土) 15:53:18.38ID:ZbPwrBbB
>>318
構造的には存在しない。
リンクリストを使う場合、ノードを指し示すためには出来る限りindex値ではなくポインタ値を使うようにして
「順繰りにたどる」
必要が無いようにする必要がある。
2020/02/29(土) 15:57:30.04ID:WzbNfV7+
>>324
それもあるけど vector は要素が連続しているという強い制約があるから場所が足りなくなったら再配置することがある。
realloc みたいなもん。
2020/02/29(土) 16:02:26.57ID:HY2ZFlSm
いやポインタ使おうが無理でしょ...
リンクリストだとポインタ飛び飛びになるんだから辿らないと無理でしょ
2020/02/29(土) 16:06:46.92ID:WzbNfV7+
>>327
もちろんどこかでは辿るが、辿った結果をインデックスとして保持してたらコストがデカいから
ポインタ (イテレータ) で保持することを心掛けてねっていう意味だと思うよ。
2020/02/29(土) 16:10:08.53ID:HY2ZFlSm
それだと298のいってること理解できるはずなんだけどね
ようわからんわ
2020/02/29(土) 16:11:07.92ID:ZbPwrBbB
>>327
「たどる」と言っても、隣のノードをたどる場合、コンパイル後のマシン語レベルだと、整数に1を足すのと同じか、その2回分程度のクロック数しか消費しない。
だから for 文で巡るときには、動的配列を巡るのと全く同じ程度しか時間が掛からない。
2020/02/29(土) 16:12:14.35ID:ZbPwrBbB
>>329
恐らく、>>298 は、リンクリストの効率の良い使い方を知らないと思われる。
2020/02/29(土) 16:13:48.55ID:VpO1O9GW
この教科書読めレベルの話、いちいち議論する必要なくね?
2020/02/29(土) 16:16:42.57ID:HY2ZFlSm
>>331
どうみても理解してると思うが
どこがおかしいとおもってるの
334デフォルトの名無しさん
垢版 |
2020/02/29(土) 16:17:00.93ID:/L84OmpW
全員が釣り師だと何もつれない。
2020/02/29(土) 16:29:33.32ID:ZbPwrBbB
>>333
「事前に挿入位置のノードのポインタを知っている状況でないといけないことに注意」
この命題自体は正しい。
しかし、「ポインタを知っている状況ではない」という状況自体が、C言語流の
文化では滅多に起き得ないことだからだ。
恐らく >>298 を書いた人は、「ポインタを知っていない状況」が高頻度で起きる
ような書き方をしているからこそそのような注意を促したと感じる。
多分、C言語とは異なる文化に長く親しんだか、少なくともC流の文化に慣れずにいきなりC++から始めたかのどちらかだと思われる。
2020/02/29(土) 16:31:36.11ID:ZbPwrBbB
>>335
または、ポインタが理解できないか、ポインタにアレルギーがあって、避けて通ってきた人かも知れない。
そういう人は多いらしい。
聞いた話だとポインタを全く使わずに配列だけでC言語を使っている人がいるそうだ。
2020/02/29(土) 16:37:43.01ID:MKbmJ2zo
要はlistとvectorの違いは何で、なぜ必要かという文脈でいいのかな
listはfor文にi++入れないための単なる糖衣構文だと思うが
基本的に自分は糖衣構文は必要ない派です
2020/02/29(土) 16:37:52.88ID:VpO1O9GW
リンクリスト万能君も老害リストに追加だね
キャッシュヒット率低いし、64bitポインタの無駄もでかいし
メモリ空間異なるところもっていくときに全部作り直しだし
昨今はむしろ使えないデータ構造扱いされること多いから
c/c++を高速化のために使ってるならなおさら
339デフォルトの名無しさん
垢版 |
2020/02/29(土) 16:38:02.22ID:/L84OmpW
長文書いてる人は全員釣り師。
340デフォルトの名無しさん
垢版 |
2020/02/29(土) 16:40:06.91ID:/L84OmpW
>>338
測定すればすぐわかる事なのにね。
そもそも教科書は挿入に焦点を当ててるけど、検索のほうがよほど問題。
algorithmと極端に相性が悪い。
listを使う理由はイテレータの安定性のみ。
2020/02/29(土) 16:45:07.46ID:ZbPwrBbB
>>340
測定だけでは見落とすことが有る。
測定しただけで std::vector の方が速いと思っている人は、数学的想像力が足りてない。
342デフォルトの名無しさん
垢版 |
2020/02/29(土) 16:47:16.55ID:/L84OmpW
>>341
だってキミ嘘しか書いてないやん。
最初から全部嘘だし。
どう見たって釣り師。
2020/02/29(土) 16:48:55.39ID:ZbPwrBbB
>>342
恐らくIQが高いので一般プログラマはついてこれない。
344デフォルトの名無しさん
垢版 |
2020/02/29(土) 16:49:11.83ID:/L84OmpW
はいもう釣り堀は終わり。
2020/02/29(土) 16:55:50.08ID:ZbPwrBbB
高IQの人と一般の人とは話が通じ合わない。
2020/02/29(土) 17:09:06.31ID:VpO1O9GW
はいこのおじいちゃんの毎度の捨て台詞いただきました
2020/02/29(土) 17:16:14.77ID:usahjc2v
> algorithmと極端に相性が悪い。
> listを使う理由はイテレータの安定性のみ。
とか書くような奴もどうかと思うわ
2020/02/29(土) 18:09:51.88ID:VOzt624K
嘘つくやつって特有の変なプライド持ってるよな。
2020/02/29(土) 19:24:46.81ID:ZbPwrBbB
話者に対してレベルが低過ぎる人には話が嘘か間違いにしか聞こえない。
2020/02/29(土) 19:55:24.32ID:8sbT/wNa
嘘つきがレベル高いってのは
赤軍派の暴力事件が相次いでいた頃の
共産主義=インテリのステータスだった時代の
今となってはもうみんな気付いている茶番とインテリぶったやつらが
真っ赤な最高学府で安々と洗脳されたバカばっかりだったという
お笑いぐさのやつだね
2020/02/29(土) 19:57:19.47ID:YiDWuwc+
動的配列より全面的に優れているって何かのギャグなの?w
2020/02/29(土) 21:20:16.71ID:GVKyjNMb
>>336
Cに慣れた人間がリンクリストを好む傾向があるのは、
動的配列が一段抽象化層を設けないと扱いづらいのに対してリンクリストはCの自然な構文で生のままで扱いやすいからだよ
君自身も君が馬鹿にしている「癖」に縛られているんだ
2020/02/29(土) 21:49:19.01ID:c0ztbNyQ
>>349
仮に IQ が存在するとして、 IQ に差があるのならば、IQの低い受け手はIQの高い話し手の発する全情報を解釈するのに困難を感じることは確かにあり得るとは思いますが、
「嘘か間違いにしか聞こえない」というのは、IQの差だけでは説明できないと思います
IQの低い私の体験としては「わからない」とはいつでもよく感じていたりするのですが、それでも「嘘だ」「間違っている」とは普通は考えませんね
2020/02/29(土) 22:20:21.84ID:gvjpz0iS
リンクリストって今時のCPUにとって非常に性能上扱いづらいものだからねぇ

順繰りにたどっていく場合に先読みがしづらい
実体を指すポインタの配列なら2つ先、3つ先のアドレスまでキャッシュに載っているから、プリフェッチが効いて必要になる頃にはキャッシュにロードされてる感じになる
2020/02/29(土) 22:36:08.55ID:rCNvcH1c
>>345
ここにはお前と話が通じない一般人しかいないから、お前と話ができる人がいるどこかよそに行った方がお互い生産的だと思うぞw
2020/02/29(土) 22:37:49.26ID:+Y3Jyqj/
>>354
デタラメ書かない
2020/02/29(土) 22:40:10.33ID:tY0zeWw8
>>356
デタラメではないでしょ
キャッシュヒット率意識するのは大事
2020/02/29(土) 22:51:13.30ID:XJV+/FNl
プリフェッチとか色々ごっちゃになってる
断片的な知識で知ったかしようとして失敗してるパターン
2020/02/29(土) 23:22:00.98ID:gvjpz0iS
要素アドレスが連続した領域に書き込まれている場合は、
コンパイラがループアンローリングして次の要素アドレスロードしてその参照先のプリフェッチ命令挿入することが可能
ってのを場合によっていくつか先まで出来る
リンクリストの場合はこうはいかない
次の要素のロードが終わらないと次の次の要素のアドレスが分からんのだから
2020/02/29(土) 23:24:07.69ID:gvjpz0iS
インテルCPUの場合はプリフェッチ入れなくても投機的にプリフェッチされてたからこそ、例の脆弱性が問題になってた
2020/03/01(日) 01:43:44.70ID:3018fiZA
実装法を理解できてないために効率よい使い方を間違っている人は遅さをすぐにキャッシュせいにしてしまう。
2020/03/01(日) 01:49:59.33ID:3018fiZA
>>355
まあそうだが、それだとおまえら一般人はいつまでたってもアホなプログラミングしかできないだろうな。
2020/03/01(日) 01:55:38.98ID:3018fiZA
>>362
俺の人生経験からすると、現実には本当に馬鹿な人にはいくら言っても無駄なようだが。
いくら言っても理解できないし、強く何度も言うと、逆に明らかに絶対やっては駄目なときでもいつもそればっかりやってしまうようになったりする。
なので周りはむしろ困ることになる。
2020/03/01(日) 02:04:09.13ID:3018fiZA
cppreferenceを含めてネットでは std::vector ばかり使われているのは、大部分のプログラマがポインタを理解できないのでリンクリストも理解出来ておらず、使いこなすことが出来ないためと踏んでいる。
正しく理解できないためにstd::listを使うと悪い使い方しかできないため、彼らの実験の仕方ではいつもstd::vectorより遅くなってしまう。
そのような人には、C++を使ってもC#以上の速度を出すことは困難で、だからこそ一般プログラマとそれ以下の人材しか集めることの出来ない多くのプロジェクトでは C#やJava,Rubyなど簡易言語が好まれて使われるようになっていると予想される。
俺とは住む世界が違うので、このことは推定に過ぎないがな。
2020/03/01(日) 02:29:46.23ID:0F9Oehpq
uint64_t の型から unsigned char の型に変換するにはどうすればよいですか?
同じ4バイトなのでどうにかすれば変換できるのではと思っているのですが。
2020/03/01(日) 02:30:41.70ID:0F9Oehpq
間違えました。
unsigned charは4バイト確保すれば同じバイト数になる。ですね。
2020/03/01(日) 03:40:24.38ID:ZtayyY2i
そのマシンのエンディアンの通りに格納したんでいいなら
uint64_t a;
unsigned char b[4];
reinterpret_cast<uint64_t &>(b) = a;
2020/03/01(日) 05:10:36.30ID:lOhQr9G7
std::vectorばかり使われる最大の理由は、C言語における配列と互換性を持つ唯一のコンテナだからでしょ。
2020/03/01(日) 05:48:12.89ID:3N/K+b45
64ビットって4バイトなのか?というつっこみ
2020/03/01(日) 07:40:13.71ID:ZtayyY2i
あ、そういえば・・・w
2020/03/01(日) 10:25:14.04ID:7BIH7/M6
>>367
それはだめでしょ
2020/03/01(日) 10:27:14.27ID:0F9Oehpq
>>367,369
間違えました。
8バイトだからこうなるんですね。
変換後の中身を確認したらエンディアンも問題なさそうです。
ありがとうございました。

uint64_t a;
unsigned char b[8];
reinterpret_cast<uint64_t &>(b) = a;
2020/03/01(日) 11:39:13.66ID:7BIH7/M6
>>372
動くだろうけどよくないやりかた
reinterpretじゃなくてmemcpyを使う
それかアライメントを合わせる
2020/03/01(日) 12:04:58.71ID:0F9Oehpq
>>373

ttps://stackoverflow.com/questions/49648033/c-convert-uint64-t-to-unsigned-char-array

上記を参考に下記でやってみたらこれもうまく行っているようです。
こんな感じでしょうか?

uint64_t a;
unsigned char b[8];
memcpy(b, &a, 8);
2020/03/01(日) 12:12:33.01ID:N+yk7N8j
>>364
あなたが書いてることのレベルが低過ぎて理解できません。
376367
垢版 |
2020/03/01(日) 12:13:34.75ID:1R5iR0i4
ああそうか、アラインメントのこと完全に忘れてたすまん
まぁmemcpy, またはunsigned charにアラインメント指定か、もしくはunsigned charごとに代入した方がいいね
動かす環境が限定されてるならreinterpretでもいいけど
2020/03/01(日) 12:18:16.41ID:7BIH7/M6
それでいいよ
ちなみにmemcpyの呼び出しコストは最適化で消えるから気にしなくていいよ
(コンパイラ依存だけど)
2020/03/01(日) 12:22:08.16ID:0F9Oehpq
>>377
ありがとうございます。
2020/03/01(日) 12:42:53.26ID:0F9Oehpq
追加で質問があります。

http://codepad.org/uN82gnco

この30〜31行目でemplace_back()、back()を使っているのですが
emplace_backを使うときはこうやって使うのであってるのでしょうか?

あと、上記をコンパイルすると下記エラーが出ます。

「エラー: オブジェクト以外がメンバ関数 ‘int Self::xxx(ITEM)’ を呼び出すことは出来ません」

今色々調べているのですが、何が悪くてどのように解決すれば良いかがまだわかりません。
どうすればよいかわかりますでしょうか?
2020/03/01(日) 12:44:04.60ID:GdO9iGlh
>cppreferenceを含めてネットでは std::vector ばかり使われているのは、大部分のプログラマがポインタを理解できないのでリンクリストも理解出来ておらず、使いこなすことが出来ないためと踏んでいる。
よくこんな頭の悪いこと思いつくよなw
2020/03/01(日) 12:47:43.45ID:PLnmvtRY
How can you be so certain?
2020/03/01(日) 13:00:27.97ID:2UJE7A6V
Self::xxxをSelfの後に書かないと。
ラムダ内部は別の関数だからthisにはアクセスできない。[&]を使うとか工夫しないと。
2020/03/01(日) 13:19:18.30ID:7BIH7/M6
>>379
emplaceを試したいならまずは余計なものいれずにやるべきだね

struct ITEM {
  ITEM(const char* p) : name(p) {}
  std::string name;
};

std::vector<ITEM> items;
items.emplace_back("ABCD");
for (auto& item : items) {
  printf("FF %s\n", item.name.c_str());
}
2020/03/01(日) 13:44:18.34ID:0F9Oehpq
>>382
"&"を使うということは構造体をポインタ渡しするということでしょうか?
下記でポインタ渡しにしたつもりですが、同じようなメッセージが出ました。
ポインタ渡しのことではないのでしょうか?

http://codepad.org/L0oOc9RF

ほぼ同じエラー →「エラー: オブジェクト以外がメンバ関数 ‘int Self::xxx(ITEM*)’ を呼び出すことは出来ません」

>>383
サンプルありがとうございます。
emplace_back()の時に直接引数に入れることができるんですね。
参考にさせていただきます。
クラス関数に構造体を渡すとエラーになったので、その質問をしたついでにemplace_back()の使い方の質問もさせていただきました。
2020/03/01(日) 13:50:29.27ID:7BIH7/M6
>>384
> emplace_back()の時に直接引数に入れることができるんですね。

それをやりたいからこそのemplaceだよ
無駄を省きたい上級者用って感じだね
まずは自分でITEMを作ってpush_backで追加するのが基本だと思うよ
2020/03/01(日) 13:52:07.36ID:cF4UfbiQ
違う違う、[](ITEM& item) を[&](ITEM& item)にしろってこと
2020/03/01(日) 14:10:29.25ID:0F9Oehpq
>>385
emplace_backは新しい文法でpush_backの方が従来のもののようですね。

>>386
その対応でエラーが消えました。
[&]が何してるのかまだ理解できていないので調べてみようと思います。
ありがとうございました。
2020/03/01(日) 14:23:08.70ID:cF4UfbiQ
あっと、[&](ITEM& item)より[this](ITEM& item)のほうがよかったか
2020/03/01(日) 15:44:10.68ID:0F9Oehpq
>>388
thisでもいけました。
数値のmemcpyを教えていただいた >>374 の件ですが、下記で確認するとバイト単位で逆になりました。
エンディアンの影響だと思いますが、unsigned charに反転せずに簡単にセットする方法はなにかありますでしょうか?

unsigned short num = 258;
unsigned char temp[2];
memcpy(temp, &num, 2);

printf("A %04X\n", num);
printf("B %02X%02X\n", temp[0], temp[1]);

下記結果になる。

A 0102
B 0201
2020/03/01(日) 16:31:11.59ID:7BIH7/M6
>>389
調子にのりすぎ
原因わかってんなら自分で解決できるだろ
頭使え
2020/03/01(日) 16:36:04.92ID:0F9Oehpq
>>390

すみません。
センスないような気がしますが下記で入れ替えようと思います。

unsigned char temp1[2];
unsigned char temp2[2];
memcpy(temp1, &num, 2);
temp2[0] = temp1[1];
temp2[1] = temp1[0];
2020/03/01(日) 17:16:47.98ID:ZpGOlbch
>>391
htons を使えばいいんじゃね?
言語仕様にあるわけじゃないけど、 POSIX と Windows で使えるからまあおおよそポータブルでしょ。
2020/03/01(日) 18:19:09.36ID:JrOSOdLx
>>391
素直に
temp[0] = (num >> 8) & 0xff;
temp[1] = (num >> 0) & 0xff;
でよくね?
2020/03/01(日) 18:30:07.18ID:wjTinnpB
C++の初心者質問スレってなかったっけ
2020/03/01(日) 18:38:25.85ID:3018fiZA
>>372
コピーも何も必要なくて、
uint64_t a;
BYTE *ptr = (BYTE *)&a;
ptr[0] : 0 バイト目
ptr[1] : 1 バイト目
・・・
ptr[7] : 7 バイト目
でいける。
2020/03/01(日) 18:41:25.44ID:3018fiZA
>>395
さらに、
union UUU {
uint64_t  m_u64;
BYTE   m_b[8];
};
uint64_t  a;   // 入力値
UUU  u;
u.m_u64 = a;
とすれば、
u.m_b[0] // 0 バイト目
・・・
u.m_b[7] // 7 バイト目
となる。
2020/03/01(日) 19:07:30.68ID:7BIH7/M6
>>396
それc++ではUBだよ
あれ君って天才君だっけ?
2020/03/01(日) 21:11:13.32ID:ZpGOlbch
汎用的に作るならこんな感じかな?

#include <type_traits>

template<class T>
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, void>::type
integral_to_bytes(T n, std::uint8_t* dest) {
for(std::size_t i=sizeof(n)-1; i<sizeof(n); i--, n/=256) dest[i] = n%256;
}
2020/03/01(日) 21:22:32.67ID:qtVJ0qYe
std::array<uint8_t, sizeof(T)>を返す方が親切だぞ
2020/03/01(日) 21:50:36.45ID:ZpGOlbch
>>399
なるほど。
整数型の大きさだからそれほど大きくなることは心配しなくていいもんな。
2020/03/01(日) 22:10:49.73ID:WtPaEung
OMP_STACKSIZEが小さいとセグフォるが1Gとか指定してもいいんか?
2020/03/02(月) 01:26:05.82ID:jXMtMdaQ
>>397
UBという証拠は?
2020/03/02(月) 01:46:27.25ID:jXMtMdaQ
>>397
少なくともちゃんと例としては使われている:
https://aticleworld.com/little-and-big-endian-importance/
2020/03/02(月) 01:47:31.58ID:jXMtMdaQ
>>403
typedef union
{
uint32_t u32RawData;
uint8_t au8DataBuff[4];
} RawData;
uint32_t ChangeEndianness(uint32_t u32Value)
{
RawData uChangeData,uOrginalData;
uOrginalData.u32RawData = u32Value;
//change the value
uChangeData.au8DataBuff[0] = uOrginalData.au8DataBuff[3];
uChangeData.au8DataBuff[1] = uOrginalData.au8DataBuff[2];
uChangeData.au8DataBuff[2] = uOrginalData.au8DataBuff[1];
uChangeData.au8DataBuff[3] = uOrginalData.au8DataBuff[0];
return (uChangeData.u32RawData);
}
2020/03/02(月) 02:13:31.73ID:jXMtMdaQ
C/C++では高速化のためCPUのマシン・アーキテクチャをそのまま使う。
マシン・アーキテクチャによって little endian と big endian の違いが有るのでC++言語仕様としては定義されてないが、「but most compilers define」なっている。
これはつまり、littele endian の CPUなら、そのまま little endian での表現がそのまま読みとられ、big endian の CPUなら、そのまま big endian での表現がそのまま読み取られることを意味している。
たとえば、cppreference では、
「reading from n or c is UB but most compilers define it」
となっており、
32BIT値の 0x12345678の場合に、unionで 16BIT 配列の0要素目に0x0011を代入すると、
0x12340011 or 0x00115678
が読み取られるように書いてある。
undefined behaviour であっても、このどちらかに限定されると言うことであろう。

https://en.cppreference.com/w/cpp/language/union

union S
{
  std::int32_t n;   // occupies 4 bytes
  std::uint16_t s[2]; // occupies 4 bytes
  std::uint8_t c;   // occupies 1 byte
};           // the whole union occupies 4 bytes

int main()
{
  S s = {0x12345678}; // initializes the first member, s.n is now the active member
  // at this point, reading from s.s or s.c is undefined behavior
  std::cout << std::hex << "s.n = " << s.n << '\n';
  s.s[0] = 0x0011; // s.s is now the active member
  // at this point, reading from n or c is UB but most compilers define it
  std::cout << "s.c is now " << +s.c << '\n' // 11 or 00, depending on platform
       << "s.n is now " << s.n << '\n'; // 12340011 or 00115678
}
406デフォルトの名無しさん
垢版 |
2020/03/02(月) 04:24:33.89ID:hM5tZRlI
先月ぼくが通った道だけど、結論が全く違ってて興味深い。
2020/03/02(月) 08:40:39.81ID:vdXXyaaZ
UBの恐ろしさを知らない子の結論だね
若いなあ
2020/03/02(月) 08:56:34.60ID:/NXxliI7
老害なのか子なのかどっちかにしろ
2020/03/02(月) 09:31:30.94ID:TcdIMkwU
>>403
cではOKなんだよ
だからわざわざc++ではって限定したんだから察せよ
cでは定義されてるから多くのコンパイラーはc++でも同様の解釈する
また実際のところ今後ずっとそうだろう(今回のケースに限っては)
でもUBはUB
屁理屈つけて自己正当化しようともそれは変わらない
エンディアンでなくライフタイムの問題でしょ、c++の常識的に
2020/03/02(月) 09:37:25.38ID:x4CDu4GY
くっそしょーもねえ
2020/03/02(月) 10:51:20.25ID:4ZdkwDZZ
>>405
ほとんどの場合に大丈夫だろうという見立ては間違ってないと私も思う。
で、大丈夫でなかったときは?
たぶんコンパイルエラーにも警告にもなることなく黙って未定義動作に突入する。

各処理系・環境での挙動が保証されている (検証が済んでいる) なら別に使ってもいいんじゃないのとは思うけど、
union を使ってすごく良くなるというわけでもないので、あえてやることもないんじゃないのとも思う。
少なくとも最初は選択肢から外すなぁ。
2020/03/02(月) 13:35:46.29ID:kyrXnWYL
本人わかってんだからそんな必死になって噛み付くようなことでもないだろ
だいたいプラットフォーム全く限定せずにC++でソフトが書けるのかと

>>411
>たぶんコンパイルエラーにも警告にもなることなく黙って未定義動作に突入する。
アホか
普段警告レベル下げてるから気付かねーんだよ
2020/03/02(月) 15:19:49.70ID:AN3bmLPv
v
2020/03/02(月) 15:20:44.34ID:AN3bmLPv
(↑のv はミスしました)
>>409 >>411
実は、union より、>>395 のように単純に書いたほうが良い。
unionの場合は、最初に代入によるコピー動作が入るが、>>395 は、単に 64bit 整数の入っている変数のアドレスを取得しているだけだから、全くコピー動作が入らず、物凄く効率が良いし、未定義動作でもない。
>>395 が未定義動作というなら、Cの根幹が揺るぐ。
2020/03/02(月) 15:23:49.36ID:AN3bmLPv
>>409
little endian と big endian の違いだけで全面的にUBということではないはず。
unionの仕様からいえば、ちゃんと 64BIT 整数をそのままイメージとして投影したものがバイト配列になって取得できるはず。
それがunionの定義なのだから。
sizeof(union型)とsizeof(unionのメンバ)の関係も定義されているので、それ以外の実装は有り得ないはず。
2020/03/02(月) 15:28:47.95ID:LGtCkZFK
>>415
お前は人のレスよく読め
cの話はしてないんだよ
2020/03/02(月) 15:43:11.75ID:x4CDu4GY
private/protectedで隠されているわけでもないPODの
ビット表現に依存するなってのは理に適わない
規格が保証しないなら自己責任というだけの話
そんなんどこにでもいくらでもある
418デフォルトの名無しさん
垢版 |
2020/03/02(月) 16:18:13.98ID:x4CDu4GY
test
2020/03/02(月) 16:23:29.71ID:AN3bmLPv
>>416
>>396 で言えば、m_u64, m_b メンバの先頭アドレスがどちらも offset 0 から始まっている限り、little endian と big endian の違いを除いては、どんな処理系でも、m_64 のメモリ中での表現がそのままバイト配列 m_b[] に投影されて読み出せる。
それがunionの定義。
メンバがすべて「offset 0」に配置されるかは、アラインだけの問題。
2020/03/02(月) 16:39:58.55ID:4ZdkwDZZ
>>415
規格では全面的に UB だよ。
C++11 の 9.5 を確認してみたんだけど、
共用体で保証されているのは

- 直近で入れたのと同じメンバで取りだす場合
- 先頭部分に共通する型を持つ標準レイアウトの型をメンバとして持つ共用体であれば共通部分を使うのはアリ (← 言い回しがややこしくてスマン)

ってことだけで、あくまでも先頭に適合する型が連続する部分に限って許してる。
そんでもってこれは規格の書き方はちょっと違うだけで C でも同じだわ。
2020/03/02(月) 16:44:13.99ID:LGtCkZFK
>>419
自称天才さんですらUBであることは認めてんのにお前ときたらw
まぁ後は好きにどうぞ
422デフォルトの名無しさん
垢版 |
2020/03/02(月) 16:57:58.17ID:N0Zwryo+
コンピュータはチューリングマシンではない!!!

理由 ---- timeGetTime();

マザボの時計は計算不可能的だ、時計を計算できる「アルゴリズム」は存在しない

理由2 multi-thread チューリングマシンはシングルスレッド的だ
理由3 multi-process シングルスレッドで並列計算を真似る
―― つまり、チューリングマシンなる理論自体はそもそも間違っている!
なぜなら単一のチューリングマシンは並列計算を真似ることができる
つまり、チューリングマシン自体は矛盾している!
(たとえば p->Update(); q->Update(); これはシングルスレッドのコードだ、
つまり、単一のチューリングマシンだ、しかし実行時の効果は並列的だ!)
2020/03/02(月) 17:05:20.01ID:x4CDu4GY
char配列とunionにしてバイトアクセスなんて
みんな自己責任でやってるに決まってるだろうが

そこへ、その案件の関係者でない者が頼まれもしないのにしゃしゃり出て
「UBだ」とキリるのが格好いいと思っているのはそいつ自身だけだ
2020/03/02(月) 17:40:48.54ID:/apuYuUB
>>423
分かってる奴が自己責任でやってるだけなら誰も止めないよ。
今回の場合、初心者の質問(>>389)に対し自称上級者がunionを使う方法(>>396)を提示したから、それはUBだと突っ込まれたんだろ。
別にUBを指摘することがカッコ良い訳ではないけど、指摘されて真っ赤になることはカッコ悪いぞw
2020/03/02(月) 17:44:58.26ID:x4CDu4GY
ああ、=にしたいわけね
いいよ別に
こっちも証明できねえし

ただ、おまえさんのアドバイスは俺の胸には全く響いていない
その事実が変わらん限り痛くも痒くもない
2020/03/02(月) 17:45:42.25ID:AN3bmLPv
>>420
しかし、メンバのアラインの問題さえクリアしていれば、union中の2つのメンバの
offset address は 共に0になる。
そして、以下の通りなので、メモリ中の同じアドレスから読み書きすることになるので、C++の仕様に明示されていなくても、m_b[k] の動作は単純に、m_u64のメモリ中のイメージをそのまま先頭から読み書きすることになる。
なので、問題が起きるとすれば m_u64 と m_b のアラインの問題のみだ。
もし、アラインが合わなかった場合には、m_b[k] が k == 0 でも、m_u64 の途中のアドレスから読み出すことになったりする事になる。
しかし、この様な場合に m_u64 と m_b のアラインが合わない処理系は多分、珍しい。

union UUU {
  uint64_t m_u64;
  BYTE   m_b[8];
};
UUU xx;

xx.m_u64 // もうこの段階で、コンパイラ内部では m_u64 が元々 union のメンバであったという情報は消えることになることが C/C++ の仕様では保障されている。。
xx.m_b[k] // もうこの段階で、コンパイラ内部では m_b が元々 union のメンバであったという情報は消えることになることが C/C++ の仕様では保障されている。。
2020/03/02(月) 17:47:34.63ID:LGtCkZFK
>>423
自己責任とかじゃねーっての
cでは合法的なtype punning
お前strict aliasing理解してるか?
2020/03/02(月) 17:53:08.73ID:vdXXyaaZ
やっぱりUBの怖さ全然わかってない子か
おっしゃる通りオフセットのアドレスはたまたま一緒かもしれないし、規格を読み解けば論理的にそうなるべきであることは導けるのかもしれない
だけどそれが何だというのか?
そのオフセット値から読み取ってくれることや、そもそも読み取り動作をしてくれるとどうして言い切れる?
未定義動作ではコンパイラが何をするのも何をしないのも完全に自由だということをお忘れなく
2020/03/02(月) 17:53:41.95ID:AN3bmLPv
https://stackoverflow.com/questions/25664848/unions-and-type-punning

4. THE SAFE CASE: unsigned char

The only safe manner of using type punning is with unsigned char or well unsigned char arrays (because we know that members of array objects are strictly contiguous and there is not any padding bytes when their size is computed with sizeof()).

 union {
   TYPE data;
   unsigned char type_punning[sizeof(TYPE)];
 } xx; 
Since we know that unsigned char is represented in strict binary form, without padding bits, the type punning can be used here to take a look to the binary represention of the member data.
This tool can be used to analyze how values of a given type are represented, in a particular implementation.

I am not able to see another safe and useful application of type punning under the standard specifications.
2020/03/02(月) 17:55:17.52ID:x4CDu4GY
>>427
いーや自己責任だ
おまえさんが知らないだけ

どの案件の関係者でもなさそうだな
2020/03/02(月) 17:56:57.42ID:vdXXyaaZ
>>429
その回答の下に「Cだけだろ」ってツッコミ入ってるだろ
このあわてんぼうさんめ
2020/03/02(月) 18:18:40.49ID:LGtCkZFK
>>430
何を根拠もなく断言しとんねんこの老害
cppreferenceはっとく
これ基本的に規格に書かれてる文と同じだ
かつこれはcにしか書かれてない
c++のは下にリンクあるから読んどけ

ttps://ja.cppreference.com/w/c/language/union
共用体の内容をアクセスするために使用されるメンバが、値を格納するために最後に使用されたメンバと同じでない場合は、格納された値のオブジェクト表現が新しい型のオブジェクト表現として再解釈されます (型のパンニングと言います)。
2020/03/02(月) 18:26:04.80ID:4ZdkwDZZ
>>426
メモリのレイアウトの話だけならそれ以外の選択肢は実質的にないだろってのはわかるよ。
そりゃそうだ。
実質的にそうだってのは今さら言わなくても知ってる。

いまどきの C++ コンパイラは未定義の挙動はどうなってもいいことを前提にした最適化をすることがあるんだよ……。
去年には LLVM が const 変数への代入を削除するってのでニュースになっただろ。
https://developers.srad.jp/story/19/09/27/1626210/
const 変数は変更されない。 それが前提なんだから変更されても知らんってわけ。

今まで緩く対応してたのが厳しくなることだってある。
共用体が使われる場面ってのはメモリのレイアウトを利用したい場合ってのは多いから
現実には急に挙動を変えるなんてことはないと思うけど、
未定義を警戒するのは最適化に対する警戒なんだよ。
2020/03/02(月) 18:29:44.89ID:EH9ZG6fb
このスレみててなんとなく餃子くいたくなったからスーパーいったけど
売りきれてたわ
2020/03/02(月) 18:33:24.10ID:AN3bmLPv
>>432
次も非常に重要:
「共用体へのポインタは、そのいずれのメンバへのポインタにもキャストできます (共用体がビットフィールドを持つ場合は、共用体へのポインタはそのビットフィールドのベースとなる型へのポインタにキャストできます)。
同様に、共用体のいずれのメンバへのポインタも、囲っている共用体へのポインタにキャストできます。」

これは、union においては、全てのメンバの先頭アドレスが、すべてoffset 0から始まることが保障されていることを意味する。

なので、>>426のアラインの心配はない事になる。
2020/03/02(月) 18:34:36.46ID:AN3bmLPv
>>435
もとい。良く考えてみるとそうでもなかった。
unionへ、または、unionから cast する際にコンパイラが何らかの offset 値を足したり引いたりする可能性があるため。
2020/03/02(月) 18:52:26.82ID:x4CDu4GY
>>432
もう一度言う
どの案件の関係者でもなさそうだな
2020/03/02(月) 19:05:25.24ID:4ZdkwDZZ
>>437
おっ。 立場を持ち出すのか?
理屈では反論する余地がないという意味?
2020/03/02(月) 19:19:56.44ID:x4CDu4GY
お? =ってことでいいのか?
ID変えるとか超しょーもねーねらーだなw
2020/03/02(月) 19:29:50.21ID:4ZdkwDZZ
>>439
俺は煽ってるだけだよ。
2020/03/02(月) 19:31:34.34ID:AN3bmLPv
>>433
「const 変数を cast してから代入する」というのはそもそも元々禁止事項だから、今回の話とはかなり違う。
2020/03/02(月) 19:35:17.26ID:4ZdkwDZZ
>>441
禁止と未定義の間に差があるという誤解?
2020/03/02(月) 19:39:18.04ID:ael5BwwH
>>407, >>438
こいつらすごい嬉しそう
こういうのでしか偉そうに出来ないんだろうなぁ
2020/03/02(月) 19:39:59.11ID:AN3bmLPv
>>445
>>442 には、以下の用になっている:
// at this point, reading from n or c is UB but most compilers define it
  std::cout << "s.c is now " << +s.c << '\n' // 11 or 00, depending on platform
       << "s.n is now " << s.n << '\n'; // 12340011 or 00115678

「 11 or 00, depending on platform」
「12340011 or 00115678」

数学的に
A or B
ということは、A または Bに限られると言うことで、それ以外の可能性がないことである。
2020/03/02(月) 19:53:14.29ID:ael5BwwH
いや、さすがにそれは「大抵のコンパイラはどちらかに定義する」だから
そうじゃないのも有り得る

ただそんな変な環境まで想定するのも非現実的だし
それを言うなら1byte=8bitsとも限らないんで、そんな環境だとuint8_tもおそらく定義されておらず
はちみつがドヤ顔で自称汎用的だと挙げた>>398も使えないわけだが
2020/03/02(月) 19:58:23.59ID:4ZdkwDZZ
>>444
それだったら UB という語を使うのがおかしいよ。
C++ (の仕様) 的には UB ってのは正しいプログラムには存在してはいけないものだ。
どちらになるのか不定という意味では普通は使わない。

11 or 00 は most compilers define it に対応してるとも解釈するのが自然だと思うよ。

>>445
せやな。
そこを言うと汎用的とは言えないな。
unsigned char で定義した方が確実だったか……。
2020/03/02(月) 20:14:13.91ID:4ZdkwDZZ
C++20 では負数は2の補数形式で定義されることになったみたい。
C++ の最新規格に追従しているコンパイラは全部 2 の補数を前提にしてたからもう 1 の補数はええやろみたいな話を聞いた。

そこまで決めるのになんで1バイトの大きさは明記しないんだろ。
1 バイトが 8 ビットじゃないアーキテクチャ (で主要 C++ コンパイラがサポートしている環境) が有るんかね?
2020/03/02(月) 20:17:54.52ID:4ZdkwDZZ
>>445
十分に汎用的とは言えないけど使えないときはコンパイルエラーになるだろうから比較的マシということで勘弁。
2020/03/02(月) 20:24:42.94ID:x4CDu4GY
>>440
超しょーもねーねらー認めやがったw
2020/03/02(月) 20:26:39.31ID:LGtCkZFK
>>447
signedのwrap aroundは定義された?
2020/03/02(月) 20:37:53.23ID:4ZdkwDZZ
>>449
ID 変えとかはしてないからね。
いまどき匿名プロキシとかあんまりないし。
俺がトリップを付けないのはつまらない質問するときだけ!
(つまらないこと聞くの恥ずかしいじゃん……///)
2020/03/02(月) 20:40:00.58ID:x4CDu4GY
>>451
人のことを=っといて虫のいいことを言うな
人間としてどうなのか疑っちまうぜ
2020/03/02(月) 20:41:39.08ID:LGtCkZFK
敗走したのにもどってくんなよ
2020/03/02(月) 20:45:07.72ID:4ZdkwDZZ
>>450
されてない。 それは従来通り。
何故なのか……。
2020/03/02(月) 21:47:32.89ID:j/GXcJfE
【ソフト名】リソーエディタ
【URL】https://github.com/katahiromz/RisohEditor
【説明】リソースデータを編集できるソフト。

これ、VS2012でビルドしたら、バイナリサイズが10MB超えてるだけど、なんとか6MB以内に縮小できないだろうか?

インラインとか関係ある?
2020/03/02(月) 22:01:25.31ID:4ZdkwDZZ
>>455
デバッグ情報は取り除いてそのサイズ?
サイズだけが重要なら UPX とか使えばいいんでね。
2020/03/02(月) 22:10:19.07ID:JxKPpJ6p
>>456
うん。zip圧縮したサイズがだいたい10MB。UPXも試したけど圧縮後のサイズには効果が薄いみたい。インライン関数がデカいのがまずいのかな?
2020/03/02(月) 22:31:49.40ID:TcdIMkwU
>>457
サイズ優先の最適化オプション試してみたら
2020/03/02(月) 23:45:22.71ID:4PGofnEL
そもそも >>398 って、割り算と剰余まで使っていて、実用的なコードとは
言いがたい。
せめて、x >>=8 と x & 255 ならまだましだが、そもそも >>395
で十分なのに、敢えて複雑にして、逆にバグが入る可能性も高い。
それと、厳密に言えば、誰かも指摘したように unsigned char が 8bit かどうか
も C や C++ の仕様としては決まってないようだし。
2020/03/02(月) 23:53:18.90ID:4PGofnEL
>>398
それはバイトの概念を直接扱えないような言語でも使えると言えば使えるかもしれないが、敢えてそんなコードを書く必要はない。
「高級アセンブラ」の名が無く。

自分が知らない処理系に誰かがコンパイルすることを想定していて不安が残る場合には、どこかに
テストコードを書いておけばいい。例えば、次のようにする:
uint32_t a = 0x11223344;
uint8_t *ptr = (uint8_t *)&a;
if ( ptr[0] == 0x44 && ptr[1] == 0x33 && ptr[2] == 0x22 && ptr[3] == 0x11 ) {
 // リトルエンディアン
}
else if ( ptr[0] == 0x11 && ptr[1] == 0x22 && ptr[2] == 0x33 && ptr[3] == 0x44 ) {
  // ビッグエンディアン
}
else {
 // エラー
}
2020/03/03(火) 00:10:54.51ID:alJFGTdC
ちなみにC++20からエンディアンも標準に入る

https://cpprefjp.github.io/reference/bit/endian.html

使えるかは知らない...
2020/03/03(火) 01:43:26.11ID:vE1VkH8+
CではOK、C++ではUB
C/C++コンパイラではたまたま動く場合が多いかもしれないけど、UBはUBなんだし回避方法もあるんだからやめとこう
ただこれだけの話なんだけど

何が気に食わないのか「わかりやすいんだ!汎用的なんだ!Cらしいんだ!俺のコンパイラでは動くんだ!この程度のテクニックも知らんのか!」
ってノリでナイーブにUB書きたがる奴が絶えないのはなんでだろうね
一度でもそういうのが引き起こす地獄みたいなバグに付き合わされたら二度とそんなことしないしさせないって思うもんなんだけどね
幸運にも遭遇したことがないのか、全部他人に解決してもらってるいい身分の人なのか
2020/03/03(火) 02:22:47.77ID:V4J60F8x
> やめとこう

何の権利で指図するんだよ
2020/03/03(火) 02:40:53.66ID:vE1VkH8+
「そんなにお酒飲み過ぎると健康に悪いよ、やめとこう?」
「一生酒を飲むなと命令するのか!何の権利で指図するんだ!」

おおめんどくさい
ただのアドバイスを命令や強要や脅迫に感じるのは鬱の初期症状だから気を付けなよ
2020/03/03(火) 03:15:03.15ID:V4J60F8x
お節介なやつは人からそう見られてるんだよ
2020/03/03(火) 03:39:42.34ID:vE1VkH8+
お節介じゃないよ
俺の関係者がここを見てここのバカに勇気付けられてUB書き散らかすようになると俺が困るから言ってるんだよ
俺のためだ
2020/03/03(火) 03:54:38.06ID:V4J60F8x
逆もしかりだ
チームに入ったばかりの新入りが「UBだ! UBだ!」と喚きだし
「おまえならどうする?」に答えられないゴミには諦めてもらうしかない
どうせunion使わないためにポインタのキャストとかだろくっだらねえ
2020/03/03(火) 04:29:39.93ID:vE1VkH8+
新入りに危険な書き方を指摘されたら「くっだらねえ」と逆ギレした上に
チームで規格を当たって検討もせずに新入りに解決策を丸投げするのか
最低だなお前
2020/03/03(火) 05:43:51.35ID:WsWEE8rZ
>>459-460
まともなコンパイラはビット演算に置き換える最適化が入ることが期待できるんだから、
割り算が実用的でないなんてことはないよ。
エンディアンの影響を避けるには良い選択のひとつだ。
2020/03/03(火) 06:03:20.43ID:WsWEE8rZ
ガチで組み込み環境のシビアなやつだとバイナリのテストの方に時間をかけたりするから
逆に言語に無頓着になる場合があるというのは聞いたことは有る。

1998 年頃の自動車制御とか携帯電話とかの話なんで、
コンパイラの規格準拠具合もそれほどあてにできなかった時代の話だけど。
2020/03/03(火) 06:14:57.83ID:jgFG2YH5
数年前に触ったdspは1byte32bitだったなー
2020/03/03(火) 06:36:20.05ID:WsWEE8rZ
>>455
実行ファイル本体はさほど大きくないじゃん。
一番大きいのは cc1.exe か……。
これって必要?
2020/03/03(火) 06:43:09.65ID:0/2hhSYY
>>468
例えばmemcpyの各プラットフォームごとに向けた最適化(の元のソース)はお前がここで言うようなUBだらけだろうし
boostなんかも各プラットフォーム向けに分けて書かれてる部分が多い
そこまでUBを避けてどんなプラットフォームでも動くように、なんてのもYAGNIの一種だと思うけどね
2020/03/03(火) 06:46:29.83ID:AJx5UoX4
>>470
ガチな組込みって言うか普通の企業なら開発環境も決め打ちで作ってテストする
2020/03/03(火) 06:53:54.29ID:AJx5UoX4
>>445 > それを言うなら1byte=8bitsとも限らないんで
>>447 > 1 バイトが 8 ビットじゃないアーキテクチャ (で主要 C++ コンパイラがサポートしている環境) が有るんかね?
>>471 > 数年前に触ったdspは1byte32bitだったなー

1byteは8bitと決まってるんですけど…
2020/03/03(火) 07:14:47.35ID:WkxUfZWu
え?
2020/03/03(火) 07:16:59.86ID:KvGr1Z90
なぜuint8_tを使わないの??、、
2020/03/03(火) 07:19:47.74ID:uPsaHRM9
>>475
え?
2020/03/03(火) 07:30:20.60ID:0/2hhSYY
2008年に一応はっきり決まったらしいね
ただしC++ではそうと決めてはいないので一応UB
2020/03/03(火) 07:33:02.45ID:2njekV5l
>>473
たぶん根本的なところで他人の発言が理解できてない
言いたいことはわかるけど、もはや議論になってないから黙ってろ
2020/03/03(火) 07:36:41.10ID:WsWEE8rZ
>>473
各プラットフォームに「対応」できてるなら別にいいんじゃね。
union の未定義がどうこう言ってるのは >>365 程度のことに
あえて各プラットフォームの事情を持ち込むのは割に合わない (そのくらい UB の厄介さには重みがある)
って話題だと俺は理解してる。

ターゲットが完全に固定されてたとしてもコンパイラが吐くコードを把握する自信は俺はないし
たぶん >>468 もないし、 >>473 だって出来れば避けて通りたくない?
その上でどうしてもいじらないといけないくらい速度に厳しい場面とかだったら嫌々やるかもしれないけど、
最初からはやらないって程度の話。 早すぎる最適化は諸悪の根源っていうし。
2020/03/03(火) 07:38:19.27ID:WsWEE8rZ
>>475
少なくとも C/C++ では決まってない。

>>477
対応する大きさの型の別名として定義される。
その大きさの型が存在しない場合は定義されるべきではないことになっている。
無ければコンパイルエラーになるだけなんで本当に 8bit キッカリであることが大切なら
uint8_t を使うべきだけれど、「1 バイト」という意味で uint8_t を使っちゃうと C++ の仕様に厳密な意味では
十分に汎用的であるとは言い難い。

ま、そんな環境はあんまりないんだけど組み込み環境だとたまにあるっぽい。

>>479
UB ではなく処理系定義というべき
2020/03/03(火) 07:45:28.78ID:0/2hhSYY
>>480-481
あのさ、一応UBってことはすぐ指摘されて本人もわかってんだよ、質問者もとっくに見てるはず
>>407辺りから意味無くマウント取るような言い方する奴(はちみつ含む)が出たから荒れてんだろ
そこまで言うなら今現在存在する環境でunionによるtype punningが出来ない環境を挙げてみろ
おそらくどこかにはあるんだろうが、1byte=8bitでない環境はすでに挙げられてるのにunionの方は全く例が出て来ない
>>480
理解出来てないのはお前だ
2020/03/03(火) 07:47:02.82ID:AJx5UoX4
>>482
> 少なくとも C/C++ では決まってない。
決まっていないという根拠よろしく
2020/03/03(火) 07:50:44.52ID:0/2hhSYY
>>484
自分で調べろ
2020/03/03(火) 08:03:53.36ID:NOkKAnZ5
>>483
UBだってことは分かってる、ぼくは>>407でカチンときて怒ってるだけだ、ってことだろ。もうただの口喧嘩でこれ以上何も議論することは無いんだからさっさと終わりにしなよ。
2020/03/03(火) 08:07:38.96ID:0/2hhSYY
お前もたいがい煽ってると思うが

>終わりにしなよ
俺に言うなよ
2020/03/03(火) 08:22:51.66ID:AJx5UoX4
>>485
傍から低能丸出しのレスかよ…
何を馬鹿にしてるのかもわかってないだろw
2020/03/03(火) 08:23:01.86ID:Pp/8GnxB
>>483
> そこまで言うなら今現在存在する環境でunionによるtype punningが出来ない環境を挙げてみろ

↓こういう例は把握してるの? >>405 みたいな理解だとこんなコードもエイリアス有効という話になっちゃいそうで危ないと思う。
https://wandbox.org/permlink/qrUVwDZbNPRnOQyN

#include <stdio.h>
#include <stdint.h>
int f(uint16_t* u16, uint32_t* u32) { *u16 = 0x1111; *u32 = 0x22222222; return *u16 + *u32; }
union U { uint16_t u16; uint32_t u32; };
int main() { union U u; printf("%08x\n", f(&u.u16, &u.u32)); }

出力 (gcc 9.2.0 -O2):
22223333
2020/03/03(火) 08:31:00.08ID:WsWEE8rZ
>>483
実際に有るか無いかなんて知らんよ。
俺は検証するのが割に合わんから可能なら避けるし、 >>365 程度のことに「あえて」使いたいという気持ちはわからんと言ってる。

俺は何がなんでも UB は絶対にダメなんてことは書いてないし、十分に検証できてるものにまで文句は付けんよ。
2020/03/03(火) 08:45:51.11ID:WsWEE8rZ
>>484
- std::uint8_t は cstdint にある。 (C++17 の 21.4.1)
- cstdint は C 標準ライブラリヘッダの stdint.h と同じように全ての型とマクロを定義する (同上)
- C++17 が参照する C の規格とは C11 (ISO/IEC 9899:2011) である (C++17 の 2)
- uintN_t はオプショナルだが 8, 16, 32, 64 については対応する型が存在するなら提供しなければならない (C11 の 7.20.1.1)
- char が 8bit ならば C++ には uint8_t は必ず存在するはずだがオプショナルであると言ってるから 8bit の型がない (char が 8bit ではない) ことは想定内なんだろう

というのが根拠。
2020/03/03(火) 08:49:11.40ID:87wKGSsV
いわゆる「悪魔の証明」ですか。
2020/03/03(火) 08:50:30.01ID:0/2hhSYY
>>489
strict aliasing rulesに対する違反にまで話広げてるんだろうけど
さすがにそこまで擁護する気は無いし自己責任じゃないの
そこまで悪質なコードになると話違ってくる

>>490
いやいや、一般的な環境で>>396みたいなのは検証するまでもないから
だいたい昔は未定義だったのが最近の仕様で変わったのもあるだろ
2020/03/03(火) 09:13:15.69ID:WsWEE8rZ
>>493
検証するまでもないという確信を持てる程度に (その現場か個人の経験として) 実績があるってことでしょ。
本当に何もないところで確信を持ってるんだったらそれはそれで駄目だと思う。
2020/03/03(火) 10:05:21.19ID:dPHWJmki
>>467
> どうせunion使わないためにポインタのキャストとかだろくっだらねえ

アウト
なぜunion使うかの前提すら理解してない
2020/03/03(火) 10:41:55.49ID:Zi2Vm8jS
>>472
必要ないファイルを削ったら3MBになった。ありがとう。
2020/03/03(火) 10:43:38.18ID:0/2hhSYY
ちなみに>>489の例はunionじゃなくて同じ変数を指すポインタ渡しても同じことになるからね
2020/03/03(火) 11:04:57.92ID:4ZFJ43jO
>>483
> そこまで言うなら今現在存在する環境でunionによるtype punningが出来ない環境を挙げてみろ

今時点では知らないしないだろうな
でも今後もそうなのかはわからない

1byteの定義なんかは処理系がターゲットcpuごとに決めるもの
エンディアンとかも
これは問題視されない

unionに関しては、そういう類いではないだろう
理由は把握してないけど、非podの場合を含めて意味論が決められない、
あるいはaliasingに関係して明確に使うなということなのかもしれない

あえてcと非互換にしているわけで、グレーであることは知っておくべき

ちなみに20からpodという文言が消えると聞いた
さらにcとの乖離が進むのかもしれない
2020/03/03(火) 12:22:06.47ID:AJx5UoX4
>>491
で、そのどこにバイトの話があるんだ?
2020/03/03(火) 12:36:13.65ID:4ZFJ43jO
CHAR_BITS の定義でしょ
自分で確認しろ
2020/03/03(火) 12:40:22.22ID:ctFzSosi
POD=trivial&&standard-layout
ってC++11の時に整理済みでしょ
概念は消えないよ
2020/03/03(火) 12:52:22.33ID:GzyUVdF6
>>489
それはgccのバグに思える。
2020/03/03(火) 12:59:47.46ID:0/2hhSYY
バグじゃないぞ
これがバグだったら最適化にかなりの制限がかかってしまう
strict aliasing ruleでググれ
2020/03/03(火) 13:01:57.30ID:GzyUVdF6
>>503
最適化しない場合とした場合とで結果が変わってくるのは駄目な最適化。
2020/03/03(火) 13:04:15.59ID:0/2hhSYY
だからググれって
鬼の首を取ったかのように叩く奴が出てくる前に教えてやってんのにw
2020/03/03(火) 13:05:53.55ID:WsWEE8rZ
>>499
肝心なことが漏れてた。 すまぬ。

C++17 だと 4.4 の脚注に

> The number of bits in a byte is reported by the macro CHAR_BIT in the header <climits>

とあって、バイトとは char の大きさのことだというのが C++ での考え方だと思っていい。

C11 だと 5.2.4.2.1 の CHAR_BIT の説明のところに

> Their implementation-defined values shall be equal or greater in agnitude
> (absolute value) to those shown, with the same sign.
>
> - number of bits for smallest object that is not a bit-field (byte)
> CHAR_BIT 8

という言い回しがあって、 CHAR_BIT は 8 以上であればいい (8 キッカリとは限らない) と解釈できる。
それと、ポインタを持てる単位がバイトだということが示唆されているとも言える。
2020/03/03(火) 13:08:55.41ID:GzyUVdF6
>>491
charのbit数は決まってないが、バイトはコンピュータ用語として8バイトと決まっているはず。
2020/03/03(火) 13:10:50.46ID:GzyUVdF6
>>506
多分、
「The number of bits in a byte is reported by the macro CHAR_BIT in the header <climits>」
は、書き間違いで、正しくは、
The number of bits in a char is reported by the macro CHAR_BIT in the header <climits>
だと思われる。
2020/03/03(火) 13:17:56.62ID:GzyUVdF6
>>507
そうか、歴史的には、byteが7bitだったこともあったんだね。
2020/03/03(火) 13:32:49.23ID:WsWEE8rZ
>>507
これな。
https://ja.wikipedia.org/wiki/IEC_80000-13
C++ が参照規格として示してないので採用してないんでしょ。

まあそんなこと言ったら英単語の意味だってどうとでもとりようがあったりするからアレだけど、
あらためて C++ の規格の中でバイトについて書いてある以上は C++ 世界では
「コンピュータ用語としてのバイト」を採用してないと解釈するのが自然。

将来的には変更されることもあるかもしれんけども。

>>508
C++20 のドラフトでもそのままなので本気で間違ってると思うなら指摘してあげればいいんじゃね?

>>509
9bit のマシンもあったらしいよ。
https://ja.wikipedia.org/wiki/ACOS-6
2020/03/03(火) 13:48:53.72ID:4ZFJ43jO
>>501
概念消えるとは言ってないけど
今回文言消す理由ってなんなの?
何も知らずに口挟むとは思えないから質問させてくれ
2020/03/03(火) 14:19:12.58ID:WsWEE8rZ
>>511
もう POD という区分が適切な場面はあんまりないから、という意味のことが書いてあるっぽい。
https://botondballo.wordpress.com/2017/11/20/trip-report-c-standards-meeting-in-albuquerque-november-2017/
2020/03/03(火) 14:41:53.95ID:ctFzSosi
trivialは生成解体の話で、standard-layoutはデータ配置の話だから
PODってのはレイヤーの違う性質が混ざってて規格に使う用語としては筋悪なんですわ
2020/03/03(火) 16:26:35.30ID:GzyUVdF6
>>510
>C++20 のドラフトでもそのままなので本気で間違ってると思うなら指摘してあげればいいんじゃね?
annotated C++ reference manual, 3.2.1c Integral Limits には、
CHAR_BIT   8  maximum bits in a byte
とあった。
2020/03/03(火) 16:39:36.38ID:GzyUVdF6
>>514
ANSI/ISO, Standard C プログラマーズ リファレンス
P.J. Plauger / Jim Brodie, 日本語訳, ASCII

第一部 第一章 基本整数型 には、
--------------------------------------------------------
表記,     最小範囲,  表現における制限
--------------------------------------------------------
char,     [0,128),  signed char か unsigned char のどちらかと等しい。
signed char, (-128,128), 少なくとも 8bit 精度の符号付整数
unsigned char, [0, 256), signed charと同じサイズ。負の数は無い。
--------------------------------------------------------

第二部 第二章 標準ヘッダ <limit.h> には、
--------------------------------------------------------
CHAR_BIT
#define CHAR_BIT <#if 式 ≧ 8>
このマクロは、char 型のデータオブジェクトを表現するのに使われているビット数の最大値と置き換わる。
--------------------------------------------------------
とある。

後半は >>514 とは異なり、byte ではなく、char となっている。
2020/03/03(火) 16:46:23.12ID:GzyUVdF6
type punning について、このスレで議論されていた union の場合は、「適合コード」の例とされている:

https://www.jpcert.or.jp/m/sc-rules/c-exp39-c.html

適合コード
以下のコード例では、オブジェクトの有効な型と互換性のある型を持つ union 型を使用している。

union {
short a[2];
int i;
} u;

u.a[0]=0x1111;
u.a[1]=0x1111;

u.i = 0x22222222;

printf("%x %x\n", u.a[0], u.a[1]);
このコード例では確実に "2222 2222" と出力される。
2020/03/03(火) 16:56:05.32ID:GzyUVdF6
union による type punning は、C99やC11では大丈夫になったのではないか。
最後に代入したメンバ以外のメンバからの読み出しは、合法になったようだが。
よく読んでないので分からん:

https://stackoverflow.com/questions/11639947/is-type-punning-through-a-union-unspecified-in-c99-and-has-it-become-specified
2020/03/03(火) 16:58:14.25ID:GzyUVdF6
>>517
Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one.
The rationale was that the behaviour would then depend on the representations of the values.
Since this point is often misunderstood, it might well be worth making it clear in the Standard.

[...]

To address the issue about "type punning", attach a new footnote 78a to the words "named member" in 6.5.2.3#3: 78a
If the member used to access the contents of a union object is not the same as the member last used to store a value in the object,
the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning").
This might be a trap representation.
2020/03/03(火) 20:10:58.79ID:6u3PFyGZ
>>515
日本語訳が間違ってる可能性もあるな
2020/03/03(火) 21:25:40.77ID:s8qGwiQH
>>514
頑なに仕様書読まないのはなぜなのか
2020/03/03(火) 22:12:33.33ID:WsWEE8rZ
>>520
仕様書が間違ってると思ってる (>>508) からじゃね。
2020/03/04(水) 00:45:53.15ID:And/nx/1
C++は間違っているからな
間違いで間違いを正すことはできな
2020/03/04(水) 01:36:12.37ID:tHLmVZnX
>>515 も仕様書だと思うのだが。
2020/03/04(水) 08:18:37.27ID:wOgWtFGu
それに基づいて作られた製品があればの話だな
2020/03/04(水) 09:01:59.59ID:obnoKtcJ
まあc++の仕様を完全に守ってる実装なんて一つもないしな。
それ確かめるのに工数かかるってどうなん?とは思う。
2020/03/04(水) 09:56:46.98ID:0Mjry1zX
>>523
それは解説書
2020/03/04(水) 10:55:23.42ID:wOgWtFGu
仕様を説明していても仕様書かどうかとは別な話だな
2020/03/04(水) 12:41:56.62ID:tHLmVZnX
>>526
実際には、あれは普通の解説書ではなく、コンパイラを実装する人が重宝するようなバッカス記法や決定性オートマトンなどを使って仕様がかなり厳密に書かれた特殊な本。
2020/03/04(水) 13:50:02.87ID:BrIasXcf
>>515
古い C では違ったのかもしれないと思って
念のために C89 も確認してみたけどそのときから >>506 と同じ文言になってるぞ。
C (の公式な仕様) では最初からバイトとは char の大きさのことと結論していい。

K&R 第二版の日本語訳の付録Bだとバイトとは書いていない。
あくまでも要約だから省略したのかもしれないし、
前書きには「予備版 (ドラフトのこと?) が出ていたので早く出せた」という意味のことが書いてあるので、
仕様の決定稿が出る前の一時期にはバイトとは記述してなかった (それを元に本にした) 可能性はあるのかもね。
2020/03/04(水) 13:54:01.41ID:BrIasXcf
C/C++ の仕様が信用ならんなと思うのは欠陥報告 (Defect Report) の存在だな。
仕様書に書いてないことの確認がとれていても仕様にないとは言い切れない。
把握できるわけないだろ!
2020/03/04(水) 14:10:16.09ID:wOgWtFGu
公文書だかんな
はい発表しましたよ、周知義務よろしく

こういう体質なのは今さら驚いても始まらん
2020/03/04(水) 14:57:19.24ID:BrIasXcf
公文書なら著作権法による保護が及ばないのでそれはそれで利点があるんだけどな。

実際には ISO は民間組織だし、正式な規格票はクソ高価すぎる。
私はドラフトと cpprefjp しか見てないんだけど、買った人いる?
2020/03/04(水) 16:25:27.01ID:tHLmVZnX
VS2019 の limits.h のコメントはこうなっている :
#define CHAR_BIT 8 // number of bits in a char
2020/03/04(水) 16:43:02.53ID:BrIasXcf
そうか。
2020/03/04(水) 16:43:03.91ID:CqUkRGBA
VSの想定環境では正しいし何の問題もないな
2020/03/04(水) 16:58:40.94ID:tHLmVZnX
CHAR_BIT なのに本当に「number of bits in a byte」が厳密定義なら、何らかの説明が欲しい所ではある。

ただ、C言語では、charは言語が扱える整数の「最小単位(?)」などと書かれている文書を見たことがある。
だとすれば、Cに高級アセンブラの地位を期待する需要が有る以上、charのbit数がbyteと一致する必要は必ずあるとは思う。
総合的に考えれば、C言語においては、char=byte でなくてはならず、もはやbyteも絶対に8BITでなければならないので
char、byteがいずれも8bit
であることは事実上、必須である。
537デフォルトの名無しさん
垢版 |
2020/03/04(水) 17:05:12.53ID:tHLmVZnX
Wikipediaの「整数型」のところで、C言語では、何があろうとsizeof(char)は必ず1になると決められており、たとえ16BITワード単位のアーキテクチャでも、CHAR_BIT は 16になるが、sizeof(char)は必ず1になるのだそうだ。
一方、sizeof(X)は、Xの「バイト数」だとされているわけだけど、はっきりいってこんな状況では総合的に考えて、charを8BIT以外には出来ない。
2020/03/04(水) 17:14:44.63ID:BrIasXcf
>>536
Rationale の 6.5.3.4 に記述がある。
http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf

sizeof(char) は 1 を返す。
たとえこの単位が 36bit 幅であっても。
C 用語の「バイト」はストレージの最小単位であることを意味する。
2020/03/04(水) 17:16:32.37ID:tHLmVZnX
>>536
>C言語では、charは言語が扱える整数の「最小単位(?)」
は、>>506 の以下の部分にも書いてあるようだ。
CHAR_BIT とは、
「bit-field以外で最小のオブジェクトのbit数(byte)」
だと:

>C11 だと 5.2.4.2.1 の CHAR_BIT の説明のところに
>> - number of bits for smallest object that is not a bit-field (byte)
2020/03/04(水) 17:18:06.36ID:BrIasXcf
ポインタを作れる単位を最小単位にするのは理に適ってるんじゃないの。
2020/03/04(水) 17:20:06.24ID:tHLmVZnX
「bit-field以外のオブジェクトの最小単位」
なわけだから、ポインタが指しうるアドレスの最小単位でもあるわけだ。
言葉が変かも知れないが。
2020/03/04(水) 17:35:08.28ID:obnoKtcJ
気にするような環境にない奴に限ってこういうこと気にするのな。
2020/03/04(水) 17:39:54.09ID:tHLmVZnX
個人的には、ソース配布してダウンロードした人が各自勝手にコンパイルするようにするようなプログラムを書いたことが無い。
必ずバイナリレベルでテストして十分デバッグ済みだと思ってからバイナリを配布してきたから。
ソース配布文化は別世界。
2020/03/04(水) 18:59:40.00ID:Py0/41jA
だから何だ
結局何が言いたいんだ
規格が間違ってるって言うならISOのWGに意見書出せよ
情報は歓迎だぞ
2020/03/04(水) 20:23:54.51ID:3yz+4Wbb
>>537
byteは16bitになる可能性を自分で示しているじゃないか。
一体何と矛盾してるんだ?
2020/03/04(水) 20:40:21.43ID:+mh63BBw
まず一生触ることのない環境のことはどうでもいい
2020/03/04(水) 20:47:19.33ID:wOgWtFGu
お、江添きたか
2020/03/04(水) 21:36:25.82ID:9NgWGcWV
>>536
C,C++ はそれぞれずっと前から "byte" を独自定義していて、 2008 年発行の IEC 80000-13 の定義は関係ないんだよ。
(・・・って >507 に書いてあったわ。なんでまだこんなこと言ってるのこの人?)
2020/03/04(水) 22:55:14.08ID:InlLUMV0
byteが何者かわからんから、オクテットとか言う呼び方があるのだろう
2020/03/04(水) 22:56:33.25ID:wOgWtFGu
nibble != 4bits ということはあるのかね
2020/03/04(水) 23:02:36.78ID:BrIasXcf
>>550
どこかに正式な定義があるかはわからんけど、
Byte の語源は Bite (噛みつく) らしいし、
それよりは控えめってニュアンスは感じるよね。
2020/03/05(木) 08:23:20.57ID:Hv5fT+Tn
c++初心者です
実際現場でよく使われる関数はどんなものがありますか?
2020/03/05(木) 08:31:27.44ID:eBZoUINk
begin, end, operator ++, operator !=
2020/03/05(木) 08:48:57.01ID:maJEmc7K
>>553はSTLしか使ったことないアマチュアの発言
2020/03/05(木) 09:32:08.09ID:eBZoUINk
STLだと? 俺はrange-based-forを想定して書いたんだが、気が付かなかったのか?
2020/03/05(木) 09:35:26.73ID:oibZ2+F1
一緒だよ
557デフォルトの名無しさん
垢版 |
2020/03/05(木) 09:44:32.03ID:tzyiEzvg
c++11でregexの正規表現で\sと\Sがエラーになるけど、
全部自分で記述で[ \t\r\n]とかしないといけないですかね?
2020/03/05(木) 10:06:12.56ID:HyVcGvBE
>>552
関数セットとしては、やはり伝統的なCのものを使うことが多いんではなかろうか。
ソートや乱数、最大最小値計算、正規表現なんかはC++風のものが好まれる傾向が出始めてるかもしれない。
文字列の一致テストなども、個人的にはCのstrcmp()、_strcmpi()、strncmp()、memcmp() なども結構使ってるけど、若い人の間では std::string の比較機能が好まれているかもしれない。
というかC++から勉強した場合、それしか知らないだけかも知れないが。
文字列表示は、ネットではなぜか cout 系で、cout << "Hello"; のようなものを良くかけるが、
表示する際の16進数と10進数の区別や、表示桁数の指定、float/double値の有効数字桁数の指定、先頭に0を付けるかどうかなどを指定し易いので、古いと言われようが個人的には昔ながらのprintf()が好きだ。
559デフォルトの名無しさん
垢版 |
2020/03/05(木) 10:22:38.04ID:TYdcXopQ
マニピュレータを作ることが出来るのでストリームを使ってるだけでは。
560デフォルトの名無しさん
垢版 |
2020/03/05(木) 10:23:41.63ID:TYdcXopQ
若い子は馬鹿なのでストリームを好むキリッって風に見えるのだろか。
2020/03/05(木) 10:59:35.38ID:HyVcGvBE
C++の文字列比較で比較開始位置や最大長さを指定したい場合、
if ( str1.compare(0, 5, "abcdefghijklmn") == 0 )
のように書く必要があるが、Cのstrncmp()だと
if ( strncmp(pszText1, pszText2, 5) == 0 )
と書ける。
後者の方が、比較する2つの文字列1, 文字列2の間にみごとな「対称性」があってとても美しい。
さらに、
C :
if ( strcmp(pszText1, pszText2) == 0 )  // 長さ指定なしの全体比較
if ( strncmp(pszText1, pszText2, 5) == 0 ) // 最大長さ指定有り。
C++のstd::string :
if ( str1 == str2 )            // 長さ指定なしの全体比較
if ( str1.compare(0, 5, str2) == 0 )    // 最大長さ指定有り。
のように、長さ指定が無い場合と有る場合の「対称性」もCの方が高い。

さらに、開始位置と長さを指定する引数の位置が、コンストラクタに置いては
std::string str2("Hello World");
std::string str1(str2, 長さ);
std::string str1(str2, 開始位置, 長さ);
なのに、比較においては
str1.compare(開始位置, 長さ, str2)
のように前後が逆転していて、ここでもまた、STLの文字列操作には「対称性」が無い。

なお、MFCのCStringの場合は、
CString str1, str2;
に対し、以下のように strcmp(), strncmp() に簡単に指定できる :
if ( str1 == str2 )        // 長さ指定なしの全体比較
if ( strcmp(str1, str2) == 0 )   // 長さ指定なしの全体比較
if ( strncmp(str1, str2, 5) == 0 ) // 最大長さ指定有り。
一方、std::string の場合、const char* 型への暗黙変換が出来ず、str.c_str() のように書かないといけないという困った問題がある「かも」知れない。
今のC++でどうなったかは知らない。
2020/03/05(木) 11:41:02.48ID:wTyki8t2
>>552
人による。
そして上のやり取りでもわかる通り玄人ぶったバカが変な思想を押し付けてくるが
気にしなくてもよい。
2020/03/05(木) 12:19:38.92ID:2gUuzrSw
>>561
そんなん好きなようにラッパー関数を書けばええがな。
2020/03/05(木) 13:09:53.92ID:HyVcGvBE
>>563
ラッパー関数とは関係ない話。
2020/03/05(木) 13:22:25.57ID:0hm1XC5v
>>558
ストリームよりprintfがましってのは同意だがprintfよりfmt使え
C++20から標準になる
2020/03/05(木) 13:31:47.82ID:HyVcGvBE
>>565
気になるので言っておく。
stream 入出力とは、古くから FILE, fopen, fclose, fgetc, fread などに対して使われていた言葉で、cout/cin 系専用の言葉ではない。
なんでもそうだが、言葉は有名なところで先に使っていた方が優先されるべきだ。
2020/03/05(木) 13:35:39.19ID:HyVcGvBE
>>566
1. Cのstdin, stdout, FILE, fopen, fclose, fgetc, fread 系の関数群のことは、
非常に古くから「Stream I/O」と呼ばれていた。
2. C++ では、「iostream」というような名称で cout/cin 系のクラスが定義された。
後者の事を単に「ストリーム」と言っても1とは区別が付かないのでやめて欲しい。
2020/03/05(木) 13:38:39.89ID:eBZoUINk
>>556
おい554、range-based-forはコア言語だぞ、断じてSTLではない
そもそも規格票に一言も出てこない用語でイキッてんなよ
俺がアマチュアかどうかも証拠持ってるわけねえよな

寝言は寝て言えタコ助
569デフォルトの名無しさん
垢版 |
2020/03/05(木) 13:39:59.47ID:TYdcXopQ
>>567
C++スレなので。
コンテキストで十分判別がつきます。
2020/03/05(木) 13:41:04.88ID:2gUuzrSw
何を使ってもいいけど、レイヤは切り分けた方がいいと思う。
string を使ってるときは char の配列と混同させて使うべきではないし、
char 配列を使っているなら string のことは忘れた方がいい。
どこがレイヤの境界なのかはっきりさせて。
2020/03/05(木) 13:41:08.45ID:HyVcGvBE
>>565
初めて聞いたが、書式で{1}{2}など C#に似た使い方が出来るが、
逆に、{ や } の記号を簡単にはかけなくなり printf より使いにくくなってしまう。
しかも、{1}{2}が使い易いとは思わない。むしろ%sや%dより混乱する気がする。
しかも標準ライブラリではない。
2020/03/05(木) 13:41:55.46ID:HyVcGvBE
>>569
付かない。
C++はCを前提にしているのだから、両者を混在して使うのが普通だし。
2020/03/05(木) 13:46:28.70ID:HyVcGvBE
>>570
仕組みを深く理解していれば混在させても問題もない。
文字列程度でレイヤー訳が必要になるんなら、Cの上位互換の名を外すべきだ。
別の言語としてやり直せ。
574デフォルトの名無しさん
垢版 |
2020/03/05(木) 13:46:40.22ID:TYdcXopQ
>>572
もうそんな時代じゃないので。
いまは、CがC++に依存する時代。
C++で書かれたAPIをCから呼び出す。
C++がスクリプト言語のような柔軟性を持ちつつ、しかしシステム言語として使われるのは、Cから呼び出せるからでは。
2020/03/05(木) 13:52:08.63ID:wTyki8t2
c++がスクリプト言語のような柔軟性をもつ?何言ってんの?病気か?
2020/03/05(木) 13:55:30.86ID:maJEmc7K
>>568
言い返すとこはそこでいいのか?w
ちなrange-based forはまだC++に慣れてない初心者に押し付けるほどのものではないし
ましてrange-basedに合わせるためにoperatorの実装を押し付けるのは論外
ドヤりたいだけの初心者は黙ってろマジ迷惑だから
2020/03/05(木) 13:59:58.25ID:HyVcGvBE
>>574
coutやstd::stringが使い易いなら誰もCでやろうとは思わないが、現実にはCの方が便利だから
あくまでも使いにくいそれらを使おうとするとのは、今のネットは新しい情報だけが上に来てしまうため、C++しか知らない人が多いためだ。
2020/03/05(木) 14:00:13.40ID:0hm1XC5v
>>571
好きにどうぞ
時代に取り残されないようにな
2020/03/05(木) 14:00:44.50ID:HyVcGvBE
>>577
一行目の「だから」の直後に「。」が抜けていた。
2020/03/05(木) 14:01:43.36ID:HyVcGvBE
>>578
古いものを知らないで勝手に変な仕様を入れてしまう人が増えているんだ。
C#やcppfmtのそれは、PerlやRubyよりも遥かに使いにくい。
581デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:10:16.89ID:TYdcXopQ
>>580
好きにどうぞ
時代に取り残されないようにな
2020/03/05(木) 14:11:08.23ID:eBZoUINk
>>576
現場でよく使われる関数は何かと尋ねられて
すぐ思い当たるものを正直に述べたのが
初心者に押しつけたように見えるのは
おまえの目か頭のどちらかがおかしいからだ
いや両方か?

C++11に付いていけず置いてかれ
C++03でドヤりたいだけなアウトカーストこそ
マトモな初心者に触るなアホが伝染るから
2020/03/05(木) 14:12:52.64ID:maJEmc7K
マジでプロでもフリーソフト開発してるアマチュアでもいいから実際の開発に使ってる人(と初心者)専用の相談スレがあった方がいいかもな
開発全くしてない人間でも別に好きにすればいいが、ここはプロや経験長い人にマウント取りたいだけのクソバカが多過ぎる(しかもそれに初心者が騙されて右往左往する)

まぁその役割は初心者スレがすでにある程度担ってんだろうけど
2020/03/05(木) 14:13:34.58ID:maJEmc7K
>>582
アマチュアで初心者でドヤりたいだけ、ってのは否定しないのかwwww
585デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:16:27.96ID:TYdcXopQ
乱数とかCライブラリでは辛すぎる。
2020/03/05(木) 14:16:37.51ID:eBZoUINk
>>584
はあ? 俺がアマチュアという事実無根の誹謗中傷をしたことを否定しないのはおまえだろ
2020/03/05(木) 14:17:44.84ID:eBZoUINk
嘘つき野郎と日本語で言っても非難の度合いが弱すぎるので英語でLIAR!!
588デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:17:54.10ID:TYdcXopQ
仕様に「任意の」とついたら、もうCでは拷問になる。
CIA真っ青級の。
589デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:18:57.32ID:TYdcXopQ
めんどくさいからそろそろ天才がどうたらいういつもの結論行って。
590デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:20:20.54ID:TYdcXopQ
Networking TSが入れば追いついてこれるものなど居ない。
2020/03/05(木) 14:21:04.08ID:wTyki8t2
江添に影響されたバカが増えたよな。
ああいうまともにコード書いてないで知ったかするカス態度はほんと害悪だわ。
2020/03/05(木) 14:23:28.86ID:eBZoUINk
生データからノイズを除去し有益な情報だけを抽出できないやつに江添の文面は無理
2020/03/05(木) 14:26:52.95ID:maJEmc7K
まぁC++専門のライター自身がC++に変な幻想抱いてるしね
スクリプト言語の代わりになったって仕方ないのに
むしろC++にそのように振る舞わせるためにユーザーがアホほどコスト掛けなきゃいけなくなるという
594デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:32:04.59ID:TYdcXopQ
>>593
https://root.cern.ch/cint
2020/03/05(木) 14:32:11.09ID:wTyki8t2
ただ新しい言語をなぜやるかの理由の一つとして
年上にマウントとるためってのは実際大きいんだろうなと思う。
これは他言語でもそうだし、昔からそう。
この点についてこの業界は50年以上全く解決されてない。
596デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:33:02.32ID:TYdcXopQ
C++でワンライナー書けるようになったら、初心者脱出。
2020/03/05(木) 14:37:10.41ID:LYrzkUWd
>>574
cがc++に依存するって何のこと言ってる?
2020/03/05(木) 14:41:02.50ID:eBZoUINk
俺が6800のマシン語やり始めた頃
ジジイたちはPCなんてオモチャとバカにしてたから
マウント取りたきゃいつでも取れてたが
そんなパンピーが考えそうなくだらねえことには興味なかった
599デフォルトの名無しさん
垢版 |
2020/03/05(木) 14:45:43.10ID:TYdcXopQ
C++を使いこなせないと老害の始まり。
2020/03/05(木) 15:16:05.18ID:maJEmc7K
>>594
時代がどうこう言ってたのに03までやんけ(´・ω・`)

>>598
老g(ry
601デフォルトの名無しさん
垢版 |
2020/03/05(木) 15:17:50.50ID:TYdcXopQ
URL見て気が付いてほしかったが。
2020/03/05(木) 15:21:51.85ID:maJEmc7K
君そのマウント癖やめた方がいいよ
しょっちゅう恥かいてるだろ?
しかも自爆でw
603デフォルトの名無しさん
垢版 |
2020/03/05(木) 15:28:42.90ID:TYdcXopQ
いや、CINTなんていにしえの遺物で、話題になることも無いし。
そこで気づいてほしかったのだが。
604デフォルトの名無しさん
垢版 |
2020/03/05(木) 15:30:00.52ID:TYdcXopQ
まさに老害にぴったりと。
2020/03/05(木) 15:35:14.30ID:LYrzkUWd
>>604
でcがc++に依存するって何のこと?
2020/03/05(木) 15:51:28.16ID:eBZoUINk
俺もぜひ拝聴したいねえ
2020/03/05(木) 16:27:00.86ID:0JAmDFqx
このスレって伸びてるときほど中身が薄くなるなw
608デフォルトの名無しさん
垢版 |
2020/03/05(木) 16:33:56.89ID:TYdcXopQ
もはやCだけで完結しない。
Cは歴史の遺物。
609デフォルトの名無しさん
垢版 |
2020/03/05(木) 16:35:18.30ID:TYdcXopQ
API呼び出したら、中身はC++で書かれてるだろ?
2020/03/05(木) 16:39:10.51ID:4O4IELXe
>>557
エラーってのがコンパイルエラーなら"\\s"とかR"(\s)"にする、実行時ならコンパイラのバージョンを上げる、でどうかな
2020/03/05(木) 16:55:10.20ID:DpzQwxFi
その理論だとc++もcでかかれたコード呼ぶだろ
ライブラリがc++のしか用意されてないとかそういう話かと思った
2020/03/05(木) 16:58:12.34ID:eBZoUINk
>>609
Cから呼び出されるC++関数を書くにはC++側でCに合わせる必要がある
そういうのをCがC++に依存したというのはちょっと無理あるだろ
2020/03/05(木) 17:08:17.82ID:LYrzkUWd
>>609
時代とか大口叩いたくせに後で矮小化すんなよ、くそださい

その例でいうと中の実装言語が何かはc側は関知してないだろ
それはcがc++に依存とは言わない
その関数が提供する機能に依存してるという特定の事例にすぎない
だいたいABIは事実上cベースしかない
c++がcのふりしてるんだよ
2020/03/05(木) 17:11:40.19ID:2VKfb2ir
名前修飾の法則は規格化されないんかね
2020/03/05(木) 17:16:22.18ID:HyVcGvBE
>>609
・Windowsの場合、C++のプログラムは最終的には、Win32を呼び出しているが、 Win32は、記述言語もインターフェースもC。
・Linuxでも同様。LinuxのKernel本体はCで書かれている。
 GTKやKDE, Qt は原則 C++ だが、最終的には Cで書かれ、かつ、Cのインターフェース を持つ System Call が呼び出される。

どちらも
C++ ---> C
の流れ。基礎部分やバックエンド部分は C になることが多い。
逆に C から C++ を呼び出すことは稀。
だから、事実とは逆。
2020/03/05(木) 17:19:27.49ID:HyVcGvBE
>>614
gccのマングリング化法は資料がある。
vc++も解析資料がある。
clangはgccのマングリング化法を使っている。
しかし、gccのマングリング化法を使うと、gnu/FSF/GPL 信者から
「真似をした、ずるい」と文句を言われたり、証拠もないのに
「勝手にソースを使った」などと風評被害があるに決まってるから
使いづらい。
2020/03/05(木) 17:19:36.10ID:2VKfb2ir
windowsはc++と混在してたはずよ
win32だけは違うとかあるかも試練が
2020/03/05(木) 17:21:34.22ID:HyVcGvBE
>>617
・GDI+ は C++ インターフェースだが、内部では Cの API を呼び出す仕組みになっている。
・DirectXも C++ インターフェースではあるが、COMだから Cからも呼び出せる。
2020/03/05(木) 17:23:03.34ID:HyVcGvBE
>>617
Win32は、GDI+以外はほぼ全て Cのはず。
MFCは、Win32をラッピングしているから、
C++(フロントエンド) ---> C(バックエンド)
の流れ。
2020/03/05(木) 17:24:33.30ID:wTyki8t2
こいつらextern "C"についてさえまともに理解してなさげ。。
2020/03/05(木) 17:37:41.82ID:HyVcGvBE
>>608
Cだけだと、少し不便なだけで完結する。
むしろ、C++ だけではスクリプト言語的なことしかできないので、完結とはいいがたい。

このスレは新しい言語である C++ をネットで学んだだけで、基礎となる C の部分が学べてない人が多いようだ。
ネットだと新しく入った機能や新しい記事だけが上位に来てしまうから、新しいことしか知らない人が書いたページだけしか見る機会がなくなってしまうが、それだと悪循環になり、古くてももっと良いものがあっても学べない。
622デフォルトの名無しさん
垢版 |
2020/03/05(木) 17:47:46.22ID:TYdcXopQ
C++を使いこなせない老害がCに固執してると見た。
2020/03/05(木) 17:48:19.67ID:maJEmc7K
このスレに限らず、検索してても初心者が過去の遺物だのオワコンだの死すべしだの
口の悪い厨二病発言するだけで上級者になったつもりのクソブログばっかり上に出るからなぁ
ABIというかマングリングとかバイナリ周りの統一に関しては、C++はいつまで経ってもCの後塵を拝する形になってるんだが、何年かC++やっててもその程度の欠点にも気付かない奴ってのは
要するにそういうことだろ・・・
624デフォルトの名無しさん
垢版 |
2020/03/05(木) 17:52:51.49ID:TYdcXopQ
Cで出来ることはC++でもできる。
C++で出来ることがCには出来ない。
Cは老害。
2020/03/05(木) 17:53:01.97ID:maJEmc7K
あんま調べてないけどモジュールも多分ソースコードレベルでのヘッダ依存の解消のためであって
ライブラリファイルみたいな外部に出す方法はまだまだ来ないだろうし
2020/03/05(木) 18:13:53.71ID:HyVcGvBE
>>624
C++はCのサブセットなので、当然それは正しいことなのだが、
このスレの人達は、「C++のうちからCの部分を除外した部分だけ」
をC++だと言い張るので異なるのだ。
2020/03/05(木) 18:17:40.92ID:HyVcGvBE
>>622
このスレで、Cを使うのを朗がい呼ばわりしている人達を見る限り、単にC++に加わった新機能を解説したサイトをネットで学んだだけで古いC++やCを知らないだけに見える。
確かに、Cより優れているC++の部分を使わないのは老害だ。
しかし、C++より優れているCの部分を使わないのは、単にCを知らないだけ。
2020/03/05(木) 18:22:08.41ID:LYrzkUWd
>>624
話をそらすな
cがc++に依存してるとか言い出したから
総ツッコミがはいったんだろが
自分で言い出したこと忘れたのか?
それ老害の先の症状だぞ
2020/03/05(木) 18:28:00.98ID:VlBePa1i
c++より優れているcの機能って言うほど無いだろ
printfとiostreamにしたって好みによるとしか

まあ次の標準に来るから使えるならfmt使っとけ
明らかに上記のどちらよりも優れているから
2020/03/05(木) 18:35:08.33ID:LYrzkUWd
>>629
fmtは{}が直接使えないからだめらしいぞ
しかしprintfの%は気にしないみたいだぞ
2020/03/05(木) 19:01:36.23ID:oXCneOog
>>615
インターフェースとか言い出したらWin32APIはPascalやでw
2020/03/05(木) 19:07:31.57ID:HyVcGvBE
>>629
昔BASICが人気があったころ、print と print using の二種類有り、
cout は前者の、printf は後者の流儀と同じである。
初心者は、print から使い始め、慣れてくると print using を使うと言われていた。
後者はとっつきにくいが独特の便利さがあるとされた。
つまり、BASICは、cout 方式も使えたのに、敢えて printf 方式も用意したのだ。
このスレやネットには初心者が多いので、覚えることの少ない coutが好まれているだけ。

なぜcoutが問題なのかと言うと、書く量が多くなることと、見た目的に結果を予想しづらくなるからだ。
printf( "(x, y, z, w)=(%d, %d, %d, %d)\n", x, y, z, w );
で済む所が、coutだと、
cout << "(x, y, z, w)=(" << x << ", " << y << ", " << z << ", " << std::eol;
などとなってしまい、打ち込みにくいだけでなく、結果がどうなるかも直感的に分かりにくい。
出力にカンマや空白を入れるのが難しいのだ。
さらに、これを16進に直したい場合、printf なら、
printf( "(x, y, z, w)=(%X, %X, %X, %X)\n", x, y, z, w );
と僅かな修正だけで済む。さらに、左に0を埋めた8桁の16進数に直したい場合には、
printf( "(x, y, z, w)=(%08X, %08X, %08X, %08X)\n", x, y, z, w );
で済むし、表示に0xを含めたい場合には、
printf( "(x, y, z, w)=(0x%08X, 0x%08X, 0x%08X, 0x%08X)\n", x, y, z, w );
で済む。これで、0x0000ABCD などと表示できる。さらに、0x0000abcd と表示したい場合は、
printf( "(x, y, z, w)=(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", x, y, z, w );
で済む。どのような表示形式にしても、コンパクトで見易い。
一方、coutでこれと同じようにしようと思ったら、見易くするためには5行くらいの長さになってしまうだろう。
それでもこのように美しい見た目にはならない。

昔のBASICのprint文にも同じような問題点がおきたから、print using が生み出されたのだ。
それを知らないで、coutがprintfより優れていると思ったら大間違いだ。
2020/03/05(木) 19:15:26.67ID:HyVcGvBE
>>632
誤: cout << "(x, y, z, w)=(" << x << ", " << y << ", " << z << ", " << std::eol;
正: cout << "(x, y, z, w)=(" << x << ", " << y << ", " << z << ", " << w << ")" << std::eol;
634デフォルトの名無しさん
垢版 |
2020/03/05(木) 19:18:12.66ID:HyVcGvBE
>>633
もっと言えば、この cout は、古いN88-BASIC言語より記述量が多い。
<< を使うからだ。N88-BASIC は、<< の部分が ; となる。
N88-BASIC なら、
print "(x, y, z, w)=("; x ; ", " ; y ; ", " ; z ; ", " ; w ; ")"
635デフォルトの名無しさん
垢版 |
2020/03/05(木) 19:22:17.12ID:HyVcGvBE
1. N88-BASIC
print "(x, y, z, w)=("; x ; ", " ; y ; ", " ; z ; ", " ; w ; ")"
2. C
printf( "(x, y, z, w)=(%d, %d, %d, %d)\n", x, y, z, w );
3. C++
cout << "(x, y, z, w)=(" << x << ", " << y << ", " << z << ", " << w << ")" << std::eol;

C++ が最も汚く、書きづらい。

N88-BASIC ---> C の printf()  // 進化と言えよう。
N88-BASIC ---> C++ の cout  // 後退のように見える。

cout は、classのパワーを例示するために用意されたと聞いている。
もともと実用性は無かったのに、それを知らない人達が使うようになってしまったのが現状である。
2020/03/05(木) 19:25:02.59ID:wTyki8t2
printfとcoutの議論はgoogleでもやってたな。
型安全と見やすさのどちらが重要かみたいなやつ。
型安全にこだわるやつはたいてい現実見てないなってのが良くわかる例になってる。
2020/03/05(木) 19:32:35.95ID:HyVcGvBE
>>635
一見、printf と cout で記述のしやすさに大差ないと思う人もいるかもしれないが、実際に入れてみると coutの記述のしにくさは異常なほどである。
特に問題なのが、後から "," の後ろに空白を入れたくなったりしたときの修正のしにくさである。
printf の場合は、最初の書式付文字列の中にまとまっているので、非常に修正し易く、数秒で修正できてしまう。
ところが cout の場合は、全体に散らばっているので修正箇所を見出すのが非常に難しく、間違いの元になり易い。
全部修正したつもりでも、いくつか入力し忘れていたり、"・・・" の中に入れなければならない所を、"・・・" の直後の「地の文」に入れてしまったりする羽目になる。
また、よくあるのは、" や << を入れ忘れたりすることである。
2020/03/05(木) 19:37:42.73ID:HyVcGvBE
>>637
coutの場合に、よくあるのが、" の内側と外側の混乱である。
"で文字列を始めたり終えたり何度も繰り返すので、目が混乱して
どっちがどっちか分からなくなる。
コンパイルしたとき、文字列が開きっぱなしになって、酷いときには
ファイルの最後までコンパイルしてしまって、エラーがどこで起きたのかさえ
分からない最悪の間違いを犯してしまう。
だから、perl,ruby,pythonでは、
"#{変数名}"
のような記述が発明された。
これは、printf を進化させたものといえよう。
しかし、coutは退化である。
2020/03/05(木) 19:39:40.38ID:ZxLAHsYQ
なんでこの子価値の無い長文書いてしまうん?
2020/03/05(木) 19:39:40.91ID:0BzRX834
>>638
エディタくらいまともなやつ使え
2020/03/05(木) 19:41:36.95ID:HyVcGvBE
>>640
そんな問題ではない。
2020/03/05(木) 19:47:23.03ID:lwuDTkr7
どんなクラスのオブジェクトでもoperator<<さえ定義すれば吐き出せるのがiostreamのメリットよ
クラスは組込型のように振る舞えるべきだっていうオブジェクト指向の理想のために必要だったんだよ
安全な後世から後出しジャンケンで叩くのはフェアじゃないよ

それはそれとしてiostreamは使いづらいクソだという意見は否定しない
2020/03/05(木) 19:48:11.76ID:LYrzkUWd
>>641
そんな既知の話ここで長々と書かんでいいから
自分のブログでやれ
ここにはリンクだけ張りに来い
2020/03/05(木) 20:14:15.18ID:0JAmDFqx
>>639
中学校が休校になって暇を持て余してるんだろう
2020/03/05(木) 20:37:19.93ID:ZVNOJjMJ
>>565
ようやく来たかー。
望んていた形そのものだわ

ID:HyVcGvBE
スレによって態度違いすぎw
2020/03/05(木) 20:38:33.78ID:eBZoUINk
>>636
両立できそうなところへ、どちらかが優れているという結論を目指すという
前提がそもそも間違っている不毛な議論だと思うが
2020/03/05(木) 20:45:44.87ID:wTyki8t2
>>646
統一したいという輩がいるんだからどっちでもいいとしても
少なくともその輩を黙らす必要はあるだろう。
まあlinusの言う通り馬鹿をプロジェクトに入れないっていうのがやっぱり正解なんだが。
2020/03/05(木) 20:52:50.83ID:BOwkxST5
>>574
>C++で書かれたAPIをCから呼び出す。
extern "C" 
でもしないかぎり、あり得ないのでは?this とかマングリングとかどうするの?
2020/03/05(木) 20:53:54.02ID:eBZoUINk
>>647
日本語でおk
2020/03/05(木) 20:54:26.10ID:BOwkxST5
>>583
>マジでプロでもフリーソフト開発してるアマチュアでもいいから実際の開発に使ってる人(と初心者)専用の相談スレがあった方がいいかもな

ここがそうだと思います
そう思えないのであれば、それはスルー力が足りないかと
2020/03/05(木) 20:54:47.02ID:wTyki8t2
なんだ日本語読めないのか。。そりゃ失礼。
2020/03/05(木) 20:55:46.47ID:eBZoUINk
>>648
関数ポインタに生アドレスを渡すとかw
GetProcAddressみたいに
QueryInterfaceと似てるけど、より面倒くさいね
2020/03/05(木) 20:56:14.98ID:BOwkxST5
>>608
そうでもないですよ
ほかの言語から自由に呼び出せるようにするため、汎用ライブラリをわざわざ C で書いたりするでしょう?
2020/03/05(木) 20:57:13.05ID:BOwkxST5
>>612
私は extern "C" くらいしか思いつかないですね…
2020/03/05(木) 20:58:06.21ID:BOwkxST5
>>615
>逆に C から C++ を呼び出すことは稀
というか皆無といういうべきでしょう、extern "C" でもしない限り
2020/03/05(木) 21:00:50.35ID:BOwkxST5
>>624
>Cで出来ることはC++でもできる。

C++ でできないこともあります
他言語から自由に呼び出せるライブラリを書くときは C で書くしかないでしょうね…
extern "C" というのは、もはや C で書いているのと一緒…
2020/03/05(木) 21:03:38.79ID:LYrzkUWd
>>656
一緒ではないだろ
APIはcで中身はc++ってのは多い
実際おれもそうしてる
c++使いたいからな
2020/03/05(木) 21:07:33.42ID:eBZoUINk
>>654
あーそうなの?
テンプレートとかムブコンとかうっすらぱーw
2020/03/05(木) 21:29:47.60ID:maJEmc7K
>>650
>ここがそうだと思います
本気でそう思えるなら自分のことしか見えてないんだろうな
あといちいち分けてレスするな
2020/03/05(木) 21:57:41.56ID:maJEmc7K
昔BeOSっていう純粋にC++で書かれたOSがあったけど、コンパイラやAPIのバージョンアップで
マングリング規則やクラスのエクスポート時の互換性が無くなって、
過去のアプリが全く動かなくなったりした(こういうのはBeOS限定の話ではないけど

クラスライブラリの互換性をどうにかするために、MSの場合はvtblが先頭にあることを利用したり
余分な引数を追加したりしてコンパイラ間の互換や後のバージョンアップに対応できるようにしたけど
そもそもvtblを先頭に置くのは規格で決まってるわけではない

上の方でUBUB言ってた人達はこういうのどう思うんだろうね
2020/03/05(木) 22:17:26.19ID:DHJqOPbR
>>610

コンパイル時にエラーが出ていました。
下記でコンパイル通りました。
ありがとうございます。

std::regex re( R"(^\s*(^\S+)\s+(\S+))")

ダブルクォーテーションの内側を全部丸括弧でくくればよくて、そのカッコは
下記の results[1] にはセットされないんですね。
知らないとちょっと戸惑いそうだ。

std::regex_search(word, results, re)
2020/03/05(木) 22:19:16.64ID:2gUuzrSw
>>660
OS の製作元と同じマイクロソフトが提供している VS で COM を作る分には別にいいんじゃないの。
移植性を考える必要もないし。

しかし、こういう変な形でなければ C++ で作ったバイナリは運用しづらいということの証明にもなってはいるよな。
2020/03/05(木) 22:24:01.52ID:LYrzkUWd
>>660
c++でUBでも処理系が定義してる範囲で、
かつその処理系に依存していいなら問題ないだろ
そのへん区別しろ
2020/03/05(木) 22:33:54.16ID:maJEmc7K
>>662
いやVS限定ではないはず、他のコンパイラからでも使えるでしょ

>>663
問題かどうかではなくて、そういうトリックを使わなければ達成できない目的があったときどうするの?みたいな話
と、バイナリ関係の規格が全然足りてないよね、という話
2020/03/05(木) 22:49:02.33ID:LYrzkUWd
>>664
わからんやっちゃな
処理系が決めてる範囲でやるんだよ
実際それでなんとかしてるだろ?
テンプレートでいきってる標準化の連中がバイナリ境界に無関心なのはカスだと思うけどな
2020/03/05(木) 22:55:28.04ID:2gUuzrSw
>>664
まあ実際には VS に合わせてるコンパイラが多いのは知ってる。
gcc とかもデフォルトではビットフィールドの割り当て順序が違ってるんだが、
VS に合わせるオプションとかが用意されてたりもするくらいには Windows では VS が基準。

ただやっぱりそこには「検証の手間」が発生するよ。
VS でやる分にはマイクロソフト自身がやってんだから疑いが入る余地はない、
確実に問題はないという意味で VS に限定して問題ないと表現した。

ひょっとしたら VS 以外のコンパイラでもドキュメントをよく見たらどっかに書いてあるのかもしれんけど、
少なくとも私はそれを確認したことはない。

---

バイナリの規格ってのは「せめて Windows 内では」とかいうレベルのこと?
違うアーキテクチャで統一できないのは仕方ないけど、
主要なアーキテクチャ/OS内ではっきりした規格を定めれていないのはなんでできないんかなぁと思わなくはないな。

うーん、でも Linux なんかだと GCC のマングルが実質的な規格そのものみたいな感じもするし、
Windows だと結局は VS に合わせるしかないんだからそれが規格みたいなもんじゃね?
その規格 (的なもの) に合わせられていないのは単純にやる機運が起こってないだけで。
2020/03/05(木) 23:15:47.07ID:maJEmc7K
>>666
マングリングは政治的な問題も絡むのか・・

すまんバイナリって言ったから誤解させたかもしれん、インターフェースの話ね
クラスのエクスポートとか回り道せずに出来るようにならないと、上でも言われてる通りいつまでもCのスタイルに合わせざるを得ない

てかvtblを先頭に置かないコンパイラを知らんのだけど、あったとして合理的な理由とかあるんだろうか
2020/03/05(木) 23:18:24.65ID:lncFD5GH
どんな状況でも動くことを考えたらCの仕様に行き着く
2020/03/06(金) 00:04:56.44ID:pppdCZrx
iostreamの使いづらさはboost::formatで大体解決する
ってかformat指定をワザワザprintfから改悪してstreamオブジェクトに余計な状態保持をさせてしまったところ

std::vector<bool>が典型的だけど、初期の頃に考えられた言語デモンストレーションの為に、実用性に疑問の残るおかしな仕様が標準化されちゃっているところがあるよね
2020/03/06(金) 00:09:16.95ID:trP/ijr0
>>630
printf が関数として、特別な機能を持たせている文字は % の1つだけ。
しかし、言語自体が \ をエスケープ記号として使っているので、合計2つが
特別な意味を持っており、これでも問題になる場合がある。

一方、cppfmt の場合、少なくとも %, {, } の3つが特殊記号になっていて、
\と合わせれば、合計4つもが特別な意味を持っており、いくらなんでも多すぎる。

それがセンスの悪さ、と呼ばれるものである。
2020/03/06(金) 00:13:54.49ID:ba67/VF+
>>670
でお前printfで64bitの整数出すのどうしてる?
正直に言ってみな
2020/03/06(金) 00:16:09.16ID:trP/ijr0
>>671
64bit モードは使う必要ない。
2020/03/06(金) 00:28:50.27ID:ba67/VF+
>>672
そうなんだ
でお前はそのお前固有の環境を前提に俺たちに何を語りかけたいのさ?
寂しいからとかやめてよ
2020/03/06(金) 00:34:13.09ID:pppdCZrx
>>670
pythonっぽいfmt::formatが{}
cっぽいfmt::formatfが%じゃないの?

前者がわざわざ2文字なのは見やすさ重視だからこそだし
2020/03/06(金) 00:53:15.12ID:trP/ijr0
メリットは何もないのに64bit使う必要なし。
2020/03/06(金) 00:56:22.87ID:8Rm5TWXP
そうか
じゃあお前だけtime_tに32bit使って2038年問題で苦しめ
2020/03/06(金) 01:00:41.40ID:pppdCZrx
printfは型と対応するformat指定法を把握していないと簡単にバグるからね
まあ、最近のまともなコンパイラだとprintfのformat解析まで静的にやって殆んどの場面でエラーなり警告なり出すから大分マシだけど
2020/03/06(金) 01:04:32.93ID:Lqsy4Vrx
(ITドカタの爺さんには)64bitはなんのメリットもない
pythonなんて当然触ったこともない
2020/03/06(金) 01:55:37.24ID:trP/ijr0
>>675
time_tの問題をコンパイラの64bit化しなくては解決できないほどプログラミング能力がないんだね。
アホみたい。
2020/03/06(金) 02:12:28.32ID:hhWvctpB
>>679
自分で自分に批判レスするってアホみたい
2020/03/06(金) 02:13:52.12ID:trP/ijr0
>>680
頭がおかしいね、あなた。
2020/03/06(金) 02:18:58.34ID:8Rm5TWXP
知らなくて驚くかもしれないけど、32bitのシステムでも64bit整数は使えるんだよ
2020/03/06(金) 02:27:44.01ID:P6VjmRBF
64ビットは不要とか言っちゃう奴がC++の仕様に文句言うとかないわw
2020/03/06(金) 02:31:48.79ID:trP/ijr0
ハード屋が単に食い扶持確保のために用意しただけのものを勝手に意味があると思い込んでいる馬鹿な人達。
2020/03/06(金) 02:59:03.29ID:8Rm5TWXP
>>684
純粋な疑問なんだけど、あなたは4294967295を超える整数を扱う必要がある時にはどうするの?
686デフォルトの名無しさん
垢版 |
2020/03/06(金) 04:22:51.72ID:89RQTO1C
構造体を使います。
687デフォルトの名無しさん
垢版 |
2020/03/06(金) 04:28:44.87ID:89RQTO1C
構造体を知らない人が64ビット言ってるんだと思います。
2020/03/06(金) 04:29:16.89ID:8Rm5TWXP
なるほどね
センス悪いねあんた
689デフォルトの名無しさん
垢版 |
2020/03/06(金) 04:32:38.83ID:89RQTO1C
何のセンスだ。
2020/03/06(金) 04:35:36.86ID:8Rm5TWXP
仕事のセンスだよ
じゃあ構造体使って1兆÷7を計算するコード書いてみてよ
64bit整数を使えば「100000000000ULL/7」だけで済むものを
どれだけ面倒で下らないコードで水増しして生産性下げてチームに迷惑かけてるのか興味あるからさ
2020/03/06(金) 04:43:17.56ID:3vh2YYy0
64bit機のNintendo64は32bit機のプレステ1に負けたよね。商業的に。
692デフォルトの名無しさん
垢版 |
2020/03/06(金) 04:53:21.52ID:89RQTO1C
>>690
構造体知らんの?
2020/03/06(金) 04:56:22.47ID:8Rm5TWXP
知らないから君の最強の多倍長整数64bit計算を見せてよ
694デフォルトの名無しさん
垢版 |
2020/03/06(金) 05:00:24.98ID:89RQTO1C
構造体学んでからもう一度質問してください。
2020/03/06(金) 05:04:01.70ID:8Rm5TWXP
というか構造体じゃなくて配列でいいよね
uint32_t trillion[2] = {232, 3567587328};
を7で割るコードを見せてください

64bit整数の割り算をわざわざ多倍長整数でやるなんてそんな無意味なコード書いたこともないから知らないんだよね
見本見せてよ
「100000000000ULL/7」よりもずっと優れてるんでしょ?
696デフォルトの名無しさん
垢版 |
2020/03/06(金) 05:06:27.71ID:89RQTO1C
構造体を学んでください。
いま素晴らしいアドバイスを与えましたよ?
2020/03/06(金) 05:12:53.95ID:8Rm5TWXP
じゃあ構造体でいいよ
struct Int64 {uint32_t high, low;};
Int64 trillion = {232, 3567587328};

さっさと7で割れや
逃げるのか?
698デフォルトの名無しさん
垢版 |
2020/03/06(金) 05:14:40.27ID:89RQTO1C
いや全然ダメ。
構造体の何たるかが全然わかっていない。
まともな師匠に師事して学ぶべきです。
2020/03/06(金) 05:29:10.46ID:8Rm5TWXP
しょうがねえな
多倍長の除算を書くのが面倒なんだったら、>>695>>697にはわざと32bit環境での多倍長演算には適さない
問題のある表現使ってやったからそのことを指摘するだけでもいいよ
それすら出来ないならお前こそまともな師匠に師事して出直してこい
700デフォルトの名無しさん
垢版 |
2020/03/06(金) 06:26:13.08ID:89RQTO1C
むしろ16ビットで十分だけどな。
2020/03/06(金) 06:41:40.07ID:8Rm5TWXP
え、マジ?>>695>>697の何がダメか本当にわかんないの?
相手して損した
702デフォルトの名無しさん
垢版 |
2020/03/06(金) 07:17:23.58ID:89RQTO1C
構造体を知らないものが64ビットを愛好するということが分かった。
2020/03/06(金) 07:25:27.16ID:hYOq9QPM
>>661
R"..." はいわゆる生文字リテラルでWindowsのファイルパスとか正規表現文字列を書き易くするための機能やね
ただ無駄に高機能で
R"***(文字列中)")***" ⇒ 文字列中)"
なんてのも指定できるけど個人的にはやりすぎとしか思えない
https://cpprefjp.github.io/lang/cpp11/raw_string_literals.html
2020/03/06(金) 08:24:11.44ID:7d5kGJiP
そもそも暗号系扱うならそんな長さじゃ全然足らんしね。
構造体構造体言ってる奴もそれわかってなさそうだが。
705デフォルトの名無しさん
垢版 |
2020/03/06(金) 08:42:39.21ID:89RQTO1C
暗号系はHaskell一択でしょ。
706デフォルトの名無しさん
垢版 |
2020/03/06(金) 10:08:00.27ID:mgb6nXCA
プログラムが実際にかかった時間とCPU時間の2つを最後に表示させるのに何か関数用意されてますか?
clock()はCPU時間だけですよね?
2020/03/06(金) 10:13:22.05ID:u9hNYNKX
>>703
それ必須(syntaxはさておき)
それなしのrawは片手落ちだよ
2020/03/06(金) 10:23:16.85ID:u9hNYNKX
>>706
clock()つかってんならtime()使えばいいじゃん
ちなみに君c++使えてる?
2020/03/06(金) 10:25:39.21ID:u9hNYNKX
>>699
この爺さんたぶん足し算引き算繰り返すんだよ
それならcarry bitだけ気にすればいいからね
32bitの乗算の結果は最大64bitだから爺さんの能力オーバーする
2020/03/06(金) 10:33:59.25ID:hYOq9QPM
>>707
それおまえさんの個人的意見だよね?
俺はPythonとかC#あたりでいいと思ってるだけの話
必須でもなんでもないよ
2020/03/06(金) 10:43:29.63ID:u9hNYNKX
>>710
意見でもあるし、定性的にそうだよ
閉じカッコを含められない制限に何か合理性ある?
ptyonだってトリプルクォートとかrawとか建て増しになってとっちらかってるわけで
2020/03/06(金) 10:46:24.85ID:u9hNYNKX
いや問題はダブルクォーテンションか
そこは訂正
2020/03/06(金) 12:26:06.89ID:hYOq9QPM
>>711-712
> 閉じカッコを含められない制限に何か合理性ある?
生文字列中にダブルクォーテーションを含めたい機会がどんだけあるんだ?
って話な
Pythonなら R"ABC" "¥"" "def" ってやるだけ(R'ABC"DEF' でもいいけど両方含む場合はとか言い出すだろうからw)
C# なら @"ABC""DEF" でできる

> ptyonだってトリプルクォートとかrawとか建て増しになってとっちらかってるわけで
トリプルクォートとRaw文字列は役割違うし別にとっちらかってないけど?
2020/03/06(金) 12:31:07.14ID:1NgZSMCO
ダブルクォート含みのCSVとかをパースするための正規表現書く時とかいくらでもあるけど
raw文字列ってそういう時のための物じゃないの?
2020/03/06(金) 13:57:40.15ID:u9hNYNKX
>>713
> トリプルクォートとRaw文字列は役割違うし別にとっちらかってないけど?

それこそお前の感想だよね?w
役割が違う言えば聞こえがいいが、pythonの文字列リテラルは機能の直行性もない短絡的な設計
rawは短い正規表現などの用途しか考えてなくて複数行でかつエスケープなしができない
でそういうのが欲しいケースはいくらでもある
JSONを文字列で埋め込んでおきたい場合とかね

c++のrawは建て増しなのは同じだけど設計の筋は通ってる
ただもう一歩がんばってindent合わせが可能な仕様にしてほしかったな
2020/03/06(金) 13:59:12.86ID:ytQa5naT
>Pythonなら R"ABC" "¥"" "def" ってやるだけ
rawの意味ねぇなww
2020/03/06(金) 14:24:22.40ID:trP/ijr0
>>690
だから、64BITの時間をそのまま7で割らなくてはならないような状況に
なってしまうあなたの数学力が足りない。
2020/03/06(金) 14:28:35.64ID:trP/ijr0
>>717
それから、本当に桁数の多い数の割り算計算が本質的に必要な場合は多倍長計算ライブラリを使えばいい。
多くのアプリではそういう状況が少ないと言うことだ。
科学技術計算では、doubleか、4倍精度float数を扱えればいいので、64BIT整数が必要な場面は今のところ少ない。
メッシュの個数やループ回数が32BITを超えるようなものは、今のCPUでは重過ぎて普通、計算できない。
2020/03/06(金) 14:38:19.40ID:2gPy1GFt
>>717
64bitの時間? おまえさんもしかして、2922億年のことを言っているのか?
64bitの1秒であろうと32bitの1秒であろうと1秒は1秒でしかないんだが
2020/03/06(金) 14:41:03.85ID:hYOq9QPM
>>715
> rawは短い正規表現などの用途しか考えてなくて複数行でかつエスケープなしができない
まさかと思うがトリプルクォートとRaw文字列を組合せて使えることも知らんのか?
そんな知識で直行性とか語るなよw
2020/03/06(金) 14:45:21.47ID:hYOq9QPM
>>716
まああんまり無いケースだから多少見辛いのはしゃーない
C#みたいな方がまだマシだとは思うが
2020/03/06(金) 14:45:22.11ID:gkPkCuAw
業界全体の傾向では「printfへの回帰」が見られる
fmtはprintfの21世紀型強化版として捉える

つまり、+や<<で連結するのはどの言語でも煩わしかった
だからprintf(のようなもの)に戻ってきている

CUIやテキストへの出力はprintf程度で充分だった、と誰もが気付いた
2020/03/06(金) 14:45:35.04ID:2gPy1GFt
複数行できるぞ

std::cout << R"(abc)"
R"(def)"
"\nghi" << std::endl;

しかもエスケープあり/なしを途中で切り替えることまでできる
724デフォルトの名無しさん
垢版 |
2020/03/06(金) 14:53:31.38ID:89RQTO1C
普通は16ビットあれば十分ですよ。
64ビット厨はプログラムしたことあるの?
2020/03/06(金) 15:11:10.95ID:/2BnMzJ+
ポインタ使えないだろ
2020/03/06(金) 15:34:10.40ID:1NgZSMCO
>>718
へー
お前の世界の普通の会計ソフトは43億円を扱えないし
お前の世界の普通の防犯カメラは43億ミリ秒(たった5日)連続稼働したら落ちるし
お前の世界の普通のOSは4GBのファイルを作れないのか

アホくさ
2020/03/06(金) 15:56:44.11ID:trP/ijr0
>>726
16BIT時代から一兆円は扱えた。
Z80 はマシン語としては整数の掛け算/割り算も浮動小数点も全くサポートしてなかったが、BASIC言語ではどれも普通に出来た。
同様に、32BIT CPUでも、64BIT整数が扱えないわけではない。
728デフォルトの名無しさん
垢版 |
2020/03/06(金) 16:00:14.00ID:89RQTO1C
intは16ビットが正解。
2020/03/06(金) 16:03:04.34ID:u9hNYNKX
>>720
まじか・・・正直その組み合わせ気づいてなかったわ
ただやはりpythonはエスケープフリーで任意の文字を含められない点で機能が不完全
2020/03/06(金) 16:40:55.40ID:7d5kGJiP
pythonは文字列まわりがとっちらかって結局2と3で分裂したが。
2020/03/06(金) 17:14:18.31ID:1NgZSMCO
python2で混乱してたのはraw周りじゃないぞ
文字列の文法は3でもほとんど変わってないはず
strとunicodeとbyte(に相当するもの)の扱いがナイーブ過ぎてグッチャグチャだったのがpython2の大問題
2020/03/06(金) 18:10:29.44ID:k+5uYmSv
>>729
pythonでも"と'を同時に使わない限り何でもかけるじゃん。
一方、c++は)"という並びを文字列中にかけない制限があるわけなんで、
もちろん後者のほうか確率は低いけど、pythonを一方的に機能不全と言えるほどじゃないなー
2020/03/06(金) 18:15:02.80ID:2gPy1GFt
>>732
書けるぞ
R"a(  )"  )a"
2020/03/06(金) 18:26:07.10ID:k+5uYmSv
>>733
回線切って吊ってくる
2020/03/06(金) 18:43:12.26ID:XdrWOsjB
>>718
>多倍長計算ライブラリ
GMP が有名どころではありますが、GPL なのが嫌ですね
そういう人のために、かなり遅いのですけれども https://mevius.5ch.net/test/read.cgi/tech/1434079972/51 を公開していますので、よろしければ使ってください
2020/03/06(金) 20:27:49.81ID:hYOq9QPM
>>732
いや書くためにユーザーに指定させるようにしてるんだけど正直そこまでやる価値はあるんか?
って話
理念はわからなくもないけどやりすぎ感半端ない
2020/03/06(金) 21:30:02.51ID:ytQa5naT
やりたくない奴はやらなきゃいいだけ
この機能はあった方がいい
ないとrawから離れてしまうのは君自身が>713で例示している
2020/03/06(金) 22:02:29.04ID:Oq5LDxMU
>>737
嫌なら使わなきゃ良いってか?
PythonなりC#.並の記述ができるならいいけどそうじゃないからねぇ
2020/03/07(土) 00:05:13.96ID:aYdkWxa2
>>51
We regret to inform you that we are shutting down code.hackerearth.com.

Apologies for any inconvenience caused.

Thank you for understanding.
2020/03/07(土) 01:02:00.91ID:aYdkWxa2
>>735
>>739
というエラーが出てページが表示できない。
2020/03/07(土) 01:12:05.61ID:S+zsWTTW
>>740
それは https://code.hackerearth.com の今のメッセージですね、サーバーシャットダウン中でごめんなさい、ですか
ではこちらをみてください https://code.hackerearth.com/11eea6E>>740
2020/03/07(土) 01:33:50.20ID:aYdkWxa2
>>741
症状変わらず。
あなた、試してないよね?
2020/03/07(土) 01:40:43.07ID:S+zsWTTW
>>742
申し訳ございません、コードを ideone に張ったものと記憶違いをしていました
>>735 より前のバージョンを https://mevius.5ch.net/test/read.cgi/tech/1434079972/37 に置いています
2020/03/07(土) 07:24:46.08ID:HWBpZxET
>>729
> ただやはりpythonはエスケープフリーで任意の文字を含められない点で機能が不完全
だから前にも書いたけどそんな機会がどんだけあるんだよって話な
ぱっと思いつくのは " や ' を含む正規表現を書きたい時ぐらいだけど毎回そんなものを書かないだろ
めったに無い時のために毎回無駄な ( ) を書かされるのはちょっと嫌
※ 最後の行は個人の見解です
2020/03/07(土) 08:46:17.40ID:CT6knIM5
すみません、教えてください
JAVAだとinterfaceを定義してsetListner的なことが出来て、リスナー不要なときはnullを指定できます。

C++だとどうかけばいいでしょうか?
interface用のクラスを一つ用意してvirtualメソッドを並べれば出来そうな気がしますが、リスナー不要な時に上位からnullを指定できない気がしていて
746デフォルトの名無しさん
垢版 |
2020/03/07(土) 09:53:24.66ID:iUAwzQ87
std::functionが一番簡単だと思いますが。
2020/03/07(土) 10:21:48.59ID:CT6knIM5
ありがとうございます。

具体的なコードを教えて頂けないでしょうか?
例えば、適当に拾った以下のJavaコードを例にして同じ事を出来るとC++のサンプルを教えて頂けると参考になります。

続く
2020/03/07(土) 10:21:58.29ID:CT6knIM5
class HeavyTask {
    private TestListener listener;
    // interface 設定
    interface TestListener {
        void onSuccess(int result);
    }
    // listener
    void setListener(TestListener listener) {
        this.listener = listener;
    }

    void taskStart() {
        int sum = 1;
        int i= 0;

        for ( ; i<  20; ){
            sum += sum;
            i++;
        }

        if(listener != null) {
            // 計算が終わったら結果をlistenerに渡す
            listener.onSuccess(sum);
        }
    }
}
749デフォルトの名無しさん
垢版 |
2020/03/07(土) 11:01:38.19ID:iUAwzQ87
え?めんどくさいですが?
2020/03/07(土) 11:04:48.12ID:CT6knIM5
すみません、簡単な例でいいので、リスナー登録してそこから複数のメソッドがイベント毎に呼ばれるようにする方法がしりたいです。。
751デフォルトの名無しさん
垢版 |
2020/03/07(土) 11:09:04.29ID:iUAwzQ87
std::functionは関数っぽいものなら何でも突っ込めるので、好きなようにお使いくださいとしか。

本当は出来ないんだろ?とか煽ればだれか書いてくれるかも。
2020/03/07(土) 11:13:54.29ID:CT6knIM5
まだイメージが沸かないですよね。。使い方も
2020/03/07(土) 11:20:59.13ID:NiWYPfBM
最初に自分がいってるとおりじゃないんか
インターフェイスの派生クラスのポインタ渡せばいいだけで
不要なら0入れて呼ぶときにチェックするだけじゃないの
2020/03/07(土) 11:27:48.77ID:AiHnVJpq
てか、C++でもほとんど>>748と同じようなコードになるだろ
2020/03/07(土) 12:03:07.45ID:CT6knIM5
具体的にfuntionを使って、リスナーをnewして呼び出すあたりとかコードがみたいです。。virtualだと誰かが継承してクラス化しないとだめですよね?

Javaのように、setListenerの引数にリスナーだけnewしてしていとか、null指定とかする方法がやっぱりよくわからないです。
2020/03/07(土) 12:05:29.33ID:qpmtEUNF
そのjava版晒せば変換してやるが
2020/03/07(土) 12:06:49.73ID:CT6knIM5
ちょっとまってください
2020/03/07(土) 12:07:03.25ID:NiWYPfBM
クラス化してポインタで管理するだけ
javaみたくnewでそのままオーバーライドはできないと思う
やりようあるんかな
2020/03/07(土) 12:10:36.55ID:NiWYPfBM
newしてラムダ式でも渡せばできるか
2020/03/07(土) 12:12:57.85ID:qpmtEUNF
new要らんのでは?
2020/03/07(土) 12:21:54.31ID:CT6knIM5
すみませんが、これでお願いします。
C++のfunctionを利用して、一番スマートな感じなコードを教えてください。
m(__)m

続く↓
2020/03/07(土) 12:22:53.25ID:CT6knIM5
// 上位からやりたいこと
class Main {
Test test = new Test();

test.setListener(null); // callback不要な時はnullを指定したい

// callbackが欲しい時はこんな感じで登録したい
test.setListener(new Test.TestListener() {
@Override
onSuccess(int result) {
System.out.println(result);
}
@Override
onError(int errorCode) {
System.out.println(errorCode);
}
});
test.run();
}
続く↓
2020/03/07(土) 12:23:36.37ID:CT6knIM5
// Testの中身の作りはどうでもいいです。
// Main側からTest側が綺麗に呼び出せれば、それに合わせてTest側を作りかえるでOKです。
class Test {
interface TestListener {
void onSuccess(int result);
void onError(int errorCode);
}
private TestListener listener;

void setListener(TestListener listener) {
this.listener = listener;
}

void run() {
if (listener != null) {
listener.onSuccess(0);
listener.onError(1);
}
}
}
2020/03/07(土) 12:24:15.53ID:CT6knIM5
スペースがちゃんと入ってなく、見づらくて申し訳ないです。
よろしくお願いしますm(__)m
2020/03/07(土) 12:37:30.49ID:+VsyTV1D
こんな自分でやる気のない人にはぜひエサを与えないでほしい。
766デフォルトの名無しさん
垢版 |
2020/03/07(土) 12:39:57.68ID:iUAwzQ87
いや、困ってるみたいだし、書いてやれよ。
俺がケチョンケチョンに添削してやるから。
2020/03/07(土) 12:40:37.61ID:CT6knIM5
やる気がないわけではなくて、勉強しているけどどう書くのか分からないだけです。。
2020/03/07(土) 12:45:37.23ID:CT6knIM5
C++だと、イメージだけど
test.setListener([](int result)) { print(result); });
みたいにかけそうってのはわかりましたが。。

NULL指定したい時とか複数のoverride対象の
メソッドを並べる書き方とか良く分からず。
2020/03/07(土) 13:05:14.05ID:ECZE2b67
class TestListener {
public:
virtual void onSuccess(int result) { }
virtual void onError(int errorCode) { }
};
2020/03/07(土) 13:09:06.48ID:ECZE2b67
class Test {
private:
TestListener *m_listener;
public:
Test() : m_listener(NULL) { }
void setListener(TestListener *listener) {
m_listener = listener;
}
void run() {
if (m_listener != NULL) {
m_listener->onSuccess(0);
m_listener->onError(1);
}
};
2020/03/07(土) 13:10:29.44ID:qpmtEUNF
https://wandbox.org/permlink/zaFleQEzG1dSUuAL
2020/03/07(土) 13:12:54.90ID:0g+cGFce
式としての匿名クラスはc++には無いよ。
クラス宣言としての無名(?)クラスは書けるけど。
https://ideone.com/SnMj5k
2020/03/07(土) 13:13:53.37ID:ECZE2b67
class MyListener : public TestListener {
public:
virtual void onSuccess(int result) {
printf("だから何?\n");
}
virtual void onError(int errorCode) {
printf("100年ROMってろ\n");
}
};

Test test;
MyListener lis;
test.setListener(&lis);
test.run();
2020/03/07(土) 13:18:44.05ID:CT6knIM5
ありがとうございます。

>>771
Test2がイメージしていたのと近いです。
こんな感じで書くんですね。
775772
垢版 |
2020/03/07(土) 13:20:39.61ID:0g+cGFce
>>768
> 複数のoverride対象のメソッドを並べる書き方とか

>>772はこれ↑についてのレスね。
foo.addMouseListener(new MouseAdapter() {
 public void mouseClicked(MouseEvent e) {}
 public void mouseMoved(MouseEvent e) {}
});
きっと↑こーいうのがやりたいんだと思って。
2020/03/07(土) 13:20:43.30ID:CT6knIM5
ちょっと試してみます
2020/03/07(土) 14:15:14.60ID:CT6knIM5
ありがとうございました。
内容は大体理解できたので、今後のテンプレとして使わせていただきます。
助かりました!
2020/03/08(日) 22:16:34.90ID:51E2S4Dp
http://codepad.org/4KkPN9ki

上記を実行すると下記結果になります。
[2]を見ると、vectorの3つ目以降はポインタのアドレスがあうのですが、2つ目までは合っていません。
MAPの方にはvectorのポインタを渡しているつもりなので、[2]のアドレスはvectorのアドレスと一致する。
が期待値なのですが、理由はわかりますでしょうか?

[1]
VECTOR ABC 0x144dd20
VECTOR DEF 0x144dd28
VECTOR GHI 0x144dd30
[2]
MAP itr GHI 0x144dd30 ←vectorの3つ目以降はポインタが一致する
MAP itr ABC 0x144dc20
MAP itr DEF 0x144dcc8
[3]
VECTOR for_each ABC 0x144dd20
VECTOR for_each DEF 0x144dd28
VECTOR for_each GHI 0x144dd30
2020/03/08(日) 23:05:19.29ID:SIolBUWz
emplace_back()の時にvectorのサイズが拡張されて中身が再配置されることがある
そうなると拡張前に取ったポインタは無効になる

嫌だったらvectorの挿入削除が一通り終わってからポインタ取るとか、
必要量でreserve()して再配置されないようにするとか、deque使うとかその辺
2020/03/09(月) 07:24:49.77ID:50Nkxt/s
vector<int> v があるとして、
for(auto i: v)
というループの中で v の要素を変更したときの挙動って言語仕様として決まってるの?

あと、
for(auto i: set<int>(v.begin(), v.end()))
みたいなループを書いたときって set の定義を外に出したときと比べてパフォーマンス上の違いある?
2020/03/09(月) 07:59:37.36ID:kzUaYlzv
&
2020/03/09(月) 08:17:06.64ID:aBhFrWy9
>>780
for(auto e: vec){ statement }
はこんな感じで展開される
{
 auto && __range = vec;

 for (auto __begin = begin(__range), __end = end(__range); __begin != __end; ++__begin) {
  auto e = *__begin;
  statement
 }
}
ポイントとしては内部でイテレータを使ってるからイテレータ無効化ルールに抵触したらおかしな動きになる
(ループの中でvec.push_back()をするとか)。

二つ目の質問については、上の例の
 auto && __range = vec;
のように最初に定義域を右辺値参照で取ってるからsetの定義を外に出す必要はない
2020/03/09(月) 10:20:22.51ID:CscrLobz
>>778
vector のイテレータが無効になる条件。
https://ja.cppreference.com/w/cpp/container/vector#.E3.82.A4.E3.83.86.E3.83.AC.E3.83.BC.E3.82.BF.E3.81.AE.E7.84.A1.E5.8A.B9.E5.8C.96
emplace_back の場合はそれを実行した後の size() が capacity() より大きいときにイテレータが無効になる。
https://ja.cppreference.com/w/cpp/container/vector/emplace_back

vector は要素が必ず隣接したアドレスに配置されるというルールなので
連続したアドレスで拡張することが出来なければ再配置することがある。
C で言うところの realloc みたいなこと。
要素の数が増えるような操作はだいたいイテレータを無効にすると覚えておけばいい。
2020/03/09(月) 22:02:02.24ID:0hJmIbuo
>>779,783

vectorは連続したアドレスだから拡張していけば必ず再配置しないといけなくなりますね。
納得しました。
reserveを検討してみます。
2020/03/09(月) 22:50:43.87ID:yYcTR1n2
inlineについて質問です。

ttps://qiita.com/omuRice/items/9e31d9ba17b32703b3b1

上記を見ると下記のように書いてあります。

//ヘッダファイルでしかinlineで定義できない
//別ファイルで書くとinline展開の時にエラーになる.

しかしヘッダファイルではなく、クラスの本体ファイルの方に書いてもエラーになりませんでした。
c++11を使っているのですが、最新ではエラーになるということでしょうか?
2020/03/09(月) 23:35:25.22ID:XT24roZc
よく読めよ

(本来だったら、ヘッダファイルにクラス定義をしてメンバ関数の実装は別ファイルで行なった方が適切です。(Allocationエラーを防げる))
2020/03/09(月) 23:41:32.15ID:otQrr6l+
inline関数を定義したファイル内からそのinline関数を呼ぶ分にはエラーにならない
別ファイルでmyClass.hppをインクルードしてinline関数を呼ぼうとするとエラーになる
という意味ではないだろうか
2020/03/09(月) 23:48:35.15ID:yYcTR1n2
>>787

なるほど。
自身のファイルならinlineの関数も見えているから展開できる。
他のファイルで使うときはinline展開する中身が見えないからエラーになる。
というのがしっくりきそうですね。
2020/03/10(火) 17:39:07.74ID:CIHR5C1w
そのAllocationエラーを防げる、って何の話だろう
2020/03/10(火) 18:47:12.48ID:VUvg76Dj
上のqiitaは初心者っぽいし正しいことを書いてるとは限らない
2020/03/10(火) 19:12:03.87ID:HIU8QCM9
>>789-790
俺はそれよりも「インラン展開」の方が気になる
2020/03/10(火) 19:21:46.83ID:VUvg76Dj
今のinlineの意味は「同じ定義である限り何度でも定義していいよ」だからな
展開云々はコンパイラが勝手にやる話であってプログラマが指定する話ではない
上のqiitaの人は昔のネット記事を読みながら勉強したんだろう
2020/03/10(火) 19:29:03.34ID:HIU8QCM9
でもまあ各翻訳単位に定義があれば結果的にインライン化しやすくはあるよな。
2020/03/10(火) 21:03:29.37ID:tA89nuFe
今のinlineの効果は元のinlineの効果の必要条件
2020/03/10(火) 22:56:08.25ID:y1k8c7Fe
788です。
私が作成しているプログラムではinlineに変えると逆に遅くなってしまったので元に戻しました。。
2020/03/11(水) 00:05:35.50ID:ECpQyQHt
>>783
>要素の数が増えるような操作はだいたいイテレータを無効にすると覚えておけばいい。
削除は!?
要素の削除はどうなるのです??!!
2020/03/11(水) 00:22:12.50ID:FbH1Tm9+
>>796
正確なところは個別の場合を見てもらうしかないんだけど、
代表的な例としてたとえば erase なら削除したとこより後のイテレータは無効になるルール。
https://ja.cppreference.com/w/cpp/container/vector/erase

shrink_to_fit は再確保が発生したなら全て無効。
https://ja.cppreference.com/w/cpp/container/vector/shrink_to_fit

pop_back なら最後の要素と終端のイテレータが無効。
https://ja.cppreference.com/w/cpp/container/vector/pop_back

常識的な実装を考えればそりゃそうだろって感じで特に意外性はない。
2020/03/11(水) 13:52:07.40ID:SPtGmxHY
……素朴に考えると範囲for文の中で削除してもよしなにやってくれそうな気はする

for(auto blt: enblts){
if( blt.isDead() ) enblts.erase(blt);
}

しかしこれはC++でもJava(remove)でも願い通りには動かない
でも弾幕ゲームをやってる初心者の直感では正しい


としたらこれから先の時代はフィルタで書いた方がいいのかもしれない

erase_if( enblts, [](Bullet blt){return blt.isDead();} );//c++, vector

enblts.remove_if( [](Bullet blt){return blt.isDead();} );//c++, list

enblts.removeIf( blt -> blt.isDead() );//java

enblts = filter( lambda blt: blt.isAlive(), enblts )#python

@enblts = grep{ $_->isAlive() } @enblts;#perl
2020/03/11(水) 16:06:43.34ID:FbH1Tm9+
>>798
C++20 で ranges が入るよ。
2020/03/11(水) 17:00:24.04ID:U2q7VXWI
https://en.cppreference.com/w/cpp/container

Iterator rinvalidationに一覧表が載ってるからみなはれ
2020/03/11(水) 18:12:50.00ID:74rzlAzp
>>798
listなら直感どおりに動くぞ
やっぱlistなんだよなあ
2020/03/11(水) 23:11:04.22ID:Z15vlJGb
↓こういう事って可能ですか?

class AClass
{
};

class BClass
{
public:
void Test();
};


int main ()
{
AClass a;
BClass b;
a += { &b, &BClass::Test }; //これを実現したい
}
2020/03/11(水) 23:16:43.17ID:U9Axp26U
>>801
ゲロ遅だけどな
2020/03/11(水) 23:17:39.42ID:U9Axp26U
>>802
何がしたいのかわからん
2020/03/11(水) 23:23:16.34ID:fq6QtVVC
>>802
何をやりたいのかよくわからんがエスパーしてみると、メンバ関数ポインタやstd::function、演算子オーバーロードあたりを使えばいいのか
2020/03/11(水) 23:36:37.62ID:74rzlAzp
AClass::operator+=(std::initializer_list<void*>)でも実装すればいいのか?試してないけど
2020/03/12(木) 00:07:14.34ID:dKrK1fwX
{}で囲った物を、演算子やら関数なんかの引数として動くようにできるのか。言語仕様的に駄目なのかよくわからん。
ちなみに{}内の要素は異なる型が混在する。
C#のeventみたいな物を非マネージC++環境で作れないかと試している。
で、クラスメンバ関数の扱いで試行錯誤中。その他もろもろの実装はやれてるので、残りはこれだけ。
2020/03/12(木) 00:27:16.78ID:FwbIBGsL
関数テンプレートのテンプレート実引数推定時、引数に渡した{}は真っ先にinitializer_listとして推論されるので、異なる型を混在できない
引数をテンプレートじゃなくて、集成体とか普通のクラスにしとけば{}で渡せるけど、予め{}の中に入れられる型を固定しなければならない
2020/03/12(木) 00:36:24.84ID:b+BTD4Kr
こういうこと?

#include <iostream>
#include <vector>
#include <functional>
class AClass {
public:
void operator+=(std::function<void()> f) { handlers.push_back(f); }
void notify() { for (auto &f : handlers) f(); }
std::vector<std::function<void()>> handlers;
};
class BClass {
public:
void Test(){std::cout << __func__ << std::endl;}
};
int main () {
AClass a;
BClass b;
a += std::bind(&BClass::Test, &b);
a.notify();
}
2020/03/12(木) 01:57:39.17ID:dKrK1fwX
>>809
一番初めに書いたけど、
a += { &b, &BClass::Test };
こういうすっきりした書き方ができないかと考えていたわけで。
std::function系はC#のeventで言う -= の挙動の実装が難なので、使っていません。

できないっぽいのでこの質問は終了とさせていただきます。
ご助言していただいた皆様ありがとうございました。
2020/03/12(木) 03:25:56.97ID:tyiaM2Xy
c#ぽく書くのには限界あるよね

自分の場合は名前付きでstd::functionで持って
a.add("b",[&]{b.Test();})
みたいにしているな。
2020/03/12(木) 12:41:33.69ID:yVQIWR3t
EnumProcessModules でメインモジュール含め、全モジュールのベースアドレスとイメージサイズをゲットできると思うんですが
この範囲にないメモリ領域かつ、プロセスがコミットしてるメモリ領域って何が載っているんでしょうか?

検索していくと、MEM_COMMIT かつ PAGE_READWRITE かつ MEM_PRIVATE で、
プログラム中に書いた文字列がヒットするような領域もあるんですが
2020/03/12(木) 13:29:56.54ID:jKEc330C
>>803
リンクリストは速度的にはオールマイティーに近いデータ構造で、イテレートの速度も配列と同程度。
2020/03/12(木) 13:32:10.32ID:jKEc330C
>>813
リンクリストが劇遅だと思っている人は、マシン語レベルでどういうコードになっているか分かって無いために、効率の良い使い方ができていないため。
正しく使えば、動的配列より平均速度もメモリ効率も速くなる確率が高いデータ構造。
815810
垢版 |
2020/03/12(木) 15:24:18.59ID:dKrK1fwX
自己レスになりますが下記様なコードで最初の目的が達成できました。可変のコンストラクタ作っとくと{}の初期化の振り分けできるんですね。
template<class FUNC_TYPE>
class MetaFunction;
template<class ...ARG>
class MetaFunction<void(ARG...)>
{
public:
template<class ...INITARG>
MetaFunction(INITARG... arg) { Init(arg...); }
template<class T>
void Init(T* Instance, void(T::*proc)(ARG... arg))
{ //メンバ関数用の初期化
}
};
template<class FUNC_TYPE>
class EventHandler;
template<class ...ARG>
class EventHandler<void(ARG...)>
{
using META_FUNC = MetaFunction<void(ARG...)>;
public:
template<class T>
void Add(T* Instance, void (T::*proc)(ARG... arg))
{ //追加処理とか
}
inline EventHandler& operator+=(const META_FUNC& func)
{
this->Add(func);
return *this;
}
};
2020/03/12(木) 16:21:53.74ID:yVQIWR3t
>>812
いろいろググってみましたが、分かったような分からんような…
とりあえず、MODULE_INFO.SizeOfImage は、読み込まれた Portable Executable のサイズを表してるっぽい?んでしょうか
コード命令が入ってる .text や、グローバル変数が入ってる .data 領域などいろいろ領域があってフォーマットが決まってるみたいだけど、
実行時のヒープやスタックとかは入ってないっていう認識で良いんでしょうか

PE のフォーマットググっても、exe をバイナリエディタで見たときのフォーマットは結構出てくるんですが、
メモリに載せた時のフォーマットって出てこないんですよね…、EXEをバイナリエディタで見た時と似たような感じだとは思うんですが多分まんまではないですよね
2020/03/12(木) 16:42:31.73ID:JixgA0dC
>>816
ReactOS のソースコードを見てみれば?
2020/03/12(木) 17:45:34.82ID:5A3Kadll
遅いと思うとかじゃなくて実際にやった結果
listは激遅 
dequeが1番良い
追加削除してもな
2020/03/12(木) 18:50:46.21ID:xw4q52xX
>>812
C++関係ないからWin32APIスレとかで聞けばいいんでないの?
2020/03/12(木) 18:52:40.90ID:xw4q52xX
>>813
リンクリストがオールマイティというのは、お前がリンクリスト使う処理しか書かないからというだけじゃね?
2020/03/12(木) 20:25:21.28ID:YvE3jgHm
天才の人でしょ
ほっとこ
2020/03/12(木) 20:30:58.97ID:9KLbHvc8
必死こいてリンクリスト宣伝して何になるんだろう
2020/03/12(木) 20:40:10.69ID:yVQIWR3t
>>817
検索してみたけど、大規模なソースコードっぽいので、じっくり調べるには時間かかりそうです
でもありがとう

>>819
なるほど、そっちの方が適切っぽいですね、ありがとう
2020/03/12(木) 21:40:44.59ID:4MxR0DBA
>>782
丁寧に説明していただいてありがとうございます!
2020/03/13(金) 03:26:23.39ID:BoiDYB4T
ウヘン参照はどんなときに役立つんだ?
即値が代入出来るようになっただけか?
2020/03/13(金) 07:01:46.94ID:8hjAly81
>>825
右辺値参照は右辺値(何もしないとその場で消えてなくなってしまうもの)をコピーを発生させずに捕まえておくことができる。
例:
>>782
  auto && __range = vec;
(正確にはauto&&はvecが左辺値の場合は通常の参照に、vecが右辺値の場合は右辺値参照になる)

他には関数のオーバーロードと組み合わせて引数が左辺値なのか右辺値なのかを区別して処理を振り分けることができる。
例:
void func(std::vector<int>& vec){ std::cout << "左辺値専用の処理" << std::endl; }
void func(std::vector<int>&& vec){ std::cout << "右辺値専用の処理" << std::endl; }
int main(){
  std::vector<int> vec;
  func(vec); // -> 左辺値専用の処理
  func(std::vector<int>{1,2,3}); // -> 右辺値専用の処理
  return 0;
}
2020/03/13(金) 09:59:34.43ID:o4vL6hq2
右辺値参照はほとんどムーブのための機能と言ってもいいかな。
左辺値か右辺値かを「区別」できることが重要であって、
参照の機能として特別なものがあるわけではない。
この区別が必要になったのはコピーの文脈かムーブの文脈かを知るため。
std::move が右辺値にキャストするだけということからも右辺値とムーブの関連性の強さが感じられる。

その上で右辺値参照と左辺値参照を自動で振り分ける参照 (ユニバーサル参照) を使えば
定義はひとつしか書いていないのに左辺値と右辺値の両方に対応できているなんてことも出来る。

ただし、右辺値参照は左辺値だということを忘れないように。
参照が左辺値参照か右辺値参照であるかを区別して再度振り分けなおすために std::forward がある。
2020/03/13(金) 11:05:37.71ID:PLNbAfh2
auto&&は右辺値参照のくせに左辺値を束縛できるぞ
2020/03/13(金) 12:25:06.20ID:0DRjOF6k
ユニバーサルはテンプレートの文脈(なおかつTがテンプレート仮引数そのもの)
でなければ使えない
便利さばっか強調してると誤解招くぞ
2020/03/13(金) 12:49:42.57ID:o4vL6hq2
>>828
auto&& はどこでもユニバーサル参照になる。
2020/03/14(土) 06:54:36.59ID:rF6MWNax
arithmeticとかpromotedってなんぞ
c++11以降のpow(int, int)の返り値はintなのですか?
2020/03/14(土) 09:56:19.78ID:LPZ7/QQq
>>831
https://wandbox.org/permlink/lvhjgR3yOrBeTqek
2020/03/14(土) 15:29:27.33ID:7CRfyKLY
>>831
候補として書いてある通りの型しかないよ。
https://ja.cppreference.com/w/cpp/numeric/math/pow
だけど、普通にオーバーロードしたら曖昧な状況が出来る場合があるだろ。

float foo(float x) { return x; }
double foo(double x) { return x; }

int main(void) {
foo(1); // どちらを呼び出せばいいのかわかんのでエラー。
return 0;
}

かといって int 版を追加、 long int 版、 long long int 版を追加……とかしていくのは面倒だなぁってことになるわけ。
それも二引数だったら全部の組み合わせが必要になってくる。
で、関数テンプレートで算術型ならなんでも受け取れるようにしておいて候補のどれかに振り分けるようにしようみたいな。
そういう感じ。
うまいこと振り分けなおす関数テンプレートがあるってだけ。
2020/03/14(土) 21:46:19.71ID:47FyzBVp
c++のお勧め本教えて
初心者ではないけど、ここの話に付いていけるようにちゃんと学習したく。
2020/03/14(土) 21:48:34.12ID:pvdkYWPZ
とりあえずeffectve modern c++読んで
次は「ISO/IEC 14882:2017 Programming Languages -- C++」とかいう本を読むといいよ
836デフォルトの名無しさん
垢版 |
2020/03/14(土) 23:28:51.97ID:mG8QFb0E
江添亮でいいのでは
2020/03/15(日) 00:20:59.48ID:CAhbnrV8
>>832-833
ありがとうございます
妄想でした
2020/03/15(日) 01:01:17.34ID:r+ZbHRhu
>>836
本の名前は?
2020/03/15(日) 07:49:43.36ID:4h5eTXB1
>>838
ほらよ
https://cpplover.blogspot.com/2013/10/c11c11.html
2020/03/15(日) 09:41:19.99ID:d31MAJ7H
捨て魔乙
2020/03/15(日) 10:23:33.77ID:b9Qsc7j/
ステマというか、C++ の開発者で、

標準化委員会の江添亮、επιστημη(エピステーメー)、高橋 晶などを、
知らない香具師は、いないだろ
2020/03/15(日) 10:26:55.73ID:xxuRolQk
そりゃ有名だが悪い意味すぎるだろ。
843841
垢版 |
2020/03/15(日) 11:28:19.19ID:b9Qsc7j/
C++11/14 コア言語、江添 亮、2015

でも、この本は、プロにとっては、神の書!
規格書の意味を、簡潔なソースコードで例示したのだから

でも、C++の恐ろしいのは、これでもすべてじゃない!
あまりにもルールが多すぎるから、省略ばっかりw
844841
垢版 |
2020/03/15(日) 11:34:21.68ID:b9Qsc7j/
組込み開発者におくるMISRA‐C:2004―C言語利用の高信頼化ガイド、MISRA‐C研究会、2006

この研究会は、トヨタなど大企業から、数十人のベテが集まって、
簡潔なソースコードで例示したけど、

江添の「C++11/14 コア言語」は、一人で書いたのが恐ろしい。
エベレスト単独登頂ぐらいの記録w

あまりにも、crazy
2020/03/15(日) 11:36:58.87ID:uLtpsypH
いまどき香具氏て…
2020/03/15(日) 12:01:05.67ID:MhnteVR9
>>844
内容に間違いないことどうやって担保してんの?
2020/03/15(日) 12:06:13.12ID:4h5eTXB1
その本に限ったことではなく
聞いた話は他のソースで裏を取るのが
騙されたくない人のすることだ

お昼のワイドショーに洗脳されるBBAがこの逆をいく例
848841
垢版 |
2020/03/15(日) 12:17:39.66ID:b9Qsc7j/
>>846
ニコ生・角川の社員が、テストするのかな?
2020/03/15(日) 12:19:04.85ID:g709JiKq
原稿のコードを自動でチェックするシステムくらいは作れるだろ
他の間違いはしらない
2020/03/15(日) 12:54:08.39ID:+dNV/3ST
とりあえず明らかな間違いはあるな。
http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#expr.pseudo
> 疑似デストラクター呼び出しとは、デストラクターを明示的に呼び出すことができる一連の式である。
2020/03/15(日) 13:31:42.55ID:kwDmCDNs
ほんとだセミコロン忘れてる
852デフォルトの名無しさん
垢版 |
2020/03/15(日) 20:45:50.04ID:jQKVyB4O
>>842
わろた
2020/03/15(日) 21:05:04.93ID:mDv1gcW7
>>849
自動チェックに使うコンパイラは?
2020/03/15(日) 21:16:57.24ID:+dNV/3ST
>>851
そこを指摘したつもりじゃなかったんだけど、確かにセミコロン抜けてるね。
> C * ptr = &c
2020/03/15(日) 21:23:17.68ID:xxuRolQk
そういうテストの発想が江添には根本的に欠けてる。
2020/03/15(日) 21:31:41.42ID:kwDmCDNs
あの人ソフトウェアエンジニアじゃないからな
2020/03/15(日) 22:05:46.40ID:xxuRolQk
言語についてあれこれ言うなら今時は必要な視点だろ。
20年前で時間が止まってんのかね。
2020/03/15(日) 22:40:56.98ID:+dNV/3ST
コードのチェックについてはその後反省して改善したらしいよ。
https://cpplover.blogspot.com/2016/09/c17.html
> 参考書のソースコードからサンプルコードを抽出してコンパイルするテストは、適当なツールがなかったので適当に実装した。C++で書いて200行ぐらいだった。
2020/03/15(日) 22:51:25.52ID:rc8Rza68
ストラウストラップの本こき下ろしてたクセにテメェもろくな本書けないっていう

ストラウストラップの本拾い読みする方が何万倍ありがたいわな
2020/03/15(日) 23:48:59.29ID:fPKa1ljm
江添さんのC++入門本を読んでいますが、「末尾再帰」を完全に間違えていますね…
私と同じ間違え方でしたが、私以外にも間違える人がまだ居るようですね

view-source:https://ezoeryou.github.io/cpp-intro/#再帰関数
>int factorial( int n )
>{
> if ( n < 1 )
> return 0 ;
> else if ( n == 1 )
> return 1 ;
> else
> return n * factorial(n-1) ;
>}
>この関数は、引数nが1未満であれば引数が間違っているので0を返す。そうでない場合でnが1であれば1を返す。それ以外の場合、n * factorial(n-1)を返す。
>このコードは末尾再帰になっている。
2020/03/16(月) 00:22:37.82ID:G3zRW41Y
ええ・・・本にする前に誰も気付かんかったんか・・・
2020/03/16(月) 00:45:44.02ID:0NEQgDaD
>>860-861 指摘はあるけど、放置されてる。
https://github.com/EzoeRyou/cpp-intro/issues/124
https://github.com/EzoeRyou/cpp-intro/issues?q=is%3Aopen
2020/03/16(月) 01:14:59.26ID:5L/YS0FP
>>860
ところでそのケースは末尾再帰ではないが、
gcc で -O2 を付けるとループに最適化するんだ。
賢いなぁ!
2020/03/16(月) 03:21:15.54ID:gTHYoNh+
大抵一番目の引数はレジスタで代用したりする最適化するよね
2020/03/16(月) 05:32:55.58ID:3/OYci0N
0の階乗は1だよ普通は
2020/03/16(月) 06:24:40.20ID:ZXIIT5PQ
>>864
それは最適化ではなくABIで決まっていることでは
2020/03/16(月) 09:19:27.29ID:BYpTFeXn
>>860
>return n * factorial(n-1) ;

n を掛けたら、ダメなのか。
return factorial(引数)としないといけないのか

関数の引数に、蓄積器を持つように、変形しないといけないのか
2020/03/16(月) 09:39:27.07ID:W7KsQnwt
スタックが何を保持しとかないといけないか考えたらわかることだけどね。
2020/03/16(月) 11:27:12.93ID:5L/YS0FP
>>867
末尾で呼び出した関数の返却値を「何も加工せずに」そのまま返却値にするような場合は、
素朴なスタックを使う ABI だと積んだのを直後に降ろす操作になるだけなんだ。
だから相殺してスタック操作を消せる。 call と ret からスタック操作を消すとジャンプになるという理屈。
Wikipedia の説明とかを見てもわかりにくいんだけど、スタックの動きで考えるとわかりやすいと私は思う。
2020/03/16(月) 17:12:50.16ID:cfMsQza/
>>869
32BIT の x86のアセンブラで書けば、
push dword ptr a2
push dword ptr a1
call func_addr
add esp,8
ret
となっているのを
mov eax,a1
mov [ebp+xxx1],eax  // xxx1は仮引数1のスタック上の相対位置
mov eax,a2
mov [ebp+xxx2],eax  // xxx2は仮引数2のスタック上の相対位置
jmp func_addr
などとすると。再帰を行わなくても
return retcode; 文は、
mov eax,retcode
add esp,8
ret
とコンパイルされるから、結局等価になる。
2020/03/17(火) 06:17:25.18ID:1m7vQNwx
コンパイラに「inline指定された部分がインライン化できなかったら警告」
みたいなオプションがあるけど、それと同様に、
プログラマが末尾再帰のつもりで書いた関数(ソースに明示する)が
実際には末尾再帰じゃない場合に指摘してくれるような機能はないじゃろか。

最適化機構の中でチェックできてるはずだし、学習の役立ちそうな気がする。
末尾再帰に慣れた人には不要な補助輪だろうけど。
872デフォルトの名無しさん
垢版 |
2020/03/17(火) 07:39:32.88ID:xTOfsl1/
二本のスタックを使って木をコピーする方法を思いついてしまったかもしれない。
2020/03/17(火) 09:20:37.53ID:wg7JTafn
心底どうでもいい機能を無駄に入れようとするな
そんなことするくらいなら自力で再帰でない書き方する方がまともな対応
スタック消費を気にするなら再帰で書こうとすること自体が間違ってる
874デフォルトの名無しさん
垢版 |
2020/03/17(火) 09:43:08.15ID:xTOfsl1/
江添さんがこのスレを見てれば委員会に提案してくれるかも。
2020/03/17(火) 12:33:47.35ID:uS/+7KOG
明示的にオーバーライドしないとできない様に制限する機能ってないの?
たまに同名同タイプで気づかずにオーバーライドしてしまった事があるんだが。
2020/03/17(火) 12:54:20.37ID:ZQD4xStF
規格はコンパイラの警告は決めてない
警告機能が欲しいならコンパイラの開発者に要望を出すんだな
2020/03/17(火) 13:00:16.10ID:vGhk4vWX
>>873
だな
2020/03/17(火) 13:22:13.65ID:Aeuh89FK
>>1
アセンブリファイル出力を行うようにコンパイルオプションを設定して、自分で出力アセンブリコードを見ればいいだけ。
2020/03/17(火) 13:44:23.77ID:vGhk4vWX
意図したとおりの訳になったかどうかが問題になるのはスポットで全域じゃないからな
ただ、そういう箇所はコンパイラの出力を参考にアセンブラで書くべきだと思うが
2020/03/17(火) 17:18:47.62ID:1m7vQNwx
>>875 gcc の ver.5 だと -Wsuggest-override って警告オプションがあるね。
これと警告をエラー扱いにする指定を組み合わせればいいのかな。
2020/03/20(金) 17:50:02.32ID:GuzL6Him
別に
アーキテクチャ依存の話を持ち出さずとも、
 fractional(n) = n * fractional(n-1)
とゆー事実をもってただちにfractional(n)は末尾再起と言える
なぜなら
 fractional(n) = n * ((n-1) * fractional(n-2))
   = n * ((n-1) * ((n-2) * fractional(n-3)))
= ....
となってfractional(0)に至るまで延々展開でき、*が可換である故にこれは
 fractional(n) = n * (n-1) * fractional(n-2)
   = n * (n-1) * (n-2) * fractional(n-3)
= ....
となって右端を延々展開して「も」得られるからである

*の可換性への依存を良しとしない立場をとったとたん、末尾再起関数と認められるものは
 f(n) = f(n-1)
とゆーnに関する恒等写像のみとなる
そう言いたいのであれば別に止めはしないがそっちの方が異端じゃないの;
つまり頭おかしい
2020/03/20(金) 20:19:49.63ID:UDatiCXC
>>881
>>881
>fractional(n) = n * fractional(n-1)

fractional(n-1) から値が帰ってきたあと、その値と n とを掛け合わせる計算は fractional(n) の関数内で実施しているでしょう?
コールした関数から戻ったときに、そのままなにもせずに得た値をリターンするのならば末尾再帰ですが、
この場合は得た値を加工してからリターンするのだから、これは末尾再帰とはいいません

> fractional(n) = n * (n-1) * fractional(n-2)
>   = n * (n-1) * (n-2) * fractional(n-3)
>= ....
>となって右端を延々展開して「も」得られるからである

展開可能であることと末尾再帰であることはなんの関係もありません

>*の可換性への依存を良しとしない立場をとったとたん、末尾再起関数と認められるものは
> f(n) = f(n-1)
>とゆーnに関する恒等写像のみとなる

* の可換性はなんの関係もありません
引数を一つに限定するのならそうですが、プログラム言語は引数を二つ以上持ってもいい
普通は f() の引数を二つ以上とって、その中にアーキュムレータを置いて末尾再帰にします。
f(s, t) = f(u, v) = f(w, x) = …
むしろこっちの方が普通の末尾再帰といっていいでしょう
2020/03/20(金) 21:29:36.56ID:GuzL6Him
>展開可能であることと末尾再帰であることはなんの関係もありません
>* の可換性はなんの関係もありません
大きく出たな…

まず右端展開の繰り返しにより表現可能でありかつ末尾再起化できない関数というものは無い
なぜなら、右端展開の繰り返しを手続き的に書けばループに他ならんぬ、、、

逆も真で、ループとして書ける関数なら右端展開の繰り返しとしても表せるんであーる
つまり、右端展開の繰り返しにより表現可能であることと、末尾再起化できる関数というものは同値
で、アキュムレータを使った複数引数の関数化というものは、関数の表現を右端展開繰り返し可能な形に直しているにすぎない

で、右端展開の繰り返しにより表現可能かどうかには演算子の結合則が関係する例は
>>881に挙げたとーり

実際、演算子の結合則が成り立たない例として、Aが行列でIが単位行列のとき
 fractional3(A) = fractional3(A - I) (A - I) ・・・(1)
というブツを考えると、この関数は右端展開可能でないからもはや末尾再帰化はできない
Aが実数でIが1なら末尾再帰化できるのに…!
2020/03/20(金) 21:39:17.70ID:VjsvYTuj
末尾再帰であることと末尾再帰に変換できることは区別しようや
2020/03/20(金) 21:44:34.16ID:aaY2QfPy
末尾再帰に書き換えられることなんか誰も否定してないのに一人で暴れてる
2020/03/20(金) 21:46:22.20ID:GuzL6Him
訂正orz、
×: 結合則
○: 交換則

あとなんか式(1)は末尾再帰化可能な気がしてきたorz
2020/03/20(金) 21:52:18.14ID:aaY2QfPy
そりゃ交換則なんか末尾最適化に何の関係もないからな
2020/03/20(金) 21:58:34.74ID:VjsvYTuj
>>886
CPSをググって赤面しておいで
2020/03/20(金) 22:00:27.81ID:UDatiCXC
>>883
>まず右端展開の繰り返しにより表現可能でありかつ末尾再起化できない関数というものは無い
>なぜなら、右端展開の繰り返しを手続き的に書けばループに他ならんぬ、、、

理解が粗いと思います
あなたのいう「右端展開」が繰り返し適応可能であればループに展開できる…@
と置いたとき、
@が事実だったとしても、それは末尾再帰となんの関係もありません
末尾再帰の最適化とは関数コール命令+関数リターン命令(call 〜 ret) をジャンプ命令に変換するという最適化でしかなく、
再帰的に記述された関数定義をループに変換する最適化の集合を「末尾再帰という」、わけではないのです

あなたは末尾再帰を広く捉えすぎです
2020/03/20(金) 22:35:40.43ID:GuzL6Him
>>888
ちょっCPSって継続と書いてある
右端展開の繰り返し表現可能ということと、継続で表せることは自明な勢いで同値なのでは…
つまり漏れの面の皮を通って赤面させるほどの目新しさのインパクトは無いキモス、

>>889
AとBに何の関係も無い、とは、Aの真偽とBの真偽が独立のことを言うはず…
この場合「右端展開の繰り返しで表現可能」と「ループに展開できる」ことが同値なのであるから、
何の関係も無いというのは強弁に過ぎるのでは…

>末尾再帰の最適化とは関数コール命令+関数リターン命令(call 〜 ret) をジャンプ命令に変換するという最適化でしかなく
最適化した結果のみを末尾再帰というのであれば狭く捉え過ぎwwwwww
徹頭徹尾アセンブラで議論してろよ;;
そうではなくて末尾再帰の最適化の話に限定するのであればスレを分けた方が適切なのでは…
2020/03/20(金) 22:46:09.76ID:aaY2QfPy
同値じゃないよ
もっとよく考えよう
2020/03/20(金) 22:48:17.04ID:UDatiCXC
>>890
>この場合「右端展開の繰り返しで表現可能」と「ループに展開できる」ことが同値なのであるから、
>何の関係も無いというのは強弁に過ぎるのでは…

>>889 はそんなことを言ってはいません
>「右端展開の繰り返しで表現可能」であれば「ループに展開できる」できる…@
とおいたとき、
@と末尾再帰とが、何の関係もない、といっているのです

>最適化した結果のみを末尾再帰というのであれば狭く捉え過ぎwwwwww
>徹頭徹尾アセンブラで議論してろよ;;

最適化を実施するのに、あれこれ解析する必要がなく機械的な命令の置き換え/書き換えだけで可能である、というのが末尾再帰の肝です
まあアセンブラを理解できないようでは C/C++ の理解も薄い弱い、とは思ってはいますが

>そうではなくて末尾再帰の最適化の話に限定するのであればスレを分けた方が適切なのでは…
まず、末尾再帰とはなにか?を両者で合致するように合意をとるのが先決でしょう
2020/03/21(土) 01:01:36.11ID:vZ2zRqlY
厨二プログラマが食いつきやすい三大話題
・再帰
・例外処理

おっさんプログラマが食いつきやすい三大話題
・インデントルール
・命名規則
2020/03/21(土) 07:13:06.62ID:WKI7E4cH
>893はID:vZ2zRqlYが指を咥えて見てるだけの話題
2020/03/21(土) 07:17:58.40ID:ywBCyuHB
厨二プログラマが食いつきやすい三大話題
・再帰
・例外処理
・標準化委員会
おっさんプログラマが食いつきやすい三大話題
・インデントルール
・命名規則
・原点回帰
2020/03/21(土) 09:05:02.13ID:uResqVEz
厨二にもおっさんにもボコボコにされるだけで歯が立たないやつ悔しそう
2020/03/21(土) 09:51:18.47ID:SLPXMQFT
malloc/freeは?
2020/03/21(土) 10:55:38.71ID:QlEyGkfm
もっと簡単に考えろ
一般に再帰は階層に復帰したときに必ず元の状態に戻さなければならない
復帰後の階層固有の計算に必要だからだ
しかし復帰後に階層固有の計算がない末尾再帰は戻す必要がない
よってループで書けるというだけの話だ

これを順序非可換の問題ととらえることはまあ理にかなっている
以下左が末尾
f(n+1)x=f(n)h(n)g(n)x≠h(n)f(n)g(n)x

f(n+1)x=h(n)f(n)g(n)x=h(n)h(n-1)f(n-1)g(n-1)g(n)x
f(n+1)x=f(n)h(n)g(n)x=f(n-1)h(n-1)g(n-1)h(n)g(n)x

h(n)h(n-1)が可能であるためにはスタックの復帰が必要よって示された
2020/03/21(土) 11:03:11.10ID:eVTFfD/2
あなた達の話は難しくてよくわかりません!
簡潔に説明すると末尾再帰ってなんなんですか?
普通の再帰と違ってスタックオーバーフローが避けられるってこと?
2020/03/21(土) 11:39:49.98ID:aPGPOclr
>>895
そしてテスト、保守性といったものには誰も興味を持たないのである。おしまい。
2020/03/21(土) 12:48:43.36ID:QlEyGkfm
>>898から、>>860は末尾再帰であると言える
g(n)x=nx,h(n)x=xと考える
2020/03/21(土) 13:15:18.72ID:dTUZOuSg
>>901 あんたきのうの>881だよね?
たぶん「末尾再帰」の定義が他の人(たとえば Wikipedia の「自身の再帰呼び出しが、
その計算における最後のステップになっているような再帰」)と違いそうだから、まず定義を示してもらいたい。
2020/03/21(土) 13:20:58.16ID:QlEyGkfm
いや違うよ
級数積が関数という認識があるかないかが彼とは違う
2020/03/21(土) 15:20:30.30ID:dTUZOuSg
違うのか、悪かった。
で、あんたの「末尾再帰」の定義はどうなってんの?
2020/03/21(土) 15:49:06.69ID:uResqVEz
その昔、こんな再帰もやったがw
JSREE EQU *
* DO PREPARE
BSR *+2
* DO SOMETHING
RTS
2020/03/21(土) 15:52:49.00ID:QlEyGkfm
「自身の再帰呼び出しが、その計算における最後のステップになっているような再帰」
に異論ない。言葉通りだ
ただしそう定義したものは、>>898の性質を持つ
2020/03/21(土) 16:17:48.51ID:dTUZOuSg
>>906
そうなると >860 の "return n * factorial(n-1) ;" における「最後のステップ」は
再帰呼び出しではなく乗算なので、その末尾再帰の定義には合致しないのでは?
2020/03/21(土) 16:25:47.20ID:QlEyGkfm
>>901を適用して
f(n+1)x=f(n)g(n)x
g(n)x=x'
として、
f(n+1)x=f(n)x'
と書けば納得いただけるだろうか
2020/03/21(土) 16:33:45.27ID:dTUZOuSg
>>908 いやサッパリ。
その g やら x やらが >860 の関数とどう関係してるか、示されてないように思うし、
関係が示されたところで "return n * factorial(n-1) ;" の最終ステップが何であるかに
影響するとは思えない。
2020/03/21(土) 16:51:25.25ID:QlEyGkfm
こう書いた方がよかったかな
f(n+1)x=f(n)g(n)x
f(n)g(n)=h(n)として
h(n+1)x=h(n)x
具体的には
(n+1)f(n+1)x=nf(n)x
例外は最上位の呼び出し元だけがf(n)xになっていることで、
実質h(n)=n * factorial(n-1)という関数の末尾再帰になっている
2020/03/21(土) 17:00:27.64ID:SLPXMQFT
f(n)xはf(n)の結果にxを掛けるんだからf(n)が最終ステップじゃないだろ
2020/03/21(土) 17:08:54.11ID:7OpdEFcp
まずfactorialを末尾再帰に書き換えられるって話なら、そんなの当たり前だし誰も否定してない
それに加えてお前の書き換え方はおかしい
二重に話が噛み合ってなくて訳がわからない
宇宙人か?
2020/03/21(土) 17:15:28.13ID:lGRjmGfi
このスレで数学持ち出すやつは軒並みカスだな
2020/03/21(土) 17:17:08.44ID:gYwBfwwG
いい加減レス違いですよ
2020/03/21(土) 17:27:27.62ID:QlEyGkfm
おそらくわからないという人は、
末尾再帰⇔ループ
の書き換えがどうなっているのかわかっていない
末尾再帰な関数は、関数の戻り値以外のローカル変数はすべて再利用可能であるのでスタックする必要がない
そしてreturnが返しているのは戻り値である
n*はリターン値に含まれている
よってn * factorial(n-1)は一つの関数単位として扱われ得る
実際にそう扱っているかどうかは実装によるだろうが末尾再帰な関数の定義からは漏れていない
2020/03/21(土) 17:44:23.10ID:dTUZOuSg
>>915
仮に「n * factorial(n-1)は一つの関数単位として扱われ得る」を認めたところで
最終ステップはその「関数単位」とやらであって「自身の再帰呼び出し」ではないので、
末尾再帰とは言えないよね。

・・・ >860 を末尾再帰と言えないと死ぬ病気か何かなの?
2020/03/21(土) 17:51:24.98ID:QlEyGkfm
>>916
factorialの呼び元は大本の読み出し元以外はすべてnがかかっていること
実際にループに書き換えられること
よって>>860を否定する必要はないというだけのこと
否定する必要があるならそれでもいいが意味はあるか?
2020/03/21(土) 17:56:13.76ID:SLPXMQFT
>n*はリターン値に含まれている
>よってn * factorial(n-1)は一つの関数単位として扱われ得る

リターン値に含まれていようが関数の呼び出しに含まれていなんだから「一つの関数単位」にはならんわな。
2020/03/21(土) 18:04:37.39ID:lGRjmGfi
そもそもこの人の数学とやらが意味不明

> (n+1)f(n+1)x=nf(n)x

乗算なのか関数の適用なのかどっちだこれ?
左辺の(n+1)はどっからでてきたんだよ
2020/03/21(土) 18:17:58.54ID:dTUZOuSg
>>917
ループに書き換えられれば末尾再帰と言えるんならやっぱり Wikipedia の定義と違うんじゃん。

>>860は末尾再帰であると言える」を否定しないと「末尾再帰」の定義(共通認識)が変わってしまうし、
共通認識を壊す行いを認めることになる。それは害悪。やめてほしい。
2020/03/21(土) 18:57:31.20ID:vbC+9hSb
末尾再帰とかschemeじゃないと意味無い話
末尾再帰だとループに最適化されることが言語で保証されてるって前提なのだから

そこで言う末尾再帰ではn*f(n-1)みたいなのは違う
だから変形して末尾再帰にしろって話になるのだから
2020/03/21(土) 19:00:28.44ID:QlEyGkfm
>>920
それは
return n * factorial(n-1);
と書いてはいけないと強制するということだろうか
だとしたらそれは間違っている
末尾再帰の定義を満たしているにもかかわらず認めないということはそういうことだ
2020/03/21(土) 19:03:53.90ID:vbC+9hSb
末尾再帰は関数の最後で自身を呼び出してそれをそのままreturnするものだけ

末尾再帰に変形できる関数は末尾再帰に変形できる関数であって、末尾再帰関数ではない
2020/03/21(土) 19:07:05.36ID:lGRjmGfi
>>922
強制とか間違ってるとか認めないとか
お前は誰と戦ってんの?
誰もそんな話してないんだが
読んでで怖いわ
2020/03/21(土) 19:07:10.79ID:QlEyGkfm
>>923
それでいいと思う
だがだとすれば君らは何がわからなかったのかそれがわからない
2020/03/21(土) 19:07:50.34ID:KIEujNy0
>>915
>n*はリターン値に含まれている
>よってn * factorial(n-1)は一つの関数単位として扱われ得る

return 式
の式に全部書いてしまえるからといっても、その式の中に存在する演算が複数あれば、それぞれの演算に順序があるわけですから
一つに扱うことはできないでしょう、この場合、リターン値を得た後で * n しているのだから、これは一つじゃなく二つ

したがって >>902 の末尾再帰の定義
>「自身の再帰呼び出しが、その計算における最後のステップになっているような再帰」

には合致せず(なぜならば、この場合の最終ステップは * n をすることだから)、>>860 で引用されたプログラムは末尾再帰ではありませんね
2020/03/21(土) 19:10:16.03ID:KIEujNy0
>>922
>それは
>return n * factorial(n-1);
>と書いてはいけないと強制するということだろうか

いいえ、単に return * factorial(n-1) と書くのならば、末尾再帰ではなくなるというだけのことです。

>末尾再帰の定義を満たしているにもかかわらず認めないということはそういうことだ

もう一度ききましょう、あなたの「末尾再帰」の定義は何ですか?
2020/03/21(土) 19:12:27.37ID:QlEyGkfm
>>927
あなたのいう、「関数」の定義は何ですか
わたしはn * factorial(n-1)は関数だと思います
2020/03/21(土) 19:15:04.74ID:Pnykjrh9
やっぱりこいつ、末尾再帰と末尾呼び出しの区別がついていないとしか思えない
2020/03/21(土) 19:17:28.36ID:QlEyGkfm
>>929
この場合同じです
2020/03/21(土) 19:18:51.72ID:SLPXMQFT
>わたしはn * factorial(n-1)は関数だと思います

これがfractional自身とは異なる以上、末尾再帰にはならんわけ。
2020/03/21(土) 19:23:27.91ID:QlEyGkfm
>>931
では何がわからなくてここまでの長い議論をしていたのですか?
末尾再帰が理解したいというのなら、定義そのままを暗記するだけで済んだはず
一連の私の書き込みは単に理解の方法を提示したに過ぎず、
それを否定するということは定義が理解できていたということでしょう?
2020/03/21(土) 19:23:55.22ID:bpzSUpq2
中置で書くから分かりづらくなる
ポーランドか逆ポーランドで書けば自明なのに
2020/03/21(土) 19:25:39.78ID:KIEujNy0
>>928
>あなたのいう、「関数」の定義は何ですか
>わたしはn * factorial(n-1)は関数だと思います

仮に関数の定義をあきらかにしたからといっても、それは末尾再帰の定義とは関係ないでしょうね

繰り返しますが、末尾再帰の定義は >>902
>>「自身の再帰呼び出しが、その計算における最後のステップになっているような再帰」
であり、>>860 で引用されたプログラムの「自身の再帰呼び出し」すなわち「return n * factorial(n-1);」
は、計算における最後のステップになっていない(なぜならば、最後のステップはこの場合 n * であるから)ので、
>>860 で引用されたプログラムは末尾再帰ではありませんね
2020/03/21(土) 19:27:37.70ID:SLPXMQFT
>>932
>>860は末尾再帰にならないということをアンタだけが理解できていないというだけ。
2020/03/21(土) 19:28:51.57ID:QlEyGkfm
>>934
それを最初から言っていれば、ここまでの無意味な議論はしなくて済んだでしょうね
よって示された
2020/03/21(土) 19:34:56.57ID:QlEyGkfm
逆になぜ末尾再帰にするかを考えれば、>>934の制限は強すぎる
2020/03/21(土) 19:38:43.38ID:g81eKbe5
ID:QlEyGkfmは何でもかんでもここのみんなに教えてもらおうとせず
まず落ち着いて自分のペースでしっかり考えてみたらどうかな
みんな呆れてるよ
2020/03/21(土) 19:46:19.04ID:KIEujNy0
>>938
昔私が末尾再帰を間違えていたとき、当時からこのコテで煽り気味にやっていたにもかかわらず、最上級の親切を示して
「末尾再帰はジャンプ最適化だ!」
と教えてくださった方がおられました、当時のその方ほどの忍耐力を今回発揮できず、申し訳ございません…
2020/03/21(土) 19:49:38.39ID:QlEyGkfm
皆さんこそ落ち着いてください
nはスタック変数ではなく、ループのインクリメント変数なんですよ
2020/03/21(土) 19:59:14.68ID:uResqVEz
「末尾再帰」という情報処理用語を定義しているJIS規格票もしくは
"tail recursion" という情報処理用語を定義しているISO規格票の
条項を出せるやついるの?

これだけ上から目線でマウント取っといて
あげくオレ用語だったら恥ずかしいぞ
2020/03/21(土) 20:03:27.21ID:bpzSUpq2
R5RSとかではなく?
2020/03/21(土) 20:13:29.14ID:7OpdEFcp
江添が間違えたのが全部悪い
奴が間違えてなければ同じ勘違いをした気違いを呼び寄せることもなかった
2020/03/21(土) 20:38:49.06ID:g81eKbe5
江添氏は勘違いと言うより
末尾再帰というもんを単に知らなかったのではと思ってる

末尾再帰の最適化が保証されてる言語使ってる人じゃないだろうから
2020/03/21(土) 20:47:14.84ID:vbC+9hSb
消費税の計算を例題にあげたけど、計算方法間違ってたみたいなもの
c++的には関係ない分野の知識
2020/03/21(土) 20:58:18.89ID:lGRjmGfi
蒸し返して悪いんだけど
>>898 の数式解読できる人いる?
この人何を勘違いしてんのか興味でてきたんだが
2020/03/21(土) 21:07:53.04ID:XPOe/jnY
「添字を持つ添字」みたいなもんを上手に管理する方法ってある?

例えば、
0 <= i < n である全ての i について a[i] を 0 から m の範囲で動かす
みたいなループの構造を想定してる。
当然大きな多重ループになるから小さい n と m についてしか使えないと思うけど、デバッグなどのときにこういうのを簡潔にミスらず書けたらと思っての質問です
2020/03/21(土) 21:15:03.39ID:lGRjmGfi
>>947
> a[i] を 0 から m の範囲で動かす
これの意味がわからない
具体例書いて
2020/03/21(土) 21:44:53.81ID:XPOe/jnY
>>948
for(a=0; a<m; a++)
 for(b=0; b<m; b++)
  for(c=0; c<m; c++)
   ...
という形の多重ループのループ変数 a, b, c,... を a[0], a[1], a[2],... にしたいという意味です。
TeX の文法で数式を書けば
\prod_{i=0}^{n} \sum_{a[i]=0}^{m}
という意味です。

・数式との対応が分かりやすい形で書きたい
・簡潔でミスしにくい形で書きたい
といった理由で質問させていただいてます。
2020/03/21(土) 21:46:40.54ID:XPOe/jnY
>>948-949
すみません。必ずしも和をとりたいだけではないので、式はあくまで例です。
あとレンジが1つずれてるのもすみません。
2020/03/21(土) 22:26:18.85ID:SLPXMQFT
>という形の多重ループのループ変数 a, b, c,... を a[0], a[1], a[2],... にしたいという意味です。

やればいいだけの話じゃなくて?質問は何だろう。
2020/03/21(土) 22:38:22.14ID:XPOe/jnY
>>951
n が実行時に決まるような場合どうしたら良いかという意味です
2020/03/21(土) 22:39:31.10ID:lGRjmGfi
>>949
ループのネストが可変なんだよね
templateが許されるなら再帰template
ダメならきれいには書けないと思う
2020/03/21(土) 22:40:14.16ID:vbC+9hSb
本当に実行時なら再帰で書くしか無いんじゃね
2020/03/21(土) 22:49:54.75ID:XPOe/jnY
>>953-954
ありがとうございます。
再帰templateで調べてみます。

あと書いてて気付いたのですが、n桁のm進数にループ変数 a[0], a[1],... をエンコードするっていうのも一つの方法かなと思いました。
2020/03/21(土) 22:50:20.71ID:lGRjmGfi
確かにtemplateでなくても再帰で可能か
ただlambdaで渡せないからstd::functionで包む必要あるね
2020/03/21(土) 22:57:37.57ID:80zI/5JK
>>949
やりたいことは、係数をm^2の2次元配列xとm^3の3次元配列yに入れておいて、2番目のループではx[a][b], 3番目のループではy[a][b][c]を使用するということか?
サイズ可変でも動的に確保すればいいだけ。
2020/03/21(土) 22:58:48.87ID:80zI/5JK
すまん、全くの検討違いだったようだ
2020/03/21(土) 23:07:32.20ID:XPOe/jnY
>>957-958
m^n 通りの添字 (a[i] for all i) の組み合わせを列挙し、その中でなんらかの処理をしたいという意味です。
説明の仕方が悪くて失礼しました。
2020/03/22(日) 00:59:09.60ID:7dJergc9
全てのa[i]が始点0,終点mならa[i]でなくてもjとかでよくね?
961デフォルトの名無しさん
垢版 |
2020/03/22(日) 01:21:14.83ID:GKarRavC
std::sortに並列化+ベクトル化指定つけて実行したら、コア数以上に高速化したんだけど、なんで?
2020/03/22(日) 01:31:16.84ID:ESnYypih
キャッシュに全部載るようになったとか
2020/03/22(日) 01:36:53.01ID:7dJergc9
>>959
あー全部使うのか
function(a[0],a[1],a[2],a[3],....)
2020/03/22(日) 02:31:12.30ID:7dJergc9
>>955
こういう解釈でいいのかな
ループがふたつになるかな

a=new int[n];
for(i=0;i<m^n;i++){
 for(j=0;j<n;j++){
  a[j]=i%m;
  i/=m;
 }
 function(a,n);
}
delete[] a;
2020/03/22(日) 02:42:13.57ID:5XORMJuJ
>>964
はい。
再帰が難しかったらそれにします。
2020/03/22(日) 11:52:38.51ID:I961moxw
>>949
こういう感じ?
https://wandbox.org/permlink/zdLQAUuB43vzYj6U

(ガバい実装ですまぬ)
967デフォルトの名無しさん
垢版 |
2020/03/22(日) 11:56:28.35ID:GKarRavC
多重継承のときのCRTPについて説明してるサイトないですか
2020/03/22(日) 14:40:43.43ID:VphPQW8g
そんなモンがあるなんて初めて知った
やはりC++は奥が深いな
2020/03/22(日) 19:39:49.88ID:HvrypJyW
>>949
>TeX の文法で数式を書けば
>\prod_{i=0}^{n} \sum_{a[i]=0}^{m}
>という意味です。
絶対ではないが、標準的な数学の記法だと、その意味では、
\sum_{a[0]=0}^{m}・・・\sum_{a[n]=0}^{m}
と書くのがが普通だと思う。
ところでそれは量子力学の経路積分か何かですか?
経路積分の場合は、本によって上記の部分に割と独特の変な記号を使う場合があって、
あなたの書いたように書いてある本もあるかもしれません。
ただ、普通の数学記法だと余り使いませんよね、その書き方は。
2020/03/22(日) 19:46:47.90ID:HvrypJyW
>>969
補足すれば、普通の数学記法だと
\sum_{a[0]=0}^{m}・・・\sum_{a[n]=0}^{m} f(a[0],・・・,a[n])  //(1)
ですね。
\prod_{i=0}^{n} \sum_{a[i]=0}^{m}  //(2)
の記号の場合は、
X= \prod_{i=0}^{n} \sum_{a[i]=0}^{m} g_i(a[i])  //(3)
の場合は、
b[i] = \sum_{a[i]=0}^{m} g_i(a[i])  //(4)
(i=0, ・・・, n)
を先に計算しておいて、
X = \prod_{i=0}^{n} b[i]   //(5)
 = b[0]・・・b[i]   //(6)
の意味に解釈するのが標準的な数学の記号の使い方だと個人的には思います。
(1)と(3)ではかなり意味が違いますが、(2)の記号を、(1)の先頭に使えるかと言えば、
絶対使えないわけでは有りませんが、使う前に何らかの補足説明が必要になりそうです。
2020/03/22(日) 19:47:50.29ID:HvrypJyW
>>970
誤: = b[0]・・・b[i]   //(6)
正: = b[0]・・・b[n]   //(6)
2020/03/22(日) 21:29:26.79ID:LOA9pF7P
>>967
派生が継承してる複数の基底を受け取りたいとか?
2020/03/23(月) 12:49:54.29ID:bf1cRh+B
int *pInts = new int[10]();
とした場合の最後の()の意味は何でしょうか?
付けない場合との差を教えてください。
2020/03/23(月) 13:29:11.05ID:FLdc410A
>>973
イニシャライザ。
普通のクラスではそれがないときはデフォルトコンストラクタで初期化される (空の括弧があっても無くても同じ挙動) けど、
int 等では初期化を明示しない限り初期化されない。
逆に言えばこの場合は初期化を明示しているので初期化される。 (0 が入る)
2020/03/23(月) 13:37:39.77ID:bf1cRh+B
>>974
有難うございます。では、
int *pInts = new int[3](1,2,3);  //(1)
int *pInts = new int[3]{1,2,3};  //(2)
の違いは何でしょうか?
2020/03/23(月) 14:11:51.67ID:FLdc410A
>>975
(2) の場合には集成体初期化になる。
https://ja.cppreference.com/w/cpp/language/new#.E6.A7.8B.E7.AF.89

(1) も C++20 からは集成体初期化になる。
だけど gcc と clang の最新版で試しても出来ないっぽいし、
あえて丸括弧で書きたい理由はないなぁ。
2020/03/23(月) 14:16:57.36ID:bf1cRh+B
>>976
ちょっとまってください。
>>973 の場合の
2020/03/23(月) 14:16:57.82ID:bf1cRh+B
>>976
ちょっとまってください。
>>973 の場合の
2020/03/23(月) 14:18:32.74ID:bf1cRh+B
>>976
ちょっと待ってください。
>>973 の場合の () は、「集成体初期化」のうちの「中身が全く入ってない括弧」と解釈してよろしいのでしょうか?
2020/03/23(月) 14:39:25.62ID:FLdc410A
>>979
いいえ。

> initializer が空の括弧の場合、それぞれの要素は値初期化されます。

に該当する。
2020/03/23(月) 16:20:38.54ID:bf1cRh+B
>>980
最初は集成体初期化を使って、
int *pInts = new int[100](1,2,3);  //(1)
int *pInts = new int[100](1,2);  //(2)
int *pInts = new int[100](1);   //(3)
int *pInts = new int[100]();    //(4)
とどんどん()の中の項目を減らして行き、最後に0個にした場合、
推論的な延長線上にあると思えるか、それとも全く違った結果になるかどちらですか?
2020/03/23(月) 17:58:00.87ID:FLdc410A
>>981
C++20 的に言えば集成体初期化の文法に統合されたということにはなるんだと思うけど、経緯はよくしらない。
2020/03/23(月) 18:27:48.17ID:bf1cRh+B
もし、
{1,2,3,0,0,0,0,0}
{1,2,0,0,0,0,0,0}
{1,0,0,0,0,0,0,0}
{0,0,0,0,0,0,0,0}
のようになるんであれば、()は(xxx)のxxxを書かない場合と捉えるのは数学的推論として
正しい見方になりますね。
実際に上のようになるのか、未初期化の部分が残るのかは知りませんが。
2020/03/23(月) 18:32:49.31ID:FLdc410A
>>983
足りない分はゼロ初期化されるよ。
C の時代からの配列の初期化の文法と一貫させてるつもりなんだと思う。
2020/03/23(月) 18:45:31.47ID:FLdc410A
>>983
空の丸括弧でゼロ初期化されるのは C++03 にはすでに有って、
波括弧で初期化する文法は C++11 から入って、
(そこから色々と条件の緩和やら変更やらがありつつ)
空ではない丸括弧で集成体初期化になるのは C++20 からという段階的な変化がある。

追加された文法が既存の文法となるべく一貫性を持つように統合しようとはしているけど、
互換性を壊さないようにというのも C++ の強い要件なので、
正確なルールはごちゃごちゃした条件の塊になりがち。

まあまあ整理されている部分もあるけど、
勝手な予想ではなくちゃんと資料にはあたった方がいいよ。
2020/03/23(月) 19:36:44.54ID:7lDoSnDw
配列の初期化方法が20通りくらいあるんじゃねえか
2020/03/23(月) 20:24:40.26ID:V7MpBiZM
結局、波括弧と丸括弧はどっちが良いの?
C++11の時点では、波括弧が使えるところでは波括弧使っとけってのがMayers神の教えだったけども
2020/03/23(月) 20:44:37.69ID:uqcQPrX7
汝の欲するところを行え
それが法とならん
2020/03/23(月) 22:25:35.27ID:d94IfFIM
好きなようにやったところで法(規格なりデファクトスタンダード)にはならんだろw
2020/03/23(月) 23:44:35.50ID:Y58N/W/D
よし、じゃあ今から俺が法な。


ここの住人は全員システムハンガリアン強制
2020/03/24(火) 00:05:30.25ID:YFRNwZnv
次スレ
C++相談室 part150
https://mevius.5ch.net/test/read.cgi/tech/1584975873/
2020/03/24(火) 00:21:01.48ID:DmQItF6u
>>987
シンタクス的にどちらでも良いときには波括弧を優先した方がよいと思う。
波括弧は縮小変換を許さないので意図しない情報の欠落は防止できる可能性が高い。
縮小変換が必要な場面に限って丸括弧を使えばそこが要注意ポイントってのがわかりやすい。

----

ところで縮小変換より狭化変換という用語の方が好きなんだけど、
みんなどっち使ってる? やっぱ縮小変換の方が標準的かな?
2020/03/24(火) 14:12:02.77ID:v3Nctwhv
>>969-971
> 絶対ではない
> 思う
> 個人的には

話にならん
2020/03/24(火) 14:21:15.32ID:Qfdj04Y0
>>992
そうなのね。ありがとうー
2020/03/24(火) 14:41:38.83ID:cFvopTvT
へぇこんな配列の初期化の仕方あるんだねぇ
お前らC++に詳しいじゃん
2020/03/24(火) 18:53:00.89ID:l++MC8Rs
C言語の時点で int a[100] = {0}; でゼロクリア
もはや裏ワザの部類

https://cpplover.blogspot.com/2010/09/blog-post_20.html
int a[2][2] = { 1, 2, 3, 4 } ;

多次元配列の初期化での謎機能
これも裏ワザにしか見えない

裏ワザ・例外・隠し機能が相まって配列の初期化だけで一冊の同人誌が出来上がる
2020/03/24(火) 20:25:22.03ID:1n+V7cka
universal initializerなんてバグの塊でしかない。
https://qiita.com/h2suzuki/items/d033679afde821d04af8
2020/03/24(火) 22:49:16.96ID:T0vrM+QL
>>993
数学の記号法と言うのは本によって違ってるから。
特に物理学は必要に迫られて新しい記法を発明してしまう。
2020/03/24(火) 22:50:59.22ID:o8Zozk/+
数学は記号定義してなんぼだからね
2020/03/24(火) 23:08:33.60ID:v3Nctwhv
>>998-999
いや、だからなんだよ
なんの主張にもなってないお気持ち表明するだけの雑魚多いな
10011001
垢版 |
Over 1000Thread
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 35日 16時間 48分 52秒
10021002
垢版 |
Over 1000Thread
5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。


───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────

会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。

▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/

▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php
レス数が1000を超えています。これ以上書き込みはできません。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況