There are various math functions which currently return a second value via a pointer given in the argument list. For example:
gentype fract (gentype x, gentype *iptr)
gentype sincos (gentype x, gentype *cosval)
A common use for sincos might be the construction of rotated unit vectors, where it would be useful to write:
float a;
vec2 v;
v = sincos(a);
Unfortunately with sincos in it’s current form it’s impossible to do this without a temporary variable, as taking the address of a vector component is illegal.
//This is illegal
vec2 v;
float a;
v.x = sincos(a, &v.y);
// So it has to be this
float t;
v.x = sincos(a, &t);
v.y = t;
This is just one use case though, and having (for example) sincos return a vec2 would stop the following
float16 a;
float16 sina, cosa;
sina = sincos(a, &cosa);
The problem here is that the function is really trying to return two values, and C has the limitation that it only has a single return value. It could return a struct, but that would need the definition of a struct for every function that wanted to do this, including all overloaded versions. Language such as Python solved this by using n-ples (n element tuples) and I think the would be a good addition to the OpenCL language. The result would be code like this:
float a1;
vec2 v;
(v.x, v.y) = sincos(a1);
float16 a2, sina, cosa;
(sina, cosa) = sincos(a2);
//Dummy definition of sincos to show function definition
(gentype, gentype) sincos(gentype angle) {
return (sin(a), cos(a));
}
In some ways this can be thought of as an anonymous struct. Maybe normal brackets are the wrong thing to use to group n-ples, as I think that return statement might already have a meaning, but that’s just syntax. Adding this would make code nicer to read, and has the advantage that it’s obvious to the compiler that the variable ‘cosa’ in the above example is being overwritten, meaning any previous value does not need to be preserved making some optimisations possible.
Any comments?