パスワードを忘れた? アカウント作成
14012353 story
プログラミング

LLVM、定数として宣言されたメモリ領域への代入を削除する最適化を導入 160

ストーリー by hylom
そんな使い方があるのか 部門より

LLVM 9.0では、定数として宣言されたメモリ領域への代入については「実行されないコード」と判定して削除するような振る舞いになったという(リリースノート@shafikyaghmour氏のTweet@shyouhei氏のTweet)。

これは、たとえばC/C++で「const」キーワード付きで宣言された変数をキャストを使って非constなものとして扱った際などに発生しうる。この結果、LLVMでコンパイルした際に今まで発生していなかった不具合が生じる可能性があるようだ。

  • by Anonymous Coward on 2019年09月28日 8時20分 (#3692670)

    その結果定数メモリへの書き込みが発生するのがバグ

    ここに返信
    • by Anonymous Coward on 2019年09月28日 8時43分 (#3692675)

      組み込みやってるとconst領域はROMに確保されるのが当たり前だったのでconst付シンボルの中身を書き換えてるソース見て何だこりゃ?って思ったっけ。
      (そのソースをそのまま組み込み機に移植したら動かなくなったのを思い出した)

      #それを相性問題で片づけたのはうちの上司
      #(Windowsプログラマ部隊より立場弱くて、更に「実績のあるソースだからそのまま使え」の通達付きだった)

      • by Anonymous Coward

        組み込みで使われがちなbusyboxもこのバグを踏んでいたというのがなんとも

      • by Anonymous Coward

        >const領域はROMに確保されるのが当たり前
        それをリンカに指定するまでが組み込みプログラマの責任
        セクションて知ってる?
        (方言でセグメントと言うかもしれん)
        それにしてもすごい会社だなそこ

        • by Anonymous Coward

          ところで、定数が定数であることはだれの責任なんでしょう?

          当時とった解決策(既設ソースは変更不可のため)。
          RAMが無駄に余裕があったので、全セクションをROMに配置したのち
          起動時にROM領域を全部RAMにコピーしてジャンプする疑似ブートローダーのバイナリ作って
          ビルド済みライブラリとしてROMイメージにくっつけた。

          #要はPC(Windows)と同じくconstも初期値付き変数も、全部RAM上ならいいんでしょ。となった。
          #後にGPIOの空き端子にジャンパピンが追加され、新旧2種類のROMイメージから起動できるようになった。
          #当然最初の要求仕様にはない追加仕様で泣きつかれた結果である

      • by Anonymous Coward

        ポインタ経由すればconst付きで宣言した変数の書換だってできますからね。
        まあROMに書き込見たいときとか値を固定したいときはdefine使えと。

    • by Anonymous Coward

      constはその領域が定数メモリ(ROM)である事を宣言するものではないので
      キャストの結果書き込みが発生しても、それはプログラマが書いた通りの挙動。

      例えばBIOS ROMがFlash Memoryだとして、普段は読み出し前提でconstを付けてるけど
      BIOS更新用の関数内だけはあえて非constにして書き換えを出来るようにしたとして
      それはバグでもなんでもないわけです。

      # そんな書き方をしたソースじゃ後でメンテで死ぬ、という話は別問題

    • by Anonymous Coward

      C++のconstはオブジェクトの定数性を示すものであって、定数ではない(ことにできる)。
      すくなくともクラスのインスタンスは。(ref. mutable)
      たとえばキャッシュを内蔵したクラスで使ってるのを見たことがある。

    • by Anonymous Coward

      非修飾型へのポインタを修飾型へのポインタにキャストするのは許容されているが、逆は未定義動作だろ

  • by Anonymous Coward on 2019年09月28日 9時00分 (#3692680)

    どういったコードを想定してるの?
    void main() {
        const int a;
        int *b;
        b = (int*) &a;
        *b = 1; /*この行が実行されない*/
    }
    て感じ?

    ここに返信
  • by Anonymous Coward on 2019年09月28日 9時41分 (#3692704)

    この話が邪悪なのはコンパイル時に無警告なこと。
    普通は未使用変数があったくらいでも警告するのに、未実行で警告しないとか頭おかしい。
    これが正規動作で修正されないなら LLVM 捨てるのが正解。

    ここに返信
    • by Anonymous Coward

      オープンソースのプロジェクトなんだからさ、
      要望があったらissue作るなりMLでリクエストするなりしたら?

      • by Anonymous Coward on 2019年09月28日 10時59分 (#3692729)

        当然、要望は既に出てる。
        警告どころか、実行不可能な文があるならコンパイル・エラーで止めるのが正しい気がする。
        トラブルのわかっていて事前に対応しなかった開発者の見識が疑われる案件。

        • by Anonymous Coward

          要望ってどれ?

        • by Anonymous Coward

          開発者の見識が疑われるって誰か自分以外の偉い人が対応するのが当然てか?
          こういうこと書くやつの見識こそ疑われるよ

      • by Anonymous Coward

        詳しい経緯聞いてからだろ。てか経緯教えろください

    • by Anonymous Coward

      たとえばぬるぽに書き込むコードに置き換えてくれる方が親切ではあるかもしれないわな。

    • by Anonymous Coward

      捨てるまではいかないが、検出できるのなら警告してくれるとありがたい

  • by Anonymous Coward on 2019年09月28日 8時11分 (#3692667)

    理解できない振る舞いされるかもしれないから、不用意にconst使うなってルールが増えそうだね

    ここに返信
  • これまでとの互換性を保つようなコンパイルオプションとか用意されてないのか?

    ここに返信
    • 定数領域をいじるなんて未定義動作なんだから、普通にソース直せばいいだけ

      ソースがいじれないほど保守的な案件なのに、コンパイラは最新バージョンのLLVMに上げろって奇妙な指示があるなら別だが

      • by Anonymous Coward

        理想を事も無げに言うだけじゃ、何も言ってないのと同じだわな

        • by Anonymous Coward

          ソース直すのが理想なわけ?
          あんたんとこでは新しいコンパイラで顕在化したバグは直さないの?

          • by Anonymous Coward

            ソース直すのが理想なわけ?
            あんたんとこでは新しいコンパイラで顕在化したバグは直さないの?

            頭でっかち派とどろどろ現場動かないと意味無い派の熱い戦いですね。
            理想と現実とどっちをとるかは人による。

        • by Anonymous Coward

          ソース直すか今使ってるコンパイラを使いつづけるのって、
          業務用途の開発でも普通に選べる選択肢なんじゃねーの?

          当たり前すぎて「何も言ってないのと同じ」ってならまだわかるが、
          「理想」って、そんな手の届かない世界のことみたいに聞こえるのか…。
          なんつーか、まぁ頑張れや。

        • by Anonymous Coward

          理想を事も無げに言うだけじゃ、何も言ってないのと同じだわな

          未定義の動作に期待しておいて何を言ってるんだか。。。

    • by Anonymous Coward

      LLVMってAppleの資金とかApple信者とかが大量に入ってそうだから、
      いつもの独善的なApple様の行動を鑑みるに、ないのではなかろうか(偏見)

      • by Anonymous Coward

        「頭悪そう」とか「自分に都合のいいことしか聞こえないのね」とか言われない?

      • by Anonymous Coward

        正しさの名の下に独善的な行為をしそうなのってGooglerの印象がある。
        Appleは自社の得にならない事はやらんでしょ。

  • by Anonymous Coward on 2019年09月28日 9時42分 (#3692706)

    そもそも C++ には const_cast なるものがあるんだけど、
    それはどうするつもりなんだろうか。

    ここに返信
    • by Anonymous Coward

      型抽出メタの糖衣みたいなもんで強制mutable変換てわけじゃないやん

  • by Anonymous Coward on 2019年09月28日 10時10分 (#3692721)

    いきなりわけわからんTweet [twitter.com]が飛び出してきてびびった。
    だったらどうしてC++のキャストは、static_cast、dynamic_cast、reinterpret_cast
    そしてconstを外すだけのconst_castに分けられたんだ?
    C形式のキャストだと何の為のキャストなのか見分けがつかないからだろ?

    そしてconstをconst &にするconst_castなんて、かのBoostですら当たり前のように使われてる。違法でも何でもない。
    テメーの中のマイルールを勝手に世間一般の常識にみたいに語るなよ。

    $ grep '#define BOOST_VERSION ' /usr/include/boost/version.hpp
    #define BOOST_VERSION 107100
     
    $ grep -r const_cast /usr/include/boost/* |wc -l
    771

    ここに返信
    • by Anonymous Coward on 2019年09月28日 10時48分 (#3692728)

      そのTweetはC++でなくてCだからね。
      JISのC (C99相当)を読んでみたけど、修飾版へ変換してよいとは書いてあるけど、
      逆は書いてないみたいだった。
      C++は外せるけど。

      const&についてだけど、C++11で確認したところ、constオブジェクトの領域は
      確保する必要がないと書いてある。ただし参照されたときはそのように振る舞う
      必要がある。

      言語仕様を語る人は多いけど、規格票を確認する人は少ないみたい。
      しかしJISもいいかげん改定してくれないかね。

      • by Anonymous Coward

        そのTweetはC++でなくてCだからね。
        JISのC (C99相当)を読んでみたけど、修飾版へ変換してよいとは書いてあるけど、
        逆は書いてないみたいだった。
        C++は外せるけど。

        C++ だと外せるんだ?
        https://godbolt.org/z/YagQXH [godbolt.org]
        https://godbolt.org/z/9pJHBg [godbolt.org]

        • by Anonymous Coward

          const修飾は外せるよ。
          理解しにくい文章だったかなあ?

          constオブジェクトの領域うんぬんは誤読だったかもしれん。
          まあ、自分で規格を読んでみて。

  • by Anonymous Coward on 2019年09月28日 11時34分 (#3692746)

    指摘がそれなりにいろいろでるんだろうけど

    UB的な類いで、サイレントに最適化で処理が消える系はいろいろあるので、そんなもんかなあ

    という気分にはなる
    # 良いかどうか微妙だけど、まあしょうがないかなあ

    ここに返信
  • by Anonymous Coward on 2019年09月28日 11時34分 (#3692747)

    .data セクションや .text セクションへの代入はできない、ってこれまで通りのことで、heap や stack にある const 変数は、const を外して代入しても OK じゃないの?

    ここに返信
    • by Anonymous Coward on 2019年09月28日 14時40分 (#3692850)

      そもそもC/C++の規格はハードやOS等から独立して書かれてるわけで、
      ROMだの何とかセクションだのセグメンテーションフォルトだのが規格に出てくるわけはなくて
      そういうものに依存するような動作は未定義・処理系定義でどうなろうと自己責任てもんじゃないかと

typodupeerror

普通のやつらの下を行け -- バッドノウハウ専門家

読み込み中...