世界を動かす技術を、日本語で。

Cの出所メモリモデル

概要

  • C言語 における ポインタの由来(provenance) に基づく新しいメモリモデルの紹介
  • ISO/IEC TS6010 として国際標準化された技術仕様の意義
  • ポインタエイリアス解析 が最適化と安全性に与える影響
  • エイリアス解析の課題と、 provenance model による解決策
  • 最適化機会とバグ回避のための 実践的指針

C言語のためのProvenance Memory Model

  • Kayvan Memarian (Cambridge)、 Peter Sewell (Cambridge)、 Martin Uecker (Graz)、 Jens Gustedt (ICube/Inria)らによる 長年の共同研究
  • C言語コミュニティ が合意した pointer provenance (ポインタの由来)という概念の導入
  • プログラム実行中に ポインタ値の起源追跡 を数学的に厳密に定義
  • 曖昧だった従来の C標準 の仕様を補完する技術仕様(ISO/IEC TS6010
  • C/C++/Rust/コンパイラ 分野での議論や実装の指針

ポインタエイリアスとプログラム最適化

  • ポインタpとqが同じメモリオブジェクトを指す場合、「エイリアス」 と呼ぶ

  • エイリアスの有無は プログラム最適化 に直接影響

  • 例:逆数近似関数(recip)では、2つのポインタ引数が

    • 異なるオブジェクト を指す場合
    • 同じオブジェクト を指す場合
  • 最適化版recip(recip⁺)は、 エイリアスがない前提 でのみ安全に動作

    • ローカル変数への読み出し・書き込みの最適化 が可能
  • エイリアスの可能性がある限り、コンパイラは大胆な最適化を自動で適用できない

    • メモリアクセスの最適化が制限
    • 本質的に異なるアルゴリズム となるリスク
  • エイリアス解析 は、どのポインタが同一オブジェクトを指すかを静的に解析する技術

    • 誤った仮定 による最適化は、バグや未定義動作の原因

    • 現代のコンパイラ における最重要解析の一つ

Provenance Modelの意義と標準化

  • ISO/IEC TS6010 による公式な技術仕様化
    • Henry Kleynhans (Bloomberg)編集
  • 情報システムの安全性・セキュリティ向上 を目的とした指針
  • ポインタの由来 に基づく一貫したメモリモデルの普及
  • 業界全体でのプラットフォーム・ツールの収束 を促進

実践的な指針とまとめ

  • エイリアスの意図を明確に

    • 同じオブジェクトを指す可能性がある場合、 仕様や実装で明示
  • restrict修飾子 など、コンパイラにヒントを与える手法の活用

  • provenance model の理解と活用による、最適化機会の最大化とバグ回避

  • プログラムの可読性・保守性 の向上

    • 安全で効率的なCプログラム設計 への道筋

Hackerたちの意見

Cは今、Unicode識別子を許可してるの?それともこれは擬似コード?コードスニペットには&も含まれてるから、HTMLへの変換で何かがうまくいかなかったみたい。

cppreferenceからの引用: 「識別子は、桁、アンダースコア、小文字と大文字のラテン文字、そしてUnicode文字の任意の長いシーケンスで、\uおよび\Uエスケープ表記を使って指定される(C99以降)、クラスXID_Continue(C23以降)。有効な識別子は、数字以外の文字(ラテン文字、アンダースコア、またはUnicodeの数字以外の文字(C99以降)(C23まで)、またはクラスXID_StartのUnicode文字(C23以降))で始まらなければならない。識別子は大文字と小文字を区別する(小文字と大文字は異なる)。すべての識別子は正規化形式Cに準拠しなければならない(C23以降)。実際にはコンパイラに依存する。」

投稿が見れないんだけど、ページがJSONみたいな内容管理システムのようになってて、白地にピンクで表示されてる。めっちゃ混乱してる。:| あなたの質問への答えは(まだ)「いいえ」みたいだね。

C23に関する兄弟コメントの他にも、GCCではちゃんと動くよ。https://godbolt.org/z/qKejzc1Kb 一方、clangは大きな声で文句を言ってるね、https://godbolt.org/z/qWrccWzYW

C99までは実装依存だったけど、C99以降はUCNsを使えば明示的に可能になったし、C23からは明示的なエンコーディングで可能になったけど、リテラルはまだ実装依存なんだよね。

おそらくこれはマークダウンか何かから変換されたもので、変換が部分的に失敗したか、入力が壊れてるね。PVIセクション以降はなんとか復旧してるけど、もし著者がこれを見てたら、投稿を修正して再変換してほしいな。編集したけど、いや、もっと後の方にもエラーがある。投稿する前にちゃんと校正が必要だったと思う。自分はこのトピックを知ってるからなんとか理解できるけど、新しい人に紹介するつもりだったら、かなり混乱するだろうね。

問題は、WordPressがどこかを編集するとこれらの設定が変わっちゃうことだよ。多分、全部再生成することになると思う。

コードブロックが正しく閉じられてないみたい、これより前のフレーズ: > 関数 reciprecip⁺ は同等ではない その後の数段落がコードブロックに飲み込まれちゃった。編集: あ、この記事が「Modern C」の著者によるものだって気づかなかった。いろんなところでおすすめされてるのを見たことある。 > Modern CのC23版は、今、無料でダウンロードできるよ https://hal.inria.fr/hal-02383654

いい本だよ。最新の版じゃなくて、第二版の方が好きかな。いわゆる「肥大化したC」はちょっと苦手。

コードサンプルを見た瞬間、ジェンだってすぐに分かったよ。

コードブロックがちゃんと閉じてないみたいだね。今は修正されたみたい。

これを見てる人には、最近統合されたLLVMの型ベースエイリアシングサニタイザーTySanも興味深いかもね: https://clang.llvm.org/docs/TypeSanitizer.html https://www.phoronix.com/news/LLVM-Merge-TySan-Type-Sanitize...

Hacker Newsで議論の続きを見る