探検
結局C++とRustってどっちが良いの?
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2023/02/25(土) 09:49:46.74ID:VRyB88xR C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな?
452デフォルトの名無しさん
2023/03/22(水) 21:46:10.74ID:vDLoPLCP 全て実行時チェックだな
453デフォルトの名無しさん
2023/03/22(水) 21:54:30.07ID:jZlOcGNt454デフォルトの名無しさん
2023/03/23(木) 11:01:43.91ID:AQHpwrnP C++で出来る人には要らん
455デフォルトの名無しさん
2023/03/23(木) 11:35:46.79ID:4E7FceMl メモリ不安全の何が悪いかってメモリリークじゃなくて間違った場所にアクセスしちゃうことだと思うのだが
456デフォルトの名無しさん
2023/03/23(木) 11:37:47.99ID:rQpQMC7M >>455
例えばどういう状況かな?
例えばどういう状況かな?
457デフォルトの名無しさん
2023/03/23(木) 13:26:58.89ID:4E7FceMl >>456
ゲームのバグとか
ゲームのバグとか
458デフォルトの名無しさん
2023/03/23(木) 13:54:38.12ID:Pj5jY94w Segmentation fault:呼んだ?
459デフォルトの名無しさん
2023/03/23(木) 14:56:19.59ID:vn3KCE0y Windowsで実行しています
https://doc.rust-lang.org/stable/std/process/
ここを観て
use std::process::{Command, Stdio};
let c = "cmd";
let a = "/c echo Hello, world!";
let o = Command::new(c).arg(a).output().expect("Failed to start process");
let v1 = o.stdout.as_slice();
すると v に必ず
[0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20,
0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x22, 0x0d, 0x0a]
が入ります
let p = Command::new(c).arg(a).stdout(Stdio::piped()).spawn().expect("Failed to start process");
let e = p.wait_with_output().expect("Failed to open stdout");
let v2 = e.stdout.as_slice();
としても結果同じです
Hello, world!"+改行
で余計な"が入っているのですがなぜでしょう?どのように取り除くのが正しい対処方法を教えて!!
https://doc.rust-lang.org/stable/std/process/
ここを観て
use std::process::{Command, Stdio};
let c = "cmd";
let a = "/c echo Hello, world!";
let o = Command::new(c).arg(a).output().expect("Failed to start process");
let v1 = o.stdout.as_slice();
すると v に必ず
[0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20,
0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x22, 0x0d, 0x0a]
が入ります
let p = Command::new(c).arg(a).stdout(Stdio::piped()).spawn().expect("Failed to start process");
let e = p.wait_with_output().expect("Failed to open stdout");
let v2 = e.stdout.as_slice();
としても結果同じです
Hello, world!"+改行
で余計な"が入っているのですがなぜでしょう?どのように取り除くのが正しい対処方法を教えて!!
460デフォルトの名無しさん
2023/03/23(木) 15:07:48.89ID:AQHpwrnP let o = Command::new(c).args(&["/c", "echo Hello, world!"]).output().expect("Failed to start process");
461デフォルトの名無しさん
2023/03/23(木) 17:25:27.77ID:v7ZfYtIP C++は例外処理とかもバグを生みやすくしていると思う
462デフォルトの名無しさん
2023/03/23(木) 19:55:36.72ID:oPmaaYed C++にmoveや右辺値参照ができる前に挫折した連中がRustスゲーとか言うのは何か違うと思う。
463デフォルトの名無しさん
2023/03/23(木) 20:30:50.18ID:xqmW5G90 失敗だか挫折だか知らんけど
失敗してもお金が減らない失敗は半分大成功だよ
失敗してもお金が減らない失敗は半分大成功だよ
464デフォルトの名無しさん
2023/03/23(木) 23:42:04.79ID:/qDbj6Pr とりあえず3つに絞るとして
(1)ダングリングがないメモリ安全性の保証
(2)データやポインタのヌル安全性の保証
(3)データ競合がない安全性の保証
Rustはコンパイラが通れば保証されるが
C++は(2)(3)は無理として(1)についてもプログラマーがどんなに複雑化してもミスなく記述できた場合のみその自己責任で実現
そのためC++ではバグやセキュリティの穴が現在進行形で量産されている
(1)ダングリングがないメモリ安全性の保証
(2)データやポインタのヌル安全性の保証
(3)データ競合がない安全性の保証
Rustはコンパイラが通れば保証されるが
C++は(2)(3)は無理として(1)についてもプログラマーがどんなに複雑化してもミスなく記述できた場合のみその自己責任で実現
そのためC++ではバグやセキュリティの穴が現在進行形で量産されている
465デフォルトの名無しさん
2023/03/23(木) 23:55:58.81ID:rQpQMC7M でもRustはLockFreeQueueをunsafeにしか書けないでしょ?
466デフォルトの名無しさん
2023/03/24(金) 00:33:14.50ID:sS+xf8yH LockFreeQueueもsafeなインタフェースを提供できている
https://docs.rs/lockfree/
中身はunsafeを使う部分が一部あるが全てコメントに理由が記述されているようにsafeな操作でありその部分の安全性のみを人が保証
Rustの最大の特徴はこのようにunsafeを使ったsafeな操作を内部に封じ込めて外部にsafeなインタフェースを提供できること
そしてそのライブラリを使った任意のプログラム全体の安全性がRustコンパイラにより保証される
https://docs.rs/lockfree/
中身はunsafeを使う部分が一部あるが全てコメントに理由が記述されているようにsafeな操作でありその部分の安全性のみを人が保証
Rustの最大の特徴はこのようにunsafeを使ったsafeな操作を内部に封じ込めて外部にsafeなインタフェースを提供できること
そしてそのライブラリを使った任意のプログラム全体の安全性がRustコンパイラにより保証される
467デフォルトの名無しさん
2023/03/24(金) 01:00:04.81ID:STP4y0mB468デフォルトの名無しさん
2023/03/24(金) 01:01:07.83ID:Qymt7I/N full safeが至上なんじゃないんだよ
それだとマイコンでrustが使えなくなるし、safe C++だって実現しなくなる
それだとマイコンでrustが使えなくなるし、safe C++だって実現しなくなる
469デフォルトの名無しさん
2023/03/24(金) 01:08:19.45ID:F7DMT464 C#もAOTコンパイルに対応したしもうこっちでよくねる
470デフォルトの名無しさん
2023/03/24(金) 01:13:06.10ID:STP4y0mB471デフォルトの名無しさん
2023/03/24(金) 01:15:17.05ID:Qymt7I/N スマポスマポいうけどさ、なら、スマポオンリーっていうpragmaつくればよくね
それとC++はなんでもかんでもnewする習慣がついちゃって、
そこはスタックに物を置きたくなるRustのほうが能率よくなっちゃってねえか
それとC++はなんでもかんでもnewする習慣がついちゃって、
そこはスタックに物を置きたくなるRustのほうが能率よくなっちゃってねえか
472デフォルトの名無しさん
2023/03/24(金) 01:22:55.16ID:IeJLDeif >>467
違いは明白
C++はプログラム全てがunsafeエリア(=人が安全性を保証する)
Rustはプログラムのほとんとがsafeエリア(=コンパイラが安全性を保証する)
(Rustには一部の閉じ込められた局所的な部分のみunsafeが存在しそこに限定して人が安全性を保証する)
違いは明白
C++はプログラム全てがunsafeエリア(=人が安全性を保証する)
Rustはプログラムのほとんとがsafeエリア(=コンパイラが安全性を保証する)
(Rustには一部の閉じ込められた局所的な部分のみunsafeが存在しそこに限定して人が安全性を保証する)
473デフォルトの名無しさん
2023/03/24(金) 01:25:05.80ID:F7DMT464 C#でいいやって時代が来そうだな
.NET7でAOTコンパイル対応したから
Rustなんかより遥かに簡単だし
.NET7でAOTコンパイル対応したから
Rustなんかより遥かに簡単だし
474デフォルトの名無しさん
2023/03/24(金) 01:25:34.49ID:Qymt7I/N たとえば、メモリマップドI/Oが扱えない言語は、本気でやりこもうとは思えない
ちなみに、C#はプリコンパイルできるスクリプト言語として、とても便利に日々使ってる
ちなみに、C#はプリコンパイルできるスクリプト言語として、とても便利に日々使ってる
475デフォルトの名無しさん
2023/03/24(金) 01:34:37.55ID:F7DMT464476デフォルトの名無しさん
2023/03/24(金) 01:35:44.19ID:STP4y0mB477デフォルトの名無しさん
2023/03/24(金) 01:36:16.07ID:IeJLDeif478デフォルトの名無しさん
2023/03/24(金) 01:39:04.57ID:F7DMT464 >>477
AOTにするとGCとか無くなるよ
AOTにするとGCとか無くなるよ
479デフォルトの名無しさん
2023/03/24(金) 01:39:24.39ID:STP4y0mB >>477
AOTに対応したんだから速度では勝負できるよ
AOTに対応したんだから速度では勝負できるよ
480デフォルトの名無しさん
2023/03/24(金) 01:41:10.62ID:F7DMT464481デフォルトの名無しさん
2023/03/24(金) 01:41:24.23ID:STP4y0mB482デフォルトの名無しさん
2023/03/24(金) 01:42:48.96ID:IeJLDeif483デフォルトの名無しさん
2023/03/24(金) 01:45:09.38ID:STP4y0mB484デフォルトの名無しさん
2023/03/24(金) 01:48:33.41ID:Qymt7I/N また髪の話してる
485デフォルトの名無しさん
2023/03/24(金) 01:52:02.45ID:7trvtA/S486デフォルトの名無しさん
2023/03/24(金) 01:54:42.93ID:GMecybVR C++って今もvectorの要素を参照しながら末尾に要素を追加しまくると参照先がいなくなる事故は発生すると思う
最近のC++はよく知らないけどスマートポインタで防げるの?
最近のC++はよく知らないけどスマートポインタで防げるの?
487デフォルトの名無しさん
2023/03/24(金) 01:54:57.32ID:STP4y0mB >>464
>(3)データ競合がない安全性の保証
共有データをスマートポインタに入れといて
アクセスする際には共有データではなくて
一時Proxyを経由してアクセスすればよい
Proxyのコンストラクタでロックしてデストラクタでアンロックする
RustのMutex相当で簡単に実装出来る
>(2)データやポインタのヌル安全性の保証
これはどういうこと? 静的に保証しろってことかな?
>(3)データ競合がない安全性の保証
共有データをスマートポインタに入れといて
アクセスする際には共有データではなくて
一時Proxyを経由してアクセスすればよい
Proxyのコンストラクタでロックしてデストラクタでアンロックする
RustのMutex相当で簡単に実装出来る
>(2)データやポインタのヌル安全性の保証
これはどういうこと? 静的に保証しろってことかな?
488デフォルトの名無しさん
2023/03/24(金) 01:57:35.21ID:STP4y0mB489デフォルトの名無しさん
2023/03/24(金) 02:03:47.17ID:STP4y0mB490デフォルトの名無しさん
2023/03/24(金) 02:07:17.26ID:GMecybVR491デフォルトの名無しさん
2023/03/24(金) 02:12:19.33ID:7trvtA/S492デフォルトの名無しさん
2023/03/24(金) 02:30:27.68ID:STP4y0mB >>491
>C++のスマポは使い方をミスったらおしまいで実際に問題を起こし続けている欠陥品
どういうミスかな? 書いてみ
>null安全か否かは言語仕様で決まりもちろん静的に防げる
これもどういうケースを言っているのか分からんので書いてみて
>vectorの自動メモリ再配置によるダングリング発生がうっかりミスで容易に発生するC++は欠陥言語
連続するアドレスに領域を取ることが保証されているコンテナはRustにはないのかな?
C++はもちろんメモリ再配置しない(領域が連続しない)コンテナを選択できる
反論したいので具体的に書いてね
無理かもしれんがもし書けるならC++のソースで例示してね
>C++のスマポは使い方をミスったらおしまいで実際に問題を起こし続けている欠陥品
どういうミスかな? 書いてみ
>null安全か否かは言語仕様で決まりもちろん静的に防げる
これもどういうケースを言っているのか分からんので書いてみて
>vectorの自動メモリ再配置によるダングリング発生がうっかりミスで容易に発生するC++は欠陥言語
連続するアドレスに領域を取ることが保証されているコンテナはRustにはないのかな?
C++はもちろんメモリ再配置しない(領域が連続しない)コンテナを選択できる
反論したいので具体的に書いてね
無理かもしれんがもし書けるならC++のソースで例示してね
493デフォルトの名無しさん
2023/03/24(金) 02:43:13.61ID:Qymt7I/N ちゃんと書けば動く、は言語として甘え
C++は一刻も早く進化すべきだ
C++は一刻も早く進化すべきだ
494デフォルトの名無しさん
2023/03/24(金) 02:54:47.10ID:STP4y0mB 具体的にね
495デフォルトの名無しさん
2023/03/24(金) 03:22:24.82ID:pHWoHRbv >>491
欠陥言語というか他の言語たちと比べればCやC++はわずかなミスで危険なことになるから大きなマイナスかもしれないけど
省メモリで高速という他の言語では得られない巨大なプラスがあるからC++は必須の存在だったのよ
今はその巨大なプラスがありつつマイナスのないRustが登場したからC++は価値がなくなり役目を終えたけどね
欠陥言語というか他の言語たちと比べればCやC++はわずかなミスで危険なことになるから大きなマイナスかもしれないけど
省メモリで高速という他の言語では得られない巨大なプラスがあるからC++は必須の存在だったのよ
今はその巨大なプラスがありつつマイナスのないRustが登場したからC++は価値がなくなり役目を終えたけどね
496デフォルトの名無しさん
2023/03/24(金) 04:28:25.21ID:F7DMT464 >>495
役目を終えたならC++で書かれた全てのソフトウェアがRustになってもおかしくないけど全くそうじゃないよな?
役目を終えたならC++で書かれた全てのソフトウェアがRustになってもおかしくないけど全くそうじゃないよな?
497デフォルトの名無しさん
2023/03/24(金) 04:38:49.00ID:pHWoHRbv498デフォルトの名無しさん
2023/03/24(金) 04:46:18.91ID:F7DMT464499デフォルトの名無しさん
2023/03/24(金) 05:43:54.98ID:pnAyfShU そもそもC++ってCと比較しても脆弱性が下がる気がする。
なんか初心者泣かせのトラップが多すぎるんだよな。
なんか初心者泣かせのトラップが多すぎるんだよな。
500デフォルトの名無しさん
2023/03/24(金) 05:50:11.50ID:G7wXKrBj >>460
ありがとうございました
ありがとうございました
501デフォルトの名無しさん
2023/03/24(金) 05:58:04.68ID:G7wXKrBj >>484
GCって禿のことだったんですね
GCって禿のことだったんですね
502デフォルトの名無しさん
2023/03/24(金) 06:06:32.31ID:G7wXKrBj503デフォルトの名無しさん
2023/03/24(金) 10:43:05.72ID:qDyrJPYZ >>492
rustのvectorは再配置される可能性がある操作時は他からの参照がないことがコンパイル時に保証されるので連続領域でも問題ないよ
rustのvectorは再配置される可能性がある操作時は他からの参照がないことがコンパイル時に保証されるので連続領域でも問題ないよ
504デフォルトの名無しさん
2023/03/24(金) 11:32:45.65ID:STP4y0mB >>503
ほう! Rustはよう知らんのでC++で聞いて申し訳ないが
以下コメントの部分(1)と(2)は
Rustで相当するコードを書いたらコンパイルが通らないということかな?
#include <iostream>
#include <vector>
#define DOUT(arg) std::cout << #arg": " << arg << '\n';
int main () {
std::vector <int> v;
v.reserve (1);
DOUT (v.capacity ());
v.push_back (10); // (1) Rustで許容 or エラー?
auto itr {v.begin ()};
DOUT (*itr);
v.push_back (11); // (2) Rustで許容 or エラー?
DOUT (v.capacity ());
// DOUT (*itr); // dangerous
return 0;
}
$ ./a.out
v.capacity (): 1
*itr: 10
v.capacity (): 2
ほう! Rustはよう知らんのでC++で聞いて申し訳ないが
以下コメントの部分(1)と(2)は
Rustで相当するコードを書いたらコンパイルが通らないということかな?
#include <iostream>
#include <vector>
#define DOUT(arg) std::cout << #arg": " << arg << '\n';
int main () {
std::vector <int> v;
v.reserve (1);
DOUT (v.capacity ());
v.push_back (10); // (1) Rustで許容 or エラー?
auto itr {v.begin ()};
DOUT (*itr);
v.push_back (11); // (2) Rustで許容 or エラー?
DOUT (v.capacity ());
// DOUT (*itr); // dangerous
return 0;
}
$ ./a.out
v.capacity (): 1
*itr: 10
v.capacity (): 2
505デフォルトの名無しさん
2023/03/24(金) 12:12:50.87ID:yujZIUnP506デフォルトの名無しさん
2023/03/24(金) 12:16:34.86ID:+nRUfXDq >>504
当然エラーは起きない
fn main() {
let mut v = Vec::<i32>::new();
v.reserve_exact(1);
dbg!(v.capacity());
v.push(10);
let first = &v[0];
dbg!(*first);
v.push(11);
dbg!(v.capacity());
dbg!(v.len());
// dbg!(*first); // dangerousなこれを入れたときだけコンパイルエラー
}
[src/main.rs:4] v.capacity() = 1
[src/main.rs:7] *first = 10
[src/main.rs:9] v.capacity() = 4
[src/main.rs:10] v.len() = 2
当然エラーは起きない
fn main() {
let mut v = Vec::<i32>::new();
v.reserve_exact(1);
dbg!(v.capacity());
v.push(10);
let first = &v[0];
dbg!(*first);
v.push(11);
dbg!(v.capacity());
dbg!(v.len());
// dbg!(*first); // dangerousなこれを入れたときだけコンパイルエラー
}
[src/main.rs:4] v.capacity() = 1
[src/main.rs:7] *first = 10
[src/main.rs:9] v.capacity() = 4
[src/main.rs:10] v.len() = 2
507デフォルトの名無しさん
2023/03/24(金) 12:23:09.85ID:STP4y0mB >>505,506
どっちが正しいんだい?
どっちが正しいんだい?
508デフォルトの名無しさん
2023/03/24(金) 12:23:39.80ID:xsjnwqf2 ああそれはそうね
509デフォルトの名無しさん
2023/03/24(金) 12:24:51.09ID:xsjnwqf2 >>506が正しいよ
オレはdangerousがある前提で考えてたから
オレはdangerousがある前提で考えてたから
510デフォルトの名無しさん
2023/03/24(金) 12:27:08.05ID:+nRUfXDq (2)の段階より前に参照や可変参照があっても
(2)の段階より後に使われなければ
(2)の段階より前までにそれらの参照のスコープが自動的に終わる(=ライフタイムが尽きる)
したがってコンフリクトは起きない
一方でもしdangerousの部分のコードがある場合は
(2)の段階より後に使われているため
コンフリクトが起きるためコンパイルエラー
(2)の段階より後に使われなければ
(2)の段階より前までにそれらの参照のスコープが自動的に終わる(=ライフタイムが尽きる)
したがってコンフリクトは起きない
一方でもしdangerousの部分のコードがある場合は
(2)の段階より後に使われているため
コンフリクトが起きるためコンパイルエラー
511デフォルトの名無しさん
2023/03/24(金) 12:31:23.73ID:STP4y0mB 有難う
reserve_exactの引数が定数1のときには
最終行のdangerousを入れるとコンパイルエラーを出すということだが
reserve_exactの引数が変数で実行時にしか定まらんときは
コンパイルエラーにできないと思うんだが危険じゃね?
reserve_exactの引数が定数1のときには
最終行のdangerousを入れるとコンパイルエラーを出すということだが
reserve_exactの引数が変数で実行時にしか定まらんときは
コンパイルエラーにできないと思うんだが危険じゃね?
512デフォルトの名無しさん
2023/03/24(金) 12:35:02.24ID:STP4y0mB513デフォルトの名無しさん
2023/03/24(金) 12:48:05.77ID:+nRUfXDq514デフォルトの名無しさん
2023/03/24(金) 13:14:43.88ID:STP4y0mB515デフォルトの名無しさん
2023/03/24(金) 13:21:48.64ID:STP4y0mB >>513
Rustのスコープ=ライフタイムとすると
デストラクタが呼ばれるタイミングが分かり難くないかい?
ちょっとソースをいじって後ろの方でインスタンスを触ると
呼ばれるデストラクタが呼ばれるタイミングも
自動的に後ろになるということかな?
C++ほどデストラクタに処理を書かないのかな?
Rustのスコープ=ライフタイムとすると
デストラクタが呼ばれるタイミングが分かり難くないかい?
ちょっとソースをいじって後ろの方でインスタンスを触ると
呼ばれるデストラクタが呼ばれるタイミングも
自動的に後ろになるということかな?
C++ほどデストラクタに処理を書かないのかな?
516デフォルトの名無しさん
2023/03/24(金) 13:23:02.73ID:+nRUfXDq >>514
再配置だけでなく値が書き換わる可能性もある
それらの可能性やそれらの操作を跨いで参照を保持してはいけない
逆に言えば参照を持ち続けることができているならば指している値が変わらないことが保証される
これはバグを防ぐとともにコンパイラによる最適化の余地も広げ高速化にも寄与する
再配置だけでなく値が書き換わる可能性もある
それらの可能性やそれらの操作を跨いで参照を保持してはいけない
逆に言えば参照を持ち続けることができているならば指している値が変わらないことが保証される
これはバグを防ぐとともにコンパイラによる最適化の余地も広げ高速化にも寄与する
517デフォルトの名無しさん
2023/03/24(金) 13:31:39.50ID:STP4y0mB >>516
なるほどね
まぁ俺は再配置が起こらないと分かるところで
いちいち参照は取り直したくはないな
Rustのデストラクタが呼ばれるタイミングは
インスタンスのライフタイムで変わりうるということで良い?
なるほどね
まぁ俺は再配置が起こらないと分かるところで
いちいち参照は取り直したくはないな
Rustのデストラクタが呼ばれるタイミングは
インスタンスのライフタイムで変わりうるということで良い?
518デフォルトの名無しさん
2023/03/24(金) 13:32:37.18ID:+nRUfXDq >>515
デストラクタが呼ばれるのはその変数の「ブロックスコープ」のブロックを出るタイミングだから一定している
デストラクタが呼ばれるのはその変数の「ブロックスコープ」のブロックを出るタイミングだから一定している
519デフォルトの名無しさん
2023/03/24(金) 13:37:44.31ID:STP4y0mB ブロックスコープって多分C++のスコープと同じだよね?
ライフタイムとまた違うのかな? 複雑だなぁ
ライフタイムとまた違うのかな? 複雑だなぁ
520デフォルトの名無しさん
2023/03/24(金) 13:53:25.98ID:+nRUfXDq >>519
誤解をしている
ブロックの途中で打ち切られる可能性があるのは参照のライフタイム
そして参照にはデストラクタはない
一方で値そのもののライフタイムつまり所有権が尽きるのは常にブロックスコープに従う
デストラクタが存在すればブロックを抜けるタイミングで呼ばれる
その後でメモリ解放が自動的に行われる
誤解をしている
ブロックの途中で打ち切られる可能性があるのは参照のライフタイム
そして参照にはデストラクタはない
一方で値そのもののライフタイムつまり所有権が尽きるのは常にブロックスコープに従う
デストラクタが存在すればブロックを抜けるタイミングで呼ばれる
その後でメモリ解放が自動的に行われる
521デフォルトの名無しさん
2023/03/24(金) 13:55:42.43ID:GMecybVR デストラクタは所有してる変数のブロックを抜けるまでに呼ばれることが保証されてるけど
正確なタイミングはコンパイラが決めてるから予測はできない
例えば何かを解放しないと以降で競合が生じる場合はブロックの途中で解放されることもある
ただ
A()
B(&A)
みたいにBがAを参照してるような状況だとBが消えるまでAを動かせないから
結果的にC++と同じように逆順で解放されることになる
ライフタイム周りはコンパイラが制約を満たせる処理順を見つけて裏で調整する感じだから
最初は戸惑うかもしれないね
正確なタイミングはコンパイラが決めてるから予測はできない
例えば何かを解放しないと以降で競合が生じる場合はブロックの途中で解放されることもある
ただ
A()
B(&A)
みたいにBがAを参照してるような状況だとBが消えるまでAを動かせないから
結果的にC++と同じように逆順で解放されることになる
ライフタイム周りはコンパイラが制約を満たせる処理順を見つけて裏で調整する感じだから
最初は戸惑うかもしれないね
522デフォルトの名無しさん
2023/03/24(金) 14:00:41.09ID:+nRUfXDq523デフォルトの名無しさん
2023/03/24(金) 14:34:12.82ID:JpLx+uLR >>520
それどこのスマポ
それどこのスマポ
524デフォルトの名無しさん
2023/03/24(金) 14:38:27.83ID:STP4y0mB525デフォルトの名無しさん
2023/03/24(金) 14:55:23.36ID:+nRUfXDq >>523
デストラクタにスマポもポインタも関係ない
Rustでは任意の自作型にデストラクタを実装できる
(ただしCopyを実装していないことが条件)
// 例えば整数i32型のみを持つ構造体Foo
struct Foo(i32);
impl Drop for Foo {
// デストラクタ実装
fn drop(&mut self) {
println!("drop: Foo({})", self.0);
}
}
fn main() {
let _x = Foo(123); // メインブロックを終えてからdropされる
{
let _x = Foo(456); // 内ブロックを終えてからdropされる
let _x = Foo(789); // 内ブロックを終えてからdropされる
println!("内ブロック終わり");
}
println!("メインブロック終わり");
}
【実行結果】
内ブロック終わり
drop: Foo(789)
drop: Foo(456)
メインブロック終わり
drop: Foo(123)
デストラクタにスマポもポインタも関係ない
Rustでは任意の自作型にデストラクタを実装できる
(ただしCopyを実装していないことが条件)
// 例えば整数i32型のみを持つ構造体Foo
struct Foo(i32);
impl Drop for Foo {
// デストラクタ実装
fn drop(&mut self) {
println!("drop: Foo({})", self.0);
}
}
fn main() {
let _x = Foo(123); // メインブロックを終えてからdropされる
{
let _x = Foo(456); // 内ブロックを終えてからdropされる
let _x = Foo(789); // 内ブロックを終えてからdropされる
println!("内ブロック終わり");
}
println!("メインブロック終わり");
}
【実行結果】
内ブロック終わり
drop: Foo(789)
drop: Foo(456)
メインブロック終わり
drop: Foo(123)
526デフォルトの名無しさん
2023/03/24(金) 15:07:39.53ID:GMecybVR527デフォルトの名無しさん
2023/03/24(金) 15:07:52.15ID:+nRUfXDq >>524
C++とRustはiteratorで指すものが微妙に異なるので要注意だがまずは折衷するとして
例えば
let mut v = vec![1, 2, 3];
for p in v.iter_mut() {
*p += 10;
}
これでイテレータを使って11,12,13
C++とRustはiteratorで指すものが微妙に異なるので要注意だがまずは折衷するとして
例えば
let mut v = vec![1, 2, 3];
for p in v.iter_mut() {
*p += 10;
}
これでイテレータを使って11,12,13
528デフォルトの名無しさん
2023/03/24(金) 15:18:17.49ID:m8vHxf3R529デフォルトの名無しさん
2023/03/24(金) 15:28:04.96ID:STP4y0mB530デフォルトの名無しさん
2023/03/24(金) 15:30:39.43ID:+nRUfXDq >>528
変数が所有している値のデストラクタが呼ばれるのはブロックを抜けた直後だけど
変数が所有しない一時的な値や変数が所有しなくなる代入前の値などは
_へ棄てるのと同じくブロック途中でデストラクタが呼ばれるね
変数が所有している値のデストラクタが呼ばれるのはブロックを抜けた直後だけど
変数が所有しない一時的な値や変数が所有しなくなる代入前の値などは
_へ棄てるのと同じくブロック途中でデストラクタが呼ばれるね
531デフォルトの名無しさん
2023/03/24(金) 15:33:55.56ID:STP4y0mB Rustってゴミ箱(_)があるんだなw
532デフォルトの名無しさん
2023/03/24(金) 15:51:46.07ID:+nRUfXDq >>529
もちろんイテレータは参照もしくは可変参照を持つ形となるのでsingle writer or multiple readersを満たす必要がある
それを満たせなければコンパイルエラーとなりデータ競合を防げる
もちろんイテレータは参照もしくは可変参照を持つ形となるのでsingle writer or multiple readersを満たす必要がある
それを満たせなければコンパイルエラーとなりデータ競合を防げる
533デフォルトの名無しさん
2023/03/24(金) 15:55:15.22ID:+nRUfXDq >>531
棄てるのは _ へ棄てなくてもいくらでも方法があり
例えばブロックを作れば
{
let _tmp = x;
}
これで_tmpへ値が移動してブロックを抜けるときに消える
他にも例えば以下の関数を定義して
fn 棄てる<T>(_tmp: T) {
// 何もなし
}
棄てる(x); とすればその関数へ値が移動して関数ブロックを抜けるときに消える
この棄てる関数は同じものがstd::mem::drop()に用意されているので意図をはっきりさせるためにはそれを使うことで可読性を持たせる
棄てるのは _ へ棄てなくてもいくらでも方法があり
例えばブロックを作れば
{
let _tmp = x;
}
これで_tmpへ値が移動してブロックを抜けるときに消える
他にも例えば以下の関数を定義して
fn 棄てる<T>(_tmp: T) {
// 何もなし
}
棄てる(x); とすればその関数へ値が移動して関数ブロックを抜けるときに消える
この棄てる関数は同じものがstd::mem::drop()に用意されているので意図をはっきりさせるためにはそれを使うことで可読性を持たせる
534デフォルトの名無しさん
2023/03/24(金) 17:20:54.03ID:ENxn1p6S >>530
細かいことだけど一時的な値は内部的に一時変数が所有してることになってて一時変数がDrop scopeを抜けていなくなるタイミングでデストラクタが実行される
let _ = Foo(123);やx = Foo(456);は代入によって値の所有者がいなくなるからそのタイミングですぐにデストラクタが実行される
細かいことだけど一時的な値は内部的に一時変数が所有してることになってて一時変数がDrop scopeを抜けていなくなるタイミングでデストラクタが実行される
let _ = Foo(123);やx = Foo(456);は代入によって値の所有者がいなくなるからそのタイミングですぐにデストラクタが実行される
535デフォルトの名無しさん
2023/03/24(金) 20:26:32.48ID:STP4y0mB >>533
こういうことだわな
#include <iostream>
using namespace std;
struct A {
A () {cout << "constructor\n";}
~A () {cout << "destructor\n";}
};
template <typename T> void drop (unique_ptr <T> &&p) {}
int main () {
auto x {make_unique <A> ()};
{
auto _tmp = move (x);
}
drop (move (x));
return 0;
}
こういうことだわな
#include <iostream>
using namespace std;
struct A {
A () {cout << "constructor\n";}
~A () {cout << "destructor\n";}
};
template <typename T> void drop (unique_ptr <T> &&p) {}
int main () {
auto x {make_unique <A> ()};
{
auto _tmp = move (x);
}
drop (move (x));
return 0;
}
536デフォルトの名無しさん
2023/03/24(金) 21:50:27.51ID:VHzrsylr dropバグっとるがな
537デフォルトの名無しさん
2023/03/24(金) 21:51:22.79ID:STP4y0mB ごめんごめん
538デフォルトの名無しさん
2023/03/25(土) 09:38:10.15ID:M09ogOTB 屁臭
539デフォルトの名無しさん
2023/03/25(土) 20:06:44.69ID:sd+PB/iL540デフォルトの名無しさん
2023/03/25(土) 20:52:44.35ID:c5G720p2 デバッガですぐに分かることなので
みょうちくりんな文法を新たに覚えようという動機にはならん
みょうちくりんな文法を新たに覚えようという動機にはならん
541デフォルトの名無しさん
2023/03/25(土) 20:56:23.22ID:VVKoWVL2 不明な挙動があるのが発見されてない時点でもデバッガ使うの? 変なコード書いた本人に自覚がないから不具合として発現するのであって、正常に動くであろうと期待できてる時点でも?
時間の無駄では?
デバッガでわかるよりコンパイラでわかるなら圧倒的にそっちがベターでもあるし
時間の無駄では?
デバッガでわかるよりコンパイラでわかるなら圧倒的にそっちがベターでもあるし
542デフォルトの名無しさん
2023/03/25(土) 20:58:28.17ID:c5G720p2543デフォルトの名無しさん
2023/03/25(土) 20:59:37.07ID:tC35D9u3544デフォルトの名無しさん
2023/03/25(土) 21:03:00.33ID:c5G720p2 コンパイル時点でチェックが入るのはRustの利点だが
C/C++と乖離した文法を新たに覚えるというコストを払おうとは全く思わん
俺がRustを覚えるとしたらシステムコールがRustで書かれたOSを
使うことになったときだけ
当分ない
C/C++と乖離した文法を新たに覚えるというコストを払おうとは全く思わん
俺がRustを覚えるとしたらシステムコールがRustで書かれたOSを
使うことになったときだけ
当分ない
545デフォルトの名無しさん
2023/03/25(土) 21:04:16.45ID:c5G720p2 >>543
でもLockFreeQueueをsafeで実装できないんでしょ?
でもLockFreeQueueをsafeで実装できないんでしょ?
546デフォルトの名無しさん
2023/03/25(土) 21:10:35.10ID:c5G720p2 周りに使用を強制されるほどRustは普及していないので
Rust推しの諸君は自らRustを選択したのだろうけど
そんなにCでのメモリの扱い方に苦労したのかい?
Rust使う人はどちらかというと言語マニアの人達だと思ってたのだが?
Rust推しの諸君は自らRustを選択したのだろうけど
そんなにCでのメモリの扱い方に苦労したのかい?
Rust使う人はどちらかというと言語マニアの人達だと思ってたのだが?
547デフォルトの名無しさん
2023/03/25(土) 21:14:16.97ID:tC35D9u3 >>545
そういうのはすべてsafeなインタフェイスでライブラリが作られてるから
LockFree{Queue,Stack,Map,Set,Chanel}すべてsafeなインタフェイスを用いてRustプログラミングできるよ
そういうのはすべてsafeなインタフェイスでライブラリが作られてるから
LockFree{Queue,Stack,Map,Set,Chanel}すべてsafeなインタフェイスを用いてRustプログラミングできるよ
548デフォルトの名無しさん
2023/03/25(土) 21:17:55.09ID:fB31q3I6549デフォルトの名無しさん
2023/03/25(土) 21:18:50.17ID:c5G720p2550デフォルトの名無しさん
2023/03/25(土) 21:23:11.57ID:tC35D9u3 >>549
すべてがunsafeなC++と違って
RustならLockFree{Queue,Stack,Map,Set,Chanel}をsafeなインタフェイスで使うことで自分の書くプログラムをsafeにできるよ
つまりRustコンパイラが書いたプログラムの安全性の保証をしてくれるよ
すべてがunsafeなC++と違って
RustならLockFree{Queue,Stack,Map,Set,Chanel}をsafeなインタフェイスで使うことで自分の書くプログラムをsafeにできるよ
つまりRustコンパイラが書いたプログラムの安全性の保証をしてくれるよ
551デフォルトの名無しさん
2023/03/25(土) 21:36:28.93ID:c5G720p2■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 【サッカー】J1昇格PO決勝戦 千葉、来季のJ1昇格が決定 17年越しの悲願叶える…オリジナル10が05年以来のJ1にそろう [久太郎★]
- 南京で「大虐殺」追悼式典 中国、高市政権をけん制 (共同通信) [少考さん★]
- 中国・ロシア両軍の爆撃機が東京方面へ向かう「異例のルート」を共同飛行…核も搭載可能、連携して威嚇か ★5 [ぐれ★]
- 【日銀】0.75%に利上げへ 来週の決定会合で、30年ぶり水準 賃金改善の継続見込む [ぐれ★]
- 緊急入院のゆたぼん「人身事故は嘘」はデマ 「滑稽ですね」救急車写真で証明、法的措置も検討 [少考さん★]
- 京都のホテル大幅値下げ 訪日中国人客、年1000万人目前で急ブレーキ ★3 [蚤の市★]
- >>5で貼られたスレにみんなで凸するスレ
- 【高市悲報】目ん玉が飛び出るほど仕事が出来ない人間の特徴に高市がぴったり合うと話題に。まさに無能な働き者 [483862913]
- どうしてコンビニって移民に乗っ取られたの?
- 上司「茨城に転勤してもらう 日立、土浦、竜ヶ崎、麻生、下妻から好きなところ選んで良いぞ🤗」👈どこがオススメ? [175344491]
- 日本人「日本1人当たりGDPはチェコ、クウェート、エストニアと同等。エンゲル係数も30%…もう先進国じゃ無いよ😂」 [441660812]
- 【実況】博衣こよりのえちえちドラクエ1&2リメイク🧪★3🏡
