Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[project-vvm-async-api] ZSTにポインタキャストして提供するのをやめる #512

Conversation

qryxip
Copy link
Member

@qryxip qryxip commented Jun 7, 2023

内容

現在project-vvm-async-apiではVoicevoxSynthesizerなどの型はZST(Zero Sized Type)として.hに載せ、Rust側ではポインタのキャストを行っているという状態になっています。これをやめ、repr(Rust)にしてポインタのキャストをやめます。

さらにこれによりC側に提供される型は正しくopaqueになり、

-typedef struct VoicevoxSynthesizer {
-
-} VoicevoxSynthesizer;
+typedef struct VoicevoxSynthesizer VoicevoxSynthesizer;

次のコードのコンパイルは拒否されるようになります。

sizeof(VoicevoxSynthesizer)
std::alignment_of<VoicevoxSynthesizer>()
VoicevoxSynthesizer *ptr;
++ptr;

以下はこのPRを作るのを決断した理由です:

  • ZSTにポインタキャストするのはC→Rustのときでは?

    そもそもqwertyさんが何故ZSTにわざわざポインタのキャストをしていたのですが、RustではCの型をRustに持って来るときに1861-extern-typesの代用としてZSTを使うという慣習があり、私が思うにおそらくそれに則ったのではないでしょうか。

    しかしRustの型をCに提供する際にはそのようなことはしなくていいはずです。Rust側はRustで定義された型のレイアウトは当然知っていいはずだし、C側に対しても上記のようにレイアウトは完全に隠蔽できます。

  • *const (impl Sized)/*mut (impl Sized)はFFI-safeであるはず

    *const T/*mut TをC側に提供するときに、T#[repr(C)]にする必要はないと思います。

    cbindgenを作っている人達もそう考えているはずだし、 shepmaster氏(Stack OverflowのRustの質問への回答で頻繁に見るカービィアイコンの人)が書いたThe Rust FFI Omnibusでも普通にrepr(Rust)な型のポインタをC側に提供しています。

  • C++ではZSTは許容されない

    次のコードはCでは0となり、C++では1となります。
    (ちなみにGCCやLLVMではCでもsizeof(void) == 1です)

    size_t size_of_zst() {
      typedef struct {} Zst;
      return sizeof(Zst);
    }

関連 Issue

その他

Copy link
Member

@Hiroshiba Hiroshiba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!!

全然よくわかっていませんが、できあがるheaderはきれいなので良いのかなと思いました!

*const T/*mut TをC側に提供するときに、Tを#[repr(C)]にする必要はないと思います。

repr(C)で構造体のメモリ構造?をCと合わせられるんですね。
構造体の定義もC側に提供する場合はC側から構造体のメンバーを正しく見れる必要がありそうなので、repr(C)が必要に思いました。(cbindgenが定義も提供することができるのか不明ですが)
今回はそうじゃないので良さそう!

@Hiroshiba
Copy link
Member

たぶん問題ないと思うのでマージします!

@Hiroshiba Hiroshiba merged commit 2e58dcd into VOICEVOX:project-vvm-async-api Jun 9, 2023
@qryxip qryxip mentioned this pull request Jun 10, 2023
67 tasks
@qryxip qryxip mentioned this pull request Jul 22, 2023
69 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants