OpenShadingLanguage icon indicating copy to clipboard operation
OpenShadingLanguage copied to clipboard

Unexpected behavior of unsized array defaults

Open dal opened this issue 7 months ago • 0 comments

Consider the following shader, in particular the declaration of the unsized array param:

shader test(int param[] = {})
{
    printf("array length %d\n", arraylength(param));
}

When running this in testshade, it prints:

array length 1

I think most people would reasonably expect that the {} in the declaration would produce a default array of length zero for param, so the resulting array with a single entry is surprising.

If a shader writer authored a for loop, for example, that did something for each value of an input array, e.g.:

shader test(int param[] = {})
{
    for (int i=0; i < arraylength(param), i++) {
        doStuff(param[i]);
    }
}

They might be surprised that their shader is executing doStuff() even when nothing is connected to param. In practice, however, we have worked around this behavior by guarding the for loop behind something like isconnected(param).

The peculiar behavior of unsized arrays makes sense, however, when considering that it's impossible to declare a fixed size array of length zero in OSL. Therefore, the best fix for this issue might be little more than adding a disclaimer in the section of the OSL language spec describing unsized array defaults.

As a footnote, we stumbled on this issue because we have a unit test that verifies the default input parameters of a set of C++ shaders and OSL shaders match, in order to prevent code drift. oslinfo always returned defaults of arrays of length one for the OSL shaders with unsized array parameters while our C++ shader parser produced zero-length arrays.

dal avatar Apr 01 '25 21:04 dal