[過去ログ] C++相談室 part156 (1002レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
673: 2021/07/11(日)00:07 ID:5nx6GB9W(1/5) AAS
>>672
外部リンク[html]:cpplover.blogspot.com
とりあえずこれとか読んでからお願いします
全体的に何が言いたいかよく分からないですがmoveならrvalueとして渡されるのでそこは理解してください
674: 2021/07/11(日)00:24 ID:YJk6tGcw(1/11) AAS
>全体的に何が言いたいかよく分からないですが
ヒエッ……このスレは荒れる……
675: 2021/07/11(日)00:27 ID:YJk6tGcw(2/11) AAS
>moveならrvalueとして渡されるのでそこは理解してください
rvalueになるのは移動の右辺であり3のケースでは(3がmoveになったとして)移動元のhogeの実体だが
take_S()に渡るのはmoveされた後のhogeなのでtake_S()の中では問題無くlvalue扱い
676: 2021/07/11(日)00:28 ID:YJk6tGcw(3/11) AAS
しつれい、
誤: take_S()に渡るのはmoveされた後のhoge
正: take_S()に渡るのは&hogeからmoveされてきたhogeの「複製」
677(1): 2021/07/11(日)00:51 ID:5nx6GB9W(2/5) AAS
リンク先読んだ?
678: 2021/07/11(日)00:53 ID:YJk6tGcw(4/11) AAS
もとから読んでるっつーの;;;
>>677はムーブコンストラクタで構築されたオブジェクトがlvalueでないと思っちゃうタイプ?
679(3): 2021/07/11(日)00:54 ID:5nx6GB9W(3/5) AAS
3.でmoveは発生しません
詳細はさっきのブログ記事に書いてあります
以上
680: 2021/07/11(日)00:55 ID:YJk6tGcw(5/11) AAS
>>679
どこか指摘できずに逃亡;;;
681: 2021/07/11(日)00:57 ID:5nx6GB9W(4/5) AAS
lvalueをmoveせよ
さて、2. はどうしたらいいだろう。moveコンストラクタを実装したものの、コンパイラは2. の場合には、moveコンストラクタを呼び出してくれない。なぜなら、コンパイラは、プログラマの脳内仕様を読んではくれないからだ。tmpが、その後に使われていないかどうかは、コンパイラは静的に決定できないのである。
そこで、プログラマが意図を伝えてやらなければならない。
X b( static_cast<X &&>(tmp) ) ;
この様に、rvalueにキャストしてやれば、moveコンストラクタを呼び出すことが出来る。
682: 2021/07/11(日)01:01 ID:YJk6tGcw(6/11) AAS
>>679はSのインスタンスhogeを関数void take_S(S) (※void take_S(S&)ではない!)に渡す際に、
take_S()の呼び出し元(この場合main())が
hogeと同じ値を持つインスタンスをtake_S()の引数用領域に構築する必要がある、というあたりからして理解していないのではないか;;;
で、問題にしているコードはリンク先の
>tmpが、その後に使われていないかどうかは、コンパイラは静的に決定できないのである。
には該当しない
683: 2021/07/11(日)01:04 ID:YJk6tGcw(7/11) AAS
なぜなら、今回のケースはコードを見たらワカルからじゃわ;;;
コンパイラは静的に決定できない、と言っているのは停止性問題を解く万能のアルゴリズムが無いことから来ているが、
特殊なケースでは停止性問題は機械的に解ける
今こそその時、
、というあたりからして>>679はちんぷんかんぷんなのではないか……
684(1): 2021/07/11(日)01:11 ID:5nx6GB9W(5/5) AAS
あーそこがわかってなかったのね
take_Sの仮引数を実引数で初期化する時に同じことが起こるだけですよ?
実引数をrvalue参照とみなしてオーバーロード解決できればmoveで仮引数が初期化される
できなければ(かつlvalue参照として解決できれば)copyで仮引数が初期化される
685(1): 2021/07/11(日)01:24 ID:YJk6tGcw(8/11) AAS
>>684
藻前の頭が固いだけなんとちゃうか;;;
>実引数をrvalue参照とみなしてオーバーロード解決できればmoveで仮引数が初期化される
この場合(すなわち実引数hogeをtake_S()の仮引数としてコピーした後呼び出し元が実引数hoge()を使わない(ことをコンパイラが機械的に判定できる)ケース)
において、実引数hogeのアドレスをrvalue参照とみなしてはいけないという根拠は?
論理的にはソースコードの意味を変えることなく整合するんだけどそういう最適化はいけないことなの?
686: 2021/07/11(日)02:58 ID:YJk6tGcw(9/11) AAS
んまーとは言ったものの、
【実験1】 >>627のコードをループにしてやって最適化「-O2」にしても"move"にならなんだorz
外部リンク:wandbox.org
結果:
default
--------
copy
0, 1
default
--------
省4
687: 2021/07/11(日)02:59 ID:YJk6tGcw(10/11) AAS
【実験2】 もちろんstd::move(hoge)したらmoveになる
(上記リンク先のコードのDO_MOVE定義のコメントアウトを外してを有効化)
結果:
default
--------
move
0, 1
default
--------
move
省10
688(1): 2021/07/11(日)03:09 ID:YJk6tGcw(11/11) AAS
(言い訳1)
実験3のような最適化が許されるのだから、copyをmoveに読み替える最適化も許されるべきだ
規格に照らしてどうなのかはC++規格の専門家の反応待ち
(言い訳2)
今回のケースでGCC様がcopyをmoveにする最適化を拒むのは、単にhogeの使用箇所の分析をサボっているか
(データフロー解析の一環として論理的には十分take_S()呼び出し後の未使用を機械的判定をやれるはずなのに…
、デストラクタのdefault[] のコストでも気にしている可能性が微レ存
(言い訳3)
>>627のコードでmoveになる、と最初に言い出したのは>>609であって漏れではない
むしろ漏れは「場合によってはcopyが起きる」(>>623)と述べてたのでcopy派である
省1
689: 2021/07/11(日)13:04 ID:G2C/uXds(1) AAS
>>685
> 論理的にはソースコードの意味を変えることなく整合するんだけどそういう最適化はいけないことなの?
コピーコンストラクタとムーブコンストラクタのどっちが呼ばれたかわかるようにログ出力とかしてたら動作が変わる。
そういう副作用を含めてコンパイラが動作を変えていいケースは >>671 で挙げられたように明示的に規定されていて、
あなたの言うケースはそうではない。
690(1): はちみつ餃子 ◆8X2XSCHEME 2021/07/11(日)18:47 ID:8K44AFaV(1) AAS
>>688
Copy になるべき場合と Move になるべき場合は条件がはっきりしている。
どちらでもいい場合は無い。
表層上の動作が仕様通りであればどうコンパイルしても良いのが C/C++ なので、
あえて、あくまでもあえてレアケースを挙げるとすれば
(見かけ上の) 動作が Copy でも Move でも同じだとコンパイラが見ぬくことが出来る場合が
あったなら Copy の場面で Move 相当の機械語が生成されることが絶対にないとは言いきれないけども、
Copy でも Move でも同じだと確信できる場合に限られるので動作からはどうせ観測できない。
意味を変える最適化をしていいという唯一のルールがコピー (またはムーブ) の省略で、
その一部が C++17 では必須化されたわけだね。
691(9): 2021/07/12(月)07:46 ID:5HFqt1x5(1/3) AAS
ある整数がある整数の n 乗であることの判定ってどうするのが良いでしょうか
(n も整数とします)
今までは
x == (int)pow((int)pow(x, 1.0/n), n)
で判定してたんですが、今の自分の環境で x = 4096、n = 6 を渡したら誤判定しました
(int) を round に変えるのを思いつきましたが、コーナーケースがあったら嫌なので、他の良い方法があったら教えてください
692(2): 2021/07/12(月)08:17 ID:K0Wntvol(1) AAS
>>691
諦めてboostの多倍長整数を使う。
上下前次1-新書関写板覧索設栞歴
あと 310 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル
ぬこの手 ぬこTOP 0.284s*