ufcpp / UfcppSample

http://ufcpp.net/ 向けのサンプル
Apache License 2.0
134 stars 40 forks source link

引数無コンストラクタ #378

Closed iwkjosec closed 2 years ago

iwkjosec commented 2 years ago

引数無しコンストラクタが入ったのでこの説明は変える必要がありそうです。 (引数無しコンストラクタを定義している場合new T()が規定値とは限らない) (引数無しコンストラクタでもすべてのメンバーを初期化しないとコンパイルエラー)

変更後のコード↓

using System;
using System.Runtime.InteropServices;

class Program
{
    static void Main()
    {
        // 16 MB
        var points = new Vector4[1024 * 1024];

        // 中身が全部 0 なことを確認してみる
        // 無理やり byte 配列扱いして、1 byte ずつ確認
        var bytes = MemoryMarshal.AsBytes<Vector4>(points);

        foreach (var v in bytes)
        {
            if (v != 0)
                Console.WriteLine("絶対通らないはず");
        }
    }
}

struct Vector4
{
    public float X, Y, Z, W;

    // C# 10.0 では、引数なしのコンストラクターが定義できるようになったけど、これは配列初期化時には呼ばれない。
    // 配列初期化時には、コンストラクターで初期化するんじゃなくて機械的に 0 埋め
    public Vector4()
    {
        Console.WriteLine("配列初期化では呼ばれない");
        (X, Y, Z, W) = (1, 1, 1, 1);
    }
}
ufcpp commented 2 years ago

C# 11 で「コンストラクター内で全てのメンバーをきっちり自分の手で初期化する必要があります」の前提も覆りそうなのでまとめて… 関連: https://github.com/ufcpp/UfcppSample/issues/393 https://github.com/ufcpp/UfcppSample/issues/353

ufcpp commented 2 years ago

配列が0初期かさてるのの確認コードは以下のものにしました。 「default(T) は引数なしコンストラクターすら無視して0埋め」という話は別途書きます。

using System.Runtime.InteropServices;

// 16 MB の巨大領域。
// 要素1個1個は初期化していないので、全部に既定値が入ってる。
var points = new Vector4[1024 * 1024];

// 中身が全部 0 なことを確認してみる。
// (無理やり byte 配列扱いして、1 byte ずつ確認。)
var bytes = MemoryMarshal.AsBytes<Vector4>(points);

foreach (var v in bytes)
{
    if (v != 0)
        Console.WriteLine("絶対通らないはず");
}

struct Vector4
{
    public float X, Y, Z, W;
}
ufcpp commented 2 years ago

修正。