公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust
Web上の実行環境
https://play.rust-lang.org
日本語の情報
https://rust-jp.rs/
※Rustを学びたい人はまず最初に公式のThe Bookを読むこと
https://doc.rust-lang.org/book/
※C++との比較は専用スレへ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/
前スレ
Rust part10
https://mevius.5ch.net/test/read.cgi/tech/1617367084/
Rust part11
■ このスレッドは過去ログ倉庫に格納されています
2021/06/17(木) 00:24:12.56ID:NvYoNP9C
2デフォルトの名無しさん
2021/06/19(土) 01:15:49.18ID:3FFA7ImF >>1 おつ
3デフォルトの名無しさん
2021/06/19(土) 01:20:06.41ID:VXoz87sA >>1
乙
乙
4デフォルトの名無しさん
2021/06/19(土) 02:14:18.53ID:tZhqlEYm 勉強中でいまいちよくわかってないんだけどさ
よくRsutでメモリの扱いが安全になるとか言われてるけど、これって解放忘れを防いでくれるだけであって、オーバーフローを防いでくれるものではないわけ?
それとも登場する全ての型がオーバーフローしないような仕組み(スタックプロテクター以上の何か)があるの?
よくRsutでメモリの扱いが安全になるとか言われてるけど、これって解放忘れを防いでくれるだけであって、オーバーフローを防いでくれるものではないわけ?
それとも登場する全ての型がオーバーフローしないような仕組み(スタックプロテクター以上の何か)があるの?
2021/06/19(土) 03:26:44.04ID:5peZoltk
>>4
型のオーバーフローっていうのは算術オーバーフロー(桁あふれ)のことかな?
であればここを読むといいと思う
https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-overflow
型のオーバーフローっていうのは算術オーバーフロー(桁あふれ)のことかな?
であればここを読むといいと思う
https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-overflow
6はちみつ餃子 ◆8X2XSCHEME
2021/06/19(土) 04:22:00.60ID:/f53/cxR スタックプロテクターの話題を出すってことは
バッファオーバーフロー (バッファオーバーラン) のことじゃないかな。
配列は大きさの情報を持っているし、
配列の一部の範囲を受け渡すときはポインタでなくスライスで扱うのが Rust の基本的な設計になってる。
ポインタと違ってスライスは範囲の情報を持っているのでチェック可能で、チェックする仕様になってるよ。
溢れたら panic する。
(もちろん unsafe な操作をしたらいくらでも危険な操作は出来る。)
絶対に溢れないことがコンパイル時に見抜ける場合であれば
チェックしないように最適化したりすることもあるし、
チェックする場合でも現代的な CPU ではほぼ確実に分岐予測が成功するから
処理速度が遅くなる分は十分に小さいとかいう話があったはず。
バッファオーバーフロー (バッファオーバーラン) のことじゃないかな。
配列は大きさの情報を持っているし、
配列の一部の範囲を受け渡すときはポインタでなくスライスで扱うのが Rust の基本的な設計になってる。
ポインタと違ってスライスは範囲の情報を持っているのでチェック可能で、チェックする仕様になってるよ。
溢れたら panic する。
(もちろん unsafe な操作をしたらいくらでも危険な操作は出来る。)
絶対に溢れないことがコンパイル時に見抜ける場合であれば
チェックしないように最適化したりすることもあるし、
チェックする場合でも現代的な CPU ではほぼ確実に分岐予測が成功するから
処理速度が遅くなる分は十分に小さいとかいう話があったはず。
2021/06/19(土) 09:47:40.12ID:5peZoltk
バッファオーバーフローのことなのか
Safe Rustでは基本的に発生しないが仕組みというより
unsafeなコードを書く人が要求された安全性を保証するという約束の上に成り立ってる
Rustの要求するメモリ安全性を保証するためには
unsafeなコードでポインタをdereferenceする前にout-of-boundsかどうかのチェックが必要
Safe Rustでは基本的に発生しないが仕組みというより
unsafeなコードを書く人が要求された安全性を保証するという約束の上に成り立ってる
Rustの要求するメモリ安全性を保証するためには
unsafeなコードでポインタをdereferenceする前にout-of-boundsかどうかのチェックが必要
2021/06/19(土) 14:15:48.54ID:lGsmv2n4
境界チェックなんて他の言語でもあるし、別にそこがRustの特別な強みではないんだよな
それよりは、
> これって解放忘れを防いでくれるだけであって
だけじゃなくて、use-after-freeとか、
思わぬ箇所でオブジェクトが変更されることによるデータ競合とか、
をコンパイル時にチェックできるのが強い
詳細はThe Book 4章に
https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html
日本語版はこっち
https://doc.rust-jp.rs/book-ja/ch04-02-references-and-borrowing.html
それよりは、
> これって解放忘れを防いでくれるだけであって
だけじゃなくて、use-after-freeとか、
思わぬ箇所でオブジェクトが変更されることによるデータ競合とか、
をコンパイル時にチェックできるのが強い
詳細はThe Book 4章に
https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html
日本語版はこっち
https://doc.rust-jp.rs/book-ja/ch04-02-references-and-borrowing.html
2021/06/19(土) 15:41:11.20ID:7Y2aa0wT
解放忘れ(メモリーリーク)はRustは
保証してないのでは?
保証してないのでは?
2021/06/19(土) 16:32:09.25ID:+A5T+Cz1
Rc/Arc以外でメモリリークって起こるの?
2021/06/19(土) 16:52:09.35ID:5/JSw/kX
Box::leakして返された参照を捨てるとメモリリーク起こせる
2021/06/20(日) 02:45:16.68ID:O2AvtKTb
最近勉強始めたんだが、正直ムズイ
特にwinapiのポインタ引数が(構造体のポインタではなく)DWORDで定義されてたりするので、
キャストするのが超絶面倒臭い
microsoftはcrate修正してほしい
まあ、rustというよりwinapiの問題なんだが……
特にwinapiのポインタ引数が(構造体のポインタではなく)DWORDで定義されてたりするので、
キャストするのが超絶面倒臭い
microsoftはcrate修正してほしい
まあ、rustというよりwinapiの問題なんだが……
13はちみつ餃子 ◆8X2XSCHEME
2021/06/20(日) 02:57:43.41ID:h62I7Iw3 わかる。
DWORD とポインタをカジュアルに同一視する API はまだマシなほうで、
Rust は文字列をスライスで扱うから単純にポインタに変換してもヌル終端されてないのがクソめんどい。
文字列を渡すとかすごく普通にあることなんで、それがこんなに面倒くさいの勘弁して欲しい。
DWORD とポインタをカジュアルに同一視する API はまだマシなほうで、
Rust は文字列をスライスで扱うから単純にポインタに変換してもヌル終端されてないのがクソめんどい。
文字列を渡すとかすごく普通にあることなんで、それがこんなに面倒くさいの勘弁して欲しい。
14デフォルトの名無しさん
2021/06/20(日) 06:34:35.27ID:9R7FlmLP 普通に書いててwinapiとか使う機会ないと思うけどOS機能を直接触る必要のあるライブラリでも書いてるのかな?
2021/06/20(日) 15:00:11.94ID:ZAMdhkls
OS層に近いAPI全く使わないならrustやc++とかデメリットの方が多いような。
16デフォルトの名無しさん
2021/06/20(日) 16:38:08.85ID:K2CzG+CP 俺も最近Rust勉強してるんだけど、GC無しでのメモリ管理が最高に気持ちいい
何もかもRustで書きたくなる
何もかもRustで書きたくなる
2021/06/20(日) 17:33:03.51ID:D+WmuL2+
ワイは基本moveってところが気に入ってる
参照をもって回るんじゃなくて
実態をmoveで渡してmoveで返されるとき清々しいのを感じる
参照をもって回るんじゃなくて
実態をmoveで渡してmoveで返されるとき清々しいのを感じる
2021/06/20(日) 17:51:48.27ID:BAitg4NO
システムコールや低レベルなライブラリをいい感じに安全にラップしてくれるcrateが提供されてるのはrustの良いところ
2021/06/20(日) 19:32:30.59ID:5UZIMOEC
moveって最適化ビルドだと消えたりしてるのかな?
2021/06/20(日) 21:04:33.39ID:BAitg4NO
moveが消えるとは?
moveがコンパイルされた結果のmemcpyなどが消えることはある
moveがコンパイルされた結果のmemcpyなどが消えることはある
2021/06/20(日) 22:37:40.54ID:X7PAuK/l
>>13
Rustのスライスは、ほぼPascal文字列だから、Cよりも古くから作法や
概念は存在している。
しかし、なぜCがPascal文字列ではなく0終端文字列にしたのかには
理由があって、文字列の途中(部分文字列)を扱わない場合においては効率が良いから。
0終端文字列の欠点は、部分文字列を扱おうとするととたんに面倒なことになること。
ただ、strcmpみたいなものを書いたり、字句解析を書いたりするときには、効率は良い。
字句解析では決定性オートマトンの理論がグラフ的(状態遷移図的)になっており、
Cの0終端文字列とはとても相性が良い。
そして、コンパイラの実行時間の大部分は、実測してみると、意外にも字句解析が占めている。
字句解析は単純ではあるが、量が多いので1クロックの差がものをいう世界である。
ただ、Pascal文字列(スライス)が字句解析でも有利に働く場面はあるにはあるが。
どちらの方式が一方的に優れているとはいえない。
Rustのスライスは、ほぼPascal文字列だから、Cよりも古くから作法や
概念は存在している。
しかし、なぜCがPascal文字列ではなく0終端文字列にしたのかには
理由があって、文字列の途中(部分文字列)を扱わない場合においては効率が良いから。
0終端文字列の欠点は、部分文字列を扱おうとするととたんに面倒なことになること。
ただ、strcmpみたいなものを書いたり、字句解析を書いたりするときには、効率は良い。
字句解析では決定性オートマトンの理論がグラフ的(状態遷移図的)になっており、
Cの0終端文字列とはとても相性が良い。
そして、コンパイラの実行時間の大部分は、実測してみると、意外にも字句解析が占めている。
字句解析は単純ではあるが、量が多いので1クロックの差がものをいう世界である。
ただ、Pascal文字列(スライス)が字句解析でも有利に働く場面はあるにはあるが。
どちらの方式が一方的に優れているとはいえない。
2021/06/20(日) 22:45:58.47ID:X7PAuK/l
>>21
すまん。今調べたら、Pascal文字列は、配列の先頭に文字数が
入っている特殊な形式で、スライスとはまた違うものだった。
今まで誤解していたわ。
Pascal文字列はダメだわ、全く意味無し。
ただ、俺が言いたかったのは、Rustのスライス方式も古くから概念自体は存在し、
Win32APIでもGetTextExtentPoint32()なんかが、ポインタと、その後に続く
文字数の両方を指定する方式を取っている。
このやり方は、文字列の中に 0x00 を埋め込まなくても部分文字列を扱えて
便利は便利。もしこれを部分文字列の場所を少しずつ変えていくようなの場合に、
0終端文字列でやろうとすると、効率が悪くなる。
ただ、いつでもスライスの方が0終端文字列より効率が良いという訳ではない。
それが>>21で言いたかったこと。決定性や非決定性オートマトンの考え方で字句解析を
する際には、Cの0終端文字列はスライスより効率が良い。
すまん。今調べたら、Pascal文字列は、配列の先頭に文字数が
入っている特殊な形式で、スライスとはまた違うものだった。
今まで誤解していたわ。
Pascal文字列はダメだわ、全く意味無し。
ただ、俺が言いたかったのは、Rustのスライス方式も古くから概念自体は存在し、
Win32APIでもGetTextExtentPoint32()なんかが、ポインタと、その後に続く
文字数の両方を指定する方式を取っている。
このやり方は、文字列の中に 0x00 を埋め込まなくても部分文字列を扱えて
便利は便利。もしこれを部分文字列の場所を少しずつ変えていくようなの場合に、
0終端文字列でやろうとすると、効率が悪くなる。
ただ、いつでもスライスの方が0終端文字列より効率が良いという訳ではない。
それが>>21で言いたかったこと。決定性や非決定性オートマトンの考え方で字句解析を
する際には、Cの0終端文字列はスライスより効率が良い。
2021/06/20(日) 22:54:46.58ID:D+WmuL2+
読む価値無い文章をダラダラ書いちゃうのって
なんらかの障害なんやろな
なんらかの障害なんやろな
2021/06/21(月) 00:08:08.49ID:85An+spJ
>>22
そのせいでPascal文字列は長さ255文字までに制限されてたのよな。
そのせいでPascal文字列は長さ255文字までに制限されてたのよな。
2021/06/21(月) 00:46:14.79ID:PP3lMGGZ
結論は、Rustがそんなにすばらしい言語とは到底思えないということだ。
2021/06/21(月) 02:03:12.76ID:wnQSc3ge
ええんやで
27デフォルトの名無しさん
2021/06/21(月) 03:36:25.54ID:JQDu6zSa >>25 まぁ用途によるやろ
発展途上なところもあるし、そもそもRustが向いてないような用途もある
発展途上なところもあるし、そもそもRustが向いてないような用途もある
28デフォルトの名無しさん
2021/06/21(月) 07:39:35.72ID:3uERIKtL >>13
様々な文字列処理をしたことがある人になら自明ですが
文字列を扱う場合は¥0終端よりもスライスのほうが圧倒的に有利です
例えば何段か深いディレクトリの絶対パスが与えられた時に各ディレクトリのリストを返す(つまりsprit)時
¥0終端方式だと元の文字列を書き換え破壊しない限りコピーが発生してしまいます
スライス方式だと書き換えもコピーも発生しません
これは正規表現によるパターンマッチングでも同じで¥0終端方式だと結果である部分文字列をコピーしなければ返せません
またHTMLやJSONなどの様々な構造データの解析結果でもそうです
JSON文字列を解析して内部構造化表現にする時もスライス方式ならば文字列のコピーが発生せずに済むわけです
様々な文字列処理をしたことがある人になら自明ですが
文字列を扱う場合は¥0終端よりもスライスのほうが圧倒的に有利です
例えば何段か深いディレクトリの絶対パスが与えられた時に各ディレクトリのリストを返す(つまりsprit)時
¥0終端方式だと元の文字列を書き換え破壊しない限りコピーが発生してしまいます
スライス方式だと書き換えもコピーも発生しません
これは正規表現によるパターンマッチングでも同じで¥0終端方式だと結果である部分文字列をコピーしなければ返せません
またHTMLやJSONなどの様々な構造データの解析結果でもそうです
JSON文字列を解析して内部構造化表現にする時もスライス方式ならば文字列のコピーが発生せずに済むわけです
2021/06/21(月) 08:53:58.31ID:xiUkcw19
2021/06/21(月) 09:07:04.10ID:WbPJLyAM
そういやRustの std::ffi::OsString って¥0終端なんだっけ?
2021/06/21(月) 09:43:03.40ID:ILFJsIgR
32デフォルトの名無しさん
2021/06/21(月) 11:29:12.30ID:+vRECSeH >>29 FFIのことを考えつつスライスの恩恵(境界チェックなど)も受けるなら今のRustの文字列に最後に\0を入れるようにしたらいいと思ったけどなんでしないんやろ
\0分の1バイトぐらい今のPCじゃ問題にならないはず
\0分の1バイトぐらい今のPCじゃ問題にならないはず
2021/06/21(月) 11:49:33.30ID:hH2X9nxJ
>>32
従来の &str (部分文字列) とnul終端文字列を区別しないといけないけど
型で区別しようとすると結局今のCStr/CStringと同じになるのでは
文字列は部分文字列含め全部Stringみたいにヒープアロケーションするなら良いけどさすがに効率が悪すぎる
従来の &str (部分文字列) とnul終端文字列を区別しないといけないけど
型で区別しようとすると結局今のCStr/CStringと同じになるのでは
文字列は部分文字列含め全部Stringみたいにヒープアロケーションするなら良いけどさすがに効率が悪すぎる
2021/06/21(月) 12:03:56.90ID:vy1X2bYf
これps5は60fpsでます??
2021/06/21(月) 12:11:12.63ID:743v8uRC
Rust違いです
ってかゲームのほうのRustって個別スレ無いんだね
ってかゲームのほうのRustって個別スレ無いんだね
2021/06/21(月) 12:12:05.66ID:oYpDc35T
FFIが必要な箇所で
let cstr = std::ffi::CString::new(str);
すれば済む話だからね
Win32APIだと\0終端の2バイト文字も渡したりするからCStringでも使い勝手悪そう
let wcstr: Vec<u16> = std::ffi::CString::new(str).to_str().unwrap().encode_utf16().collect();
で動くかな(試してない)
こっちは自分で'\0'足す方が簡単かもしれない
let cstr = std::ffi::CString::new(str);
すれば済む話だからね
Win32APIだと\0終端の2バイト文字も渡したりするからCStringでも使い勝手悪そう
let wcstr: Vec<u16> = std::ffi::CString::new(str).to_str().unwrap().encode_utf16().collect();
で動くかな(試してない)
こっちは自分で'\0'足す方が簡単かもしれない
2021/06/21(月) 12:43:27.64ID:UE5kS0Iw
2021/06/21(月) 12:53:52.20ID:UE5kS0Iw
何度も言うが、全面的にスライスが良いならC言語でも0終端文字列をやめに
してしまえばいいのだが、そういう訳ではない。
>>28 に挙がっているようなケースで、自分も同じような気持ちになったことは有るが、
一方で 0終端文字列の方が効率が良い例も少なからず存在しているので全面的に
スライス方式に変えてしまうのは難しい。
一番単純な例を書けば、英大文字の部分だけを読み飛ばす場合、
(1) ptrが0終端文字列を挿している場合:
while ( *ptr >= 'A' && *ptr <= 'Z' ) ptr++;
(2) (ptr, len)でスライス文字列を表現している場合 :
int cnt = 0;
while ( cnt < len && *ptr >= 'A' && *ptr <= 'Z' ) {ptr++; cnt++;}
後者だと、cnt < len と cnt++; の部分が追加されて効率が落ちる。
してしまえばいいのだが、そういう訳ではない。
>>28 に挙がっているようなケースで、自分も同じような気持ちになったことは有るが、
一方で 0終端文字列の方が効率が良い例も少なからず存在しているので全面的に
スライス方式に変えてしまうのは難しい。
一番単純な例を書けば、英大文字の部分だけを読み飛ばす場合、
(1) ptrが0終端文字列を挿している場合:
while ( *ptr >= 'A' && *ptr <= 'Z' ) ptr++;
(2) (ptr, len)でスライス文字列を表現している場合 :
int cnt = 0;
while ( cnt < len && *ptr >= 'A' && *ptr <= 'Z' ) {ptr++; cnt++;}
後者だと、cnt < len と cnt++; の部分が追加されて効率が落ちる。
2021/06/21(月) 13:02:34.21ID:WbPJLyAM
Linuxカーネル開発における「Rust」採用の動き、グーグルとISRGがさらなる後押し
https://japan.zdnet.com/article/35172646/
> Googleは、ウェブサーバーソフトウェアの「Apache HTTP Server」向けのモジュールをRustによるモジュールで置き換えるというISRGのプロジェクトも支援している。
https://japan.zdnet.com/article/35172646/
> Googleは、ウェブサーバーソフトウェアの「Apache HTTP Server」向けのモジュールをRustによるモジュールで置き換えるというISRGのプロジェクトも支援している。
2021/06/21(月) 13:11:18.52ID:+4cAknZI
windows apiを使ってメッセージダイアログボックスを表示するサンプルが載ってるサイト教えてください
2021/06/21(月) 13:25:05.28ID:hH2X9nxJ
>>38
今のcpuとコンパイラの最適化で両者にどれくらいの性能差があるか示したベンチマークなどある?
rustでも文字列末尾に0を差し込めば同じことはできるので、本当に速くなるなら最適化の手法として採用しても良いかもしれない
今のcpuとコンパイラの最適化で両者にどれくらいの性能差があるか示したベンチマークなどある?
rustでも文字列末尾に0を差し込めば同じことはできるので、本当に速くなるなら最適化の手法として採用しても良いかもしれない
2021/06/21(月) 13:41:31.99ID:G7rEBmCP
2021/06/21(月) 13:52:57.02ID:xiUkcw19
>>40
use winapi::um::winuser::*;
fn main() {
let str: Vec<u16> = "Hello, world!".encode_utf16().chain(Some(0)).collect();
unsafe{
MessageBoxW(std::ptr::null_mut(), str.as_ptr() , str.as_ptr(), MB_OK);
}
}
use winapi::um::winuser::*;
fn main() {
let str: Vec<u16> = "Hello, world!".encode_utf16().chain(Some(0)).collect();
unsafe{
MessageBoxW(std::ptr::null_mut(), str.as_ptr() , str.as_ptr(), MB_OK);
}
}
2021/06/21(月) 14:00:39.66ID:yyeRDQfZ
設計判断ってのは常にトードオフの選択だからな
ヌル終端にすることで得られるものと失うものを天秤にかける必要がある
得られるものしか見ないやつは設計からは手を引け
ヌル終端にすることで得られるものと失うものを天秤にかける必要がある
得られるものしか見ないやつは設計からは手を引け
2021/06/21(月) 14:01:15.31ID:yyeRDQfZ
トレードオフね
あー恥ずかし
あー恥ずかし
2021/06/21(月) 14:13:19.21ID:t12YpwM9
ああトードオフは重要だよな
2021/06/21(月) 14:31:05.42ID:ILFJsIgR
48デフォルトの名無しさん
2021/06/21(月) 14:45:15.77ID:6c6Y8dXA Rustってなんでprintlnの後にビックリマークあるの?
2021/06/21(月) 14:51:45.48ID:G7rEBmCP
2021/06/21(月) 14:58:01.41ID:oYpDc35T
2021/06/21(月) 15:29:27.47ID:+4cAknZI
>>43
先輩ありがとうございます!
先輩ありがとうございます!
2021/06/21(月) 15:40:08.22ID:WbPJLyAM
そういや、可変長引数を直接書けないからRustはクソって言う人はまだ見た事ないな
あんまり使わないからかな?
あんまり使わないからかな?
2021/06/21(月) 16:23:01.35ID:hH2X9nxJ
2021/06/21(月) 16:29:47.09ID:hH2X9nxJ
>>52
Cで可変長引数使いたくなるのってprintf系関数以外なんかある?
Cで可変長引数使いたくなるのってprintf系関数以外なんかある?
55デフォルトの名無しさん
2021/06/21(月) 16:52:01.19ID:xiUkcw192021/06/21(月) 17:01:59.90ID:UE5kS0Iw
2021/06/21(月) 17:23:50.71ID:a6mPBEl9
2021/06/21(月) 17:32:00.25ID:xiUkcw19
議論するのそこ?
むしろセキュリティ(バッファオーバーランの危険性)とパフォーマンスを秤にかけて
rustはセキュリティの方を採用したってだけじゃない?
パスカル文字列なんて昔からあったわけだし
むしろセキュリティ(バッファオーバーランの危険性)とパフォーマンスを秤にかけて
rustはセキュリティの方を採用したってだけじゃない?
パスカル文字列なんて昔からあったわけだし
59はちみつ餃子 ◆8X2XSCHEME
2021/06/21(月) 17:54:38.56ID:5bV+3LP72021/06/21(月) 18:00:00.24ID:W8eb/Sbg
2021/06/21(月) 18:49:34.95ID:xiUkcw19
2021/06/21(月) 19:12:19.82ID:Qd3Oxzyr
2021/06/21(月) 21:14:54.92ID:MXwcp+e6
winapiクレートを使うことってもうなくね?
Microsoft公式のwindiwsクレートの方がよっぽど使いやすいよ
Microsoft公式のwindiwsクレートの方がよっぽど使いやすいよ
64デフォルトの名無しさん
2021/06/21(月) 21:47:08.31ID:L+7FW+LR >>38
>(1) ptrが0終端文字列を挿している場合:
>while ( *ptr >= 'A' && *ptr <= 'Z' ) ptr++;
その場合でも、まず与えられたデータが0終端しているかどうかを確認する必要がありますよね。
データがどこから来るのかは、
ネット上の通信相手か
ディスク上のファイルか
メモリ上の他言語等APIかになりますが、
いずれも盲目的に信頼せずに処理する必要があります。
そして小さいデータならばどんな処理方法でも誤差になるのでしょうが、
大きなデータの場合は>>28のように元はJSONとかHTMLのように構造をもっており、
その解析結果である各一部分が対象文字列になります。
すると0終端させた方がわずかに速く扱える可能性があるからといって、元の大きなデータから毎回コピーして0終端文字列を作る場合と、
コピーをせずにスライスのまま部分文字列を扱う場合との、比較になるのでははいでしょうか?
>(1) ptrが0終端文字列を挿している場合:
>while ( *ptr >= 'A' && *ptr <= 'Z' ) ptr++;
その場合でも、まず与えられたデータが0終端しているかどうかを確認する必要がありますよね。
データがどこから来るのかは、
ネット上の通信相手か
ディスク上のファイルか
メモリ上の他言語等APIかになりますが、
いずれも盲目的に信頼せずに処理する必要があります。
そして小さいデータならばどんな処理方法でも誤差になるのでしょうが、
大きなデータの場合は>>28のように元はJSONとかHTMLのように構造をもっており、
その解析結果である各一部分が対象文字列になります。
すると0終端させた方がわずかに速く扱える可能性があるからといって、元の大きなデータから毎回コピーして0終端文字列を作る場合と、
コピーをせずにスライスのまま部分文字列を扱う場合との、比較になるのでははいでしょうか?
2021/06/21(月) 22:00:11.19ID:xiUkcw19
2021/06/21(月) 22:22:17.51ID:oYpDc35T
2021/06/21(月) 22:57:58.01ID:xiUkcw19
>>66
なるほど、理解した
なるほど、理解した
2021/06/21(月) 22:58:56.43ID:ILFJsIgR
その比較は部分文字列をコピーするかスライスで表現するかの違いであって
0終端文字列のメリット・デメリットとは少し違うんじゃない?
0終端でも同じようにスライスを(ptr, len)で作ればコピーは不要
0終端文字列のメリット・デメリットとは少し違うんじゃない?
0終端でも同じようにスライスを(ptr, len)で作ればコピーは不要
2021/06/21(月) 23:46:42.70ID:oYpDc35T
>>68
> 0終端でも同じようにスライスを(ptr, len)で作ればコピーは不要
それをやってしまうとその部分文字列に対して0終端のメリットが効かなくなるわけで
コピーしないとメリットを得られないというのがデメリットになってる
> 0終端でも同じようにスライスを(ptr, len)で作ればコピーは不要
それをやってしまうとその部分文字列に対して0終端のメリットが効かなくなるわけで
コピーしないとメリットを得られないというのがデメリットになってる
70デフォルトの名無しさん
2021/06/22(火) 02:10:06.59ID:JEO56Dr7 つまり部分文字列を扱う場合は、コピーが発生する0終端方式が不利になりますね。
具体的にファイルパスからディレクトリ部分を得るとか、URLからホスト名を得るとか、元データを破壊したくない時は0終端方式だとコピーするしかないです。
つまり一貫してRustのように始点&長さ方式の方が、有利かつメモリ安全ではないでしょうか?
さらに文字列比較の場合も長さ方式よりも0終端方式が不利です。
これはCのmemcmpとstrcmpの比較に還元されますが、
memcmpは64bit比較やSIMD利用ができるからです。
具体的にファイルパスからディレクトリ部分を得るとか、URLからホスト名を得るとか、元データを破壊したくない時は0終端方式だとコピーするしかないです。
つまり一貫してRustのように始点&長さ方式の方が、有利かつメモリ安全ではないでしょうか?
さらに文字列比較の場合も長さ方式よりも0終端方式が不利です。
これはCのmemcmpとstrcmpの比較に還元されますが、
memcmpは64bit比較やSIMD利用ができるからです。
71デフォルトの名無しさん
2021/06/22(火) 02:44:25.97ID:fStlaCDg &strって3つの意味があると思うんだよね
1: 文字列リテラル
2: Stringの参照
3: 部分文字列
文字列リテラルとStringは終端にNULLを付けるようにして(今まで通りlenやcapは残す)、部分文字列は部分文字列を意味する別の型を作ればいいと思った
こうすることでRust側ではlenやcapを使い、C側ではNULL終端を利用できるという状態になる(Stringや&strをRustで使ってもCで使ってもゼロコスト)
もしNULL終端ではない部分文字列をCで使いたければStringに変換すれば使えるようになる(これはコストがかかるけどCの文字列も同じ問題を抱えてるので問題なし)
1: 文字列リテラル
2: Stringの参照
3: 部分文字列
文字列リテラルとStringは終端にNULLを付けるようにして(今まで通りlenやcapは残す)、部分文字列は部分文字列を意味する別の型を作ればいいと思った
こうすることでRust側ではlenやcapを使い、C側ではNULL終端を利用できるという状態になる(Stringや&strをRustで使ってもCで使ってもゼロコスト)
もしNULL終端ではない部分文字列をCで使いたければStringに変換すれば使えるようになる(これはコストがかかるけどCの文字列も同じ問題を抱えてるので問題なし)
2021/06/22(火) 08:19:32.37ID:7Ks2gqqv
>>70
それやるには文字列がimmutableでなければならないから、それによって生じるスペースコストとどっちをとるかって話だな。
それにimmutableな文字列って、部分変更に相当する処理をする場合に逆にコピーが必要になるし。
どっちにしても一概に、コピー不要だからこっちが有利、みたいな話にはならんかと。
それやるには文字列がimmutableでなければならないから、それによって生じるスペースコストとどっちをとるかって話だな。
それにimmutableな文字列って、部分変更に相当する処理をする場合に逆にコピーが必要になるし。
どっちにしても一概に、コピー不要だからこっちが有利、みたいな話にはならんかと。
2021/06/22(火) 12:15:08.38ID:UUxAOJV3
rustで初心者がハマるポイントを初心者が紹介します
・所有権の概念が難しい
・何をするにしても外部ライブラリが必要(乱数生成など)
・ポインタが難しい
・所有権の概念が難しい
・何をするにしても外部ライブラリが必要(乱数生成など)
・ポインタが難しい
2021/06/22(火) 12:16:52.83ID:hfO2UPRV
・検索すると同名のゲームの話ばかり出てくる
2021/06/22(火) 12:26:02.44ID:jOUHjhXv
・static変数の扱いが面倒臭い
76デフォルトの名無しさん
2021/06/22(火) 12:52:20.13ID:P9tLBTwV >>64
>その場合でも、まず与えられたデータが0終端しているかどうかを確認する必要がありますよね。
「0終端文字列」
というのは、必ず0終端されている文字列の事なので確認は不要。
それを明確にするために、C言語では、const char *pszText; のように、
psz という接頭辞をつける流儀がある。
psz = pointer to string ending with zero.
「0で終端している文字列へのポインタ」
という意味。これは、単なる const char *ptr; とは意味が異なる。
char c = 'A';
const char *ptr = &c; // 単なる文字へのポインタ。0終端されていない。
char szText[] = "Hello"; // 0終端文字列。0終端されている。
const char *pszText = szText; // 0終端文字列へのポインタ。0終端されている。
>その場合でも、まず与えられたデータが0終端しているかどうかを確認する必要がありますよね。
「0終端文字列」
というのは、必ず0終端されている文字列の事なので確認は不要。
それを明確にするために、C言語では、const char *pszText; のように、
psz という接頭辞をつける流儀がある。
psz = pointer to string ending with zero.
「0で終端している文字列へのポインタ」
という意味。これは、単なる const char *ptr; とは意味が異なる。
char c = 'A';
const char *ptr = &c; // 単なる文字へのポインタ。0終端されていない。
char szText[] = "Hello"; // 0終端文字列。0終端されている。
const char *pszText = szText; // 0終端文字列へのポインタ。0終端されている。
2021/06/22(火) 13:23:35.92ID:D73AVe+6
>>76
ファイルから読んだデータをpszHogeに格納するときにゼロ終端の要件満たしてるか確認する必要あるよねって話だぞ
ファイルから読んだデータをpszHogeに格納するときにゼロ終端の要件満たしてるか確認する必要あるよねって話だぞ
2021/06/22(火) 13:25:24.28ID:RVuteXyT
>>74がマジで深刻すぎる
ついでに加藤純一っていうゲーム実況者とかとじゅんっていうRust/Scala使いがいるのも紛らわしい
ついでに加藤純一っていうゲーム実況者とかとじゅんっていうRust/Scala使いがいるのも紛らわしい
2021/06/22(火) 13:35:53.88ID:IhZgQU+B
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 高市早苗総理 G20サミット“遅刻” 会議後の夕食会出席も見送り [Hitzeschleier★]
- 【毎日世論調査】高市内閣の支持率65% 日中関係悪化も高水準維持、若年層に強み [蚤の市★]
- 【産経新聞】高市政権をバッシングする勢力、中国と一部のオールドメディアと緊縮財政派か [Hitzeschleier★]
- 小泉進次郎防衛相「共産党が日本の弾薬の数や配備を質問してきた、そんなこと言うわけない、手の内を見せるべきではない」 [お断り★]
- 【裁判】山上徹也被告の妹「大好きなお兄ちゃん」「旧統一教会信者の叔母から、選挙時に自民党の特定の候補に入れてほしいと…」奈良地裁 [1ゲットロボ★]
- 【石破茂前首相】台湾有事巡る高市発言に苦言 神経使う日中関係「よく認識しながらやって」 [ぐれ★]
- 京都競馬4回6日目マイルチャンピオンシップ
- 他サポ 2025-265
- 2025 SUPER FORMULA Lap21 【歩夢、伝説へ】
- 【DAZN】フォーミュラGP【F1 2 3 SF P】Lap1809
- とらせん 2
- 札幌実況
- 高市早苗、イタリアのメローニ首相に突然抱き着く...飲みィのやりィの濃密接触レズ営業外交成功か🤗💕 [856698234]
- 【悲報】Twitter、登録国を表示できる機能を追加し大炎上 [347751896]
- 勤労感謝🙏の日のちゅちょ👶り放題スレ🏡
- 【悲報】「みいちゃんと山田さん」とうとう一流紙に名指しで批判される [811796219]
- スキンシップ高市、G20でメローニ氏とハグ🌱 [399259198]
- 【悲報】暇空「カルピス軍団はVPN使って暴れてる」→自分が使ってたことが判明 [268718286]
