shader-slang / slang

Making it easier to work with shaders
MIT License
1.78k stars 159 forks source link

Initializers example in the Slang User Guide does not compile. #4461

Open tomas-davidovic opened 4 days ago

tomas-davidovic commented 4 days ago

I've been hunting down some unexpected behavior, and in the process found that the example from https://shader-slang.com/slang/user-guide/convenience-features.html#initializers won't even compile for me:

The code is:

RWStructuredBuffer<uint> output;
struct MyType
{
    int myVal;
    __init(int a, int b)
    {
        myVal = a + b;
    }
}

[numthreads(16, 1, 1)]
void testInitializers(uint3 threadID: SV_DispatchThreadID)
{
    if (threadID.x != 0)
        return;

   MyType instance = {1, 2};
   output[0] = instance.myVal;
}

the error is:

D:\Projects\Falcor\Source\Tools\FalcorTest\Tests\Slang\InitializerTestsSimple.cs.slang(100): error 30500: too many initializers (expected 1, got 2)
        MyType instance = {1, 2};

The behavior seems to be that, contrary to the text in the guide You may also use C++ style initializer list to invoke a constructor it does not invoke the constructor, but instead does the C-style member initialization. So instead of calling __init(int a, int b) it is trying to initialize the first two members of the struct to values 1 and 2 and since the struct has only one member, it errors out.

This also explains why Test test; has a different behavior from Test test = {} and Test test = Test(1) has a different behavior from Test test = {1}. I don't know if the intent is to call __init() and it is the codegen that needs a fix, or if the intent is to do this C style struct initialization, in which case the guide/docs needs a fix.

In the latter case also please specify what happens when the initializer list is shorter than the number of member variables. I know that if the variable is in the form int foo = 3; then it gets initialized to 3 with the Test test ={};, but I don't know if it gets default initialized to any specific value if it is just int foo;.

ArielG-NV commented 4 days ago

This is likely a bug from how it looks. This task is related to a planned initializer list rework: #3406