パスワードを忘れた? アカウント作成
この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。

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

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

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

      修正してやったゾ


      int main() {
              extern const int a;
              int *b;
              b = (int*) &a;
              *b = 1; /*この行が実行されない*/
      }

      https://godbolt.org/z/9pJHBg [godbolt.org]

      親コメント
      • by Anonymous Coward on 2019年09月28日 18時58分 (#3692966)

        みんなが知りたいのは、

        int main() {
          const int foo = 1;
          *((int*) (&foo)) = 2;
          return foo;
        }

        が1を返すのか、2を返すのか、アクセス違反で死ぬのか、だと思うけど。

        https://godbolt.org/z/tqNafV [godbolt.org]
        によるとどのバージョンでも、clangでは1でgccは2らしいんで、今更な気がする。クロスコンパイルができないのは、やっぱ仕様的にも未定義ってことじゃない?

        規格的にはconstついてるとromに入れる動作はアリ(つまり、上の組み込み屋さんのは規格通り)らしいんで、確かにconstを取るキャストは失敗してもいいんだと思う。

        親コメント
        • by Anonymous Coward

          お、テストコードがわかりやすくなった。

        • by Anonymous Coward

          それ、foo と *((int*) (&foo)) を clang が同じオブジェクトと認識できてないだけ。

        • by Anonymous Coward

          https://godbolt.org/z/tqNafV [godbolt.org]
          によるとどのバージョンでも、clangでは1でgccは2らしいんで、今更な気がする。

          え? 何言ってんのこの人
          https://godbolt.org/z/hWHeyF [godbolt.org]

          • by Anonymous Coward

            gccは8.1から-Oつけると1になるね

      • by Anonymous Coward

        https://godbolt.org/z/9pJHBg [godbolt.org]
        ありがとう。
        久しぶりにアセンブリみたよ

      • by Anonymous Coward

        こうすると書き換えない?

        __attribute__((noinline)) void sub01(int *b) { *b = 1; }
        int main() {
                extern const int a;
                int *b;
                b = (int*) &a;
                sub01(b);
        }

        インライン有無で挙動が違うということ?

        • by Anonymous Coward

          非インライン(というかexternなスコープ)だと、sub01(int *b)のbがReadOnlyな保証が無くなるからコードを削除するわけにはいかないということでは?

          • by Anonymous Coward

            __attribute__((noinline)) を削除すると、インライン展開されて、ReadOnlyな保証が有効になって、
            *b = 1;が実行されない

            すなわち、インライン展開の有無で動作が変わってしまうってことがいいたいの。
            (https://godbolt.org/z/9pJHBg で確認)

      • by Anonymous Coward

        そもそも、プログラマが意図してそのようなコードを書く理由は何。
        マイコン系でコンパイルをすると、固定値はROM内に持ってかれたりするわけでいきなりスタック上には展開しない。
        そんなハードウェア条件では処理に失敗しないか。

        # プログラムメモリに置かれるコードなんかは、しらんがつか、どんな裏技なんだ。

吾輩はリファレンスである。名前はまだ無い -- perlの中の人

処理中...