Skip to content

[Bug] 型をまたぐ静的フィールドの初期化の環が、診断なく本文が触れる順に依存した値を捨てる #249

Open

Description

@routersys

領域

シェーダーのHLSLへの変換

パッケージの版数

ComputeWeave 2.6.0(既定ブランチの a8245449、v2.6.0 のタグと同じ木)の生成器に PR #243 の枝(5cce9d1f)を重ねた木で測りました。PR #243 の歩きは同じ型の中の順序だけを見るので、この形は既定ブランチでも同じです。

診断ID

無し。

期待した挙動

外の型が2つあり、それぞれの静的フィールドの初期化子が相手の型を読む形は、断られること。C# は型の静的初期化子を、その型が最初に触れられたときに走らせるので、この形の値は本文がどちらの型を先に触れるかで変わります。生成HLSLは取り込みが終わった順で1つの値を計算するので、片方の順にしか一致しません。

実際の挙動

診断なく通り、本文が後ろの型を先に触れる形では C# と違う値を計算します。

値 C#(本文が B を先に触れる) C#(本文が A を先に触れる) 生成HLSL
A.X 1 11 11
B.Y 10 10 10

C# の列はコンソールで走らせて読み、生成HLSLの列は生成物と同じ並びの手書きの HLSL を同梱の DXC(1.7.2308.7)と SDK 10.0.26100.0 の FXC へ当てて格納される値を読みました。実機では読んでいません。

再現手順

using ComputeWeave;

namespace Shaders;

internal static class A
{
    public static readonly float W = 5.0f;

    public static readonly float X = B.Y + 1;
}

internal static class B
{
    public static readonly float Y = A.W * 2;
}

[ThreadGroupSize(DefaultThreadGroupSizes.X)]
[GeneratedComputeShaderDescriptor]
internal readonly partial struct Shader : IComputeShader
{
    private readonly ReadWriteBuffer<float> buffer;

    public void Execute()
    {
        this.buffer[0] = B.Y;
        this.buffer[1] = A.X;
    }
}

C# では本文が B.Y を先に触れるので B の初期化子が走り、A.W を読んだ時点で A の初期化子が走ります。そこで A.X が B.Y を読みますが、B の初期化はまだ途中で Y は既定値の 0 なので、A.X は 1 です。生成HLSLは取り込みが終わった順に並び、B.Y が初期化された後に A.X が読むので 11 になります。

static const float Shaders_A_W = 5.0;

static const float Shaders_B_Y = Shaders_A_W * 2;

static const float Shaders_A_X = Shaders_B_Y + 1;

切り分け

どちらの型にも、同じ型の後ろのフィールドを読む形はありません。PR #243 の歩きは、初期化子ごとにその型の順番がまだ来ていないフィールドの読み書きを報告するもので、この形では A.X の歩きが B.Y の初期化子へ入って A.W を読みますが、W は X より前なので報告しません。型をまたぐ環は、型の初期化がどちらから始まるかという別の軸です。

本文が A.X を先に触れる形では C# も 11 を計算し、生成HLSLと一致します。生成HLSLは本文の順を見ず、取り込みが終わった順で1つの並びを選びます。

何を保証すべきか

C# の値が本文の触れる順で変わる形は、生成HLSLが1つの順を選ぶ以上、写せません。取り込んだ型の初期化子が互いの型へ届く環は断るのが筋です。断る位置は、環を閉じる側の読みです。

測っていないこと

実機の値。Direct2D 側。3つ以上の型で閉じる環。

デバイス

統合GPU

アダプターとドライバー

Intel(R) Iris(R) Xe Graphics, 32.0.101.7085

Windowsの版数

Windows 11 Pro 24H2, 26200

.NET SDKの版数

10.0.400

デバッグレイヤーの出力

No response

その他

PR #243 の自己再評価で、歩きの模型「他の型の初期化子は、その型が最初に触れられたときに走る」の裏を取る中で見つけました。同じ型の中の順序(課題 #239、#240、#245)とは別の族なので、別の課題にします。

提出の前に

  • 最新の公開版を使っています。
  • 既存の課題を検索し、重複でないことを確認しました。
  • 独自の ID3D12MemoryAllocator を設定していないことを確認しました。

Activity

  1. added
    bugSomething isn't working / 不具合が起きている
    analyzer or generatorAnalyzer or generator / アナライザーまたはジェネレーター
    on Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    analyzer or generatorAnalyzer or generator / アナライザーまたはジェネレーターbugSomething isn't working / 不具合が起きている

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions