3

From the OpenGL Wiki page on "Data Type (GLSL)", I found a pretty broad statement about initializer lists.

...Therefore, GLSL takes a feature from C++11 and allows the initialization of any type by using an initializer list. An initializer list is a list of initializers (which themselves could be initializer lists) that are used to initialize a variable. Initializer lists are bounded by curly braces ("{" and "}").

Initializer lists do not require specifying the type name; the compiler will deduce it correctly. And this deduction extends down the hierarchy of objects in aggregates (structs/arrays). For example, the above code could be initialized with the following initializer list:

Data dataArray[3] = { {...}, ... }

I have tried a number of variations on initializer lists, and I'm not convinced.

# version 330
vec4 by_return(void) { return {1.0}; } // unexpected '{', expecting "::"
vec4 by_decl(void) { vec4 x = {1}; return x; } // too little data in initialization

Okay, initializer lists are not equivalent to constructors of the deduced type, e.g. vec4(1.0)...

vec4 by_decl(void) { vec4 x = {1,0,0,0}; return x; }
// OpenGL does not allow C style initializers

...but it's moot. Just in case "any type" was more broad than intended, I made sure to try a variant where a struct should be deduced in an outer initializer list, and another with an explicit constructor but arguments given as initializer lists:

struct Dual { vec4 u, v; }
Dual struct_outer(void) { return {vec4(1,0,0,0), vec4(0,0,0,0)}; } // unexpected '{', expecting "::"
Dual struct_inner(void) { return Dual({1,0,0,0}, {0,0,0,0}); } // unexpected '{', expecting "::"

Contrast that result with the next few lines of the Wiki:

The compiler automatically deduces that the second element of each Data member is an vec2. This is based on the definition of Data.

Finally, arrays should be no different from structs, so this should come as no surprise:

vec4[2] as_array(void) { return {{1,0,0,0},{0,0,0,0}}; } // unexpected '{', expecting "::"
vec4[2] as_array2(void) { vec4 x[2] = {{1,0,0,0},{0,0,0,0}}; return x; }
//    OpenGL does not allow C style initializers
vec4[2] as_array3(void) { return {vec4(1), vec4(1)}; } // unexpected '{', expecting "::"
vec4[2] as_array4(void) { return vec4[2]{vec4(1), vec4(1)}; } // unexpected '{', expecting "::"
vec4[2] as_array5(void) { vec4[2] x; x[0] = {1,0,0,0}; x[1] = {0,0,0,0}; return x; } // unexpected '{', expecting "::"

From everything I've seen so far, it looks the compiler is capable of parsing a "C style initializer", but only in assignment, and for the sole purpose of rejecting it more explicitly.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
John P
  • 1,463
  • 3
  • 19
  • 39

1 Answers1

4

Initializer lists are a later addition to OpenGL. The Wiki notes off to the side that this feature is "core since version 4.2". I made sure to include my #version 330 statement because I was so sure that initializer lists were an earlier addition than GL 3.3, and I didn't even question that until the moment I was about to submit the question. Lesson learned, I think.

John P
  • 1,463
  • 3
  • 19
  • 39